@@ -431,6 +431,40 @@ def foo(a: int, b: str) -> str:
431431 RETURN_VALUE
432432"""
433433
434+ issue_135700 = """\
435+ 22
436+ 333
437+ __dataclass_fields__: ClassVar
438+ """
439+
440+ class _B :
441+ 2
442+ c : int
443+
444+ dis_issue_135700_class = """\
445+ Disassembly of __annotate_func__:
446+ -- COPY_FREE_VARS 1
447+
448+ %3d RESUME 0
449+ LOAD_FAST_BORROW 0 (format)
450+ LOAD_SMALL_INT 2
451+ COMPARE_OP 132 (>)
452+ POP_JUMP_IF_FALSE 3 (to L1)
453+ NOT_TAKEN
454+ LOAD_COMMON_CONSTANT 1 (NotImplementedError)
455+ RAISE_VARARGS 1
456+ L1: BUILD_MAP 0
457+
458+ %3d LOAD_DEREF 1 (__classdict__)
459+ LOAD_FROM_DICT_OR_GLOBALS 0 (int)
460+ COPY 2
461+ LOAD_CONST 1 ('c')
462+
463+ %3d STORE_SUBSCR
464+ RETURN_VALUE
465+
466+ """ % (_B .__firstlineno__ , _B .__firstlineno__ + 2 , _B .__firstlineno__ )
467+
434468compound_stmt_str = """\
435469 x = 0
436470while 1:
@@ -1124,6 +1158,24 @@ def test_bug_46724(self):
11241158 # Test that negative operargs are handled properly
11251159 self .do_disassembly_test (bug46724 , dis_bug46724 )
11261160
1161+ def test_annotate_no_spurious_first_node_positions (self ):
1162+ # Test that __annotate__ code doesn't inherit first AST node positions
1163+ annotate_code = compile (issue_135700 , "<string>" , "exec" ).co_consts [1 ]
1164+ instructions = list (dis .Bytecode (annotate_code ))
1165+
1166+ spurious_positions = 0
1167+ for instr in instructions :
1168+ if (instr .positions and
1169+ instr .positions .lineno == 1 and
1170+ instr .positions .col_offset == 0 and
1171+ instr .positions .end_col_offset == 1 ):
1172+ spurious_positions += 1
1173+
1174+ self .assertEqual (spurious_positions , 0 ,
1175+ "No instructions should have first statement's position" )
1176+ got = self .get_disassembly (_B , depth = 1 )
1177+ self .do_disassembly_compare (got , dis_issue_135700_class )
1178+
11271179 def test_kw_names (self ):
11281180 # Test that value is displayed for keyword argument names:
11291181 self .do_disassembly_test (wrap_func_w_kwargs , dis_kw_names )
0 commit comments