From 4c64297518972bc175ad79868af1ab52f42c86c9 Mon Sep 17 00:00:00 2001
From: mrbean-bremen <hansemrbean@googlemail.com>
Date: Fri, 22 Jul 2022 20:53:29 +0200
Subject: [PATCH] Revert some performance optimizations

- have been made in version 3.3.0,
  apparently cause hanging tests with torch import
- no performance degradation detected
- see #693
---
 CHANGES.md                           |  6 +++++
 pyfakefs/fake_filesystem_unittest.py | 36 +++++++++++-----------------
 2 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index b4e4e6e9..84bad43e 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,12 @@
 # pyfakefs Release Notes
 The released versions correspond to PyPi releases.
 
+## Unreleased
+
+### Fixes
+* reverted a performance optimization introduced in version 3.3.0 that
+  caused hanging tests with installed torch (see [#693](../../issues/693))
+
 ## [Version 4.6.3](https://pypi.python.org/pypi/pyfakefs/4.6.3) (2022-07-20)
 Another patch release that fixes a regression in version 4.6.
 
diff --git a/pyfakefs/fake_filesystem_unittest.py b/pyfakefs/fake_filesystem_unittest.py
index 2b7a2bf0..389a8841 100644
--- a/pyfakefs/fake_filesystem_unittest.py
+++ b/pyfakefs/fake_filesystem_unittest.py
@@ -605,34 +605,26 @@ def _is_fs_module(self, mod: ModuleType,
                       name: str,
                       module_names: List[str]) -> bool:
         try:
-            # check for __name__ first and ignore the AttributeException
-            # if it does not exist - avoids calling expansive ismodule
-            if mod.__name__ in module_names and inspect.ismodule(mod):
-                return True
+            return (inspect.ismodule(mod) and
+                    mod.__name__ in module_names
+                    or inspect.isclass(mod) and
+                    mod.__module__ in self._class_modules.get(name, []))
         except Exception:
-            pass
-        try:
-            if (name in self._class_modules and
-                    mod.__module__ in self._class_modules[name]):
-                return inspect.isclass(mod)
-        except Exception:
-            # handle AttributeError and any other exception possibly triggered
-            # by side effects of inspect methods
-            pass
-        return False
+            # handle cases where the module has no __name__ or __module__
+            # attribute - see #460, and any other exception triggered
+            # by inspect functions
+            return False
 
     def _is_fs_function(self, fct: FunctionType) -> bool:
         try:
-            # check for __name__ first and ignore the AttributeException
-            # if it does not exist - avoids calling expansive inspect
-            # methods in most cases
-            return (fct.__name__ in self._fake_module_functions and
+            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__] and
-                    (inspect.isfunction(fct) or inspect.isbuiltin(fct)))
+                        fct.__name__])
         except Exception:
-            # handle AttributeError and any other exception possibly triggered
-            # by side effects of inspect methods
+            # handle cases where the function has no __name__ or __module__
+            # attribute, or any other exception in inspect functions
             return False
 
     def _def_values(