Skip to content

Unload all modules loaded during the test #503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
18 changes: 12 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,19 @@ 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]
# Dereference all modules loaded during the test so they will reload on
# the next use, ensuring that no faked modules are referenced after the
# test.
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