Package: src:python-executing
Version: 1.2.0-2
Severity: important
Tags: sid trixie
User: debian-pyt...@lists.debian.org
Usertags: python3.12

python-executing's autopkg tests fail with Python 3.12:

[...]
289s I: pybuild base:310: cd /tmp/autopkgtest.o73qqW/autopkgtest_tmp/build; python3.12 -m pytest tests 290s ============================= test session starts ==============================
290s platform linux -- Python 3.12.0+, pytest-7.4.3, pluggy-1.3.0
290s rootdir: /tmp/autopkgtest.o73qqW/autopkgtest_tmp/build
290s collected 60 items
290s
293s tests/test_main.py ......FF........F.....F.........sssssssssssssssF [ 80%] 293s tests/test_pytest.py ............ [100%]
293s
293s =================================== FAILURES =================================== 293s ___________________________ TestStuff.test_decorator ___________________________
293s
293s self = <tests.test_main.TestStuff testMethod=test_decorator>
293s
293s     def test_decorator(self):
293s         @empty_decorator  # 0
293s         @decorator_with_args(tester('123'), x=int())  # 1
293s         @tester(list(tuple([1, 2])))  # 2!
293s         @tester(  # 3!
293s             list(
293s                 tuple(
293s                     [3, 4])),
293s             )
293s         @empty_decorator  # 4
293s         @decorator_with_args(  # 5
293s             str(),
293s             x=int())
293s         @tester(list(tuple([5, 6])))  # 6!
293s >       @tester(list(tuple([7, 8])))  # 7!
293s
293s tests/test_main.py:83:
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s tests/utils.py:63: in __call__
293s     self.check(call.args[0], arg)
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s
293s self = <tests.utils.Tester object at 0x7f7fef4dde80>
293s node = <ast.Call object at 0x7f7fef447390>
293s value = <function TestStuff.test_decorator.<locals>.foo at 0x7f7fef17f560>
293s
293s     def check(self, node, value):
293s         frame = inspect.currentframe().f_back.f_back
293s         result = eval(
293s compile(ast.Expression(node), frame.f_code.co_filename, 'eval'),
293s             frame.f_globals,
293s             frame.f_locals,
293s         )
293s >       assert result == value, (result, value)
293s E AssertionError: ([7, 8], <function TestStuff.test_decorator.<locals>.foo at 0x7f7fef17f560>)
293s
293s tests/utils.py:51: AssertionError
293s __________________ TestStuff.test_decorator_cache_instruction __________________
293s
293s self = <tests.test_main.TestStuff testMethod=test_decorator_cache_instruction>
293s
293s     def test_decorator_cache_instruction(self):
293s         frame = inspect.currentframe()
293s
293s         def deco(f):
293s             assert f.__name__ == "foo"
293s             ex = Source.executing(frame)
293s             assert isinstance(ex.node, ast.FunctionDef)
293s             assert isinstance(ex.decorator, ast.Name)
293s
293s >       @deco
293s
293s tests/test_main.py:587:
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s tests/test_main.py:583: in deco
293s     ex = Source.executing(frame)
293s /usr/lib/python3/dist-packages/executing/executing.py:368: in executing
293s     node_finder = NodeFinder(frame, stmts, tree, lasti, source)
293s /usr/lib/python3/dist-packages/executing/_position_node_finder.py:158: in __init__
293s     self.verify(self.result, self.instruction(lasti))
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s
293s self = <executing._position_node_finder.PositionNodeFinder object at 0x7f7fef450140>
293s node = <ast.Name object at 0x7f7fef215450>
293s instruction = Instruction(opname='CALL', opcode=171, arg=0, argval=0, argrepr='', offset=60, starts_line=587, is_jump_target=False, positions=Positions(lineno=587, end_lineno=587, col_offset=9, end_col_offset=13))
293s
293s def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None:
293s         """
293s         checks if this node could gererate this instruction
293s         """
293s
293s         op_name = instruction.opname
293s         extra_filter: Callable[[EnhancedAST], bool] = lambda e: True
293s         ctx: Type = type(None)
293s
293s def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool:
293s             """
293s             match instruction
293s
293s             Parameters:
293s opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname`
293s                 **kwargs: every arg has to match inst.arg
293s
293s             Returns:
293s                 True if all conditions match the instruction
293s
293s             """
293s
293s             if isinstance(opnames, str):
293s                 opnames = [opnames]
293s             return instruction.opname in opnames and kwargs == {
293s                 k: getattr(instruction, k) for k in kwargs
293s             }
293s
293s def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
293s             """
293s             match the ast-node
293s
293s             Parameters:
293s                 node_type: type of the node
293s                 **kwargs: every `arg` has to be equal `node.arg`
293s or `node.arg` has to be an instance of `arg` if it is a type.
293s             """
293s             return isinstance(node, node_type) and all(
293s                 isinstance(getattr(node, k), v)
293s                 if isinstance(v, type)
293s                 else getattr(node, k) == v
293s                 for k, v in kwargs.items()
293s             )
293s
293s         if op_name == "CACHE":
293s             return
293s
293s if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)):
293s             # call to context.__exit__
293s             return
293s
293s         if inst_match(("CALL", "LOAD_FAST")) and node_match(
293s             (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp)
293s         ):
293s             # call to the generator function
293s             return
293s
293s         if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match(
293s             (ast.ClassDef, ast.Call)
293s         ):
293s             return
293s
293s if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match(
293s             ast.Compare
293s         ):
293s             return
293s
293s if inst_match("LOAD_NAME", argval="__annotations__") and node_match(
293s             ast.AnnAssign
293s         ):
293s             return
293s
293s         if (
293s             (
293s                 inst_match("LOAD_METHOD", argval="join")
293s                 or inst_match(("CALL", "BUILD_STRING"))
293s             )
293s             and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod)
293s and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str)
293s         ):
293s             # "..."%(...) uses "".join
293s             return
293s
293s         if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign):
293s             # data: int
293s             return
293s
293s         if self.is_except_cleanup(instruction, node):
293s             return
293s
293s         if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match(
293s             ast.Name, id=instruction.argval, ctx=ast.Del
293s         ):
293s             return
293s
293s         if inst_match("BUILD_STRING") and (
293s node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod)
293s         ):
293s             return
293s
293s if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With):
293s             return
293s
293s if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match(
293s             ast.Constant
293s         ):
293s             # store docstrings
293s             return
293s
293s         if (
293s inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF"))
293s             and node_match(ast.ExceptHandler)
293s             and instruction.argval == mangled_name(node)
293s         ):
293s             # store exception in variable
293s             return
293s
293s         if (
293s inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL"))
293s             and node_match((ast.Import, ast.ImportFrom))
293s and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names)
293s         ):
293s             # store imported module in variable
293s             return
293s
293s         if (
293s inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL"))
293s             and (
293s node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef))
293s                 or node_match(
293s                     ast.Name,
293s                     ctx=ast.Store,
293s                 )
293s             )
293s             and instruction.argval == mangled_name(node)
293s         ):
293s             return
293s
293s         if False:
293s             # TODO: match expressions are not supported for now
293s             if inst_match(("STORE_FAST", "STORE_NAME")) and node_match(
293s                 ast.MatchAs, name=instruction.argval
293s             ):
293s                 return
293s
293s if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence):
293s                 return
293s
293s if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue):
293s                 return
293s
293s         if inst_match("BINARY_OP") and node_match(
293s ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")]
293s         ):
293s             # a+=5
293s             return
293s
293s         if node_match(ast.Attribute, ctx=ast.Del) and inst_match(
293s             "DELETE_ATTR", argval=mangled_name(node)
293s         ):
293s             return
293s
293s if inst_match(("JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP")) and node_match(
293s             ast.BoolOp
293s         ):
293s             # and/or short circuit
293s             return
293s
293s if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del):
293s             return
293s
293s         if node_match(ast.Name, ctx=ast.Load) and inst_match(
293s ("LOAD_NAME", "LOAD_FAST", "LOAD_GLOBAL"), argval=mangled_name(node)
293s         ):
293s             return
293s
293s         if node_match(ast.Name, ctx=ast.Del) and inst_match(
293s             ("DELETE_NAME", "DELETE_GLOBAL"), argval=mangled_name(node)
293s         ):
293s             return
293s
293s         # old verifier
293s
293s         typ: Type = type(None)
293s         op_type: Type = type(None)
293s
293s         if op_name.startswith(("BINARY_SUBSCR", "SLICE+")):
293s             typ = ast.Subscript
293s             ctx = ast.Load
293s         elif op_name.startswith("BINARY_"):
293s             typ = ast.BinOp
293s             op_type = op_type_map[instruction.argrepr]
293s extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type)
293s         elif op_name.startswith("UNARY_"):
293s             typ = ast.UnaryOp
293s             op_type = dict(
293s                 UNARY_POSITIVE=ast.UAdd,
293s                 UNARY_NEGATIVE=ast.USub,
293s                 UNARY_NOT=ast.Not,
293s                 UNARY_INVERT=ast.Invert,
293s             )[op_name]
293s extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type)
293s         elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD"):
293s             typ = ast.Attribute
293s             ctx = ast.Load
293s extra_filter = lambda e: mangled_name(e) == instruction.argval
293s         elif op_name in (
293s             "LOAD_NAME",
293s             "LOAD_GLOBAL",
293s             "LOAD_FAST",
293s             "LOAD_DEREF",
293s             "LOAD_CLASSDEREF",
293s         ):
293s             typ = ast.Name
293s             ctx = ast.Load
293s extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval
293s         elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"):
293s             typ = ast.Compare
293s             extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1
293s         elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")):
293s             ctx = ast.Store
293s             typ = ast.Subscript
293s         elif op_name.startswith("STORE_ATTR"):
293s             ctx = ast.Store
293s             typ = ast.Attribute
293s extra_filter = lambda e: mangled_name(e) == instruction.argval
293s
293s         node_ctx = getattr(node, "ctx", None)
293s
293s         ctx_match = (
293s             ctx is not type(None)
293s             or not hasattr(node, "ctx")
293s             or isinstance(node_ctx, ctx)
293s         )
293s
293s         # check for old verifier
293s         if isinstance(node, typ) and ctx_match and extra_filter(node):
293s             return
293s
293s         # generate error
293s
293s         title = "ast.%s is not created from %s" % (
293s             type(node).__name__,
293s             instruction.opname,
293s         )
293s
293s >       raise VerifierFailure(title, node, instruction)
293s E executing._exceptions.VerifierFailure: ast.Name is not created from CALL
293s
293s /usr/lib/python3/dist-packages/executing/_position_node_finder.py:545: VerifierFailure 293s ___________________________ TestStuff.test_listcomp ____________________________
293s
293s self = <tests.test_main.TestStuff testMethod=test_listcomp>
293s
293s     def test_listcomp(self):
293s         if sys.version_info >= (3, 11):
293s             result = [calling_expression() for e in [1]]
293s >           self.assertIsInstance(result[0], ast.ListComp)
293s E AssertionError: <ast.Call object at 0x7f7fee085350> is not an instance of <class 'ast.ListComp'>
293s
293s tests/test_main.py:576: AssertionError
293s _____________________________ TestStuff.test_names _____________________________
293s
293s self = <tests.test_main.TestStuff testMethod=test_names>
293s
293s     def test_names(self):
293s         with self.assert_name_error():
293s             self, completely_nonexistent  # noqa
293s
293s         with self.assert_name_error():
293s             self, global_never_defined  # noqa
293s
293s         with self.assert_name_error():
293s >           self, local_not_defined_yet  # noqa
293s E UnboundLocalError: cannot access local variable 'local_not_defined_yet' where it is not associated with a value
293s
293s tests/test_main.py:554: UnboundLocalError
293s
293s During handling of the above exception, another exception occurred:
293s
293s self = <tests.test_main.TestStuff testMethod=test_names>
293s
293s     def test_names(self):
293s         with self.assert_name_error():
293s             self, completely_nonexistent  # noqa
293s
293s         with self.assert_name_error():
293s             self, global_never_defined  # noqa
293s
293s >       with self.assert_name_error():
293s
293s tests/test_main.py:553:
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s /usr/lib/python3.12/contextlib.py:158: in __exit__
293s     self.gen.throw(value)
293s tests/test_main.py:539: in assert_name_error
293s     ex = Source.executing(tb.tb_next)
293s /usr/lib/python3/dist-packages/executing/executing.py:368: in executing
293s     node_finder = NodeFinder(frame, stmts, tree, lasti, source)
293s /usr/lib/python3/dist-packages/executing/_position_node_finder.py:158: in __init__
293s     self.verify(self.result, self.instruction(lasti))
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s
293s self = <executing._position_node_finder.PositionNodeFinder object at 0x7f7febe09100>
293s node = <ast.Name object at 0x7f7fef18bc90>
293s instruction = Instruction(opname='LOAD_FAST_CHECK', opcode=127, arg=1, argval='local_not_defined_yet', argrepr='local_not_defined_ye...rts_line=None, is_jump_target=False, positions=Positions(lineno=554, end_lineno=554, col_offset=18, end_col_offset=39))
293s
293s def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None:
293s         """
293s         checks if this node could gererate this instruction
293s         """
293s
293s         op_name = instruction.opname
293s         extra_filter: Callable[[EnhancedAST], bool] = lambda e: True
293s         ctx: Type = type(None)
293s
293s def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool:
293s             """
293s             match instruction
293s
293s             Parameters:
293s opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname`
293s                 **kwargs: every arg has to match inst.arg
293s
293s             Returns:
293s                 True if all conditions match the instruction
293s
293s             """
293s
293s             if isinstance(opnames, str):
293s                 opnames = [opnames]
293s             return instruction.opname in opnames and kwargs == {
293s                 k: getattr(instruction, k) for k in kwargs
293s             }
293s
293s def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
293s             """
293s             match the ast-node
293s
293s             Parameters:
293s                 node_type: type of the node
293s                 **kwargs: every `arg` has to be equal `node.arg`
293s or `node.arg` has to be an instance of `arg` if it is a type.
293s             """
293s             return isinstance(node, node_type) and all(
293s                 isinstance(getattr(node, k), v)
293s                 if isinstance(v, type)
293s                 else getattr(node, k) == v
293s                 for k, v in kwargs.items()
293s             )
293s
293s         if op_name == "CACHE":
293s             return
293s
293s if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)):
293s             # call to context.__exit__
293s             return
293s
293s         if inst_match(("CALL", "LOAD_FAST")) and node_match(
293s             (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp)
293s         ):
293s             # call to the generator function
293s             return
293s
293s         if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match(
293s             (ast.ClassDef, ast.Call)
293s         ):
293s             return
293s
293s if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match(
293s             ast.Compare
293s         ):
293s             return
293s
293s if inst_match("LOAD_NAME", argval="__annotations__") and node_match(
293s             ast.AnnAssign
293s         ):
293s             return
293s
293s         if (
293s             (
293s                 inst_match("LOAD_METHOD", argval="join")
293s                 or inst_match(("CALL", "BUILD_STRING"))
293s             )
293s             and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod)
293s and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str)
293s         ):
293s             # "..."%(...) uses "".join
293s             return
293s
293s         if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign):
293s             # data: int
293s             return
293s
293s         if self.is_except_cleanup(instruction, node):
293s             return
293s
293s         if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match(
293s             ast.Name, id=instruction.argval, ctx=ast.Del
293s         ):
293s             return
293s
293s         if inst_match("BUILD_STRING") and (
293s node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod)
293s         ):
293s             return
293s
293s if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With):
293s             return
293s
293s if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match(
293s             ast.Constant
293s         ):
293s             # store docstrings
293s             return
293s
293s         if (
293s inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF"))
293s             and node_match(ast.ExceptHandler)
293s             and instruction.argval == mangled_name(node)
293s         ):
293s             # store exception in variable
293s             return
293s
293s         if (
293s inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL"))
293s             and node_match((ast.Import, ast.ImportFrom))
293s and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names)
293s         ):
293s             # store imported module in variable
293s             return
293s
293s         if (
293s inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL"))
293s             and (
293s node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef))
293s                 or node_match(
293s                     ast.Name,
293s                     ctx=ast.Store,
293s                 )
293s             )
293s             and instruction.argval == mangled_name(node)
293s         ):
293s             return
293s
293s         if False:
293s             # TODO: match expressions are not supported for now
293s             if inst_match(("STORE_FAST", "STORE_NAME")) and node_match(
293s                 ast.MatchAs, name=instruction.argval
293s             ):
293s                 return
293s
293s if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence):
293s                 return
293s
293s if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue):
293s                 return
293s
293s         if inst_match("BINARY_OP") and node_match(
293s ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")]
293s         ):
293s             # a+=5
293s             return
293s
293s         if node_match(ast.Attribute, ctx=ast.Del) and inst_match(
293s             "DELETE_ATTR", argval=mangled_name(node)
293s         ):
293s             return
293s
293s if inst_match(("JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP")) and node_match(
293s             ast.BoolOp
293s         ):
293s             # and/or short circuit
293s             return
293s
293s if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del):
293s             return
293s
293s         if node_match(ast.Name, ctx=ast.Load) and inst_match(
293s ("LOAD_NAME", "LOAD_FAST", "LOAD_GLOBAL"), argval=mangled_name(node)
293s         ):
293s             return
293s
293s         if node_match(ast.Name, ctx=ast.Del) and inst_match(
293s             ("DELETE_NAME", "DELETE_GLOBAL"), argval=mangled_name(node)
293s         ):
293s             return
293s
293s         # old verifier
293s
293s         typ: Type = type(None)
293s         op_type: Type = type(None)
293s
293s         if op_name.startswith(("BINARY_SUBSCR", "SLICE+")):
293s             typ = ast.Subscript
293s             ctx = ast.Load
293s         elif op_name.startswith("BINARY_"):
293s             typ = ast.BinOp
293s             op_type = op_type_map[instruction.argrepr]
293s extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type)
293s         elif op_name.startswith("UNARY_"):
293s             typ = ast.UnaryOp
293s             op_type = dict(
293s                 UNARY_POSITIVE=ast.UAdd,
293s                 UNARY_NEGATIVE=ast.USub,
293s                 UNARY_NOT=ast.Not,
293s                 UNARY_INVERT=ast.Invert,
293s             )[op_name]
293s extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type)
293s         elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD"):
293s             typ = ast.Attribute
293s             ctx = ast.Load
293s extra_filter = lambda e: mangled_name(e) == instruction.argval
293s         elif op_name in (
293s             "LOAD_NAME",
293s             "LOAD_GLOBAL",
293s             "LOAD_FAST",
293s             "LOAD_DEREF",
293s             "LOAD_CLASSDEREF",
293s         ):
293s             typ = ast.Name
293s             ctx = ast.Load
293s extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval
293s         elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"):
293s             typ = ast.Compare
293s             extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1
293s         elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")):
293s             ctx = ast.Store
293s             typ = ast.Subscript
293s         elif op_name.startswith("STORE_ATTR"):
293s             ctx = ast.Store
293s             typ = ast.Attribute
293s extra_filter = lambda e: mangled_name(e) == instruction.argval
293s
293s         node_ctx = getattr(node, "ctx", None)
293s
293s         ctx_match = (
293s             ctx is not type(None)
293s             or not hasattr(node, "ctx")
293s             or isinstance(node_ctx, ctx)
293s         )
293s
293s         # check for old verifier
293s         if isinstance(node, typ) and ctx_match and extra_filter(node):
293s             return
293s
293s         # generate error
293s
293s         title = "ast.%s is not created from %s" % (
293s             type(node).__name__,
293s             instruction.opname,
293s         )
293s
293s >       raise VerifierFailure(title, node, instruction)
293s E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_CHECK
293s
293s /usr/lib/python3/dist-packages/executing/_position_node_finder.py:545: VerifierFailure 293s ___________________________ test_global_tester_calls ___________________________
293s
293s     def test_global_tester_calls():
293s         # tester calls should be tested at global scope
293s >       from . import global_tester_calls
293s
293s tests/test_main.py:1397:
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s tests/global_tester_calls.py:13: in <module>
293s     assert -tester is +tester is ~tester is tester
293s tests/utils.py:131: in __invert__
293s     node = self.get_node(ast.UnaryOp)
293s tests/utils.py:35: in get_node
293s     ex = self.get_executing(inspect.currentframe().f_back.f_back)
293s tests/utils.py:42: in get_executing
293s     return Source.executing(frame)
293s /usr/lib/python3/dist-packages/executing/executing.py:368: in executing
293s     node_finder = NodeFinder(frame, stmts, tree, lasti, source)
293s /usr/lib/python3/dist-packages/executing/_position_node_finder.py:158: in __init__
293s     self.verify(self.result, self.instruction(lasti))
293s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
293s
293s self = <executing._position_node_finder.PositionNodeFinder object at 0x7f7fef4ca480>
293s node = <ast.UnaryOp object at 0x7f7febe23c50>
293s instruction = Instruction(opname='CALL_INTRINSIC_1', opcode=173, arg=5, argval=5, argrepr='INTRINSIC_UNARY_POSITIVE', offset=176, starts_line=None, is_jump_target=False, positions=Positions(lineno=13, end_lineno=13, col_offset=18, end_col_offset=25))
293s
293s def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None:
293s         """
293s         checks if this node could gererate this instruction
293s         """
293s
293s         op_name = instruction.opname
293s         extra_filter: Callable[[EnhancedAST], bool] = lambda e: True
293s         ctx: Type = type(None)
293s
293s def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool:
293s             """
293s             match instruction
293s
293s             Parameters:
293s opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname`
293s                 **kwargs: every arg has to match inst.arg
293s
293s             Returns:
293s                 True if all conditions match the instruction
293s
293s             """
293s
293s             if isinstance(opnames, str):
293s                 opnames = [opnames]
293s             return instruction.opname in opnames and kwargs == {
293s                 k: getattr(instruction, k) for k in kwargs
293s             }
293s
293s def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
293s             """
293s             match the ast-node
293s
293s             Parameters:
293s                 node_type: type of the node
293s                 **kwargs: every `arg` has to be equal `node.arg`
293s or `node.arg` has to be an instance of `arg` if it is a type.
293s             """
293s             return isinstance(node, node_type) and all(
293s                 isinstance(getattr(node, k), v)
293s                 if isinstance(v, type)
293s                 else getattr(node, k) == v
293s                 for k, v in kwargs.items()
293s             )
293s
293s         if op_name == "CACHE":
293s             return
293s
293s if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)):
293s             # call to context.__exit__
293s             return
293s
293s         if inst_match(("CALL", "LOAD_FAST")) and node_match(
293s             (ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp)
293s         ):
293s             # call to the generator function
293s             return
293s
293s         if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match(
293s             (ast.ClassDef, ast.Call)
293s         ):
293s             return
293s
293s if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match(
293s             ast.Compare
293s         ):
293s             return
293s
293s if inst_match("LOAD_NAME", argval="__annotations__") and node_match(
293s             ast.AnnAssign
293s         ):
293s             return
293s
293s         if (
293s             (
293s                 inst_match("LOAD_METHOD", argval="join")
293s                 or inst_match(("CALL", "BUILD_STRING"))
293s             )
293s             and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod)
293s and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str)
293s         ):
293s             # "..."%(...) uses "".join
293s             return
293s
293s         if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign):
293s             # data: int
293s             return
293s
293s         if self.is_except_cleanup(instruction, node):
293s             return
293s
293s         if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match(
293s             ast.Name, id=instruction.argval, ctx=ast.Del
293s         ):
293s             return
293s
293s         if inst_match("BUILD_STRING") and (
293s node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod)
293s         ):
293s             return
293s
293s if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With):
293s             return
293s
293s if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match(
293s             ast.Constant
293s         ):
293s             # store docstrings
293s             return
293s
293s         if (
293s inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF"))
293s             and node_match(ast.ExceptHandler)
293s             and instruction.argval == mangled_name(node)
293s         ):
293s             # store exception in variable
293s             return
293s
293s         if (
293s inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL"))
293s             and node_match((ast.Import, ast.ImportFrom))
293s and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names)
293s         ):
293s             # store imported module in variable
293s             return
293s
293s         if (
293s inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL"))
293s             and (
293s node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef))
293s                 or node_match(
293s                     ast.Name,
293s                     ctx=ast.Store,
293s                 )
293s             )
293s             and instruction.argval == mangled_name(node)
293s         ):
293s             return
293s
293s         if False:
293s             # TODO: match expressions are not supported for now
293s             if inst_match(("STORE_FAST", "STORE_NAME")) and node_match(
293s                 ast.MatchAs, name=instruction.argval
293s             ):
293s                 return
293s
293s if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence):
293s                 return
293s
293s if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue):
293s                 return
293s
293s         if inst_match("BINARY_OP") and node_match(
293s ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")]
293s         ):
293s             # a+=5
293s             return
293s
293s         if node_match(ast.Attribute, ctx=ast.Del) and inst_match(
293s             "DELETE_ATTR", argval=mangled_name(node)
293s         ):
293s             return
293s
293s if inst_match(("JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP")) and node_match(
293s             ast.BoolOp
293s         ):
293s             # and/or short circuit
293s             return
293s
293s if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del):
293s             return
293s
293s         if node_match(ast.Name, ctx=ast.Load) and inst_match(
293s ("LOAD_NAME", "LOAD_FAST", "LOAD_GLOBAL"), argval=mangled_name(node)
293s         ):
293s             return
293s
293s         if node_match(ast.Name, ctx=ast.Del) and inst_match(
293s             ("DELETE_NAME", "DELETE_GLOBAL"), argval=mangled_name(node)
293s         ):
293s             return
293s
293s         # old verifier
293s
293s         typ: Type = type(None)
293s         op_type: Type = type(None)
293s
293s         if op_name.startswith(("BINARY_SUBSCR", "SLICE+")):
293s             typ = ast.Subscript
293s             ctx = ast.Load
293s         elif op_name.startswith("BINARY_"):
293s             typ = ast.BinOp
293s             op_type = op_type_map[instruction.argrepr]
293s extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type)
293s         elif op_name.startswith("UNARY_"):
293s             typ = ast.UnaryOp
293s             op_type = dict(
293s                 UNARY_POSITIVE=ast.UAdd,
293s                 UNARY_NEGATIVE=ast.USub,
293s                 UNARY_NOT=ast.Not,
293s                 UNARY_INVERT=ast.Invert,
293s             )[op_name]
293s extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type)
293s         elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD"):
293s             typ = ast.Attribute
293s             ctx = ast.Load
293s extra_filter = lambda e: mangled_name(e) == instruction.argval
293s         elif op_name in (
293s             "LOAD_NAME",
293s             "LOAD_GLOBAL",
293s             "LOAD_FAST",
293s             "LOAD_DEREF",
293s             "LOAD_CLASSDEREF",
293s         ):
293s             typ = ast.Name
293s             ctx = ast.Load
293s extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval
293s         elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"):
293s             typ = ast.Compare
293s             extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1
293s         elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")):
293s             ctx = ast.Store
293s             typ = ast.Subscript
293s         elif op_name.startswith("STORE_ATTR"):
293s             ctx = ast.Store
293s             typ = ast.Attribute
293s extra_filter = lambda e: mangled_name(e) == instruction.argval
293s
293s         node_ctx = getattr(node, "ctx", None)
293s
293s         ctx_match = (
293s             ctx is not type(None)
293s             or not hasattr(node, "ctx")
293s             or isinstance(node_ctx, ctx)
293s         )
293s
293s         # check for old verifier
293s         if isinstance(node, typ) and ctx_match and extra_filter(node):
293s             return
293s
293s         # generate error
293s
293s         title = "ast.%s is not created from %s" % (
293s             type(node).__name__,
293s             instruction.opname,
293s         )
293s
293s >       raise VerifierFailure(title, node, instruction)
293s E executing._exceptions.VerifierFailure: ast.UnaryOp is not created from CALL_INTRINSIC_1
293s
293s /usr/lib/python3/dist-packages/executing/_position_node_finder.py:545: VerifierFailure 293s =========================== short test summary info ============================ 293s FAILED tests/test_main.py::TestStuff::test_decorator - AssertionError: ([7, 8... 293s FAILED tests/test_main.py::TestStuff::test_decorator_cache_instruction - exec... 293s FAILED tests/test_main.py::TestStuff::test_listcomp - AssertionError: <ast.Ca... 293s FAILED tests/test_main.py::TestStuff::test_names - executing._exceptions.Veri... 293s FAILED tests/test_main.py::test_global_tester_calls - executing._exceptions.V... 293s =================== 5 failed, 40 passed, 15 skipped in 3.41s ===================

Reply via email to