Return the spec for the specified module. First, sys.modules is checked to see if the module was already imported. If so, then sys.modules[name].__spec__ is returned. If that happens to be set to None, then ValueError is raised. If the module is not in sys.modules, then sys.met
(name, package=None)
| 72 | |
| 73 | |
| 74 | def find_spec(name, package=None): |
| 75 | """Return the spec for the specified module. |
| 76 | |
| 77 | First, sys.modules is checked to see if the module was already imported. If |
| 78 | so, then sys.modules[name].__spec__ is returned. If that happens to be |
| 79 | set to None, then ValueError is raised. If the module is not in |
| 80 | sys.modules, then sys.meta_path is searched for a suitable spec with the |
| 81 | value of 'path' given to the finders. None is returned if no spec could |
| 82 | be found. |
| 83 | |
| 84 | If the name is for submodule (contains a dot), the parent module is |
| 85 | automatically imported. |
| 86 | |
| 87 | The name and package arguments work the same as importlib.import_module(). |
| 88 | In other words, relative module names (with leading dots) work. |
| 89 | |
| 90 | """ |
| 91 | fullname = resolve_name(name, package) if name.startswith('.') else name |
| 92 | if fullname not in sys.modules: |
| 93 | parent_name = fullname.rpartition('.')[0] |
| 94 | if parent_name: |
| 95 | parent = __import__(parent_name, fromlist=['__path__']) |
| 96 | try: |
| 97 | parent_path = parent.__path__ |
| 98 | except AttributeError as e: |
| 99 | raise ModuleNotFoundError( |
| 100 | f"__path__ attribute not found on {parent_name!r} " |
| 101 | f"while trying to find {fullname!r}", name=fullname) from e |
| 102 | else: |
| 103 | parent_path = None |
| 104 | return _find_spec(fullname, parent_path) |
| 105 | else: |
| 106 | module = sys.modules[fullname] |
| 107 | if module is None: |
| 108 | return None |
| 109 | try: |
| 110 | spec = module.__spec__ |
| 111 | except AttributeError: |
| 112 | raise ValueError('{}.__spec__ is not set'.format(name)) from None |
| 113 | else: |
| 114 | if spec is None: |
| 115 | raise ValueError('{}.__spec__ is None'.format(name)) |
| 116 | return spec |
| 117 | |
| 118 | |
| 119 | @contextmanager |
no test coverage detected