Skip to content

Commit f4d483c

Browse files
committed
Only trigger new assertions in tests
1 parent 99ddb91 commit f4d483c

18 files changed

Lines changed: 57 additions & 37 deletions

mypyc/codegen/emit.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class EmitterContext:
103103
def __init__(
104104
self,
105105
names: NameGenerator,
106+
strict_traceback_checks: bool,
106107
group_name: str | None = None,
107108
group_map: dict[str, str | None] | None = None,
108109
) -> None:
@@ -130,6 +131,8 @@ def __init__(
130131
self.declarations: dict[str, HeaderDeclaration] = {}
131132

132133
self.literals = Literals()
134+
# See mypyc/options.py for context.
135+
self.strict_traceback_checks = strict_traceback_checks
133136

134137

135138
class ErrorHandler:
@@ -1201,7 +1204,8 @@ def _emit_traceback(
12011204
type_str: str = "",
12021205
src: str = "",
12031206
) -> None:
1204-
assert traceback_entry[1] >= 0, "Traceback cannot have a negative line number"
1207+
if self.context.strict_traceback_checks:
1208+
assert traceback_entry[1] >= 0, "Traceback cannot have a negative line number"
12051209
globals_static = self.static_name("globals", module_name)
12061210
line = '%s("%s", "%s", %d, %s' % (
12071211
func,

mypyc/codegen/emitfunc.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -921,9 +921,10 @@ def emit_traceback(self, op: Branch) -> None:
921921

922922
def emit_attribute_error(self, op: Branch, class_name: str, attr: str) -> None:
923923
assert op.traceback_entry is not None
924-
assert (
925-
op.traceback_entry[1] >= 0
926-
), "AttributeError traceback cannot have a negative line number"
924+
if self.emitter.context.strict_traceback_checks:
925+
assert (
926+
op.traceback_entry[1] >= 0
927+
), "AttributeError traceback cannot have a negative line number"
927928
globals_static = self.emitter.static_name("globals", self.module_name)
928929
self.emit_line(
929930
'CPy_AttributeError("%s", "%s", "%s", "%s", %d, %s);'

mypyc/codegen/emitmodule.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,9 +249,9 @@ def compile_scc_to_ir(
249249
for module in modules.values():
250250
for fn in module.functions:
251251
# Insert checks for uninitialized values.
252-
insert_uninit_checks(fn)
252+
insert_uninit_checks(fn, compiler_options.strict_traceback_checks)
253253
# Insert exception handling.
254-
insert_exception_handling(fn)
254+
insert_exception_handling(fn, compiler_options.strict_traceback_checks)
255255
# Insert reference count handling.
256256
insert_ref_count_opcodes(fn)
257257

@@ -535,7 +535,7 @@ def __init__(
535535
"""
536536
self.modules = modules
537537
self.source_paths = source_paths
538-
self.context = EmitterContext(names, group_name, group_map)
538+
self.context = EmitterContext(names, compiler_options.strict_traceback_checks, group_name, group_map)
539539
self.names = names
540540
# Initializations of globals to simple values that we can't
541541
# do statically because the windows loader is bad.

mypyc/ir/ops.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,6 @@ class RaiseStandardError(RegisterOp):
12161216

12171217
def __init__(self, class_name: str, value: str | Value | None, line: int) -> None:
12181218
super().__init__(line)
1219-
assert line >= 0, "RaiseStandardError cannot have a negative line number"
12201219
self.class_name = class_name
12211220
self.value = value
12221221
self.type = bool_rprimitive

mypyc/options.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def __init__(
1919
log_trace: bool = False,
2020
depends_on_librt_internal: bool = False,
2121
experimental_features: bool = False,
22+
strict_traceback_checks: bool = False,
2223
) -> None:
2324
self.strip_asserts = strip_asserts
2425
self.multi_file = multi_file
@@ -60,3 +61,15 @@ def __init__(
6061
# experimental mode (e.g. use _experimental suffix in librt run test).
6162
# These can't be used with a librt wheel installed from PyPI.
6263
self.experimental_features = experimental_features
64+
# If enabled, mypyc will assert that every traceback it generates has a
65+
# positive line number.
66+
# Currently each AST node is assigned line number -1 by default to indicate
67+
# that it's unset. If the line number is never set and a traceback is
68+
# generated that points at such node, then the line number will be interpreted
69+
# as None instead of an integer by Python and potentially crash code that
70+
# expects an integer, such as pytest.
71+
# The goal is to prevent the incorrect tracebacks but it will require a lot
72+
# of changes across mypyc. In the meantime, this option should be enabled in
73+
# tests to make sure that no new code which leads to incorrect tracebacks is
74+
# added.
75+
self.strict_traceback_checks = strict_traceback_checks

mypyc/test/test_analysis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
4242
for fn in ir:
4343
if fn.name == TOP_LEVEL_NAME and not testcase.name.endswith("_toplevel"):
4444
continue
45-
exceptions.insert_exception_handling(fn)
45+
exceptions.insert_exception_handling(fn, True)
4646
actual.extend(format_func(fn))
4747
cfg = dataflow.get_cfg(fn.blocks)
4848
args: set[Value] = set(fn.arg_regs)

mypyc/test/test_emit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
class TestEmitter(unittest.TestCase):
2525
def setUp(self) -> None:
2626
self.n = Register(int_rprimitive, "n")
27-
self.context = EmitterContext(NameGenerator([["mod"]]))
27+
self.context = EmitterContext(NameGenerator([["mod"]]), True)
2828
self.emitter = Emitter(self.context, {})
2929

3030
ir = ClassIR("A", "mod")

mypyc/test/test_emitfunc.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def add_local(name: str, rtype: RType) -> Register:
128128
)
129129
self.st = add_local("st", self.struct_type)
130130

131-
self.context = EmitterContext(NameGenerator([["mod"]]))
131+
self.context = EmitterContext(NameGenerator([["mod"]]), True)
132132

133133
def test_goto(self) -> None:
134134
self.assert_emit(Goto(BasicBlock(2)), "goto CPyL2;")
@@ -974,7 +974,7 @@ def test_simple(self) -> None:
974974
[self.block],
975975
)
976976
value_names = generate_names_for_ir(fn.arg_regs, fn.blocks)
977-
emitter = Emitter(EmitterContext(NameGenerator([["mod"]])), value_names)
977+
emitter = Emitter(EmitterContext(NameGenerator([["mod"]]), True), value_names)
978978
generate_native_function(fn, emitter, "prog.py", "prog")
979979
result = emitter.fragments
980980
assert_string_arrays_equal(
@@ -994,7 +994,7 @@ def test_register(self) -> None:
994994
[self.block],
995995
)
996996
value_names = generate_names_for_ir(fn.arg_regs, fn.blocks)
997-
emitter = Emitter(EmitterContext(NameGenerator([["mod"]])), value_names)
997+
emitter = Emitter(EmitterContext(NameGenerator([["mod"]]), True), value_names)
998998
generate_native_function(fn, emitter, "prog.py", "prog")
999999
result = emitter.fragments
10001000
assert_string_arrays_equal(

mypyc/test/test_emitwrapper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
class TestArgCheck(unittest.TestCase):
1313
def setUp(self) -> None:
14-
self.context = EmitterContext(NameGenerator([["mod"]]))
14+
self.context = EmitterContext(NameGenerator([["mod"]]), True)
1515

1616
def test_check_list(self) -> None:
1717
emitter = Emitter(self.context)

mypyc/test/test_exceptions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
4545
for fn in ir:
4646
if fn.name == TOP_LEVEL_NAME and not testcase.name.endswith("_toplevel"):
4747
continue
48-
insert_uninit_checks(fn)
49-
insert_exception_handling(fn)
48+
insert_uninit_checks(fn, True)
49+
insert_exception_handling(fn, True)
5050
insert_ref_count_opcodes(fn)
5151
actual.extend(format_func(fn))
5252
if testcase.name.endswith("_freq"):

0 commit comments

Comments
 (0)