Skip to content

Commit

Permalink
Unload all modules loaded during the test
Browse files Browse the repository at this point in the history
- these module can still hold references to fake modules
- modules already loaded at test start are not affected
- see pytest-dev#501 and pytest-dev#427
  • Loading branch information
mrbean-bremen committed Nov 15, 2019
1 parent 4309b65 commit ba38ced
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
6 changes: 3 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ the proposed changes so you can be ready.

### Fixes
* fixed side effect of calling `DirEntry.stat()` under Windows (changed
st_nlink) ([#502](../../issues/502))
* fixed a problem related to patching `distutils` functions
([#501](../../issues/501))
st_nlink) (see [#502](../../issues/502))
* fixed problem of fake modules still referenced after a test in modules
loaded during the test (see [#501](../../issues/501) and [#427](../../issues/427))
* correctly handle missing read permission for parent directory
(see [#496](../../issues/496))
* raise for `os.scandir` with non-existing directory
Expand Down
17 changes: 11 additions & 6 deletions pyfakefs/fake_filesystem_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,11 @@
import tempfile
import unittest
import warnings
import zipfile # noqa: F401 make sure it gets correctly stubbed, see #427
import distutils.file_util # noqa: F401 same reason - see #501

from pyfakefs.deprecator import Deprecator
from pyfakefs.fake_filesystem import set_uid, set_gid, reset_ids

from pyfakefs.helpers import IS_PY2, IS_PYPY

from pyfakefs.deprecator import Deprecator

try:
from importlib.machinery import ModuleSpec
except ImportError:
Expand Down Expand Up @@ -643,14 +639,15 @@ def __exit__(self, *args):

class DynamicPatcher(object):
"""A file loader that replaces file system related modules by their
fake implementation if they are loaded after calling `setupPyFakefs()`.
fake implementation if they are loaded after calling `setUpPyfakefs()`.
Implements the protocol needed for import hooks.
"""

def __init__(self, patcher):
self._patcher = patcher
self.sysmodules = {}
self.modules = self._patcher.fake_modules
self._loaded_module_names = set()

# remove all modules that have to be patched from `sys.modules`,
# otherwise the find_... methods will not be called
Expand All @@ -668,10 +665,18 @@ def cleanup(self):
for module in self._patcher.modules_to_reload:
if module.__name__ in sys.modules:
reload(module)
reloaded_module_names = [module.__name__
for module in self._patcher.modules_to_reload]
# force all modules loaded during the test to reload on next use,
# to ensure that no faked modules are still hold in these modules
for name in self._loaded_module_names:
if name in sys.modules and name not in reloaded_module_names:
del sys.modules[name]

def needs_patch(self, name):
"""Check if the module with the given name shall be replaced."""
if name not in self.modules:
self._loaded_module_names.add(name)
return False
if (name in sys.modules and
type(sys.modules[name]) == self.modules[name]):
Expand Down
2 changes: 1 addition & 1 deletion pyfakefs/tests/dynamic_patch_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# limitations under the License.

"""
Tests for patching modules loaded after `setupPyfakefs()`.
Tests for patching modules loaded after `setUpPyfakefs()`.
"""
import sys
import unittest
Expand Down

0 comments on commit ba38ced

Please sign in to comment.