Try to find a module in all available sources. Returns: ``(result, can_be_cached)`` pair.
(self, id: str, use_typeshed: bool)
| 396 | return False |
| 397 | |
| 398 | def _find_module(self, id: str, use_typeshed: bool) -> tuple[ModuleSearchResult, bool]: |
| 399 | """Try to find a module in all available sources. |
| 400 | |
| 401 | Returns: |
| 402 | ``(result, can_be_cached)`` pair. |
| 403 | """ |
| 404 | fscache = self.fscache |
| 405 | |
| 406 | # Fast path for any modules in the current source set. |
| 407 | # This is particularly important when there are a large number of search |
| 408 | # paths which share the first (few) component(s) due to the use of namespace |
| 409 | # packages, for instance: |
| 410 | # foo/ |
| 411 | # company/ |
| 412 | # __init__.py |
| 413 | # foo/ |
| 414 | # bar/ |
| 415 | # company/ |
| 416 | # __init__.py |
| 417 | # bar/ |
| 418 | # baz/ |
| 419 | # company/ |
| 420 | # __init__.py |
| 421 | # baz/ |
| 422 | # |
| 423 | # mypy gets [foo/company/foo, bar/company/bar, baz/company/baz, ...] as input |
| 424 | # and computes [foo, bar, baz, ...] as the module search path. |
| 425 | # |
| 426 | # This would result in O(n) search for every import of company.*, leading to |
| 427 | # O(n**2) behavior in load_graph as such imports are unsurprisingly present |
| 428 | # at least once, and usually many more times than that, in each and every file |
| 429 | # being parsed. |
| 430 | # |
| 431 | # Thankfully, such cases are efficiently handled by looking up the module path |
| 432 | # via BuildSourceSet. |
| 433 | p = ( |
| 434 | self.find_module_via_source_set(id) |
| 435 | if (self.options is not None and self.options.fast_module_lookup) |
| 436 | else None |
| 437 | ) |
| 438 | if p: |
| 439 | return p, True |
| 440 | |
| 441 | # If we're looking for a module like 'foo.bar.baz', it's likely that most of the |
| 442 | # many elements of lib_path don't even have a subdirectory 'foo/bar'. Discover |
| 443 | # that only once and cache it for when we look for modules like 'foo.bar.blah' |
| 444 | # that will require the same subdirectory. |
| 445 | components = id.split(".") |
| 446 | dir_chain = os.sep.join(components[:-1]) # e.g., 'foo/bar' |
| 447 | |
| 448 | # We have two sets of folders so that we collect *all* stubs folders and |
| 449 | # put them in the front of the search path |
| 450 | third_party_inline_dirs: PackageDirs = [] |
| 451 | third_party_stubs_dirs: PackageDirs = [] |
| 452 | found_possible_third_party_missing_type_hints = False |
| 453 | # Third-party stub/typed packages |
| 454 | candidate_package_dirs = { |
| 455 | package_dir[0] |
no test coverage detected