We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Error when importing networkx: "module 'importlib' has no attribute 'machinery'"
When importing networkx, the error `AttributeError: module 'importlib' has no attribute 'machinery'` occurs.

It seems like networkx is not importing `importlib.machinery`.

### Steps to Reproduce
```
$ sudo docker run -it --rm fedora:35
# dnf install -y python3 python3-pip
# pip3 install networkx
# python3 --version
Python 3.10.0rc2
# python3 -c "import importlib; print(dir(importlib))"
['_RELOADING', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__import__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_bootstrap', '_bootstrap_external', '_imp', '_pack_uint32', '_unpack_uint32', 'find_loader', 'import_module', 'invalidate_caches', 'reload', 'sys', 'warnings']
# python3 -c "import networkx"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/local/lib/python3.10/site-packages/networkx/__init__.py", line 59, in <module>
    from networkx import utils
  File "/usr/local/lib/python3.10/site-packages/networkx/utils/__init__.py", line 1, in <module>
    from networkx.utils.misc import *
  File "/usr/local/lib/python3.10/site-packages/networkx/utils/misc.py", line 23, in <module>
    np = nx.lazy_import("numpy")
  File "/usr/local/lib/python3.10/site-packages/networkx/lazy_imports.py", line 138, in lazy_import
    tmp_loader = importlib.machinery.SourceFileLoader(module, path=None)
AttributeError: module 'importlib' has no attribute 'machinery'
# python3 -c "import importlib; import importlib.machinery; import networkx"
```

