Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
91228b1
Some foundation
ilevkivskyi Mar 27, 2026
beeb100
Remove guard for overloads
ilevkivskyi Mar 27, 2026
6af211e
Mark some generated things as generated
ilevkivskyi Mar 27, 2026
eb41ad2
Write indirect dependencies separately
ilevkivskyi Mar 29, 2026
f3b4878
Fix fixing awaitable generator
ilevkivskyi Mar 29, 2026
025a25d
Check initializers as part of top levels
ilevkivskyi Mar 29, 2026
ed1cdc6
Do not double-process methods in nested classes
ilevkivskyi Mar 29, 2026
966020b
Simplify class checker scope
ilevkivskyi Mar 29, 2026
c30a0d2
Fix function redefinition
ilevkivskyi Mar 29, 2026
d2c6312
Make decorator inference in semanal consistent with checker
ilevkivskyi Mar 29, 2026
efd98b3
Skip/tweak some more tests
ilevkivskyi Mar 29, 2026
36f9d8f
Split remaining two tests
ilevkivskyi Mar 29, 2026
2e5f7d5
Cleanups/comments
ilevkivskyi Mar 31, 2026
59ea2a0
Some more comments and refactoring
ilevkivskyi Mar 31, 2026
0ddd940
Add a test for accidental discord.py fix
ilevkivskyi Apr 6, 2026
c79069b
Merge remote-tracking branch 'upstream/master' into intf-impl-parallel
ilevkivskyi Apr 6, 2026
1dd01db
Reset lambda argument types in empty context
ilevkivskyi Apr 10, 2026
47bcf75
Merge remote-tracking branch 'upstream/master' into intf-impl-parallel
ilevkivskyi Apr 10, 2026
106c8a6
Apply the blocker error fix
ilevkivskyi Apr 10, 2026
a068037
Another little optimization
ilevkivskyi Apr 11, 2026
19b2445
Get rid of intermediate ack; update docstring
ilevkivskyi Apr 12, 2026
cad8624
Merge remote-tracking branch 'upstream/master' into intf-impl-parallel
ilevkivskyi Apr 13, 2026
484d26d
Refactor stats to record all sends
ilevkivskyi Apr 13, 2026
ce41436
Merge remote-tracking branch 'upstream/master' into intf-impl-parallel
ilevkivskyi Apr 13, 2026
27d6bae
Some more CR
ilevkivskyi Apr 13, 2026
1bd047b
Some final touches
ilevkivskyi Apr 14, 2026
6aa0c6e
Merge remote-tracking branch 'upstream/master' into intf-impl-parallel
ilevkivskyi Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Check initializers as part of top levels
  • Loading branch information
ilevkivskyi committed Mar 29, 2026
commit 025a25dde9c0caf499f0e778b69a1ed3aa56d2cc
26 changes: 21 additions & 5 deletions mypy/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,13 @@ def _visit_overloaded_func_def(self, defn: OverloadedFuncDef) -> None:
settable = defn.items[0].var.is_settable_property
# Do not visit the second time the items we checked above.
if (settable and i > 1) or (not settable and i > 0):
# Type check initialization expressions.
def_item = defn.items[0].func
body_is_trivial = is_trivial_body(def_item.body)
if not self.can_skip_diagnostics:
self.dynamic_funcs.append(def_item.is_dynamic())
self.check_default_params(def_item, body_is_trivial)
self.dynamic_funcs.pop()
self.check_func_item(fdef.func, name=fdef.func.name, allow_empty=True)
else:
# Perform full check for real overloads to infer type of all decorated
Expand Down Expand Up @@ -1192,6 +1199,12 @@ def get_generator_return_type(self, return_type: Type, is_coroutine: bool) -> Ty
return NoneType()

