Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
6
venv/Lib/site-packages/testpath/__init__.py
Normal file
6
venv/Lib/site-packages/testpath/__init__.py
Normal file
|
@ -0,0 +1,6 @@
|
|||
"""Test utilities for code working with files and commands"""
|
||||
from .asserts import *
|
||||
from .env import temporary_env, modified_env, make_env_restorer
|
||||
from .commands import MockCommand, assert_calls
|
||||
|
||||
__version__ = '0.4.4'
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
venv/Lib/site-packages/testpath/__pycache__/env.cpython-36.pyc
Normal file
BIN
venv/Lib/site-packages/testpath/__pycache__/env.cpython-36.pyc
Normal file
Binary file not shown.
Binary file not shown.
199
venv/Lib/site-packages/testpath/asserts.py
Normal file
199
venv/Lib/site-packages/testpath/asserts.py
Normal file
|
@ -0,0 +1,199 @@
|
|||
import os
|
||||
import stat
|
||||
|
||||
try:
|
||||
from pathlib import Path
|
||||
except ImportError:
|
||||
try:
|
||||
# Python 2 backport
|
||||
from pathlib2 import Path
|
||||
except ImportError:
|
||||
class Path(object):
|
||||
"""Dummy for isinstance checks"""
|
||||
pass
|
||||
|
||||
|
||||
__all__ = ['assert_path_exists', 'assert_not_path_exists',
|
||||
'assert_isfile', 'assert_not_isfile',
|
||||
'assert_isdir', 'assert_not_isdir',
|
||||
'assert_islink', 'assert_not_islink',
|
||||
'assert_ispipe', 'assert_not_ispipe',
|
||||
'assert_issocket', 'assert_not_issocket',
|
||||
]
|
||||
|
||||
|
||||
if hasattr(os, 'fspath'):
|
||||
_strpath = os.fspath
|
||||
else:
|
||||
def _strpath(p):
|
||||
if hasattr(p, '__fspath__'):
|
||||
return p.__fspath__()
|
||||
elif isinstance(p, Path):
|
||||
return str(p)
|
||||
return p
|
||||
|
||||
def _stat_for_assert(path, follow_symlinks=True, msg=None):
|
||||
stat = os.stat if follow_symlinks else os.lstat
|
||||
try:
|
||||
return stat(path)
|
||||
except OSError:
|
||||
if msg is None:
|
||||
msg = "Path does not exist, or can't be stat-ed: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_path_exists(path, msg=None):
|
||||
"""Assert that something exists at the given path.
|
||||
"""
|
||||
_stat_for_assert(_strpath(path), True, msg)
|
||||
|
||||
def assert_not_path_exists(path, msg=None):
|
||||
"""Assert that nothing exists at the given path.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
if os.path.exists(path):
|
||||
if msg is None:
|
||||
msg = "Path exists: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_isfile(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists and is a regular file.
|
||||
|
||||
With follow_symlinks=True, the default, this will pass if path is a symlink
|
||||
to a regular file. With follow_symlinks=False, it will fail in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if not stat.S_ISREG(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path exists, but is not a regular file: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_not_isfile(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists but is not a regular file.
|
||||
|
||||
With follow_symlinks=True, the default, this will fail if path is a symlink
|
||||
to a regular file. With follow_symlinks=False, it will pass in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if stat.S_ISREG(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path is a regular file: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_isdir(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists and is a directory.
|
||||
|
||||
With follow_symlinks=True, the default, this will pass if path is a symlink
|
||||
to a directory. With follow_symlinks=False, it will fail in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if not stat.S_ISDIR(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path exists, but is not a directory: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_not_isdir(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists but is not a directory.
|
||||
|
||||
With follow_symlinks=True, the default, this will fail if path is a symlink
|
||||
to a directory. With follow_symlinks=False, it will pass in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if stat.S_ISDIR(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path is a directory: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
_link_target_msg = """Symlink target of:
|
||||
{path}
|
||||
Expected:
|
||||
{expected}
|
||||
Actual:
|
||||
{actual}
|
||||
"""
|
||||
|
||||
def assert_islink(path, to=None, msg=None):
|
||||
"""Assert that path exists and is a symlink.
|
||||
|
||||
If to is specified, also check that it is the target of the symlink.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, False, msg)
|
||||
if not stat.S_ISLNK(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path exists, but is not a symlink: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
if to is not None:
|
||||
to = _strpath(to)
|
||||
target = os.readlink(path)
|
||||
# TODO: Normalise the target to an absolute path?
|
||||
if target != to:
|
||||
if msg is None:
|
||||
msg = _link_target_msg.format(path=path, expected=to, actual=target)
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_not_islink(path, msg=None):
|
||||
"""Assert that path exists but is not a symlink.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, False, msg)
|
||||
if stat.S_ISLNK(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path is a symlink: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_ispipe(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists and is a named pipe (FIFO).
|
||||
|
||||
With follow_symlinks=True, the default, this will pass if path is a symlink
|
||||
to a named pipe. With follow_symlinks=False, it will fail in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if not stat.S_ISFIFO(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path exists, but is not a named pipe: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_not_ispipe(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists but is not a named pipe (FIFO).
|
||||
|
||||
With follow_symlinks=True, the default, this will fail if path is a symlink
|
||||
to a named pipe. With follow_symlinks=False, it will pass in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if stat.S_ISFIFO(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path is a named pipe: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_issocket(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists and is a Unix domain socket.
|
||||
|
||||
With follow_symlinks=True, the default, this will pass if path is a symlink
|
||||
to a Unix domain socket. With follow_symlinks=False, it will fail in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if not stat.S_ISSOCK(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path exists, but is not a socket: %r" % path
|
||||
raise AssertionError(msg)
|
||||
|
||||
def assert_not_issocket(path, follow_symlinks=True, msg=None):
|
||||
"""Assert that path exists but is not a Unix domain socket.
|
||||
|
||||
With follow_symlinks=True, the default, this will fail if path is a symlink
|
||||
to a Unix domain socket. With follow_symlinks=False, it will pass in that case.
|
||||
"""
|
||||
path = _strpath(path)
|
||||
st = _stat_for_assert(path, follow_symlinks, msg)
|
||||
if stat.S_ISSOCK(st.st_mode):
|
||||
if msg is None:
|
||||
msg = "Path is a socket: %r" % path
|
||||
raise AssertionError(msg)
|
BIN
venv/Lib/site-packages/testpath/cli-32.exe
Normal file
BIN
venv/Lib/site-packages/testpath/cli-32.exe
Normal file
Binary file not shown.
BIN
venv/Lib/site-packages/testpath/cli-64.exe
Normal file
BIN
venv/Lib/site-packages/testpath/cli-64.exe
Normal file
Binary file not shown.
150
venv/Lib/site-packages/testpath/commands.py
Normal file
150
venv/Lib/site-packages/testpath/commands.py
Normal file
|
@ -0,0 +1,150 @@
|
|||
import contextlib
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
__all__ = ['MockCommand', 'assert_calls']
|
||||
|
||||
pkgdir = os.path.dirname(__file__)
|
||||
|
||||
recording_dir = None
|
||||
|
||||
def prepend_to_path(dir):
|
||||
os.environ['PATH'] = dir + os.pathsep + os.environ['PATH']
|
||||
|
||||
def remove_from_path(dir):
|
||||
path_dirs = os.environ['PATH'].split(os.pathsep)
|
||||
path_dirs.remove(dir)
|
||||
os.environ['PATH'] = os.pathsep.join(path_dirs)
|
||||
|
||||
|
||||
_record_run = """#!{python}
|
||||
import os, sys
|
||||
import json
|
||||
|
||||
with open({recording_file!r}, 'a') as f:
|
||||
json.dump({{'env': dict(os.environ),
|
||||
'argv': sys.argv,
|
||||
'cwd': os.getcwd()}},
|
||||
f)
|
||||
f.write('\\x1e') # ASCII record separator
|
||||
"""
|
||||
|
||||
# TODO: Overlapping calls to the same command may interleave writes.
|
||||
|
||||
class MockCommand(object):
|
||||
"""Context manager to mock a system command.
|
||||
|
||||
The mock command will be written to a directory at the front of $PATH,
|
||||
taking precedence over any existing command with the same name.
|
||||
|
||||
By specifying content as a string, you can determine what running the
|
||||
command will do. The default content records each time the command is
|
||||
called and exits: you can access these records with mockcmd.get_calls().
|
||||
|
||||
On Windows, the specified content will be run by the Python interpreter in
|
||||
use. On Unix, it should start with a shebang (``#!/path/to/interpreter``).
|
||||
"""
|
||||
def __init__(self, name, content=None):
|
||||
global recording_dir
|
||||
self.name = name
|
||||
self.content = content
|
||||
|
||||
if recording_dir is None:
|
||||
recording_dir = tempfile.mkdtemp()
|
||||
fd, self.recording_file = tempfile.mkstemp(dir=recording_dir,
|
||||
prefix=name, suffix='.json')
|
||||
os.close(fd)
|
||||
self.command_dir = tempfile.mkdtemp()
|
||||
|
||||
def _copy_exe(self):
|
||||
bitness = '64' if (sys.maxsize > 2**32) else '32'
|
||||
src = os.path.join(pkgdir, 'cli-%s.exe' % bitness)
|
||||
dst = os.path.join(self.command_dir, self.name+'.exe')
|
||||
shutil.copy(src, dst)
|
||||
|
||||
@property
|
||||
def _cmd_path(self):
|
||||
# Can only be used once commands_dir has been set
|
||||
p = os.path.join(self.command_dir, self.name)
|
||||
if os.name == 'nt':
|
||||
p += '-script.py'
|
||||
return p
|
||||
|
||||
def __enter__(self):
|
||||
if os.path.isfile(self._cmd_path):
|
||||
raise EnvironmentError("Command %r already exists at %s" %
|
||||
(self.name, self._cmd_path))
|
||||
|
||||
if self.content is None:
|
||||
self.content = _record_run.format(python=sys.executable,
|
||||
recording_file=self.recording_file)
|
||||
|
||||
with open(self._cmd_path, 'w') as f:
|
||||
f.write(self.content)
|
||||
|
||||
if os.name == 'nt':
|
||||
self._copy_exe()
|
||||
else:
|
||||
os.chmod(self._cmd_path, 0o755) # Set executable bit
|
||||
|
||||
prepend_to_path(self.command_dir)
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, etype, evalue, tb):
|
||||
remove_from_path(self.command_dir)
|
||||
shutil.rmtree(self.command_dir, ignore_errors=True)
|
||||
|
||||
def get_calls(self):
|
||||
"""Get a list of calls made to this mocked command.
|
||||
|
||||
This relies on the default script content, so it will return an
|
||||
empty list if you specified a different content parameter.
|
||||
|
||||
For each time the command was run, the list will contain a dictionary
|
||||
with keys argv, env and cwd.
|
||||
"""
|
||||
if recording_dir is None:
|
||||
return []
|
||||
if not os.path.isfile(self.recording_file):
|
||||
return []
|
||||
|
||||
with open(self.recording_file, 'r') as f:
|
||||
# 1E is ASCII record separator, last chunk is empty
|
||||
chunks = f.read().split('\x1e')[:-1]
|
||||
|
||||
return [json.loads(c) for c in chunks]
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def assert_calls(cmd, args=None):
|
||||
"""Assert that a block of code runs the given command.
|
||||
|
||||
If args is passed, also check that it was called at least once with the
|
||||
given arguments (not including the command name).
|
||||
|
||||
Use as a context manager, e.g.::
|
||||
|
||||
with assert_calls('git'):
|
||||
some_function_wrapping_git()
|
||||
|
||||
with assert_calls('git', ['add', myfile]):
|
||||
some_other_function()
|
||||
"""
|
||||
with MockCommand(cmd) as mc:
|
||||
yield
|
||||
|
||||
calls = mc.get_calls()
|
||||
assert calls != [], "Command %r was not called" % cmd
|
||||
|
||||
if args is not None:
|
||||
if not any(args == c['argv'][1:] for c in calls):
|
||||
msg = ["Command %r was not called with specified args (%r)" %
|
||||
(cmd, args),
|
||||
"It was called with these arguments: "]
|
||||
for c in calls:
|
||||
msg.append(' %r' % c['argv'][1:])
|
||||
raise AssertionError('\n'.join(msg))
|
83
venv/Lib/site-packages/testpath/env.py
Normal file
83
venv/Lib/site-packages/testpath/env.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
import contextlib
|
||||
import os
|
||||
|
||||
@contextlib.contextmanager
|
||||
def temporary_env(newenv):
|
||||
"""Completely replace the environment variables with the specified dict.
|
||||
|
||||
Use as a context manager::
|
||||
|
||||
with temporary_env({'PATH': my_path}):
|
||||
...
|
||||
"""
|
||||
orig_env = os.environ.copy()
|
||||
os.environ.clear()
|
||||
os.environ.update(newenv)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
os.environ.clear()
|
||||
os.environ.update(orig_env)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def modified_env(changes, snapshot=True):
|
||||
"""Temporarily modify environment variables.
|
||||
|
||||
Specify the changes as a dictionary mapping names to new values, using
|
||||
None as the value for names that should be deleted.
|
||||
|
||||
Example use::
|
||||
|
||||
with modified_env({'SHELL': 'bash', 'PYTHONPATH': None}):
|
||||
...
|
||||
|
||||
When the context exits, there are two possible ways to restore the
|
||||
environment. If *snapshot* is True, the default, it will reset the whole
|
||||
environment to its state when the context was entered. If *snapshot* is
|
||||
False, it will restore only the specific variables it modified, leaving
|
||||
any changes made to other environment variables in the context.
|
||||
"""
|
||||
def update_del(changes):
|
||||
for k, v in changes.items():
|
||||
if v is None:
|
||||
os.environ.pop(k, None)
|
||||
else:
|
||||
os.environ[k] = v
|
||||
|
||||
if snapshot:
|
||||
saved_variables = os.environ.copy()
|
||||
else:
|
||||
saved_variables = {}
|
||||
for k,v in changes.items():
|
||||
saved_variables[k] = os.environ.get(k, None)
|
||||
|
||||
update_del(changes)
|
||||
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if snapshot:
|
||||
os.environ.clear()
|
||||
os.environ.update(saved_variables)
|
||||
else:
|
||||
update_del(saved_variables)
|
||||
|
||||
def make_env_restorer():
|
||||
"""Snapshot the current environment, return a function to restore that.
|
||||
|
||||
This is intended to produce cleanup functions for tests. For example,
|
||||
using the :class:`unittest.TestCase` API::
|
||||
|
||||
def setUp(self):
|
||||
self.addCleanup(testpath.make_env_restorer())
|
||||
|
||||
Any changes a test makes to the environment variables will be wiped out
|
||||
before the next test is run.
|
||||
"""
|
||||
orig_env = os.environ.copy()
|
||||
|
||||
def restore():
|
||||
os.environ.clear()
|
||||
os.environ.update(orig_env)
|
||||
|
||||
return restore
|
154
venv/Lib/site-packages/testpath/tempdir.py
Normal file
154
venv/Lib/site-packages/testpath/tempdir.py
Normal file
|
@ -0,0 +1,154 @@
|
|||
"""TemporaryDirectory class, copied from Python 3
|
||||
|
||||
NamedFileInTemporaryDirectory and TemporaryWorkingDirectory from IPython, which
|
||||
uses the 3-clause BSD license.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os as _os
|
||||
import warnings as _warnings
|
||||
import sys as _sys
|
||||
|
||||
# This code should only be used in Python versions < 3.2, since after that we
|
||||
# can rely on the stdlib itself.
|
||||
try:
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
except ImportError:
|
||||
from tempfile import mkdtemp, template
|
||||
|
||||
class TemporaryDirectory(object):
|
||||
"""Create and return a temporary directory. This has the same
|
||||
behavior as mkdtemp but can be used as a context manager. For
|
||||
example:
|
||||
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
...
|
||||
|
||||
Upon exiting the context, the directory and everything contained
|
||||
in it are removed.
|
||||
"""
|
||||
|
||||
def __init__(self, suffix="", prefix=template, dir=None):
|
||||
self.name = mkdtemp(suffix, prefix, dir)
|
||||
self._closed = False
|
||||
|
||||
def __enter__(self):
|
||||
return self.name
|
||||
|
||||
def cleanup(self, _warn=False):
|
||||
if self.name and not self._closed:
|
||||
try:
|
||||
self._rmtree(self.name)
|
||||
except (TypeError, AttributeError) as ex:
|
||||
# Issue #10188: Emit a warning on stderr
|
||||
# if the directory could not be cleaned
|
||||
# up due to missing globals
|
||||
if "None" not in str(ex):
|
||||
raise
|
||||
print("ERROR: {!r} while cleaning up {!r}".format(ex, self,),
|
||||
file=_sys.stderr)
|
||||
return
|
||||
self._closed = True
|
||||
if _warn:
|
||||
self._warn("Implicitly cleaning up {!r}".format(self),
|
||||
Warning)
|
||||
|
||||
def __exit__(self, exc, value, tb):
|
||||
self.cleanup()
|
||||
|
||||
def __del__(self):
|
||||
# Issue a ResourceWarning if implicit cleanup needed
|
||||
self.cleanup(_warn=True)
|
||||
|
||||
|
||||
# XXX (ncoghlan): The following code attempts to make
|
||||
# this class tolerant of the module nulling out process
|
||||
# that happens during CPython interpreter shutdown
|
||||
# Alas, it doesn't actually manage it. See issue #10188
|
||||
_listdir = staticmethod(_os.listdir)
|
||||
_path_join = staticmethod(_os.path.join)
|
||||
_isdir = staticmethod(_os.path.isdir)
|
||||
_remove = staticmethod(_os.remove)
|
||||
_rmdir = staticmethod(_os.rmdir)
|
||||
_os_error = _os.error
|
||||
_warn = _warnings.warn
|
||||
|
||||
def _rmtree(self, path):
|
||||
# Essentially a stripped down version of shutil.rmtree. We can't
|
||||
# use globals because they may be None'ed out at shutdown.
|
||||
for name in self._listdir(path):
|
||||
fullname = self._path_join(path, name)
|
||||
try:
|
||||
isdir = self._isdir(fullname)
|
||||
except self._os_error:
|
||||
isdir = False
|
||||
if isdir:
|
||||
self._rmtree(fullname)
|
||||
else:
|
||||
try:
|
||||
self._remove(fullname)
|
||||
except self._os_error:
|
||||
pass
|
||||
try:
|
||||
self._rmdir(path)
|
||||
except self._os_error:
|
||||
pass
|
||||
|
||||
|
||||
class NamedFileInTemporaryDirectory(object):
|
||||
"""Open a file named `filename` in a temporary directory.
|
||||
|
||||
This context manager is preferred over :class:`tempfile.NamedTemporaryFile`
|
||||
when one needs to reopen the file, because on Windows only one handle on a
|
||||
file can be open at a time. You can close the returned handle explicitly
|
||||
inside the context without deleting the file, and the context manager will
|
||||
delete the whole directory when it exits.
|
||||
|
||||
Arguments `mode` and `bufsize` are passed to `open`.
|
||||
Rest of the arguments are passed to `TemporaryDirectory`.
|
||||
|
||||
Usage example::
|
||||
|
||||
with NamedFileInTemporaryDirectory('myfile', 'wb') as f:
|
||||
f.write('stuff')
|
||||
f.close()
|
||||
# You can now pass f.name to things that will re-open the file
|
||||
"""
|
||||
def __init__(self, filename, mode='w+b', bufsize=-1, **kwds):
|
||||
self._tmpdir = TemporaryDirectory(**kwds)
|
||||
path = _os.path.join(self._tmpdir.name, filename)
|
||||
self.file = open(path, mode, bufsize)
|
||||
|
||||
def cleanup(self):
|
||||
self.file.close()
|
||||
self._tmpdir.cleanup()
|
||||
|
||||
__del__ = cleanup
|
||||
|
||||
def __enter__(self):
|
||||
return self.file
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.cleanup()
|
||||
|
||||
|
||||
class TemporaryWorkingDirectory(TemporaryDirectory):
|
||||
"""
|
||||
Creates a temporary directory and sets the cwd to that directory.
|
||||
Automatically reverts to previous cwd upon cleanup.
|
||||
|
||||
Usage example::
|
||||
|
||||
with TemporaryWorkingDirectory() as tmpdir:
|
||||
...
|
||||
"""
|
||||
def __enter__(self):
|
||||
self.old_wd = _os.getcwd()
|
||||
_os.chdir(self.name)
|
||||
return super(TemporaryWorkingDirectory, self).__enter__()
|
||||
|
||||
def __exit__(self, exc, value, tb):
|
||||
_os.chdir(self.old_wd)
|
||||
return super(TemporaryWorkingDirectory, self).__exit__(exc, value, tb)
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue