Skip to content

Commit

Permalink
Handle AttributeError triggered by modules without __module__ attribute
Browse files Browse the repository at this point in the history
- fixes #460
  • Loading branch information
mrbean-bremen committed Dec 19, 2018
1 parent 7214609 commit d1d7be2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ The release versions are PyPi releases.
* fixed `AttributeError` shown while displaying `fs` in a failing pytest
in Python 2
* fixed permission handling for root user
* avoid `AttributeError` triggered by modules without `__module__` attribute
(see [#460](../../issues/460))

## [Version 3.5.3](https://pypi.python.org/pypi/pyfakefs/3.5.3)

Expand Down
35 changes: 26 additions & 9 deletions pyfakefs/fake_filesystem_unittest.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,30 @@ def _find_modules(self):
Later, `setUp()` will stub these with the fake file system
modules.
"""

def is_fs_module(mod, name):
try:
return (inspect.ismodule(mod) and
mod.__name__ in module_names
or inspect.isclass(mod) and
mod.__module__ in self._class_modules.get(name, []))
except AttributeError:
# handle cases where the module has no __name__ or __module__
# attribute - see #460
return False

def is_fs_function(fct):
try:
return ((inspect.isfunction(fct) or
inspect.isbuiltin(fct)) and
fct.__name__ in self._fake_module_functions and
fct.__module__ in self._fake_module_functions[
fct.__name__])
except AttributeError:
# handle cases where the function has no __name__ or __module__
# attribute
return False

module_names = list(self._fake_module_classes.keys()) + [PATH_MODULE]
for name, module in set(sys.modules.items()):
try:
Expand All @@ -446,20 +470,13 @@ def _find_modules(self):
continue

modules = {name: mod for name, mod in module.__dict__.items()
if inspect.ismodule(mod) and
mod.__name__ in module_names
or inspect.isclass(mod) and
mod.__module__ in self._class_modules.get(name, [])}
if is_fs_module(mod, name)}
for name, mod in modules.items():
self._modules.setdefault(name, set()).add((module,
mod.__name__))

functions = {name: fct for name, fct in module.__dict__.items()
if (inspect.isfunction(fct) or
inspect.isbuiltin(fct)) and
fct.__name__ in self._fake_module_functions and
fct.__module__ in self._fake_module_functions[
fct.__name__]}
if is_fs_function(fct)}
for name, fct in functions.items():
self._fct_modules.setdefault(
(name, fct.__name__, fct.__module__), set()).add(module)
Expand Down

0 comments on commit d1d7be2

Please sign in to comment.