[ty] Fix namespace packages that behave like partial stubs (#19994)

In implementing partial stubs I had observed that this continue in the
namespace package code seemed erroneous since the same continue for
partial stubs didn't work. Unfortunately I wasn't confident enough to
push on that hunch. Fortunately I remembered that hunch to make this an
easy fix.

The issue with the continue is that it bails out of the current
search-path without testing any .py files. This breaks when for example
`google` and `google-stubs`/`types-google` are both in the same
site-packages dir -- failing to find a module in `types-google` has us
completely skip over `google`!

Fixes https://github.com/astral-sh/ty/issues/520
This commit is contained in:
Aria Desires 2025-08-19 16:34:39 -04:00 committed by GitHub
parent 58efd19f11
commit c82e255ca8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 58 additions and 14 deletions

View file

@ -54,9 +54,9 @@ partial
```pyi ```pyi
``` ```
`/packages/foo-stubs/both.py`: `/packages/foo-stubs/both.pyi`:
```py ```pyi
class Both: class Both:
both: str both: str
other: int other: int
@ -107,9 +107,9 @@ extra-paths = ["/packages"]
```pyi ```pyi
``` ```
`/packages/foo-stubs/both.py`: `/packages/foo-stubs/both.pyi`:
```py ```pyi
class Both: class Both:
both: str both: str
other: int other: int
@ -165,9 +165,9 @@ extra-paths = ["/packages"]
```pyi ```pyi
``` ```
`/packages/foo-stubs/both.py`: `/packages/foo-stubs/both.pyi`:
```py ```pyi
class Both: class Both:
both: str both: str
other: int other: int
@ -230,9 +230,9 @@ extra-paths = ["/packages"]
```pyi ```pyi
``` ```
`/packages/foo-stubs/bar/both.py`: `/packages/foo-stubs/bar/both.pyi`:
```py ```pyi
class Both: class Both:
both: str both: str
other: int other: int
@ -305,9 +305,9 @@ partial/n
```pyi ```pyi
``` ```
`/packages/foo-stubs/bar/both.py`: `/packages/foo-stubs/bar/both.pyi`:
```py ```pyi
class Both: class Both:
both: str both: str
other: int other: int
@ -380,9 +380,9 @@ pArTiAl\n
```pyi ```pyi
``` ```
`/packages/foo-stubs/bar/both.py`: `/packages/foo-stubs/bar/both.pyi`:
```py ```pyi
class Both: class Both:
both: str both: str
other: int other: int
@ -423,3 +423,48 @@ reveal_type(Both().both) # revealed: str
reveal_type(Impl().impl) # revealed: Unknown reveal_type(Impl().impl) # revealed: Unknown
reveal_type(Fake().fake) # revealed: Unknown reveal_type(Fake().fake) # revealed: Unknown
``` ```
## Namespace stub with missing module
Namespace stubs are always partial.
This is a regression test for <https://github.com/astral-sh/ty/issues/520>.
```toml
[environment]
extra-paths = ["/packages"]
```
`/packages/parent-stubs/foo/both.pyi`:
```pyi
class Both:
both: str
other: int
```
`/packages/parent/foo/both.py`:
```py
class Both: ...
```
`/packages/parent/foo/impl.py`:
```py
class Impl:
impl: str
other: int
```
`main.py`:
```py
from parent.foo.both import Both
from parent.foo.impl import Impl
from parent.foo.fake import Fake # error: "Cannot resolve"
reveal_type(Both().both) # revealed: str
reveal_type(Impl().impl) # revealed: str
reveal_type(Fake().fake) # revealed: Unknown
```

View file

@ -723,8 +723,7 @@ fn resolve_name(db: &dyn Db, name: &ModuleName, mode: ModuleResolveMode) -> Opti
`{name}` but it is a namespace package, keep going." `{name}` but it is a namespace package, keep going."
); );
// stub exists, but the module doesn't. But this is a namespace package, // stub exists, but the module doesn't. But this is a namespace package,
// keep searching the next search path for a stub package with the same name. // fall through to looking for a non-stub package
continue;
} }
} }
} }