diff --git a/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.dot b/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.dot index 04dd3d5332..0aa21f25c1 100644 --- a/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.dot +++ b/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.dot @@ -81,53 +81,121 @@ digraph python_import_resolution { correspond to a directory that contains an
`__init__.py` or an `__init__.pyi`? >]; - determine_parent_kind -> maybe_package [label="Yes"]; - determine_parent_kind -> namespace_parent1 [label="No"]; + determine_parent_kind -> regular_parent_std [label="Yes"]; + determine_parent_kind -> namespace_parent_regular_check [label="No"]; - namespace_parent1 [label=< + regular_parent_std [label=< + Does the search path correspond to the standard library? + >]; + regular_parent_std -> resolved_parent_package [label="No"]; + regular_parent_std -> regular_parent_typeshed_check [label="Yes"]; + + regular_parent_typeshed_check [label=< + Does every parent package of
+ `module_name` exist on the configured
+ Python version according to
+ typeshed's VERSIONS file? + >]; + regular_parent_typeshed_check -> resolved_parent_package [label="Yes"]; + regular_parent_typeshed_check -> bail [label="No"]; + + namespace_parent_regular_check [label=< Is the direct parent package
a directory that contains
an `__init__.py` or `__init__.pyi`? >]; - namespace_parent1 -> bail [label="Yes"]; - namespace_parent1 -> namespace_parent2 [label="No"]; + namespace_parent_regular_check -> bail [label="Yes"]; + namespace_parent_regular_check -> namespace_parent_std [label="No"]; - namespace_parent2 [label=< + namespace_parent_std [label=< + Does the search path correspond to the standard library? + >]; + namespace_parent_std -> namespace_parent_module_check [label="No"]; + namespace_parent_std -> namespace_parent_typeshed_check [label="Yes"]; + + namespace_parent_typeshed_check [label=< + Does the direct parent package of
+ `module_name` exist on the configured
+ Python version according to
+ typeshed's VERSIONS file? + >]; + namespace_parent_typeshed_check -> namespace_parent_module_check [label="Yes"]; + namespace_parent_typeshed_check -> bail [label="No"]; + + namespace_parent_module_check [label=< Does the direct parent package
have a sibling file with the same
basename and a `py` or `pyi` extension?
>]; - namespace_parent2 -> bail [label="Yes"]; - namespace_parent2 -> namespace_parent3 [label="No"]; + namespace_parent_module_check -> bail [label="Yes"]; + namespace_parent_module_check -> namespace_parent_above [label="No"]; - namespace_parent3 [label=< + namespace_parent_above [label=< Is every parent above the direct
parent package a normal package or
otherwise satisfy the previous two
namespace package requirements? >]; - namespace_parent3 -> bail [label="No"]; - namespace_parent3 -> maybe_package [label="Yes"]; + namespace_parent_above -> bail [label="No"]; + namespace_parent_above -> resolved_parent_package [label="Yes"]; - maybe_package [label=< + resolved_parent_package [label=< After replacing `.` with `/` in module name,
does `{path}/__init__.py` or `{path}/__init__.pyi` exist? >]; - maybe_package -> package [label="Yes"]; - maybe_package -> maybe_module [label="No"]; + resolved_parent_package -> package [label="Yes"]; + resolved_parent_package -> maybe_module [label="No"]; maybe_module [label=< Does `{path}.py` or `{path}.pyi` exist? >]; - maybe_module -> module [label="Yes"]; + maybe_module -> maybe_module_std [label="Yes"]; maybe_module -> maybe_namespace [label="No"]; + maybe_module_std [label=< + Does the search path correspond to the standard library? + >]; + maybe_module_std -> module [label="No"]; + maybe_module_std -> maybe_module_typeshed_check [label="Yes"]; + + maybe_module_typeshed_check [label=< + Does the module corresponding to `{path}`
+ exist on the configured
+ Python version according to
+ typeshed's VERSIONS file? + >]; + maybe_module_typeshed_check -> module [label="Yes"]; + maybe_module_typeshed_check -> maybe_namespace [label="No"]; + + // N.B. In the actual implementation, this check is + // only done when the search path *isn't* the standard + // library. That's because typeshed doesn't use namespace + // packages, so this (and the typeshed VERSIONS check) + // can all be skipped as an optimization. But the flow + // diagram still represents this because this could in + // theory change and optimizations really should be the + // domain of the implementation, not the spec. maybe_namespace [label=< Is `{path}` a directory? >]; - maybe_namespace -> namespace_package [label="Yes"]; + maybe_namespace -> maybe_namespace_std [label="Yes"]; maybe_namespace -> bail [label="No"]; + maybe_namespace_std [label=< + Does the search path correspond to the standard library? + >]; + maybe_namespace_std -> namespace_package [label="No"]; + maybe_namespace_std -> maybe_namespace_typeshed_check [label="Yes"]; + + maybe_namespace_typeshed_check [label=< + Does the module corresponding to `{path}`
+ exist on the configured
+ Python version according to
+ typeshed's VERSIONS file? + >]; + maybe_namespace_typeshed_check -> namespace_package [label="Yes"]; + maybe_namespace_typeshed_check -> bail [label="No"]; + bail [label=< Is `module_name` set to a stub package candidate? >]; diff --git a/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.svg b/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.svg index 7584e5134f..82c8f64d76 100644 --- a/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.svg +++ b/crates/ty_python_semantic/src/module_resolver/import-resolution-diagram.svg @@ -4,15 +4,15 @@ - - + + python_import_resolution - -         -Python import resolution flow diagram for a single module name in a single "search path" -         -(assumes that the module name is valid and that stubs are allowed)     + +         +Python import resolution flow diagram for a single module name in a single "search path" +         +(assumes that the module name is valid and that stubs are allowed)     module @@ -31,266 +31,438 @@ namespace_package - - -Namespace Package + + +Namespace Package not_found - - -Module Not Found + + +Module Not Found START - -START + +START non_shadowable - -        Is the search path not the standard library and -        the module name is `types` or some other built-in?     + +        Is the search path not the standard library and +        the module name is `types` or some other built-in?     START->non_shadowable - - + + non_shadowable->not_found - - -Yes + + +Yes stub_package_check - -        Is the search path in the standard library?     + +        Is the search path in the standard library?     non_shadowable->stub_package_check - - -No + + +No stub_package_set - -        Set `module_name` to `{top-package}-stubs.{rest}`     + +        Set `module_name` to `{top-package}-stubs.{rest}`     stub_package_check->stub_package_set - - -No + + +No determine_parent_kind - -        Does every parent package of `module_name` -        correspond to a directory that contains an -        `__init__.py` or an `__init__.pyi`?     + +        Does every parent package of `module_name` +        correspond to a directory that contains an +        `__init__.py` or an `__init__.pyi`?     stub_package_check->determine_parent_kind - - -Yes + + +Yes stub_package_set->determine_parent_kind - - + + - + -maybe_package - -        After replacing `.` with `/` in module name, -        does `{path}/__init__.py` or `{path}/__init__.pyi` exist?     +regular_parent_std + +        Does the search path correspond to the standard library?     - + -determine_parent_kind->maybe_package - - -Yes +determine_parent_kind->regular_parent_std + + +Yes - + -namespace_parent1 - -        Is the direct parent package -        a directory that contains -        an `__init__.py` or `__init__.pyi`?     +namespace_parent_regular_check + +        Is the direct parent package +        a directory that contains +        an `__init__.py` or `__init__.pyi`?     - + -determine_parent_kind->namespace_parent1 - - -No +determine_parent_kind->namespace_parent_regular_check + + +No - - -maybe_package->package - - -Yes + + +resolved_parent_package + +        After replacing `.` with `/` in module name, +        does `{path}/__init__.py` or `{path}/__init__.pyi` exist?     - - -maybe_module - -        Does `{path}.py` or `{path}.pyi` exist?     + + +regular_parent_std->resolved_parent_package + + +No - - -maybe_package->maybe_module - - -No + + +regular_parent_typeshed_check + +        Does every parent package of +        `module_name` exist on the configured +        Python version according to +        typeshed's VERSIONS file?     + + + +regular_parent_std->regular_parent_typeshed_check + + +Yes - + bail - -        Is `module_name` set to a stub package candidate?     + +        Is `module_name` set to a stub package candidate?     - - -namespace_parent1->bail - - -Yes + + +namespace_parent_regular_check->bail + + +Yes - - -namespace_parent2 - -        Does the direct parent package -        have a sibling file with the same -        basename and a `py` or `pyi` extension? -     + + +namespace_parent_std + +        Does the search path correspond to the standard library?     - - -namespace_parent1->namespace_parent2 - - -No + + +namespace_parent_regular_check->namespace_parent_std + + +No + + + +resolved_parent_package->package + + +Yes + + + +maybe_module + +        Does `{path}.py` or `{path}.pyi` exist?     + + + +resolved_parent_package->maybe_module + + +No + + + +regular_parent_typeshed_check->resolved_parent_package + + +Yes + + + +regular_parent_typeshed_check->bail + + +No - + bail->not_found - - -No + + +No - + retry - -        Reset `module_name` to original     + +        Reset `module_name` to original     - + bail->retry - - -Yes + + +Yes - - -namespace_parent2->bail - - -Yes + + +namespace_parent_module_check + +        Does the direct parent package +        have a sibling file with the same +        basename and a `py` or `pyi` extension? +     - - -namespace_parent3 - -        Is every parent above the direct -        parent package a normal package or -        otherwise satisfy the previous two -        namespace package requirements?     + + +namespace_parent_std->namespace_parent_module_check + + +No - - -namespace_parent2->namespace_parent3 - - -No + + +namespace_parent_typeshed_check + +        Does the direct parent package of +        `module_name` exist on the configured +        Python version according to +        typeshed's VERSIONS file?     - - -namespace_parent3->maybe_package - - -Yes + + +namespace_parent_std->namespace_parent_typeshed_check + + +Yes - - -namespace_parent3->bail - - -No + + +namespace_parent_module_check->bail + + +Yes - + + +namespace_parent_above + +        Is every parent above the direct +        parent package a normal package or +        otherwise satisfy the previous two +        namespace package requirements?     + + + +namespace_parent_module_check->namespace_parent_above + + +No + + + +namespace_parent_typeshed_check->bail + + +No + + -maybe_module->module - - -Yes +namespace_parent_typeshed_check->namespace_parent_module_check + + +Yes + + + +namespace_parent_above->resolved_parent_package + + +Yes + + + +namespace_parent_above->bail + + +No + + + +maybe_module_std + +        Does the search path correspond to the standard library?     + + + +maybe_module->maybe_module_std + + +Yes - + maybe_namespace - -        Is `{path}` a directory?     + +        Is `{path}` a directory?     - + maybe_module->maybe_namespace - - -No + + +No - - -maybe_namespace->namespace_package - - -Yes + + +maybe_module_std->module + + +No + + + +maybe_module_typeshed_check + +        Does the module corresponding to `{path}` +        exist on the configured +        Python version according to +        typeshed's VERSIONS file?     + + + +maybe_module_std->maybe_module_typeshed_check + + +Yes - + maybe_namespace->bail - - -No + + +No + + + +maybe_namespace_std + +        Does the search path correspond to the standard library?     + + + +maybe_namespace->maybe_namespace_std + + +Yes + + + +maybe_module_typeshed_check->module + + +Yes + + + +maybe_module_typeshed_check->maybe_namespace + + +No + + + +maybe_namespace_std->namespace_package + + +No + + + +maybe_namespace_typeshed_check + +        Does the module corresponding to `{path}` +        exist on the configured +        Python version according to +        typeshed's VERSIONS file?     + + + +maybe_namespace_std->maybe_namespace_typeshed_check + + +Yes + + + +maybe_namespace_typeshed_check->namespace_package + + +Yes + + + +maybe_namespace_typeshed_check->bail + + +No - + retry->determine_parent_kind - - + +