Skip to content

Commit 3bc82e6

Browse files
committed
Merge remote-tracking branch 'upstream/master' into librt_base64_simd_cpu_dispatch
2 parents d0eda17 + 1f09855 commit 3bc82e6

24 files changed

+1095
-36
lines changed

mypy/nodes.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3732,12 +3732,18 @@ def get_method(self, name: str) -> FuncBase | Decorator | None:
37323732
for cls in self.mro:
37333733
if name in cls.names:
37343734
node = cls.names[name].node
3735-
if isinstance(node, SYMBOL_FUNCBASE_TYPES):
3736-
return node
3737-
elif isinstance(node, Decorator): # Two `if`s make `mypyc` happy
3738-
return node
3739-
else:
3740-
return None
3735+
elif possible_redefinitions := sorted(
3736+
[n for n in cls.names.keys() if n.startswith(f"{name}-redefinition")]
3737+
):
3738+
node = cls.names[possible_redefinitions[-1]].node
3739+
else:
3740+
continue
3741+
if isinstance(node, SYMBOL_FUNCBASE_TYPES):
3742+
return node
3743+
elif isinstance(node, Decorator): # Two `if`s make `mypyc` happy
3744+
return node
3745+
else:
3746+
return None
37413747
return None
37423748

37433749
def calculate_metaclass_type(self) -> mypy.types.Instance | None:

mypy/partially_defined.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,13 @@ def __init__(self) -> None:
206206
# disable_branch_skip is used to disable skipping a branch due to a return/raise/etc. This is useful
207207
# in things like try/except/finally statements.
208208
self.disable_branch_skip = False
209+
self.in_finally = False
209210

210211
def copy(self) -> DefinedVariableTracker:
211212
result = DefinedVariableTracker()
212213
result.scopes = [s.copy() for s in self.scopes]
213214
result.disable_branch_skip = self.disable_branch_skip
215+
result.in_finally = self.in_finally
214216
return result
215217

216218
def _scope(self) -> Scope:
@@ -579,7 +581,9 @@ def process_try_stmt(self, o: TryStmt) -> None:
579581
self.tracker.end_branch_statement()
580582

581583
if o.finally_body is not None:
584+
self.tracker.in_finally = True
582585
o.finally_body.accept(self)
586+
self.tracker.in_finally = False
583587

584588
def visit_while_stmt(self, o: WhileStmt) -> None:
585589
o.expr.accept(self)
@@ -620,7 +624,10 @@ def visit_starred_pattern(self, o: StarredPattern) -> None:
620624
def visit_name_expr(self, o: NameExpr) -> None:
621625
if o.name in self.builtins and self.tracker.in_scope(ScopeType.Global):
622626
return
623-
if self.tracker.is_possibly_undefined(o.name):
627+
if (
628+
self.tracker.is_possibly_undefined(o.name)
629+
and self.tracker.in_finally == self.tracker.disable_branch_skip
630+
):
624631
# A variable is only defined in some branches.
625632
self.variable_may_be_undefined(o.name, o)
626633
# We don't want to report the error on the same variable multiple times.

