Skip to content

Commit 705ffe4

Browse files
committed
Merge remote-tracking branch 'upstream/master' into ff-cache
2 parents 418fd1f + 206b739 commit 705ffe4

34 files changed

Lines changed: 1356 additions & 160 deletions

mypy/checker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5502,7 +5502,7 @@ def visit_with_stmt(self, s: WithStmt) -> None:
55025502
self.accept(s.body)
55035503

55045504
def check_untyped_after_decorator(self, typ: Type, func: FuncDef) -> None:
5505-
if not self.options.disallow_any_decorated or self.is_stub:
5505+
if not self.options.disallow_any_decorated or self.is_stub or self.current_node_deferred:
55065506
return
55075507

55085508
if mypy.checkexpr.has_any_type(typ):

mypy/semanal.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5332,13 +5332,15 @@ def visit_expression_stmt(self, s: ExpressionStmt) -> None:
53325332
s.expr.accept(self)
53335333

53345334
def visit_return_stmt(self, s: ReturnStmt) -> None:
5335+
old = self.statement
53355336
self.statement = s
53365337
if not self.is_func_scope():
53375338
self.fail('"return" outside function', s)
53385339
if self.return_stmt_inside_except_star_block:
53395340
self.fail('"return" not allowed in except* block', s, serious=True)
53405341
if s.expr:
53415342
s.expr.accept(self)
5343+
self.statement = old
53425344

53435345
def visit_raise_stmt(self, s: RaiseStmt) -> None:
53445346
self.statement = s

mypy/test/testsolve.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,14 @@ def test_multiple_variables(self) -> None:
6464
)
6565

6666
def test_no_constraints_for_var(self) -> None:
67-
self.assert_solve([self.fx.t], [], [self.fx.uninhabited])
68-
self.assert_solve([self.fx.t, self.fx.s], [], [self.fx.uninhabited, self.fx.uninhabited])
67+
self.assert_solve([self.fx.t], [], [self.fx.a_uninhabited])
68+
self.assert_solve(
69+
[self.fx.t, self.fx.s], [], [self.fx.a_uninhabited, self.fx.a_uninhabited]
70+
)
6971
self.assert_solve(
7072
[self.fx.t, self.fx.s],
7173
[self.supc(self.fx.s, self.fx.a)],
72-
[self.fx.uninhabited, self.fx.a],
74+
[self.fx.a_uninhabited, self.fx.a],
7375
)
7476

7577
def test_simple_constraints_with_dynamic_type(self) -> None:
@@ -116,7 +118,7 @@ def test_poly_no_constraints(self) -> None:
116118
self.assert_solve(
117119
[self.fx.t, self.fx.u],
118120
[],
119-
[self.fx.uninhabited, self.fx.uninhabited],
121+
[self.fx.a_uninhabited, self.fx.a_uninhabited],
120122
allow_polymorphic=True,
121123
)
122124

@@ -152,7 +154,7 @@ def test_poly_free_pair_with_bounds_uninhabited(self) -> None:
152154
self.assert_solve(
153155
[self.fx.ub, self.fx.uc],
154156
[self.subc(self.fx.ub, self.fx.uc)],
155-
[self.fx.uninhabited, self.fx.uninhabited],
157+
[self.fx.a_uninhabited, self.fx.a_uninhabited],
156158
[],
157159
allow_polymorphic=True,
158160
)

mypy/test/typefixture.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ def make_type_var(
7878
self.anyt = AnyType(TypeOfAny.special_form)
7979
self.nonet = NoneType()
8080
self.uninhabited = UninhabitedType()
81+
self.a_uninhabited = UninhabitedType()
82+
self.a_uninhabited.ambiguous = True
8183

8284
# Abstract class TypeInfos
8385

mypy/types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,10 +1386,10 @@ def accept(self, visitor: TypeVisitor[T]) -> T:
13861386
return visitor.visit_uninhabited_type(self)
13871387

13881388
def __hash__(self) -> int:
1389-
return hash(UninhabitedType)
1389+
return hash((UninhabitedType, self.ambiguous))
13901390

13911391
def __eq__(self, other: object) -> bool:
1392-
return isinstance(other, UninhabitedType)
1392+
return isinstance(other, UninhabitedType) and other.ambiguous == self.ambiguous
13931393

13941394
def serialize(self) -> JsonDict:
13951395
return {".class": "UninhabitedType"}

mypyc/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
MODULE_PREFIX: Final = "CPyModule_" # Cached modules
1616
TYPE_VAR_PREFIX: Final = "CPyTypeVar_" # Type variables when using new-style Python 3.12 syntax
1717
ATTR_PREFIX: Final = "_" # Attributes
18+
FAST_PREFIX: Final = "__mypyc_fast_" # Optimized methods in non-extension classes
1819

1920
ENV_ATTR_NAME: Final = "__mypyc_env__"
2021
NEXT_LABEL_ATTR_NAME: Final = "__mypyc_next_label__"

mypyc/ir/class_ir.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ def __init__(
210210
# per-type free "list" of up to length 1.
211211
self.reuse_freed_instance = False
212212

213+
# Is this a class inheriting from enum.Enum? Such classes can be special-cased.
214+
self.is_enum = False
215+
213216
def __repr__(self) -> str:
214217
return (
215218
"ClassIR("
@@ -410,6 +413,7 @@ def serialize(self) -> JsonDict:
410413
"init_self_leak": self.init_self_leak,
411414
"env_user_function": self.env_user_function.id if self.env_user_function else None,
412415
"reuse_freed_instance": self.reuse_freed_instance,
416+
"is_enum": self.is_enum,
413417
}
414418

415419
@classmethod
@@ -466,6 +470,7 @@ def deserialize(cls, data: JsonDict, ctx: DeserMaps) -> ClassIR:
466470
ctx.functions[data["env_user_function"]] if data["env_user_function"] else None
467471
)
468472
ir.reuse_freed_instance = data["reuse_freed_instance"]
473+
ir.is_enum = data["is_enum"]
469474

470475
return ir
471476

mypyc/ir/rtypes.py

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ def may_be_immortal(self) -> bool:
192192
def serialize(self) -> str:
193193
return "void"
194194

195-
def __eq__(self, other: object) -> bool:
195+
def __eq__(self, other: object) -> TypeGuard[RVoid]:
196196
return isinstance(other, RVoid)
197197

198198
def __hash__(self) -> int:
@@ -279,7 +279,7 @@ def serialize(self) -> str:
279279
def __repr__(self) -> str:
280280
return "<RPrimitive %s>" % self.name
281281

282-
def __eq__(self, other: object) -> bool:
282+
def __eq__(self, other: object) -> TypeGuard[RPrimitive]:
283283
return isinstance(other, RPrimitive) and other.name == self.name
284284

285285
def __hash__(self) -> int:
@@ -522,15 +522,15 @@ def is_native_rprimitive(rtype: RType) -> bool:
522522
return isinstance(rtype, RPrimitive) and rtype.name in KNOWN_NATIVE_TYPES
523523

524524

525-
def is_tagged(rtype: RType) -> bool:
525+
def is_tagged(rtype: RType) -> TypeGuard[RPrimitive]:
526526
return rtype is int_rprimitive or rtype is short_int_rprimitive
527527

528528

529-
def is_int_rprimitive(rtype: RType) -> bool:
529+
def is_int_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
530530
return rtype is int_rprimitive
531531

532532

533-
def is_short_int_rprimitive(rtype: RType) -> bool:
533+
def is_short_int_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
534534
return rtype is short_int_rprimitive
535535

536536

@@ -544,7 +544,7 @@ def is_int32_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
544544
)
545545

546546

547-
def is_int64_rprimitive(rtype: RType) -> bool:
547+
def is_int64_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
548548
return rtype is int64_rprimitive or (
549549
rtype is c_pyssize_t_rprimitive and rtype._ctype == "int64_t"
550550
)
@@ -563,81 +563,93 @@ def is_uint8_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
563563
return rtype is uint8_rprimitive
564564

565565

566-
def is_uint32_rprimitive(rtype: RType) -> bool:
566+
def is_uint32_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
567567
return rtype is uint32_rprimitive
568568

569569

570-
def is_uint64_rprimitive(rtype: RType) -> bool:
570+
def is_uint64_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
571571
return rtype is uint64_rprimitive
572572

573573

574-
def is_c_py_ssize_t_rprimitive(rtype: RType) -> bool:
574+
def is_c_py_ssize_t_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
575575
return rtype is c_pyssize_t_rprimitive
576576

577577

578-
def is_pointer_rprimitive(rtype: RType) -> bool:
578+
def is_pointer_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
579579
return rtype is pointer_rprimitive
580580