### Environment
Python version: Python 3.10.0rc2
NetworkX version: networkx-2.7

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `networkx/lazy_imports.py`
Content:
```
1 import importlib
2 import importlib.util
3 import types
4 import os
5 import sys
6 
7 
8 __all__ = ["attach", "lazy_import"]
9 
10 
11 def attach(module_name, submodules=None, submod_attrs=None):
12     """Attach lazily loaded submodules, and functions or other attributes.
13 
14     Typically, modules import submodules and attributes as follows::
15 
16       import mysubmodule
17       import anothersubmodule
18 
19       from .foo import someattr
20 
21     The idea of  this function is to replace the `__init__.py`
22     module's `__getattr__`, `__dir__`, and `__all__` attributes such that
23     all imports work exactly the way they normally would, except that the
24     actual import is delayed until the resulting module object is first used.
25 
26     The typical way to call this function, replacing the above imports, is::
27 
28       __getattr__, __lazy_dir__, __all__ = lazy.attach(
29           __name__,
30           ['mysubmodule', 'anothersubmodule'],
31           {'foo': 'someattr'}
32       )
33 
34     This functionality requires Python 3.7 or higher.
35 
36     Parameters
37     ----------
38     module_name : str
39         Typically use __name__.
40     submodules : set
41         List of submodules to lazily import.
42     submod_attrs : dict
43         Dictionary of submodule -> list of attributes / functions.
44         These attributes are imported as they are used.
45 
46     Returns
47     -------
48     __getattr__, __dir__, __all__
49 
50     """
51     if submod_attrs is None:
52         submod_attrs = {}
53 
54     if submodules is None:
55         submodules = set()
56     else:
57         submodules = set(submodules)
58 
59     attr_to_modules = {
60         attr: mod for mod, attrs in submod_attrs.items() for attr in attrs
61     }
62 
63     __all__ = list(submodules | attr_to_modules.keys())
64 
65     def __getattr__(name):
66         if name in submodules:
67             return importlib.import_module(f"{module_name}.{name}")
68         elif name in attr_to_modules:
69             submod = importlib.import_module(f"{module_name}.{attr_to_modules[name]}")
70             return getattr(submod, name)
71         else:
72             raise AttributeError(f"No {module_name} attribute {name}")
73 
74     def __dir__():
75         return __all__
76 
77     if os.environ.get("EAGER_IMPORT", ""):
78         for attr in set(attr_to_modules.keys()) | submodules:
79             __getattr__(attr)
80 
81     return __getattr__, __dir__, list(__all__)
82 
83 
84 def lazy_import(fullname):
85     """Return a lazily imported proxy for a module or library.
86 
87     We often see the following pattern::
88 
89       def myfunc():
90           import scipy as sp
91           sp.argmin(...)
92           ....
93 
94     This is to prevent a library, in this case `scipy`, from being
95     imported at function definition time, since that can be slow.
96 
97     This function provides a proxy module that, upon access, imports
98     the actual module.  So the idiom equivalent to the above example is::
99 
100       sp = lazy.load("scipy")
101 
102       def myfunc():
103           sp.argmin(...)
104           ....
105 
106     The initial import time is fast because the actual import is delayed
107     until the first attribute is requested. The overall import time may
108     decrease as well for users that don't make use of large portions
109     of the library.
110 
111     Parameters
112     ----------
113     fullname : str
114         The full name of the package or subpackage to import.  For example::
115 
116           sp = lazy.load('scipy')  # import scipy as sp
117           spla = lazy.load('scipy.linalg')  # import scipy.linalg as spla
118 
119     Returns
120     -------
121     pm : importlib.util._LazyModule
122         Proxy module. Can be used like any regularly imported module.
123         Actual loading of the module occurs upon first attribute request.
124 
125     """
126     try:
127         return sys.modules[fullname]
128     except:
129         pass
130 
131     # Not previously loaded -- look it up
132     spec = importlib.util.find_spec(fullname)
133 
134     if spec is None:
135         # module not found - construct a DelayedImportErrorModule
136         spec = importlib.util.spec_from_loader(fullname, loader=None)
137         module = importlib.util.module_from_spec(spec)
138         tmp_loader = importlib.machinery.SourceFileLoader(module, path=None)
139         loader = DelayedImportErrorLoader(tmp_loader)
140         loader.exec_module(module)
141         # dont add to sys.modules. The module wasn't found.
142         return module
143 
144     module = importlib.util.module_from_spec(spec)
145     sys.modules[fullname] = module
146 
147     loader = importlib.util.LazyLoader(spec.loader)
148     loader.exec_module(module)
149 
150     return module
151 
152 
153 class DelayedImportErrorLoader(importlib.util.LazyLoader):
154     def exec_module(self, module):
155         super().exec_module(module)
156         module.__class__ = DelayedImportErrorModule
157 
158 
159 class DelayedImportErrorModule(types.ModuleType):
160     def __getattribute__(self, attr):
161         """Trigger a ModuleNotFoundError upon attribute access"""
162         spec = super().__getattribute__("__spec__")
163         # allows isinstance and type functions to work without raising error
164         if attr in ["__class__"]:
165             return super().__getattribute__("__class__")
166 
167         raise ModuleNotFoundError(
168             f"Delayed Report: module named '{spec.name}' not found.\n"
169             "Reporting was Lazy -- delayed until module attributes accessed.\n"
170             f"Most likely, {spec.name} is not installed"
171         )
172
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/networkx/lazy_imports.py b/networkx/lazy_imports.py
--- a/networkx/lazy_imports.py
+++ b/networkx/lazy_imports.py
@@ -1,5 +1,6 @@
 import importlib
 import importlib.util
+import inspect
 import types
 import os
 import sys
@@ -81,6 +82,24 @@
     return __getattr__, __dir__, list(__all__)
 
 
+class DelayedImportErrorModule(types.ModuleType):
+    def __init__(self, frame_data, *args, **kwargs):
+        self.__frame_data = frame_data
+        super().__init__(*args, **kwargs)
+
+    def __getattr__(self, x):
+        if x in ("__class__", "__file__", "__frame_data"):
+            super().__getattr__(x)
+        else:
+            fd = self.__frame_data
+            raise ModuleNotFoundError(
+                f"No module named '{fd['spec']}'\n\n"
+                "This error is lazily reported, having originally occured in\n"
+                f'  File {fd["filename"]}, line {fd["lineno"]}, in {fd["function"]}\n\n'
+                f'----> {"".join(fd["code_context"]).strip()}'
+            )
+
+
 def lazy_import(fullname):
     """Return a lazily imported proxy for a module or library.
 
@@ -132,14 +151,18 @@
     spec = importlib.util.find_spec(fullname)
 
     if spec is None:
-        # module not found - construct a DelayedImportErrorModule
-        spec = importlib.util.spec_from_loader(fullname, loader=None)
-        module = importlib.util.module_from_spec(spec)
-        tmp_loader = importlib.machinery.SourceFileLoader(module, path=None)
-        loader = DelayedImportErrorLoader(tmp_loader)
-        loader.exec_module(module)
-        # dont add to sys.modules. The module wasn't found.
-        return module
+        try:
+            parent = inspect.stack()[1]
+            frame_data = {
+                "spec": fullname,
+                "filename": parent.filename,
+                "lineno": parent.lineno,
+                "function": parent.function,
+                "code_context": parent.code_context,
+            }
+            return DelayedImportErrorModule(frame_data, "DelayedImportErrorModule")
+        finally:
+            del parent
 
     module = importlib.util.module_from_spec(spec)
     sys.modules[fullname] = module
@@ -148,24 +171,3 @@
     loader.exec_module(module)
 
     return module
-
-
-class DelayedImportErrorLoader(importlib.util.LazyLoader):
-    def exec_module(self, module):
-        super().exec_module(module)
-        module.__class__ = DelayedImportErrorModule
-
-
-class DelayedImportErrorModule(types.ModuleType):
-    def __getattribute__(self, attr):
-        """Trigger a ModuleNotFoundError upon attribute access"""
-        spec = super().__getattribute__("__spec__")
-        # allows isinstance and type functions to work without raising error
-        if attr in ["__class__"]:
-            return super().__getattribute__("__class__")
-
-        raise ModuleNotFoundError(
-            f"Delayed Report: module named '{spec.name}' not found.\n"
-            "Reporting was Lazy -- delayed until module attributes accessed.\n"
-            f"Most likely, {spec.name} is not installed"
-        )

{"golden_diff": "diff --git a/networkx/lazy_imports.py b/networkx/lazy_imports.py\n--- a/networkx/lazy_imports.py\n+++ b/networkx/lazy_imports.py\n@@ -1,5 +1,6 @@\n import importlib\n import importlib.util\n+import inspect\n import types\n import os\n import sys\n@@ -81,6 +82,24 @@\n     return __getattr__, __dir__, list(__all__)\n \n \n+class DelayedImportErrorModule(types.ModuleType):\n+    def __init__(self, frame_data, *args, **kwargs):\n+        self.__frame_data = frame_data\n+        super().__init__(*args, **kwargs)\n+\n+    def __getattr__(self, x):\n+        if x in (\"__class__\", \"__file__\", \"__frame_data\"):\n+            super().__getattr__(x)\n+        else:\n+            fd = self.__frame_data\n+            raise ModuleNotFoundError(\n+                f\"No module named '{fd['spec']}'\\n\\n\"\n+                \"This error is lazily reported, having originally occured in\\n\"\n+                f'  File {fd[\"filename\"]}, line {fd[\"lineno\"]}, in {fd[\"function\"]}\\n\\n'\n+                f'----> {\"\".join(fd[\"code_context\"]).strip()}'\n+            )\n+\n+\n def lazy_import(fullname):\n     \"\"\"Return a lazily imported proxy for a module or library.\n \n@@ -132,14 +151,18 @@\n     spec = importlib.util.find_spec(fullname)\n \n     if spec is None:\n-        # module not found - construct a DelayedImportErrorModule\n-        spec = importlib.util.spec_from_loader(fullname, loader=None)\n-        module = importlib.util.module_from_spec(spec)\n-        tmp_loader = importlib.machinery.SourceFileLoader(module, path=None)\n-        loader = DelayedImportErrorLoader(tmp_loader)\n-        loader.exec_module(module)\n-        # dont add to sys.modules. The module wasn't found.\n-        return module\n+        try:\n+            parent = inspect.stack()[1]\n+            frame_data = {\n+                \"spec\": fullname,\n+                \"filename\": parent.filename,\n+                \"lineno\": parent.lineno,\n+                \"function\": parent.function,\n+                \"code_context\": parent.code_context,\n+            }\n+            return DelayedImportErrorModule(frame_data, \"DelayedImportErrorModule\")\n+        finally:\n+            del parent\n \n     module = importlib.util.module_from_spec(spec)\n     sys.modules[fullname] = module\n@@ -148,24 +171,3 @@\n     loader.exec_module(module)\n \n     return module\n-\n-\n-class DelayedImportErrorLoader(importlib.util.LazyLoader):\n-    def exec_module(self, module):\n-        super().exec_module(module)\n-        module.__class__ = DelayedImportErrorModule\n-\n-\n-class DelayedImportErrorModule(types.ModuleType):\n-    def __getattribute__(self, attr):\n-        \"\"\"Trigger a ModuleNotFoundError upon attribute access\"\"\"\n-        spec = super().__getattribute__(\"__spec__\")\n-        # allows isinstance and type functions to work without raising error\n-        if attr in [\"__class__\"]:\n-            return super().__getattribute__(\"__class__\")\n-\n-        raise ModuleNotFoundError(\n-            f\"Delayed Report: module named '{spec.name}' not found.\\n\"\n-            \"Reporting was Lazy -- delayed until module attributes accessed.\\n\"\n-            f\"Most likely, {spec.name} is not installed\"\n-        )\n", "issue": "Error when importing networkx: \"module 'importlib' has no attribute 'machinery'\"\nWhen importing networkx, the error `AttributeError: module 'importlib' has no attribute 'machinery'` occurs.\r\n\r\nIt seems like networkx is not importing `importlib.machinery`.\r\n\r\n### Steps to Reproduce\r\n```\r\n$ sudo docker run -it --rm fedora:35\r\n# dnf install -y python3 python3-pip\r\n# pip3 install networkx\r\n# python3 --version\r\nPython 3.10.0rc2\r\n# python3 -c \"import importlib; print(dir(importlib))\"\r\n['_RELOADING', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__import__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_bootstrap', '_bootstrap_external', '_imp', '_pack_uint32', '_unpack_uint32', 'find_loader', 'import_module', 'invalidate_caches', 'reload', 'sys', 'warnings']\r\n# python3 -c \"import networkx\"\r\nTraceback (most recent call last):\r\n  File \"<string>\", line 1, in <module>\r\n  File \"/usr/local/lib/python3.10/site-packages/networkx/__init__.py\", line 59, in <module>\r\n    from networkx import utils\r\n  File \"/usr/local/lib/python3.10/site-packages/networkx/utils/__init__.py\", line 1, in <module>\r\n    from networkx.utils.misc import *\r\n  File \"/usr/local/lib/python3.10/site-packages/networkx/utils/misc.py\", line 23, in <module>\r\n    np = nx.lazy_import(\"numpy\")\r\n  File \"/usr/local/lib/python3.10/site-packages/networkx/lazy_imports.py\", line 138, in lazy_import\r\n    tmp_loader = importlib.machinery.SourceFileLoader(module, path=None)\r\nAttributeError: module 'importlib' has no attribute 'machinery'\r\n# python3 -c \"import importlib; import importlib.machinery; import networkx\"\r\n```\r\n\r\n### Environment\r\nPython version: Python 3.10.0rc2\r\nNetworkX version: networkx-2.7\n", "before_files": [{"content": "import importlib\nimport importlib.util\nimport types\nimport os\nimport sys\n\n\n__all__ = [\"attach\", \"lazy_import\"]\n\n\ndef attach(module_name, submodules=None, submod_attrs=None):\n    \"\"\"Attach lazily loaded submodules, and functions or other attributes.\n\n    Typically, modules import submodules and attributes as follows::\n\n      import mysubmodule\n      import anothersubmodule\n\n      from .foo import someattr\n\n    The idea of  this function is to replace the `__init__.py`\n    module's `__getattr__`, `__dir__`, and `__all__` attributes such that\n    all imports work exactly the way they normally would, except that the\n    actual import is delayed until the resulting module object is first used.\n\n    The typical way to call this function, replacing the above imports, is::\n\n      __getattr__, __lazy_dir__, __all__ = lazy.attach(\n          __name__,\n          ['mysubmodule', 'anothersubmodule'],\n          {'foo': 'someattr'}\n      )\n\n    This functionality requires Python 3.7 or higher.\n\n    Parameters\n    ----------\n    module_name : str\n        Typically use __name__.\n    submodules : set\n        List of submodules to lazily import.\n    submod_attrs : dict\n        Dictionary of submodule -> list of attributes / functions.\n        These attributes are imported as they are used.\n\n    Returns\n    -------\n    __getattr__, __dir__, __all__\n\n    \"\"\"\n    if submod_attrs is None:\n        submod_attrs = {}\n\n    if submodules is None:\n        submodules = set()\n    else:\n        submodules = set(submodules)\n\n    attr_to_modules = {\n        attr: mod for mod, attrs in submod_attrs.items() for attr in attrs\n    }\n\n    __all__ = list(submodules | attr_to_modules.keys())\n\n    def __getattr__(name):\n        if name in submodules:\n            return importlib.import_module(f\"{module_name}.{name}\")\n        elif name in attr_to_modules:\n            submod = importlib.import_module(f\"{module_name}.{attr_to_modules[name]}\")\n            return getattr(submod, name)\n        else:\n            raise AttributeError(f\"No {module_name} attribute {name}\")\n\n    def __dir__():\n        return __all__\n\n    if os.environ.get(\"EAGER_IMPORT\", \"\"):\n        for attr in set(attr_to_modules.keys()) | submodules:\n            __getattr__(attr)\n\n    return __getattr__, __dir__, list(__all__)\n\n\ndef lazy_import(fullname):\n    \"\"\"Return a lazily imported proxy for a module or library.\n\n    We often see the following pattern::\n\n      def myfunc():\n          import scipy as sp\n          sp.argmin(...)\n          ....\n\n    This is to prevent a library, in this case `scipy`, from being\n    imported at function definition time, since that can be slow.\n\n    This function provides a proxy module that, upon access, imports\n    the actual module.  So the idiom equivalent to the above example is::\n\n      sp = lazy.load(\"scipy\")\n\n      def myfunc():\n          sp.argmin(...)\n          ....\n\n    The initial import time is fast because the actual import is delayed\n    until the first attribute is requested. The overall import time may\n    decrease as well for users that don't make use of large portions\n    of the library.\n\n    Parameters\n    ----------\n    fullname : str\n        The full name of the package or subpackage to import.  For example::\n\n          sp = lazy.load('scipy')  # import scipy as sp\n          spla = lazy.load('scipy.linalg')  # import scipy.linalg as spla\n\n    Returns\n    -------\n    pm : importlib.util._LazyModule\n        Proxy module. Can be used like any regularly imported module.\n        Actual loading of the module occurs upon first attribute request.\n\n    \"\"\"\n    try:\n        return sys.modules[fullname]\n    except:\n        pass\n\n    # Not previously loaded -- look it up\n    spec = importlib.util.find_spec(fullname)\n\n    if spec is None:\n        # module not found - construct a DelayedImportErrorModule\n        spec = importlib.util.spec_from_loader(fullname, loader=None)\n        module = importlib.util.module_from_spec(spec)\n        tmp_loader = importlib.machinery.SourceFileLoader(module, path=None)\n        loader = DelayedImportErrorLoader(tmp_loader)\n        loader.exec_module(module)\n        # dont add to sys.modules. The module wasn't found.\n        return module\n\n    module = importlib.util.module_from_spec(spec)\n    sys.modules[fullname] = module\n\n    loader = importlib.util.LazyLoader(spec.loader)\n    loader.exec_module(module)\n\n    return module\n\n\nclass DelayedImportErrorLoader(importlib.util.LazyLoader):\n    def exec_module(self, module):\n        super().exec_module(module)\n        module.__class__ = DelayedImportErrorModule\n\n\nclass DelayedImportErrorModule(types.ModuleType):\n    def __getattribute__(self, attr):\n        \"\"\"Trigger a ModuleNotFoundError upon attribute access\"\"\"\n        spec = super().__getattribute__(\"__spec__\")\n        # allows isinstance and type functions to work without raising error\n        if attr in [\"__class__\"]:\n            return super().__getattribute__(\"__class__\")\n\n        raise ModuleNotFoundError(\n            f\"Delayed Report: module named '{spec.name}' not found.\\n\"\n            \"Reporting was Lazy -- delayed until module attributes accessed.\\n\"\n            f\"Most likely, {spec.name} is not installed\"\n        )\n", "path": "networkx/lazy_imports.py"}], "after_files": [{"content": "import importlib\nimport importlib.util\nimport inspect\nimport types\nimport os\nimport sys\n\n\n__all__ = [\"attach\", \"lazy_import\"]\n\n\ndef attach(module_name, submodules=None, submod_attrs=None):\n    \"\"\"Attach lazily loaded submodules, and functions or other attributes.\n\n    Typically, modules import submodules and attributes as follows::\n\n      import mysubmodule\n      import anothersubmodule\n\n      from .foo import someattr\n\n    The idea of  this function is to replace the `__init__.py`\n    module's `__getattr__`, `__dir__`, and `__all__` attributes such that\n    all imports work exactly the way they normally would, except that the\n    actual import is delayed until the resulting module object is first used.\n\n    The typical way to call this function, replacing the above imports, is::\n\n      __getattr__, __lazy_dir__, __all__ = lazy.attach(\n          __name__,\n          ['mysubmodule', 'anothersubmodule'],\n          {'foo': 'someattr'}\n      )\n\n    This functionality requires Python 3.7 or higher.\n\n    Parameters\n    ----------\n    module_name : str\n        Typically use __name__.\n    submodules : set\n        List of submodules to lazily import.\n    submod_attrs : dict\n        Dictionary of submodule -> list of attributes / functions.\n        These attributes are imported as they are used.\n\n    Returns\n    -------\n    __getattr__, __dir__, __all__\n\n    \"\"\"\n    if submod_attrs is None:\n        submod_attrs = {}\n\n    if submodules is None:\n        submodules = set()\n    else:\n        submodules = set(submodules)\n\n    attr_to_modules = {\n        attr: mod for mod, attrs in submod_attrs.items() for attr in attrs\n    }\n\n    __all__ = list(submodules | attr_to_modules.keys())\n\n    def __getattr__(name):\n        if name in submodules:\n            return importlib.import_module(f\"{module_name}.{name}\")\n        elif name in attr_to_modules:\n            submod = importlib.import_module(f\"{module_name}.{attr_to_modules[name]}\")\n            return getattr(submod, name)\n        else:\n            raise AttributeError(f\"No {module_name} attribute {name}\")\n\n    def __dir__():\n        return __all__\n\n    if os.environ.get(\"EAGER_IMPORT\", \"\"):\n        for attr in set(attr_to_modules.keys()) | submodules:\n            __getattr__(attr)\n\n    return __getattr__, __dir__, list(__all__)\n\n\nclass DelayedImportErrorModule(types.ModuleType):\n    def __init__(self, frame_data, *args, **kwargs):\n        self.__frame_data = frame_data\n        super().__init__(*args, **kwargs)\n\n    def __getattr__(self, x):\n        if x in (\"__class__\", \"__file__\", \"__frame_data\"):\n            super().__getattr__(x)\n        else:\n            fd = self.__frame_data\n            raise ModuleNotFoundError(\n                f\"No module named '{fd['spec']}'\\n\\n\"\n                \"This error is lazily reported, having originally occured in\\n\"\n                f'  File {fd[\"filename\"]}, line {fd[\"lineno\"]}, in {fd[\"function\"]}\\n\\n'\n                f'----> {\"\".join(fd[\"code_context\"]).strip()}'\n            )\n\n\ndef lazy_import(fullname):\n    \"\"\"Return a lazily imported proxy for a module or library.\n\n    We often see the following pattern::\n\n      def myfunc():\n          import scipy as sp\n          sp.argmin(...)\n          ....\n\n    This is to prevent a library, in this case `scipy`, from being\n    imported at function definition time, since that can be slow.\n\n    This function provides a proxy module that, upon access, imports\n    the actual module.  So the idiom equivalent to the above example is::\n\n      sp = lazy.load(\"scipy\")\n\n      def myfunc():\n          sp.argmin(...)\n          ....\n\n    The initial import time is fast because the actual import is delayed\n    until the first attribute is requested. The overall import time may\n    decrease as well for users that don't make use of large portions\n    of the library.\n\n    Parameters\n    ----------\n    fullname : str\n        The full name of the package or subpackage to import.  For example::\n\n          sp = lazy.load('scipy')  # import scipy as sp\n          spla = lazy.load('scipy.linalg')  # import scipy.linalg as spla\n\n    Returns\n    -------\n    pm : importlib.util._LazyModule\n        Proxy module. Can be used like any regularly imported module.\n        Actual loading of the module occurs upon first attribute request.\n\n    \"\"\"\n    try:\n        return sys.modules[fullname]\n    except:\n        pass\n\n    # Not previously loaded -- look it up\n    spec = importlib.util.find_spec(fullname)\n\n    if spec is None:\n        try:\n            parent = inspect.stack()[1]\n            frame_data = {\n                \"spec\": fullname,\n                \"filename\": parent.filename,\n                \"lineno\": parent.lineno,\n                \"function\": parent.function,\n                \"code_context\": parent.code_context,\n            }\n            return DelayedImportErrorModule(frame_data, \"DelayedImportErrorModule\")\n        finally:\n            del parent\n\n    module = importlib.util.module_from_spec(spec)\n    sys.modules[fullname] = module\n\n    loader = importlib.util.LazyLoader(spec.loader)\n    loader.exec_module(module)\n\n    return module\n", "path": "networkx/lazy_imports.py"}]}