Cycle when resolving an imported module with __all__ (original) (raw)

Summary

play.py:

from foo import bar

revealed on main: Never

revealed before __all__ support: <module 'foo.bar'>

reveal_type(bar)

foo/__init__.pyi:

from foo import bar

all = ["bar"]

foo/bar/__init__.pyi (empty file):

Running this with:

cargo run --bin ty -- check --project=/path/to/project

This is reproduced with or without the custom typeshed that I've provided below.

Trace logs that are interesting and reveals a cycle on symbol query:

Resolving import statement from module `foo` into file `/Users/dhruv/playground/ty/isolated3/play.py`
(query) resolve_module{name=foo}
Resolved module `foo` to `/Users/dhruv/playground/ty/isolated3/foo/__init__.pyi`
(query) infer_definition_types{range=48..51, file=File(System("/Users/dhruv/playground/ty/isolated3/play.py"))}
(query) member_lookup_with_policy: <module 'foo'>.bar
imported_symbol: "bar" in /Users/dhruv/playground/ty/isolated3/foo/__init__.pyi
(query) symbol{name="bar", file=/Users/dhruv/playground/ty/isolated3/foo/__init__.pyi}
(query) dunder_all_names{file=System("/Users/dhruv/playground/ty/isolated3/foo/__init__.pyi")}
(query) infer_definition_types{range=16..19, file=File(System("/Users/dhruv/playground/ty/isolated3/foo/__init__.pyi"))}
(query) member_lookup_with_policy: <module 'foo'>.bar
imported_symbol: "bar" in /Users/dhruv/playground/ty/isolated3/foo/__init__.pyi
(query) (CYCLE) symbol{name="bar", file=/Users/dhruv/playground/ty/isolated3/foo/__init__.pyi}

This might be related to #113.

The reason this isn't occurring before __all__ support is that the bar module is not being re-exported in foo/__init__.pyi via "redundant alias" but is via __all__. So, before __all__ support, it wouldn't trigger the infer_definition_types query and fallback to using Type::ModuleType.to_instance(db).member(db, name) instead which would avoid the cycle.

Custom typeshed with only the following files:

stdlib/builtins.pyi:

class object: ... class type: ... class int: ... class str: ... class list: ...

stdlib/types.pyi:

all = ["ModuleType"]

class ModuleType: ...

stdlib/typing.pyi:

all = ["reveal_type"]

def reveal_type[T](obj: T, /) -> T: ...

stdlib/VERSIONS:

builtins: 3.0-
types: 3.0-
typing: 3.5-

Version

No response