581581

582-
def is_float_rprimitive(rtype: RType) -> bool:
582+
def is_float_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
583583
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.float"
584584

585585

586-
def is_bool_rprimitive(rtype: RType) -> bool:
586+
def is_bool_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
587587
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.bool"
588588

589589

590-
def is_bit_rprimitive(rtype: RType) -> bool:
590+
def is_bit_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
591591
return isinstance(rtype, RPrimitive) and rtype.name == "bit"
592592

593593

594-
def is_bool_or_bit_rprimitive(rtype: RType) -> bool:
594+
def is_bool_or_bit_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
595595
return is_bool_rprimitive(rtype) or is_bit_rprimitive(rtype)
596596

597597

598-
def is_object_rprimitive(rtype: RType) -> bool:
598+
def is_object_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
599599
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.object"
600600

601601

602-
def is_none_rprimitive(rtype: RType) -> bool:
602+
def is_none_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
603603
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.None"
604604

605605

606-
def is_list_rprimitive(rtype: RType) -> bool:
606+
def is_list_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
607607
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.list"
608608

609609

610-
def is_dict_rprimitive(rtype: RType) -> bool:
610+
def is_dict_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
611611
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.dict"
612612

613613

614-
def is_set_rprimitive(rtype: RType) -> bool:
614+
def is_set_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
615615
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.set"
616616

617617

618-
def is_frozenset_rprimitive(rtype: RType) -> bool:
618+
def is_frozenset_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
619619
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.frozenset"
620620

621621

622-
def is_str_rprimitive(rtype: RType) -> bool:
622+
def is_str_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
623623
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.str"
624624

625625

626-
def is_bytes_rprimitive(rtype: RType) -> bool:
626+
def is_bytes_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
627627
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.bytes"
628628

629629

630-
def is_tuple_rprimitive(rtype: RType) -> bool:
630+
def is_tuple_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
631631
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.tuple"
632632

633633

634-
def is_range_rprimitive(rtype: RType) -> bool:
634+
def is_range_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
635635
return isinstance(rtype, RPrimitive) and rtype.name == "builtins.range"
636636

637637

638-
def is_sequence_rprimitive(rtype: RType) -> bool:
638+
def is_sequence_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
639639
return isinstance(rtype, RPrimitive) and (
640-
is_list_rprimitive(rtype) or is_tuple_rprimitive(rtype) or is_str_rprimitive(rtype)
640+
is_list_rprimitive(rtype)
641+
or is_tuple_rprimitive(rtype)
642+
or is_str_rprimitive(rtype)
643+
or is_bytes_rprimitive(rtype)
644+
)
645+
646+
647+
def is_immutable_rprimitive(rtype: RType) -> TypeGuard[RPrimitive]:
648+
return (
649+
is_str_rprimitive(rtype)
650+
or is_bytes_rprimitive(rtype)
651+
or is_tuple_rprimitive(rtype)
652+
or is_frozenset_rprimitive(rtype)
641653
)
642654

643655

@@ -726,7 +738,7 @@ def __str__(self) -> str:
726738
def __repr__(self) -> str:
727739
return "<RTuple %s>" % ", ".join(repr(typ) for typ in self.types)
728740

729-
def __eq__(self, other: object) -> bool:
741+
def __eq__(self, other: object) -> TypeGuard[RTuple]:
730742
return isinstance(other, RTuple) and self.types == other.types
731743

732744
def __hash__(self) -> int:
@@ -859,7 +871,7 @@ def __repr__(self) -> str:
859871
", ".join(name + ":" + repr(typ) for name, typ in zip(self.names, self.types)),
860872
)
861873

