Skip to content

Commit 6f8b2d2

Browse files
committed
Merge remote-tracking branch 'upstream/master' into fix-generic-classvar
2 parents 0f61182 + 2ba79cb commit 6f8b2d2

File tree

8 files changed

+105
-4
lines changed

8 files changed

+105
-4
lines changed

docs/source/error_code_list2.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ Example:
616616
617617
.. _code-exhaustive-match:
618618

619-
Check that match statements match exhaustively [match-exhaustive]
619+
Check that match statements match exhaustively [exhaustive-match]
620620
-----------------------------------------------------------------------
621621

622622
If enabled with :option:`--enable-error-code exhaustive-match <mypy --enable-error-code>`,

mypy/checkexpr.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4288,7 +4288,9 @@ def check_boolean_op(self, e: OpExpr, context: Context) -> Type:
42884288
):
42894289
self.msg.unreachable_right_operand(e.op, e.right)
42904290

4291-
right_type = self.analyze_cond_branch(right_map, e.right, expanded_left_type)
4291+
right_type = self.analyze_cond_branch(
4292+
right_map, e.right, self._combined_context(expanded_left_type)
4293+
)
42924294

42934295
if left_map is None and right_map is None:
42944296
return UninhabitedType()
@@ -5919,6 +5921,16 @@ def analyze_cond_branch(
59195921
self.chk.push_type_map(map)
59205922
return self.accept(node, type_context=context, allow_none_return=allow_none_return)
59215923

5924+
def _combined_context(self, ty: Type | None) -> Type | None:
5925+
ctx_items = []
5926+
if ty is not None:
5927+
ctx_items.append(ty)
5928+
if self.type_context and self.type_context[-1] is not None:
5929+
ctx_items.append(self.type_context[-1])
5930+
if ctx_items:
5931+
return make_simplified_union(ctx_items)
5932+
return None
5933+
59225934
#
59235935
# Helpers
59245936
#

mypy/checkmember.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1234,14 +1234,20 @@ def analyze_class_attribute_access(
12341234
is_trivial_self = node.node.is_trivial_self
12351235
if isinstance(t, FunctionLike) and is_classmethod and not is_trivial_self:
12361236
t = check_self_arg(t, mx.self_type, False, mx.context, name, mx.msg)
1237-
result = add_class_tvars(
1237+
t = add_class_tvars(
12381238
t,
12391239
isuper,
12401240
is_classmethod,
12411241
mx,
12421242
original_vars=original_vars,
12431243
is_trivial_self=is_trivial_self,
12441244
)
1245+
if is_decorated and not is_staticmethod:
1246+
t = expand_self_type_if_needed(
1247+
t, mx, cast(Decorator, node.node).var, itype, is_class=is_classmethod
1248+
)
1249+
1250+
result = t
12451251
# __set__ is not called on class objects.
12461252
if not mx.is_lvalue:
12471253
result = analyze_descriptor_access(result, mx)

mypy/join.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,8 @@ def visit_literal_type(self, t: LiteralType) -> ProperType:
625625
if self.s.fallback.type.is_enum and t.fallback.type.is_enum:
626626
return mypy.typeops.make_simplified_union([self.s, t])
627627
return join_types(self.s.fallback, t.fallback)
628+
elif isinstance(self.s, Instance) and self.s.last_known_value == t:
629+
return t
628630
else:
629631
return join_types(self.s, t.fallback)
630632

mypyc/codegen/emitmodule.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ def generate_c_for_modules(self) -> list[tuple[str, str]]:
582582
fn, emitter, self.source_paths[module_name], module_name
583583
)
584584
if multi_file:
585-
name = f"__native_{emitter.names.private_name(module_name)}.c"
585+
name = f"__native_{exported_name(module_name)}.c"
586586
file_contents.append((name, "".join(emitter.fragments)))
587587

588588
# The external header file contains type declarations while

test-data/unit/check-inference-context.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,3 +1510,24 @@ def mymin(
15101510
def check(paths: Iterable[str], key: Callable[[str], int]) -> Union[str, None]:
15111511
return mymin(paths, key=key, default=None)
15121512
[builtins fixtures/tuple.pyi]
1513+
1514+
[case testBinaryOpInferenceContext]
1515+
from typing import Literal, TypeVar
1516+
1517+
T = TypeVar("T")
1518+
1519+
def identity(x: T) -> T:
1520+
return x
1521+
1522+
def check1(use: bool, val: str) -> "str | Literal[True]":
1523+
return use or identity(val)
1524+
1525+
def check2(use: bool, val: str) -> "str | bool":
1526+
return use or identity(val)
1527+
1528+
def check3(use: bool, val: str) -> "str | Literal[False]":
1529+
return use and identity(val)
1530+
1531+
def check4(use: bool, val: str) -> "str | bool":
1532+
return use and identity(val)
1533+
[builtins fixtures/tuple.pyi]

test-data/unit/check-literal.test

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2976,3 +2976,22 @@ x: Type[Literal[1]] # E: Type[...] can't contain "Literal[...]"
29762976
y: Type[Union[Literal[1], Literal[2]]] # E: Type[...] can't contain "Union[Literal[...], Literal[...]]"
29772977
z: Type[Literal[1, 2]] # E: Type[...] can't contain "Union[Literal[...], Literal[...]]"
29782978
[builtins fixtures/tuple.pyi]
2979+
2980+
[case testJoinLiteralAndInstance]
2981+
from typing import Generic, TypeVar, Literal
2982+
2983+
T = TypeVar("T")
2984+
2985+
class A(Generic[T]): ...
2986+
2987+
def f(a: A[T], t: T) -> T: ...
2988+
def g(a: T, t: A[T]) -> T: ...
2989+
2990+
def check(obj: A[Literal[1]]) -> None:
2991+
reveal_type(f(obj, 1)) # N: Revealed type is "Literal[1]"
2992+
reveal_type(f(obj, '')) # E: Cannot infer type argument 1 of "f" \
2993+
# N: Revealed type is "Any"
2994+
reveal_type(g(1, obj)) # N: Revealed type is "Literal[1]"
2995+
reveal_type(g('', obj)) # E: Cannot infer type argument 1 of "g" \
2996+
# N: Revealed type is "Any"
2997+
[builtins fixtures/tuple.pyi]

test-data/unit/check-selftype.test

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,3 +2232,44 @@ class X:
22322232
cls._inst = cls()
22332233
return cls._inst
22342234
[builtins fixtures/tuple.pyi]
2235+
2236+
[case testSelfInFuncDecoratedClassmethod]
2237+
from collections.abc import Callable
2238+
from typing import Self, TypeVar
2239+
2240+
T = TypeVar("T")
2241+
2242+
def debug(make: Callable[[type[T]], T]) -> Callable[[type[T]], T]:
2243+
return make
2244+
2245+
class Foo:
2246+
@classmethod
2247+
@debug
2248+
def make(cls) -> Self:
2249+
return cls()
2250+
2251+
class Bar(Foo): ...
2252+
2253+
reveal_type(Foo.make()) # N: Revealed type is "__main__.Foo"
2254+
reveal_type(Foo().make()) # N: Revealed type is "__main__.Foo"
2255+
reveal_type(Bar.make()) # N: Revealed type is "__main__.Bar"
2256+
reveal_type(Bar().make()) # N: Revealed type is "__main__.Bar"
2257+
[builtins fixtures/tuple.pyi]
2258+
2259+
[case testSelfInClassDecoratedClassmethod]
2260+
from typing import Callable, Generic, TypeVar, Self
2261+
2262+
T = TypeVar("T")
2263+
2264+
class W(Generic[T]):
2265+
def __init__(self, fn: Callable[..., T]) -> None: ...
2266+
def __call__(self) -> T: ...
2267+
2268+
class Check:
2269+
@W
2270+
def foo(self) -> Self:
2271+
...
2272+
2273+
reveal_type(Check.foo()) # N: Revealed type is "def () -> __main__.Check"
2274+
reveal_type(Check().foo()) # N: Revealed type is "__main__.Check"
2275+
[builtins fixtures/tuple.pyi]

0 commit comments

Comments
 (0)