Skip to content

Commit

Permalink
Make Session.chdir() a context manager
Browse files Browse the repository at this point in the history
Author:    Author: Tolker-KU <55140581+Tolker-KU@users.noreply.github.com>
  • Loading branch information
cjolowicz authored and Tolker-KU committed Dec 27, 2021
1 parent fcaafa1 commit 87c0386
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
35 changes: 32 additions & 3 deletions nox/sessions.py
Expand Up @@ -21,6 +21,7 @@
import sys
import unicodedata
import warnings
from types import TracebackType
from typing import (
Any,
Callable,
Expand All @@ -31,6 +32,7 @@
Optional,
Sequence,
Tuple,
Type,
Union,
)

Expand Down Expand Up @@ -210,10 +212,37 @@ def invoked_from(self) -> str:
"""
return self._runner.global_config.invoked_from

def chdir(self, dir: Union[str, os.PathLike]) -> None:
"""Change the current working directory."""
class _WorkingDirContext:
def __init__(self, dir: Union[str, os.PathLike]) -> None:
self._prev_working_dir = os.getcwd()
os.chdir(dir)

def __enter__(self) -> "Session._WorkingDirContext":
return self

def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_value: Optional[BaseException],
traceback: Optional[TracebackType],
) -> None:
os.chdir(self._prev_working_dir)

def chdir(self, dir: Union[str, os.PathLike]) -> "Session._WorkingDirContext":
"""Change the current working directory.
Can be used as a context manager to automatically restore the working directory::
with session.chdir("somewhere/deep/in/monorepo"):
# Runs in "/somewhere/deep/in/monorepo"
session.run("pytest")
# Runs in original working directory
session.run("flake8")
"""
self.log(f"cd {dir}")
os.chdir(dir)
return Session._WorkingDirContext(dir)

cd = chdir
"""An alias for :meth:`chdir`."""
Expand Down
13 changes: 13 additions & 0 deletions tests/test_sessions.py
Expand Up @@ -164,6 +164,19 @@ def test_chdir(self, tmpdir):
assert os.getcwd() == cdto
os.chdir(current_cwd)

def test_chdir_ctx(self, tmpdir):
cdto = str(tmpdir.join("cdbby").ensure(dir=True))
current_cwd = os.getcwd()

session, _ = self.make_session_and_runner()

with session.chdir(cdto):
assert os.getcwd() == cdto

assert os.getcwd() == current_cwd

os.chdir(current_cwd)

def test_invoked_from(self, tmpdir):
cdto = str(tmpdir.join("cdbby").ensure(dir=True))
current_cwd = os.getcwd()
Expand Down

0 comments on commit 87c0386

Please sign in to comment.