Try to find a spec for the specified module. Returns the matching spec, or None if not found.
(self, fullname, target=None)
| 1350 | submodule_search_locations=smsl) |
| 1351 | |
| 1352 | def find_spec(self, fullname, target=None): |
| 1353 | """Try to find a spec for the specified module. |
| 1354 | |
| 1355 | Returns the matching spec, or None if not found. |
| 1356 | """ |
| 1357 | is_namespace = False |
| 1358 | tail_module = fullname.rpartition('.')[2] |
| 1359 | try: |
| 1360 | mtime = _path_stat(self.path or _os.getcwd()).st_mtime |
| 1361 | except OSError: |
| 1362 | mtime = -1 |
| 1363 | if mtime != self._path_mtime: |
| 1364 | self._fill_cache() |
| 1365 | self._path_mtime = mtime |
| 1366 | # tail_module keeps the original casing, for __file__ and friends |
| 1367 | if _relax_case(): |
| 1368 | cache = self._relaxed_path_cache |
| 1369 | cache_module = tail_module.lower() |
| 1370 | else: |
| 1371 | cache = self._path_cache |
| 1372 | cache_module = tail_module |
| 1373 | # Check if the module is the name of a directory (and thus a package). |
| 1374 | if cache_module in cache: |
| 1375 | base_path = _path_join(self.path, tail_module) |
| 1376 | for suffix, loader_class in self._loaders: |
| 1377 | init_filename = '__init__' + suffix |
| 1378 | full_path = _path_join(base_path, init_filename) |
| 1379 | if _path_isfile(full_path): |
| 1380 | return self._get_spec(loader_class, fullname, full_path, [base_path], target) |
| 1381 | else: |
| 1382 | # If a namespace package, return the path if we don't |
| 1383 | # find a module in the next section. |
| 1384 | is_namespace = _path_isdir(base_path) |
| 1385 | # Check for a file w/ a proper suffix exists. |
| 1386 | for suffix, loader_class in self._loaders: |
| 1387 | try: |
| 1388 | full_path = _path_join(self.path, tail_module + suffix) |
| 1389 | except ValueError: |
| 1390 | return None |
| 1391 | _bootstrap._verbose_message('trying {}', full_path, verbosity=2) |
| 1392 | if cache_module + suffix in cache: |
| 1393 | if _path_isfile(full_path): |
| 1394 | return self._get_spec(loader_class, fullname, full_path, |
| 1395 | None, target) |
| 1396 | if is_namespace: |
| 1397 | _bootstrap._verbose_message('possible namespace for {}', base_path) |
| 1398 | spec = _bootstrap.ModuleSpec(fullname, None) |
| 1399 | spec.submodule_search_locations = [base_path] |
| 1400 | return spec |
| 1401 | return None |
| 1402 | |
| 1403 | def _fill_cache(self): |
| 1404 | """Fill the cache of potential modules and packages for this directory.""" |