def visit_func_def(self, defn: FuncDef) -> None:
# Type check initialization expressions.
body_is_trivial = is_trivial_body(defn.body)
if not self.can_skip_diagnostics:
self.dynamic_funcs.append(defn.is_dynamic())
self.check_default_params(defn, body_is_trivial)
self.dynamic_funcs.pop()
if not self.recurse_into_functions and not defn.def_or_infer_vars:
return
with self.tscope.function_scope(defn), self.set_recurse_into_functions():
Expand Down Expand Up @@ -1362,11 +1375,6 @@ def check_func_def(
# Need to store arguments again for the expanded item.
store_argument_type(item, i, typ, self.named_generic_type)

# Type check initialization expressions.
body_is_trivial = is_trivial_body(defn.body)
if not self.can_skip_diagnostics:
self.check_default_params(item, body_is_trivial)

# Type check body in a new scope.
with self.binder.top_frame_context():
# Copy some type narrowings from an outer function when it seems safe enough
Expand Down Expand Up @@ -1423,6 +1431,7 @@ def check_func_def(
self.binder.pop_frame(True, 0)

if not unreachable:
body_is_trivial = is_trivial_body(defn.body)
if defn.is_generator or is_named_instance(
self.return_types[-1], "typing.AwaitableGenerator"
):
Expand Down Expand Up @@ -5601,6 +5610,13 @@ def visit_decorator_inner(
typ = defn.type.copy_modified(ret_type=ret_type)
defn.type = typ

# Type check initialization expressions.
body_is_trivial = is_trivial_body(defn.body)
if not self.can_skip_diagnostics:
self.dynamic_funcs.append(defn.is_dynamic())
self.check_default_params(defn, body_is_trivial)
self.dynamic_funcs.pop()

if self.recurse_into_functions or e.func.def_or_infer_vars:
with self.tscope.function_scope(e.func), self.set_recurse_into_functions():
self.check_func_item(e.func, name=e.func.name, allow_empty=allow_empty)
Expand Down
7 changes: 2 additions & 5 deletions test-data/unit/check-final.test
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ reveal_type(C().f) # N: Revealed type is "Overload(def (x: builtins.int) -> bui
[case testFinalDefiningMethOverloadedStubs]
from mod import C

reveal_type(C().f)
reveal_type(C().f) # N: Revealed type is "Overload(def (x: builtins.int) -> builtins.int, def (x: builtins.str) -> builtins.str)"
[file mod.pyi]
from typing import final, overload

Expand All @@ -157,12 +157,9 @@ class C:

@overload
def bad(self, x: int) -> int: ...
@final # Error!
@final # E: In a stub file @final must be applied only to the first overload
@overload
def bad(self, x: str) -> str: ...
[out]
tmp/mod.pyi:12: error: In a stub file @final must be applied only to the first overload
main:3: note: Revealed type is "Overload(def (x: builtins.int) -> builtins.int, def (x: builtins.str) -> builtins.str)"

[case testFinalDefiningProperty]
from typing import final
Expand Down
7 changes: 2 additions & 5 deletions test-data/unit/check-inference.test
Original file line number Diff line number Diff line change
Expand Up @@ -2412,15 +2412,12 @@ class R:
[case testMultipassAndMultipleFiles]
import m
def f() -> None:
x()
x() # E: "int" not callable
x = 0
[file m.py]
def g() -> None:
y()
y() # E: "int" not callable
y = 0
[out]
tmp/m.py:2: error: "int" not callable
main:3: error: "int" not callable

[case testForwardReferenceToDecoratedClassMethod]
from typing import TypeVar, Callable
Expand Down
42 changes: 10 additions & 32 deletions test-data/unit/check-modules.test
Original file line number Diff line number Diff line change
Expand Up @@ -365,23 +365,20 @@ main:4: error: Too many arguments for "x"
[case testRelativeImports]
import typing
import m.a
m.a.x = m.a.y # Error
m.a.x = m.a.y # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[file m/__init__.py]
[file m/a.py]
import typing
from .b import A, B, x, y
z = x
if int():
z = y # Error
z = y # E: Incompatible types in assignment (expression has type "B", variable has type "A")
[file m/b.py]
import typing
class A: pass
class B: pass
x = A()
y = B()
[out]
tmp/m/a.py:5: error: Incompatible types in assignment (expression has type "B", variable has type "A")
main:3: error: Incompatible types in assignment (expression has type "B", variable has type "A")

[case testRelativeImports2]
import typing
Expand Down Expand Up @@ -2083,29 +2080,19 @@ def __getattr__(name: str) -> str: ...
[case testModuleLevelGetattrInvalidSignature]
import has_getattr

reveal_type(has_getattr.any_attribute)
reveal_type(has_getattr.any_attribute) # N: Revealed type is "builtins.str"

[file has_getattr.pyi]
def __getattr__(x: int, y: str) -> str: ...

[out]
tmp/has_getattr.pyi:1: error: Invalid signature "Callable[[int, str], str]" for "__getattr__"
main:3: note: Revealed type is "builtins.str"

def __getattr__(x: int, y: str) -> str: ... # E: Invalid signature "Callable[[int, str], str]" for "__getattr__"
[builtins fixtures/module.pyi]

[case testModuleLevelGetattrNotCallable]
import has_getattr

reveal_type(has_getattr.any_attribute)
reveal_type(has_getattr.any_attribute) # N: Revealed type is "Any"

[file has_getattr.pyi]
__getattr__ = 3

[out]
tmp/has_getattr.pyi:1: error: Invalid signature "int" for "__getattr__"
main:3: note: Revealed type is "Any"

__getattr__ = 3 # E: Invalid signature "int" for "__getattr__"
[builtins fixtures/module.pyi]

[case testModuleLevelGetattrUntyped]
Expand Down Expand Up @@ -2195,17 +2182,13 @@ __getattr__ = make_getattr_good() # OK

[case testModuleLevelGetattrAssignedBad]
import non_stub
reveal_type(non_stub.name)
reveal_type(non_stub.name) # N: Revealed type is "builtins.int"

[file non_stub.py]
from typing import Callable

def make_getattr_bad() -> Callable[[], int]: ...
__getattr__ = make_getattr_bad()

[out]
tmp/non_stub.py:4: error: Invalid signature "Callable[[], int]" for "__getattr__"
main:2: note: Revealed type is "builtins.int"
__getattr__ = make_getattr_bad() # E: Invalid signature "Callable[[], int]" for "__getattr__"

[case testModuleLevelGetattrImportedGood]
import non_stub
Expand All @@ -2219,18 +2202,13 @@ def __getattr__(name: str) -> int: ...

[case testModuleLevelGetattrImportedBad]
import non_stub
reveal_type(non_stub.name)
reveal_type(non_stub.name) # N: Revealed type is "builtins.int"

[file non_stub.py]
from has_getattr import __getattr__

[file has_getattr.py]
def __getattr__() -> int: ...

[out]
tmp/has_getattr.py:1: error: Invalid signature "Callable[[], int]" for "__getattr__"
main:2: note: Revealed type is "builtins.int"

def __getattr__() -> int: ... # E: Invalid signature "Callable[[], int]" for "__getattr__"
[builtins fixtures/module.pyi]

-- Parallel mode gives only_once notes once *per worker*
Expand Down
45 changes: 12 additions & 33 deletions test-data/unit/check-newsemanal.test
Original file line number Diff line number Diff line change
Expand Up @@ -231,26 +231,21 @@ import a
class T1(TypedDict):
x: A
class A: pass
reveal_type(T1(x=A())) # E
reveal_type(T1(x=A())) # N: Revealed type is "TypedDict('__main__.T1', {'x': __main__.A})"

[file a.py]
from typing import TypedDict
from b import TD1 as TD2, TD3
class T2(TD3):
x: int
reveal_type(T2(x=2)) # E
reveal_type(T2(x=2)) # N: Revealed type is "TypedDict('a.T2', {'x': builtins.int})"

[file b.py]
from a import TypedDict as TD1
from a import TD2 as TD3
[builtins fixtures/dict.pyi]
[typing fixtures/typing-typeddict.pyi]

[out]
tmp/a.py:5: note: Revealed type is "TypedDict('a.T2', {'x': builtins.int})"
main:6: note: Revealed type is "TypedDict('__main__.T1', {'x': __main__.A})"


[case testNewAnalyzerTypedDictClassInheritance]
from typing import TypedDict

Expand Down Expand Up @@ -2783,13 +2778,13 @@ t = typing.typevar('t') # E: Module has no attribute "typevar"

[case testNewAnalyzerImportFromTopLevelFunction]
import a.b # This works at runtime
reveal_type(a.b) # N
reveal_type(a.b) # N: Revealed type is "def ()"
[file a/__init__.py]
from .b import B
from . import b as c
def b() -> None: pass
reveal_type(b) # N
reveal_type(c.B()) # N
reveal_type(b) # N: Revealed type is "def ()"
reveal_type(c.B()) # N: Revealed type is "a.b.B"
x: Forward
class Forward:
...
Expand All @@ -2798,21 +2793,16 @@ class Forward:
class B: ...
[builtins fixtures/module.pyi]

[out]
tmp/a/__init__.py:4: note: Revealed type is "def ()"
tmp/a/__init__.py:5: note: Revealed type is "a.b.B"
main:2: note: Revealed type is "def ()"

[case testNewAnalyzerImportFromTopLevelAlias]
import a.b # This works at runtime
reveal_type(a.b) # N
reveal_type(a.b) # N: Revealed type is "def () -> builtins.int"
[file a/__init__.py]
from .b import B
from . import b as c
b = int
y: b
reveal_type(y) # N
reveal_type(c.B) # N
reveal_type(y) # N: Revealed type is "builtins.int"
reveal_type(c.B) # N: Revealed type is "def () -> a.b.B"
x: Forward
class Forward:
...
Expand All @@ -2821,21 +2811,16 @@ class Forward:
class B: ...
[builtins fixtures/module.pyi]

[out]
tmp/a/__init__.py:5: note: Revealed type is "builtins.int"
tmp/a/__init__.py:6: note: Revealed type is "def () -> a.b.B"
main:2: note: Revealed type is "def () -> builtins.int"

[case testNewAnalyzerImportAmbiguousWithTopLevelFunction]
import a.b # This works at runtime
x: a.b.B # E
reveal_type(a.b) # N
x: a.b.B # E: Name "a.b.B" is not defined
reveal_type(a.b) # N: Revealed type is "def ()"
[file a/__init__.py]
import a.b
import a.b as c
def b() -> None: pass
reveal_type(b) # N
reveal_type(c.B()) # N
reveal_type(b) # N: Revealed type is "def ()"
reveal_type(c.B()) # N: Revealed type is "a.b.B"
x: Forward
class Forward:
...
Expand All @@ -2844,12 +2829,6 @@ class Forward:
class B: ...
[builtins fixtures/module.pyi]

[out]
tmp/a/__init__.py:4: note: Revealed type is "def ()"
tmp/a/__init__.py:5: note: Revealed type is "a.b.B"
main:2: error: Name "a.b.B" is not defined
main:3: note: Revealed type is "def ()"

[case testNewAnalyzerConfusingImportConflictingNames]
# flags: --follow-imports=skip --ignore-missing-imports
# cmd: mypy -m other a.b a
Expand Down