Skip to content

Commit d52dfe0

Browse files
committed
Removed the unneeded workarounds for tempfile
- remove special_names argument - use modules_to_reload instead to reload tempfile - fixes #340
1 parent 08f45ff commit d52dfe0

File tree

4 files changed

+25
-56
lines changed

4 files changed

+25
-56
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ must use pyfakefs 3.3 or earlier.
88

99
#### New Features
1010
* Added support to fake out backported `scandir` module ([#332](../../issues/332))
11+
* Dynamic loading of modules after setup is now on by default and no more considered experimental (see [#340](../../issues/340)).
1112

1213
#### Infrastructure
1314
* Changed API to be PEP-8 conform [#186](../../issues/186). Note: The old API is still available.

pyfakefs/fake_filesystem_unittest.py

+14-52
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585

8686
def load_doctests(loader, tests, ignore, module,
8787
additional_skip_names=None,
88-
patch_path=True, special_names=None): # pylint: disable=unused-argument
88+
patch_path=True): # pylint: disable=unused-argument
8989
"""Load the doctest tests for the specified module into unittest.
9090
Args:
9191
loader, tests, ignore : arguments passed in from `load_tests()`
@@ -96,7 +96,7 @@ def load_doctests(loader, tests, ignore, module,
9696
File `example_test.py` in the pyfakefs release provides a usage example.
9797
"""
9898
_patcher = Patcher(additional_skip_names=additional_skip_names,
99-
patch_path=patch_path, special_names=special_names)
99+
patch_path=patch_path)
100100
globs = _patcher.replace_globs(vars(module))
101101
tests.addTests(doctest.DocTestSuite(module,
102102
globs=globs,
@@ -111,7 +111,7 @@ class TestCase(unittest.TestCase):
111111
"""
112112

113113
def __init__(self, methodName='runTest', additional_skip_names=None,
114-
patch_path=True, special_names=None,
114+
patch_path=True,
115115
modules_to_reload=None,
116116
use_dynamic_patch=True):
117117
"""Creates the test class instance and the stubber used to stub out
@@ -129,11 +129,6 @@ def __init__(self, methodName='runTest', additional_skip_names=None,
129129
130130
Irrespective of patch_path, module 'os.path' is still correctly faked
131131
if imported the usual way using `import os` or `import os.path`.
132-
special_names: A dictionary with module names as key and a dictionary as
133-
value, where the key is the original name of the module to be patched,
134-
and the value is the name as it is imported.
135-
This allows to patch modules where some of the file system modules are
136-
imported as another name (e.g. `import os as _os`).
137132
modules_to_reload (experimental): A list of modules that need to be reloaded
138133
to be patched dynamically; may be needed if the module
139134
imports file system modules under an alias
@@ -155,20 +150,13 @@ class MyTestCase(fake_filesystem_unittest.TestCase):
155150
def __init__(self, methodName='runTest'):
156151
super(MyTestCase, self).__init__(
157152
methodName=methodName, additional_skip_names=['posixpath'])
158-
159-
160-
class AnotherTestCase(fake_filesystem_unittest.TestCase):
161-
def __init__(self, methodName='runTest'):
162-
# allow patching a module that imports `os` as `my_os`
163-
special_names = {'amodule': {'os': 'my_os'}}
164-
super(MyTestCase, self).__init__(
165-
methodName=methodName, special_names=special_names)
166153
"""
167154
super(TestCase, self).__init__(methodName)
168155
self._stubber = Patcher(additional_skip_names=additional_skip_names,
169-
patch_path=patch_path,
170-
special_names=special_names)
171-
self._modules_to_reload = modules_to_reload or []
156+
patch_path=patch_path)
157+
self._modules_to_reload = [tempfile]
158+
if modules_to_reload is not None:
159+
self._modules_to_reload.extend(modules_to_reload)
172160
self._use_dynamic_patch = use_dynamic_patch
173161

174162
@property
@@ -223,15 +211,19 @@ def setUpPyfakefs(self):
223211
"""
224212
self._stubber.setUp()
225213
self.addCleanup(self._stubber.tearDown)
214+
dyn_patcher = DynamicPatcher(self._stubber)
215+
sys.meta_path.insert(0, dyn_patcher)
226216

227217
for module in self._modules_to_reload:
228218
if module.__name__ in sys.modules:
229219
reload(module)
220+
230221
if self._use_dynamic_patch:
231-
dyn_patcher = DynamicPatcher(self._stubber)
232-
sys.meta_path.insert(0, dyn_patcher)
233222
self.addCleanup(lambda: sys.meta_path.pop(0))
234223
self.addCleanup(dyn_patcher.cleanup)
224+
else:
225+
dyn_patcher.cleanup()
226+
sys.meta_path.pop(0)
235227

236228
@DeprecationWarning
237229
def tearDownPyfakefs(self):
@@ -268,13 +260,10 @@ class Patcher(object):
268260
if HAS_PATHLIB:
269261
SKIPNAMES.add('pathlib')
270262

271-
def __init__(self, additional_skip_names=None, patch_path=True,
272-
special_names=None):
263+
def __init__(self, additional_skip_names=None, patch_path=True):
273264
"""For a description of the arguments, see TestCase.__init__"""
274265

275266
self._skipNames = self.SKIPNAMES.copy()
276-
self._special_names = special_names or {}
277-
self._special_names['tempfile'] = {'os': '_os', 'io': '_io'}
278267

279268
if additional_skip_names is not None:
280269
self._skipNames.update(additional_skip_names)
@@ -343,12 +332,6 @@ def _find_modules(self):
343332
for name in self._modules:
344333
if inspect.ismodule(module.__dict__.get(name)):
345334
self._modules[name].add((module, name))
346-
if '__name__' in module.__dict__ and module.__name__ in self._special_names:
347-
module_names = self._special_names[module.__name__]
348-
for name in self._modules:
349-
if name in module_names:
350-
if inspect.ismodule(module.__dict__.get(module_names[name])):
351-
self._modules[name].add((module, module_names[name]))
352335

353336
def _refresh(self):
354337
"""Renew the fake file system and set the _isStale flag to `False`."""
@@ -362,29 +345,8 @@ def _refresh(self):
362345
self._fake_modules['path'] = self._fake_modules['os'].path
363346
self.fake_open = fake_filesystem.FakeFileOpen(self.fs)
364347

365-
if not self.IS_WINDOWS and 'tempfile' in sys.modules:
366-
self._patch_tempfile()
367-
368348
self._isStale = False
369349

370-
def _patch_tempfile(self):
371-
"""Hack to work around cached `os` functions in `tempfile`.
372-
Shall be replaced by a more generic mechanism.
373-
"""
374-
if 'unlink' in tempfile._TemporaryFileWrapper.__dict__:
375-
# Python 2.7 to 3.2: unlink is a class method of _TemporaryFileWrapper
376-
tempfile._TemporaryFileWrapper.unlink = self._fake_modules['os'].unlink
377-
378-
# Python 3.0 to 3.2 (and PyPy3 based on Python 3.2):
379-
# `TemporaryDirectory._rmtree` is used instead of `shutil.rmtree`
380-
# which uses several cached os functions - replace it with `shutil.rmtree`
381-
if 'TemporaryDirectory' in tempfile.__dict__:
382-
tempfile.TemporaryDirectory._rmtree = lambda o, path: shutil.rmtree(path)
383-
else:
384-
# Python > 3.2 - unlink is a default parameter of _TemporaryFileCloser
385-
tempfile._TemporaryFileCloser.close.__defaults__ = (
386-
self._fake_modules['os'].unlink,)
387-
388350
def setUp(self, doctester=None):
389351
"""Bind the file-related modules to the :py:mod:`pyfakefs` fake
390352
modules real ones. Also bind the fake `file()` and `open()` functions.

tests/fake_filesystem_shutil_test.py

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
from pyfakefs import fake_filesystem_unittest
2828
from tests.test_utils import RealFsTestMixin
2929

30+
is_windows = sys.platform == 'win32'
31+
3032

3133
class RealFsTestCase(fake_filesystem_unittest.TestCase, RealFsTestMixin):
3234
def __init__(self, methodName='runTest'):
@@ -91,6 +93,7 @@ def test_rmtree_without_permission_for_a_file_in_windows(self):
9193
self.assertTrue(os.path.exists(file_path))
9294
self.os.chmod(file_path, 0o666)
9395

96+
@unittest.skipIf(is_windows, 'Posix specific behavior')
9497
def test_rmtree_without_permission_for_a_dir_in_posix(self):
9598
self.check_posix_only()
9699
dir_path = self.make_path('foo')
@@ -102,6 +105,7 @@ def test_rmtree_without_permission_for_a_dir_in_posix(self):
102105
self.assertTrue(os.path.exists(file_path))
103106
self.os.chmod(dir_path, 0o777)
104107

108+
@unittest.skipIf(is_windows, 'Posix specific behavior')
105109
def test_rmtree_with_open_file_posix(self):
106110
self.check_posix_only()
107111
dir_path = self.make_path('foo')
@@ -405,6 +409,7 @@ def test_raises_if_dest_exists_and_is_not_writable(self):
405409
self.assertRaises(IOError, shutil.copyfile, src_file, dst_file)
406410
os.chmod(dst_file, 0o666)
407411

412+
@unittest.skipIf(is_windows, 'Posix specific behavior')
408413
def test_raises_if_dest_dir_is_not_writable_under_posix(self):
409414
self.check_posix_only()
410415
src_file = self.make_path('xyzzy')
@@ -425,6 +430,7 @@ def test_raises_if_src_doesnt_exist(self):
425430
self.assertFalse(os.path.exists(src_file))
426431
self.assertRaises(IOError, shutil.copyfile, src_file, dst_file)
427432

433+
@unittest.skipIf(is_windows, 'Posix specific behavior')
428434
def test_raises_if_src_not_readable(self):
429435
self.check_posix_only()
430436
src_file = self.make_path('xyzzy')

tests/fake_filesystem_unittest_test.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
from pyfakefs import fake_filesystem_unittest
3131
from pyfakefs.fake_filesystem_unittest import Patcher
32-
from tests.import_as_example import check_if_exists
32+
import tests.import_as_example
3333

3434
if sys.version_info >= (3, 4):
3535
import pathlib
@@ -135,9 +135,9 @@ def test_fakepathlib(self):
135135

136136
class TestImportAsOtherName(fake_filesystem_unittest.TestCase):
137137
def __init__(self, methodName='RunTest'):
138-
special_names = {'tests.import_as_example': {'os': '_os'}}
138+
modules_to_load = [tests.import_as_example]
139139
super(TestImportAsOtherName, self).__init__(methodName,
140-
special_names=special_names)
140+
modules_to_reload=modules_to_load)
141141

142142
def setUp(self):
143143
self.setUpPyfakefs()
@@ -146,7 +146,7 @@ def test_file_exists(self):
146146
file_path = '/foo/bar/baz'
147147
self.fs.create_file(file_path)
148148
self.assertTrue(self.fs.exists(file_path))
149-
self.assertTrue(check_if_exists(file_path))
149+
self.assertTrue(tests.import_as_example.check_if_exists(file_path))
150150

151151

152152
from tests.fixtures import module_with_attributes

0 commit comments

Comments
 (0)