Skip to content

Commit a79e85e

Browse files
feat: add helpful info to internal AssertionError excs (#19404)
I added some contextual information to various assert statements throughout the repo. This information is helpful for me while debugging [Issue 1116](mypyc/mypyc#1116) and should be similarly useful in many other debugging contexts.
1 parent 35d8c69 commit a79e85e

23 files changed

+50
-52
lines changed

mypy/checker.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7273,7 +7273,7 @@ def named_type(self, name: str) -> Instance:
72737273
if isinstance(node, TypeAlias):
72747274
assert isinstance(node.target, Instance) # type: ignore[misc]
72757275
node = node.target.type
7276-
assert isinstance(node, TypeInfo)
7276+
assert isinstance(node, TypeInfo), node
72777277
any_type = AnyType(TypeOfAny.from_omitted_generics)
72787278
return Instance(node, [any_type] * len(node.defn.type_vars))
72797279

@@ -7292,7 +7292,7 @@ def lookup_typeinfo(self, fullname: str) -> TypeInfo:
72927292
# Assume that the name refers to a class.
72937293
sym = self.lookup_qualified(fullname)
72947294
node = sym.node
7295-
assert isinstance(node, TypeInfo)
7295+
assert isinstance(node, TypeInfo), node
72967296
return node
72977297

72987298
def type_type(self) -> Instance:

mypy/checkpattern.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,9 +796,9 @@ def get_var(expr: Expression) -> Var:
796796
Warning: this in only true for expressions captured by a match statement.
797797
Don't call it from anywhere else
798798
"""
799-
assert isinstance(expr, NameExpr)
799+
assert isinstance(expr, NameExpr), expr
800800
node = expr.node
801-
assert isinstance(node, Var)
801+
assert isinstance(node, Var), node
802802
return node
803803

804804

mypy/plugins/attrs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def _analyze_class(
458458
if isinstance(node, PlaceholderNode):
459459
# This node is not ready yet.
460460
continue
461-
assert isinstance(node, Var)
461+
assert isinstance(node, Var), node
462462
node.is_initialized_in_class = False
463463

464464
# Traverse the MRO and collect attributes from the parents.

mypy/plugins/dataclasses.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ def collect_attributes(self) -> list[DataclassAttribute] | None:
610610
# We will issue an error later.
611611
continue
612612

613-
assert isinstance(node, Var)
613+
assert isinstance(node, Var), node
614614

615615
# x: ClassVar[int] is ignored by dataclasses.
616616
if node.is_classvar:

mypy/semanal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6630,7 +6630,7 @@ def named_type(self, fullname: str, args: list[Type] | None = None) -> Instance:
66306630
sym = self.lookup_fully_qualified(fullname)
66316631
assert sym, "Internal error: attempted to construct unknown type"
66326632
node = sym.node
6633-
assert isinstance(node, TypeInfo)
6633+
assert isinstance(node, TypeInfo), node
66346634
if args:
66356635
# TODO: assert len(args) == len(node.defn.type_vars)
66366636
return Instance(node, args)

mypy/semanal_main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ def process_functions(graph: Graph, scc: list[str], patches: Patches) -> None:
290290

291291
for module, target, node, active_type in order_by_subclassing(all_targets):
292292
analyzer = graph[module].manager.semantic_analyzer
293-
assert isinstance(node, (FuncDef, OverloadedFuncDef, Decorator))
293+
assert isinstance(node, (FuncDef, OverloadedFuncDef, Decorator)), node
294294
process_top_level_function(
295295
analyzer, graph[module], module, target, node, active_type, patches
296296
)

mypyc/analysis/attrdefined.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,15 +285,15 @@ def mark_attr_initialization_ops(
285285
def attributes_initialized_by_init_call(op: Call) -> set[str]:
286286
"""Calculate attributes that are always initialized by a super().__init__ call."""
287287
self_type = op.fn.sig.args[0].type
288-
assert isinstance(self_type, RInstance)
288+
assert isinstance(self_type, RInstance), self_type
289289
cl = self_type.class_ir
290290
return {a for base in cl.mro for a in base.attributes if base.is_always_defined(a)}
291291

292292

293293
def attributes_maybe_initialized_by_init_call(op: Call) -> set[str]:
294294
"""Calculate attributes that may be initialized by a super().__init__ call."""
295295
self_type = op.fn.sig.args[0].type
296-
assert isinstance(self_type, RInstance)
296+
assert isinstance(self_type, RInstance), self_type
297297
cl = self_type.class_ir
298298
return attributes_initialized_by_init_call(op) | cl._sometimes_initialized_attrs
299299

mypyc/analysis/selfleaks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def visit_call(self, op: Call) -> GenAndKill:
9292
fn = op.fn
9393
if fn.class_name and fn.name == "__init__":
9494
self_type = op.fn.sig.args[0].type
95-
assert isinstance(self_type, RInstance)
95+
assert isinstance(self_type, RInstance), self_type
9696
cl = self_type.class_ir
9797
if not cl.init_self_leak:
9898
return CLEAN

mypyc/codegen/emit.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ def emit_cast_error_handler(
742742
self.emit_traceback(error.source_path, error.module_name, error.traceback_entry)
743743
self.emit_line("goto %s;" % error.label)
744744
else:
745-
assert isinstance(error, ReturnHandler)
745+
assert isinstance(error, ReturnHandler), error
746746
self.emit_line("return %s;" % error.value)
747747

748748
def emit_union_cast(
@@ -871,7 +871,7 @@ def emit_unbox(
871871
elif isinstance(error, GotoHandler):
872872
failure = "goto %s;" % error.label
873873
else:
874-
assert isinstance(error, ReturnHandler)
874+
assert isinstance(error, ReturnHandler), error
875875
failure = "return %s;" % error.value
876876
if raise_exception:
877877
raise_exc = f'CPy_TypeError("{self.pretty_name(typ)}", {src}); '

mypyc/codegen/emitfunc.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def generate_native_function(
160160
# eliminated during code generation.
161161
for block in fn.blocks:
162162
terminator = block.terminator
163-
assert isinstance(terminator, ControlOp)
163+
assert isinstance(terminator, ControlOp), terminator
164164

165165
for target in terminator.targets():
166166
is_next_block = target.label == block.label + 1
@@ -309,7 +309,7 @@ def visit_assign(self, op: Assign) -> None:
309309

310310
def visit_assign_multi(self, op: AssignMulti) -> None:
311311
typ = op.dest.type
312-
assert isinstance(typ, RArray)
312+
assert isinstance(typ, RArray), typ
313313
dest = self.reg(op.dest)
314314
# RArray values can only be assigned to once, so we can always
315315
# declare them on initialization.
@@ -586,7 +586,7 @@ def visit_method_call(self, op: MethodCall) -> None:
586586
def emit_method_call(self, dest: str, op_obj: Value, name: str, op_args: list[Value]) -> None:
587587
obj = self.reg(op_obj)
588588
rtype = op_obj.type
589-
assert isinstance(rtype, RInstance)
589+
assert isinstance(rtype, RInstance), rtype
590590
class_ir = rtype.class_ir
591591
method = rtype.class_ir.get_method(name)
592592
assert method is not None
@@ -805,7 +805,7 @@ def visit_get_element_ptr(self, op: GetElementPtr) -> None:
805805
dest = self.reg(op)
806806
src = self.reg(op.src)
807807
# TODO: support tuple type
808-
assert isinstance(op.src_type, RStruct)
808+
assert isinstance(op.src_type, RStruct), op.src_type
809809
assert op.field in op.src_type.names, "Invalid field name."
810810
self.emit_line(
811811
"{} = ({})&(({} *){})->{};".format(

0 commit comments

Comments
 (0)