mypy/semanal.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7030,7 +7030,12 @@ def add_symbol_table_node(
70307030
if not is_same_symbol(old, new):
70317031
if isinstance(new, (FuncDef, Decorator, OverloadedFuncDef, TypeInfo)):
70327032
self.add_redefinition(names, name, symbol)
7033-
if not (isinstance(new, (FuncDef, Decorator)) and self.set_original_def(old, new)):
7033+
if isinstance(old, Var) and is_init_only(old):
7034+
if old.has_explicit_value:
7035+
self.fail("InitVar with default value cannot be redefined", context)
7036+
elif not (
7037+
isinstance(new, (FuncDef, Decorator)) and self.set_original_def(old, new)
7038+
):
70347039
self.name_already_defined(name, context, existing)
70357040
elif type_param or (
70367041
name not in self.missing_names[-1] and "*" not in self.missing_names[-1]
@@ -8279,3 +8284,10 @@ def halt(self, reason: str = ...) -> NoReturn:
82798284
return isinstance(stmt, PassStmt) or (
82808285
isinstance(stmt, ExpressionStmt) and isinstance(stmt.expr, EllipsisExpr)
82818286
)
8287+
8288+
8289+
def is_init_only(node: Var) -> bool:
8290+
return (
8291+
isinstance(type := get_proper_type(node.type), Instance)
8292+
and type.type.fullname == "dataclasses.InitVar"
8293+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from typing import final
2+
3+
from mypy_extensions import i64, u8
4+
5+
@final
6+
class BytesWriter:
7+
def append(self, /, x: int) -> None: ...
8+
def write(self, /, b: bytes) -> None: ...
9+
def getvalue(self) -> bytes: ...
10+
def truncate(self, /, size: i64) -> None: ...
11+
def __len__(self) -> i64: ...
12+
def __getitem__(self, /, i: i64) -> u8: ...
13+
def __setitem__(self, /, i: i64, x: u8) -> None: ...

mypy/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
# - Release versions have the form "1.2.3".
99
# - Dev versions have the form "1.2.3+dev" (PLUS sign to conform to PEP 440).
1010
# - Before 1.0 we had the form "0.NNN".
11-
__version__ = "1.19.0+dev"
11+
__version__ = "1.20.0+dev"
1212
base_version = __version__
1313

1414
mypy_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))

mypyc/build.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class ModDesc(NamedTuple):
5353

5454
LIBRT_MODULES = [
5555
ModDesc("librt.internal", ["librt_internal.c"], [], []),
56+
ModDesc("librt.strings", ["librt_strings.c"], [], []),
5657
ModDesc(
5758
"librt.base64",
5859
[

mypyc/codegen/emitmodule.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,8 @@ def generate_c_for_modules(self) -> list[tuple[str, str]]:
611611
ext_declarations.emit_line("#include <librt_internal.h>")
612612
if any("librt.base64" in mod.capsules for mod in self.modules.values()):
613613
ext_declarations.emit_line("#include <librt_base64.h>")
614+
if any("librt.strings" in mod.capsules for mod in self.modules.values()):
615+
ext_declarations.emit_line("#include <librt_strings.h>")
614616

615617
declarations = Emitter(self.context)
616618
declarations.emit_line(f"#ifndef MYPYC_LIBRT_INTERNAL{self.group_suffix}_H")
@@ -1045,6 +1047,10 @@ def emit_module_exec_func(
10451047
emitter.emit_line("if (import_librt_base64() < 0) {")
10461048
emitter.emit_line("return -1;")
10471049
emitter.emit_line("}")
1050+
if "librt.strings" in module.capsules:
1051+
emitter.emit_line("if (import_librt_strings() < 0) {")
1052+
emitter.emit_line("return -1;")
1053+
emitter.emit_line("}")
10481054
emitter.emit_line("PyObject* modname = NULL;")
10491055
if self.multi_phase_init:
10501056
emitter.emit_line(f"{module_static} = module;")

mypyc/ir/ops.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,15 @@ class to enable the new behavior. Sometimes adding a new abstract
3737
RStruct,
3838
RTuple,
3939
RType,
40+
RUnion,
4041
RVoid,
4142
bit_rprimitive,
4243
bool_rprimitive,
4344
cstring_rprimitive,
4445
float_rprimitive,
4546
int_rprimitive,
4647
is_bool_or_bit_rprimitive,
48+
is_fixed_width_rtype,
4749
is_int_rprimitive,
4850
is_none_rprimitive,
4951
is_pointer_rprimitive,
@@ -688,7 +690,7 @@ class PrimitiveDescription:
688690
Primitives get lowered into lower-level ops before code generation.
689691
690692
If c_function_name is provided, a primitive will be lowered into a CallC op.
691-
Otherwise custom logic will need to be implemented to transform the
693+
Otherwise, custom logic will need to be implemented to transform the
692694
primitive into lower-level ops.
693695
"""
694696

@@ -737,11 +739,24 @@ def __init__(
737739
# Capsule that needs to imported and configured to call the primitive
738740
# (name of the target module, e.g. "librt.base64").
739741
self.capsule = capsule
742+
# Native integer types such as u8 can cause ambiguity in primitive
743+
# matching, since these are assignable to plain int *and* vice versa.
744+
# If this flag is set, the primitive has native integer types and must
745+
# be matched using more complex rules.
746+
self.is_ambiguous = any(has_fixed_width_int(t) for t in arg_types)
740747

741748
def __repr__(self) -> str:
742749
return f"<PrimitiveDescription {self.name!r}: {self.arg_types}>"
743750

744751

752+
def has_fixed_width_int(t: RType) -> bool:
753+
if isinstance(t, RTuple):
754+
return any(has_fixed_width_int(t) for t in t.types)
755+
elif isinstance(t, RUnion):
756+
return any(has_fixed_width_int(t) for t in t.items)
757+
return is_fixed_width_rtype(t)
758+
759+
745760
@final
746761
class PrimitiveOp(RegisterOp):
747762
"""A higher-level primitive operation.

mypyc/ir/rtypes.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,11 @@ def __hash__(self) -> int:
514514

515515
KNOWN_NATIVE_TYPES: Final = {
516516
name: RPrimitive(name, is_unboxed=False, is_refcounted=True)
517-
for name in ["librt.internal.WriteBuffer", "librt.internal.ReadBuffer"]
517+
for name in [
518+
"librt.internal.WriteBuffer",
519+
"librt.internal.ReadBuffer",
520+
"librt.strings.BytesWriter",
521+
]
518522
}
519523

520524

mypyc/irbuild/expression.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,8 @@ def transform_super_expr(builder: IRBuilder, o: SuperExpr) -> Value:
296296
# Grab first argument
297297
vself: Value = next(iter_env)
298298
if builder.fn_info.is_generator:
299-
# grab sixth argument (see comment in translate_super_method_call)
300-
self_targ = list(builder.symtables[-1].values())[6]
299+
# grab seventh argument (see comment in translate_super_method_call)
300+
self_targ = list(builder.symtables[-1].values())[7]
301301
vself = builder.read(self_targ, builder.fn_info.fitem.line)
302302
elif not ir.is_ext_class:
303303
vself = next(iter_env) # second argument is self if non_extension class

0 commit comments

Comments
 (0)