862-
def __eq__(self, other: object) -> bool:
874+
def __eq__(self, other: object) -> TypeGuard[RStruct]:
863875
return (
864876
isinstance(other, RStruct)
865877
and self.name == other.name
@@ -929,7 +941,7 @@ def attr_type(self, name: str) -> RType:
929941
def __repr__(self) -> str:
930942
return "<RInstance %s>" % self.name
931943

932-
def __eq__(self, other: object) -> bool:
944+
def __eq__(self, other: object) -> TypeGuard[RInstance]:
933945
return isinstance(other, RInstance) and other.name == self.name
934946

935947
def __hash__(self) -> int:
@@ -983,7 +995,7 @@ def __str__(self) -> str:
983995
return "union[%s]" % ", ".join(str(item) for item in self.items)
984996

985997
# We compare based on the set because order in a union doesn't matter
986-
def __eq__(self, other: object) -> bool:
998+
def __eq__(self, other: object) -> TypeGuard[RUnion]:
987999
return isinstance(other, RUnion) and self.items_set == other.items_set
9881000

9891001
def __hash__(self) -> int:
@@ -1025,7 +1037,7 @@ def optional_value_type(rtype: RType) -> RType | None:
10251037
return None
10261038

10271039

1028-
def is_optional_type(rtype: RType) -> bool:
1040+
def is_optional_type(rtype: RType) -> TypeGuard[RUnion]:
10291041
"""Is rtype an optional type with exactly two union items?"""
10301042
return optional_value_type(rtype) is not None
10311043

@@ -1057,7 +1069,7 @@ def __str__(self) -> str:
10571069
def __repr__(self) -> str:
10581070
return f"<RArray {self.item_type!r}[{self.length}]>"
10591071

1060-
def __eq__(self, other: object) -> bool:
1072+
def __eq__(self, other: object) -> TypeGuard[RArray]:
10611073
return (
10621074
isinstance(other, RArray)
10631075
and self.item_type == other.item_type

mypyc/irbuild/builder.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
RType,
9292
RUnion,
9393
bitmap_rprimitive,
94+
bytes_rprimitive,
9495
c_pyssize_t_rprimitive,
9596
dict_rprimitive,
9697
int_rprimitive,
@@ -962,8 +963,12 @@ def get_sequence_type_from_type(self, target_type: Type) -> RType:
962963
elif isinstance(target_type, Instance):
963964
if target_type.type.fullname == "builtins.str":
964965
return str_rprimitive
965-
else:
966+
elif target_type.type.fullname == "builtins.bytes":
967+
return bytes_rprimitive
968+
try:
966969
return self.type_to_rtype(target_type.args[0])
970+
except IndexError:
971+
raise ValueError(f"{target_type!r} is not a valid sequence.") from None
967972
# This elif-blocks are needed for iterating over classes derived from NamedTuple.
968973
elif isinstance(target_type, TypeVarLikeType):
969974
return self.get_sequence_type_from_type(target_type.upper_bound)

mypyc/irbuild/classdef.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
)
6767
from mypyc.irbuild.prepare import GENERATOR_HELPER_NAME
6868
from mypyc.irbuild.util import dataclass_type, get_func_def, is_constant, is_dataclass_decorator
69-
from mypyc.primitives.dict_ops import dict_new_op, dict_set_item_op
69+
from mypyc.primitives.dict_ops import dict_new_op, exact_dict_set_item_op
7070
from mypyc.primitives.generic_ops import (
7171
iter_op,
7272
next_op,
@@ -271,8 +271,8 @@ def finalize(self, ir: ClassIR) -> None:
271271
)
272272

273273
# Add the non-extension class to the dict
274-
self.builder.primitive_op(
275-
dict_set_item_op,
274+
self.builder.call_c(
275+
exact_dict_set_item_op,
276276
[
277277
self.builder.load_globals_dict(),
278278
self.builder.load_str(self.cdef.name),
@@ -487,8 +487,10 @@ def allocate_class(builder: IRBuilder, cdef: ClassDef) -> Value:
487487
builder.add(InitStatic(tp, cdef.name, builder.module_name, NAMESPACE_TYPE))
488488

489489
# Add it to the dict
490-
builder.primitive_op(
491-
dict_set_item_op, [builder.load_globals_dict(), builder.load_str(cdef.name), tp], cdef.line
490+
builder.call_c(
491+
exact_dict_set_item_op,
492+
[builder.load_globals_dict(), builder.load_str(cdef.name), tp],
493+
cdef.line,
492494
)
493495

494496
return tp
@@ -672,7 +674,7 @@ def add_non_ext_class_attr_ann(
672674
typ = builder.add(LoadAddress(type_object_op.type, type_object_op.src, stmt.line))
673675

674676
key = builder.load_str(lvalue.name)
675-
builder.primitive_op(dict_set_item_op, [non_ext.anns, key, typ], stmt.line)
677+
builder.call_c(exact_dict_set_item_op, [non_ext.anns, key, typ], stmt.line)
676678

677679

678680
def add_non_ext_class_attr(

0 commit comments

Comments
 (0)