MCPcopy
hub / github.com/python/mypy / find_modules_recursive

Method find_modules_recursive

mypy/modulefinder.py:619–674  ·  view source on GitHub ↗
(self, module: str)

Source from the content-addressed store, hash-verified

617 return ModuleNotFoundReason.NOT_FOUND, True
618
619 def find_modules_recursive(self, module: str) -> list[BuildSource]:
620 module_path = self.find_module(module, fast_path=True)
621 if isinstance(module_path, ModuleNotFoundReason):
622 return []
623 sources = [BuildSource(module_path, module, None)]
624
625 package_path = None
626 if is_init_file(module_path):
627 package_path = os.path.dirname(module_path)
628 elif self.fscache.isdir(module_path):
629 package_path = module_path
630 if package_path is None:
631 return sources
632
633 # This logic closely mirrors that in find_sources. One small but important difference is
634 # that we do not sort names with keyfunc. The recursive call to find_modules_recursive
635 # calls find_module, which will handle the preference between packages, pyi and py.
636 # Another difference is it doesn't handle nested search paths / package roots.
637
638 seen: set[str] = set()
639 names = sorted(self.fscache.listdir(package_path))
640 for name in names:
641 # Skip certain names altogether
642 if name in ("__pycache__", "site-packages", "node_modules") or name.startswith("."):
643 continue
644 subpath = os_path_join(package_path, name)
645
646 if self.options and matches_exclude(
647 subpath, self.options.exclude, self.fscache, self.options.verbosity >= 2
648 ):
649 continue
650 if (
651 self.options
652 and self.options.exclude_gitignore
653 and matches_gitignore(subpath, self.fscache, self.options.verbosity >= 2)
654 ):
655 continue
656
657 if self.fscache.isdir(subpath):
658 # Only recurse into packages
659 if (self.options and self.options.namespace_packages) or (
660 self.fscache.isfile(os_path_join(subpath, "__init__.py"))
661 or self.fscache.isfile(os_path_join(subpath, "__init__.pyi"))
662 ):
663 seen.add(name)
664 sources.extend(self.find_modules_recursive(module + "." + name))
665 else:
666 stem, suffix = os.path.splitext(name)
667 if stem == "__init__":
668 continue
669 if stem not in seen and "." not in stem and suffix in PYTHON_EXTENSIONS:
670 # (If we sorted names by keyfunc) we could probably just make the BuildSource
671 # ourselves, but this ensures compatibility with find_module / the cache
672 seen.add(stem)
673 sources.extend(self.find_modules_recursive(module + "." + stem))
674 return sources
675
676

Callers 3

build_stubsFunction · 0.95
process_optionsFunction · 0.95

Calls 15

find_moduleMethod · 0.95
os_path_joinFunction · 0.90
isinstanceFunction · 0.85
BuildSourceClass · 0.85
is_init_fileFunction · 0.85
setClass · 0.85
sortedFunction · 0.85
matches_excludeFunction · 0.85
matches_gitignoreFunction · 0.85
extendMethod · 0.80
isdirMethod · 0.45
listdirMethod · 0.45

Tested by 1

build_stubsFunction · 0.76