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 @@
-