Iterate through all modules needed to be watched.
(modules, extra_files)
| 125 | |
| 126 | @lru_cache(maxsize=1) |
| 127 | def iter_modules_and_files(modules, extra_files): |
| 128 | """Iterate through all modules needed to be watched.""" |
| 129 | sys_file_paths = [] |
| 130 | for module in modules: |
| 131 | # During debugging (with PyDev) the 'typing.io' and 'typing.re' objects |
| 132 | # are added to sys.modules, however they are types not modules and so |
| 133 | # cause issues here. |
| 134 | if not isinstance(module, ModuleType): |
| 135 | continue |
| 136 | if module.__name__ in ("__main__", "__mp_main__"): |
| 137 | # __main__ (usually manage.py) doesn't always have a __spec__ set. |
| 138 | # Handle this by falling back to using __file__, resolved below. |
| 139 | # See https://docs.python.org/reference/import.html#main-spec |
| 140 | # __file__ may not exists, e.g. when running ipdb debugger. |
| 141 | if hasattr(module, "__file__"): |
| 142 | sys_file_paths.append(module.__file__) |
| 143 | continue |
| 144 | if getattr(module, "__spec__", None) is None: |
| 145 | continue |
| 146 | spec = module.__spec__ |
| 147 | # Modules could be loaded from places without a concrete location. If |
| 148 | # this is the case, skip them. |
| 149 | if spec.has_location: |
| 150 | origin = ( |
| 151 | spec.loader.archive |
| 152 | if isinstance(spec.loader, zipimporter) |
| 153 | else spec.origin |
| 154 | ) |
| 155 | sys_file_paths.append(origin) |
| 156 | |
| 157 | results = set() |
| 158 | for filename in itertools.chain(sys_file_paths, extra_files): |
| 159 | if not filename: |
| 160 | continue |
| 161 | path = Path(filename) |
| 162 | try: |
| 163 | if not path.exists(): |
| 164 | # The module could have been removed, don't fail loudly if this |
| 165 | # is the case. |
| 166 | continue |
| 167 | except ValueError as e: |
| 168 | # Network filesystems may return null bytes in file paths. |
| 169 | logger.debug('"%s" raised when resolving path: "%s"', e, path) |
| 170 | continue |
| 171 | resolved_path = path.resolve().absolute() |
| 172 | results.add(resolved_path) |
| 173 | return frozenset(results) |
| 174 | |
| 175 | |
| 176 | @lru_cache(maxsize=1) |