Fix #11481: 1.1.410 detects type as module#11501
Open
rchiodo wants to merge 2 commits into
Open
Conversation
When a package re-exports (via 'from .sub import *') a name that is both an implicitly-imported submodule and a class/function/variable of the same name, the wildcard merge introduced in microsoft#11396 propagated only the submodule alias, dropping the real symbol. The re-exported name then resolved to a Module instead of the class. _addWildcardImportedModuleAlias now only treats the wildcard re-export as a pure submodule re-export when the module alias is the imported symbol's effective (last) declaration; otherwise it falls through so a normal alias declaration is created that resolves to the winning symbol. Fixes microsoft#11481 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
rchiodo
commented
Jun 18, 2026
rchiodo
commented
Jun 18, 2026
rchiodo
commented
Jun 18, 2026
Collaborator
Author
|
Sound, minimal fix with good regression coverage — approving. A couple of non-blocking follow-ups worth considering: (1) the new guard keys off the raw last |
…ubmodule re-export - Explain why the guard intentionally uses the raw last declaration rather than getLastTypedDeclarationForSymbol (alias decls are untyped) and note the deliberate loss of submoduleFallback when the class wins. - Drop inline issue links per repo convention (kept in PR/commit metadata). - Add a companion fourslash assertion verifying a pure submodule re-export still resolves as a module with accessible members. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
Diff from mypy_primer, showing the effect of this PR on open source code: sympy (https://github.com/sympy/sympy)
- .../projects/sympy/sympy/solvers/tests/test_solvers.py:1216:18 - error: Operator "+" not supported for types "Basic" and "Expr" (reportOperatorIssue)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:315:25 - error: "Set" is not iterable
+ "__iter__" method not defined (reportGeneralTypeIssues)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:315:25 - error: "ConditionSet" is not iterable
+ "__iter__" method not defined (reportGeneralTypeIssues)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2030:20 - error: "__getitem__" method not defined on type "Basic" (reportIndexIssue)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2042:20 - error: "__getitem__" method not defined on type "Basic" (reportIndexIssue)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2055:20 - error: "__getitem__" method not defined on type "Basic" (reportIndexIssue)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2076:16 - error: Argument of type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" cannot be assigned to parameter "obj" of type "Sized" in function "len"
+ Type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" is not assignable to type "Sized"
+ "Set" is incompatible with protocol "Sized"
+ "__len__" is not present (reportArgumentType)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2077:20 - error: "__getitem__" method not defined on type "Basic" (reportIndexIssue)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2270:16 - error: Argument of type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" cannot be assigned to parameter "obj" of type "Sized" in function "len"
+ Type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" is not assignable to type "Sized"
+ "Set" is incompatible with protocol "Sized"
+ "__len__" is not present (reportArgumentType)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2351:16 - error: Argument of type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" cannot be assigned to parameter "obj" of type "Sized" in function "len"
+ Type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" is not assignable to type "Sized"
+ "Set" is incompatible with protocol "Sized"
+ "__len__" is not present (reportArgumentType)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2364:16 - error: Argument of type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" cannot be assigned to parameter "obj" of type "Sized" in function "len"
+ Type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" is not assignable to type "Sized"
+ "Set" is incompatible with protocol "Sized"
+ "__len__" is not present (reportArgumentType)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2370:16 - error: Argument of type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" cannot be assigned to parameter "obj" of type "Sized" in function "len"
+ Type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" is not assignable to type "Sized"
+ "Set" is incompatible with protocol "Sized"
+ "__len__" is not present (reportArgumentType)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2538:16 - error: Argument of type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" cannot be assigned to parameter "obj" of type "Sized" in function "len"
+ Type "Unknown | FiniteSet | Set | Intersection | Union | Complement | Any | ConditionSet" is not assignable to type "Sized"
+ "Set" is incompatible with protocol "Sized"
+ "__len__" is not present (reportArgumentType)
+ .../projects/sympy/sympy/solvers/tests/test_solveset.py:2541:20 - error: Argument of type "Unknown | Basic | Any" cannot be assigned to parameter "obj" of type "Sized" in function "len"
+ Type "Unknown | Basic | Any" is not assignable to type "Sized"
+ "Basic" is incompatible with protocol "Sized"
+ "__len__" is not present (reportArgumentType)
- .../projects/sympy/sympy/stats/crv_types.py:2544:9 - error: Method "_cdf" overrides class "SingleContinuousDistribution" in an incompatible manner
- Return type mismatch: base method returns type "None", override returns type "ComplexInfinity | NaN | Rational | Unknown | Zero | Expr"
- Type "ComplexInfinity | NaN | Rational | Unknown | Zero | Expr" is not assignable to type "None"
- "Expr" is not assignable to "None" (reportIncompatibleMethodOverride)
- .../projects/sympy/sympy/stats/crv_types.py:2723:9 - error: Method "_cdf" overrides class "SingleContinuousDistribution" in an incompatible manner
- Return type mismatch: base method returns type "None", override returns type "Expr | NaN | ComplexInfinity | Rational | Unknown | One | NegativeOne | Zero | Integer"
- Type "Expr | NaN | ComplexInfinity | Rational | Unknown | One | NegativeOne | Zero | Integer" is not assignable to type "None"
- "Expr" is not assignable to "None" (reportIncompatibleMethodOverride)
- .../projects/sympy/sympy/stats/drv.py:269:22 - error: Argument of type "Generator[tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Add | Zero | NaN | Piecewise | Basic | int | None, None, None]" cannot be assigned to parameter "iterable" of type "Iterable[_SupportsSumNoDefaultT@sum]" in function "sum"
+ .../projects/sympy/sympy/stats/drv.py:269:22 - error: Argument of type "Generator[tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Zero | NaN | Piecewise | Basic | int | None, None, None]" cannot be assigned to parameter "iterable" of type "Iterable[_SupportsSumNoDefaultT@sum]" in function "sum"
- "Generator[tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Add | Zero | NaN | Piecewise | Basic | int | None, None, None]" is not assignable to "Iterable[_SupportsSumNoDefaultT@sum]"
+ "Generator[tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Zero | NaN | Piecewise | Basic | int | None, None, None]" is not assignable to "Iterable[_SupportsSumNoDefaultT@sum]"
- Type parameter "_T_co@Iterable" is covariant, but "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Add | Zero | NaN | Piecewise | Basic | int | None" is not a subtype of "_SupportsSumNoDefaultT@sum"
+ Type parameter "_T_co@Iterable" is covariant, but "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Zero | NaN | Piecewise | Basic | int | None" is not a subtype of "_SupportsSumNoDefaultT@sum"
- Type "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Add | Zero | NaN | Piecewise | Basic | int | None" is not assignable to type "_SupportsSumWithNoDefaultGiven"
+ Type "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Zero | NaN | Piecewise | Basic | int | None" is not assignable to type "_SupportsSumWithNoDefaultGiven"
- Type "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Add | Zero | NaN | Piecewise | Basic | int | None" is not assignable to type "_SupportsSumWithNoDefaultGiven"
+ Type "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Zero | NaN | Piecewise | Basic | int | None" is not assignable to type "_SupportsSumWithNoDefaultGiven"
- .../projects/sympy/sympy/stats/drv_types.py:293:16 - error: Operator "*" not supported for types "Expr" and "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Add | Zero | NaN | Piecewise | Basic"
+ .../projects/sympy/sympy/stats/drv_types.py:293:16 - error: Operator "*" not supported for types "Expr" and "tuple[Unknown, ...] | Unknown | Sum | Expr | ZeroMatrix | Zero | NaN | Piecewise | Basic"
- .../projects/sympy/sympy/stats/frv_types.py:139:17 - error: Argument of type "NaN | ComplexInfinity | Rational | Unknown | Expr" cannot be assigned to parameter "value" of type "int" in function "__setitem__"
- Type "NaN | ComplexInfinity | Rational | Unknown | Expr" is not assignable to type "int"
- "Expr" is not assignable to "int" (reportArgumentType)
- .../projects/sympy/sympy/stats/rv.py:473:25 - error: Argument of type "Expr | Lambda | Zero | One | Integral | Unknown | Probability | tuple[Unknown, ...] | Sum | ZeroMatrix | Add | NaN | Piecewise | Basic | NegativeOne | Integer | ComplexInfinity | Rational | Infinity | NegativeInfinity | Float | Number | int" cannot be assigned to parameter "args" of type "Expr | complex" in function "__new__"
+ .../projects/sympy/sympy/stats/rv.py:473:25 - error: Argument of type "Expr | Lambda | Zero | One | Integral | Unknown | Probability | tuple[Unknown, ...] | Sum | ZeroMatrix | NaN | Piecewise | Basic | NegativeOne | Integer | ComplexInfinity | Rational | Infinity | NegativeInfinity | Float | Number | int" cannot be assigned to parameter "args" of type "Expr | complex" in function "__new__"
- Type "Expr | Lambda | Zero | One | Integral | Unknown | Probability | tuple[Unknown, ...] | Sum | ZeroMatrix | Add | NaN | Piecewise | Basic | NegativeOne | Integer | ComplexInfinity | Rational | Infinity | NegativeInfinity | Float | Number | int" is not assignable to type "Expr | complex"
+ Type "Expr | Lambda | Zero | One | Integral | Unknown | Probability | tuple[Unknown, ...] | Sum | ZeroMatrix | NaN | Piecewise | Basic | NegativeOne | Integer | ComplexInfinity | Rational | Infinity | NegativeInfinity | Float | Number | int" is not assignable to type "Expr | complex"
... (truncated 657 lines) ...
jax (https://github.com/google/jax)
- .../projects/jax/jax/experimental/mosaic/gpu/examples/flash_attention.py:222:20 - error: Module is not callable (reportCallIssue)
- .../projects/jax/jax/experimental/mosaic/gpu/examples/flash_attention.py:255:24 - error: Module is not callable (reportCallIssue)
- .../projects/jax/jax/experimental/mosaic/gpu/examples/flash_attention.py:444:18 - error: Module is not callable (reportCallIssue)
- .../projects/jax/jax/experimental/mosaic/gpu/examples/flash_attention.py:480:22 - error: Module is not callable (reportCallIssue)
- .../projects/jax/jax/experimental/mosaic/gpu/examples/matmul.py:91:11 - error: Module is not callable (reportCallIssue)
- .../projects/jax/jax/experimental/mosaic/gpu/examples/matmul.py:94:12 - error: Type "Unknown | WGMMAAccumulator" is not assignable to return type "dict[str, WGMMAAccumulator]"
+ .../projects/jax/jax/experimental/mosaic/gpu/examples/matmul.py:94:12 - error: Type "WGMMAAccumulator" is not assignable to return type "dict[str, WGMMAAccumulator]"
- Type "Unknown | WGMMAAccumulator" is not assignable to type "dict[str, WGMMAAccumulator]"
- "WGMMAAccumulator" is not assignable to "dict[str, WGMMAAccumulator]" (reportReturnType)
+ "WGMMAAccumulator" is not assignable to "dict[str, WGMMAAccumulator]" (reportReturnType)
- 3402 errors, 90 warnings, 0 informations
+ 3397 errors, 90 warnings, 0 informations
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
When a package re-exports (via a wildcard
from .sub import *) a name that is both an implicitly-imported submodule and a class of the same name, Pylance 1.1.410 incorrectly resolved the name to the submodule instead of the class. This broke using the name as a type annotation or calling it.How you figured out what to do
Reproduced the issue with a package whose submodule (
ImageView.py) defines a class (ImageView) re-exported through wildcard imports. The symbol ended up with multiple declarations: an implicit submodule alias and the class. The binder's multipart module-alias handling treated the wildcard re-export as a pure submodule re-export, shadowing the class even though the non-module declaration is the symbol's effective (last) declaration.Implementation
In
binder.ts, the wildcard re-export is now only treated as a pure submodule re-export when the module alias is the symbol's effective (last) declaration. When a later non-module declaration (the class) wins, the binder falls through to create a normal alias declaration that resolves to the winning symbol.Testing
Added a fourslash regression test (
import.multipartModuleClassShadow.fourslash.ts) that sets up a package re-exporting a class whose name matches a submodule. It verifies the name resolves totype[ImageView], can be used as a type annotation and called, with no diagnostics.Run with:
Addresses
Fixes https://github.com/microsoft/pylance-release/issues/11481
Generated by fix_all_my_issues pipeline