File tree Expand file tree Collapse file tree 2 files changed +13
-2
lines changed
crates/ty_python_semantic Expand file tree Collapse file tree 2 files changed +13
-2
lines changed Original file line number Diff line number Diff line change @@ -8,7 +8,8 @@ is unbound.
88
99``` py
1010reveal_type(__name__ ) # revealed: str
11- reveal_type(__file__ ) # revealed: str | None
11+ # Typeshed says this is str | None, but for a pure-Python on-disk module its always str
12+ reveal_type(__file__ ) # revealed: str
1213reveal_type(__loader__) # revealed: LoaderProtocol | None
1314reveal_type(__package__ ) # revealed: str | None
1415reveal_type(__doc__ ) # revealed: str | None
@@ -52,6 +53,10 @@ import typing
5253reveal_type(typing.__name__ ) # revealed: str
5354reveal_type(typing.__init__ ) # revealed: bound method ModuleType.__init__(name: str, doc: str | None = ellipsis) -> None
5455
56+ # For a stub module, we don't know that `__file__` is a string (at runtime it may be entirely
57+ # unset, but we follow typeshed here):
58+ reveal_type(typing.__file__ ) # revealed: str | None
59+
5560# These come from `builtins.object`, not `types.ModuleType`:
5661reveal_type(typing.__eq__ ) # revealed: bound method ModuleType.__eq__(value: object, /) -> bool
5762
Original file line number Diff line number Diff line change @@ -982,12 +982,18 @@ mod implicit_globals {
982982 db : & ' db dyn Db ,
983983 name : & str ,
984984 ) -> SymbolAndQualifiers < ' db > {
985+ // We special-case `__file__` here because we know that for an internal implicit global
986+ // lookup in a Python module, it is always a string, even though typeshed says `str |
987+ // None`.
988+ if name == "__file__" {
989+ Symbol :: bound ( KnownClass :: Str . to_instance ( db) ) . into ( )
990+ }
985991 // In general we wouldn't check to see whether a symbol exists on a class before doing the
986992 // `.member()` call on the instance type -- we'd just do the `.member`() call on the instance
987993 // type, since it has the same end result. The reason to only call `.member()` on `ModuleType`
988994 // when absolutely necessary is that this function is used in a very hot path (name resolution
989995 // in `infer.rs`). We use less idiomatic (and much more verbose) code here as a micro-optimisation.
990- if module_type_symbols ( db)
996+ else if module_type_symbols ( db)
991997 . iter ( )
992998 . any ( |module_type_member| & * * module_type_member == name)
993999 {
You can’t perform that action at this time.
0 commit comments