Hello, in Fedora we are rebuilding all Python packages with the upcoming Python 3.12, currently 7th alpha.
I'd like to ask for help with the following test failures. Thank you.
=================================== FAILURES ===================================
___________________________ TestStuff.test_decorator ___________________________
self = <tests.test_main.TestStuff testMethod=test_decorator>
def test_decorator(self):
@empty_decorator # 0
@decorator_with_args(tester('123'), x=int()) # 1
@tester(list(tuple([1, 2]))) # 2!
@tester( # 3!
list(
tuple(
[3, 4])),
)
@empty_decorator # 4
@decorator_with_args( # 5
str(),
x=int())
@tester(list(tuple([5, 6]))) # 6!
> @tester(list(tuple([7, 8]))) # 7!
tests/test_main.py:83:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/utils.py:63: in __call__
self.check(call.args[0], arg)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <tests.utils.Tester object at 0x7f702c74c050>
node = <ast.Call object at 0x7f702c7f22d0>
value = <function TestStuff.test_decorator.<locals>.foo at 0x7f702c62b740>
def check(self, node, value):
frame = inspect.currentframe().f_back.f_back
result = eval(
compile(ast.Expression(node), frame.f_code.co_filename, 'eval'),
frame.f_globals,
frame.f_locals,
)
> assert result == value, (result, value)
E AssertionError: ([7, 8], <function TestStuff.test_decorator.<locals>.foo at 0x7f702c62b740>)
tests/utils.py:51: AssertionError
__________________ TestStuff.test_decorator_cache_instruction __________________
self = <tests.test_main.TestStuff testMethod=test_decorator_cache_instruction>
def test_decorator_cache_instruction(self):
frame = inspect.currentframe()
def deco(f):
assert f.__name__ == "foo"
ex = Source.executing(frame)
assert isinstance(ex.node, ast.FunctionDef)
assert isinstance(ex.decorator, ast.Name)
> @deco
tests/test_main.py:587:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_main.py:583: in deco
ex = Source.executing(frame)
executing/executing.py:368: in executing
node_finder = NodeFinder(frame, stmts, tree, lasti, source)
executing/_position_node_finder.py:158: in __init__
self.verify(self.result, self.instruction(lasti))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <executing._position_node_finder.PositionNodeFinder object at 0x7f702c3f75c0>
node = <ast.Name object at 0x7f702c5875d0>
instruction = Instruction(opname='CALL', opcode=171, arg=0, argval=0, argrepr='', offset=62, starts_line=587, is_jump_target=False, positions=Positions(lineno=587, end_lineno=587, col_offset=9, end_col_offset=13))
def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None:
"""
checks if this node could gererate this instruction
"""
op_name = instruction.opname
extra_filter: Callable[[EnhancedAST], bool] = lambda e: True
ctx: Type = type(None)
def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool:
"""
match instruction
Parameters:
opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname`
**kwargs: every arg has to match inst.arg
Returns:
True if all conditions match the instruction
"""
if isinstance(opnames, str):
opnames = [opnames]
return instruction.opname in opnames and kwargs == {
k: getattr(instruction, k) for k in kwargs
}
def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
"""
match the ast-node
Parameters:
node_type: type of the node
**kwargs: every `arg` has to be equal `node.arg`
or `node.arg` has to be an instance of `arg` if it is a type.
"""
return isinstance(node, node_type) and all(
isinstance(getattr(node, k), v)
if isinstance(v, type)
else getattr(node, k) == v
for k, v in kwargs.items()
)
if op_name == "CACHE":
return
if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)):
# call to context.__exit__
return
if inst_match(("CALL", "LOAD_FAST")) and node_match(
(ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp)
):
# call to the generator function
return
if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match(
(ast.ClassDef, ast.Call)
):
return
if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match(
ast.Compare
):
return
if inst_match("LOAD_NAME", argval="__annotations__") and node_match(
ast.AnnAssign
):
return
if (
(
inst_match("LOAD_METHOD", argval="join")
or inst_match(("CALL", "BUILD_STRING"))
)
and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod)
and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str)
):
# "..."%(...) uses "".join
return
if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign):
# data: int
return
if self.is_except_cleanup(instruction, node):
return
if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match(
ast.Name, id=instruction.argval, ctx=ast.Del
):
return
if inst_match("BUILD_STRING") and (
node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod)
):
return
if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With):
return
if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match(
ast.Constant
):
# store docstrings
return
if (
inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF"))
and node_match(ast.ExceptHandler)
and instruction.argval == mangled_name(node)
):
# store exception in variable
return
if (
inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL"))
and node_match((ast.Import, ast.ImportFrom))
and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names)
):
# store imported module in variable
return
if (
inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL"))
and (
node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef))
or node_match(
ast.Name,
ctx=ast.Store,
)
)
and instruction.argval == mangled_name(node)
):
return
if False:
# TODO: match expressions are not supported for now
if inst_match(("STORE_FAST", "STORE_NAME")) and node_match(
ast.MatchAs, name=instruction.argval
):
return
if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence):
return
if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue):
return
if inst_match("BINARY_OP") and node_match(
ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")]
):
# a+=5
return
if node_match(ast.Attribute, ctx=ast.Del) and inst_match(
"DELETE_ATTR", argval=mangled_name(node)
):
return
if inst_match(("JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP")) and node_match(
ast.BoolOp
):
# and/or short circuit
return
if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del):
return
if node_match(ast.Name, ctx=ast.Load) and inst_match(
("LOAD_NAME", "LOAD_FAST", "LOAD_GLOBAL"), argval=mangled_name(node)
):
return
if node_match(ast.Name, ctx=ast.Del) and inst_match(
("DELETE_NAME", "DELETE_GLOBAL"), argval=mangled_name(node)
):
return
# old verifier
typ: Type = type(None)
op_type: Type = type(None)
if op_name.startswith(("BINARY_SUBSCR", "SLICE+")):
typ = ast.Subscript
ctx = ast.Load
elif op_name.startswith("BINARY_"):
typ = ast.BinOp
op_type = op_type_map[instruction.argrepr]
extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type)
elif op_name.startswith("UNARY_"):
typ = ast.UnaryOp
op_type = dict(
UNARY_POSITIVE=ast.UAdd,
UNARY_NEGATIVE=ast.USub,
UNARY_NOT=ast.Not,
UNARY_INVERT=ast.Invert,
)[op_name]
extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type)
elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD"):
typ = ast.Attribute
ctx = ast.Load
extra_filter = lambda e: mangled_name(e) == instruction.argval
elif op_name in (
"LOAD_NAME",
"LOAD_GLOBAL",
"LOAD_FAST",
"LOAD_DEREF",
"LOAD_CLASSDEREF",
):
typ = ast.Name
ctx = ast.Load
extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval
elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"):
typ = ast.Compare
extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1
elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")):
ctx = ast.Store
typ = ast.Subscript
elif op_name.startswith("STORE_ATTR"):
ctx = ast.Store
typ = ast.Attribute
extra_filter = lambda e: mangled_name(e) == instruction.argval
node_ctx = getattr(node, "ctx", None)
ctx_match = (
ctx is not type(None)
or not hasattr(node, "ctx")
or isinstance(node_ctx, ctx)
)
# check for old verifier
if isinstance(node, typ) and ctx_match and extra_filter(node):
return
# generate error
title = "ast.%s is not created from %s" % (
type(node).__name__,
instruction.opname,
)
> raise VerifierFailure(title, node, instruction)
E executing._exceptions.VerifierFailure: ast.Name is not created from CALL
executing/_position_node_finder.py:545: VerifierFailure
_____________________________ TestStuff.test_names _____________________________
self = <tests.test_main.TestStuff testMethod=test_names>
@contextlib.contextmanager
def assert_name_error(self):
try:
> yield
tests/test_main.py:536:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <tests.test_main.TestStuff testMethod=test_names>
def test_names(self):
with self.assert_name_error():
self, completely_nonexistent # noqa
with self.assert_name_error():
self, global_never_defined # noqa
with self.assert_name_error():
> self, local_not_defined_yet # noqa
E UnboundLocalError: cannot access local variable 'local_not_defined_yet' where it is not associated with a value
tests/test_main.py:554: UnboundLocalError
During handling of the above exception, another exception occurred:
self = <tests.test_main.TestStuff testMethod=test_names>
def test_names(self):
with self.assert_name_error():
self, completely_nonexistent # noqa
with self.assert_name_error():
self, global_never_defined # noqa
> with self.assert_name_error():
tests/test_main.py:553:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.12/contextlib.py:155: in __exit__
self.gen.throw(value)
tests/test_main.py:539: in assert_name_error
ex = Source.executing(tb.tb_next)
executing/executing.py:368: in executing
node_finder = NodeFinder(frame, stmts, tree, lasti, source)
executing/_position_node_finder.py:158: in __init__
self.verify(self.result, self.instruction(lasti))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <executing._position_node_finder.PositionNodeFinder object at 0x7f7029434e30>
node = <ast.Name object at 0x7f702c781450>
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))
def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None:
"""
checks if this node could gererate this instruction
"""
op_name = instruction.opname
extra_filter: Callable[[EnhancedAST], bool] = lambda e: True
ctx: Type = type(None)
def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool:
"""
match instruction
Parameters:
opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname`
**kwargs: every arg has to match inst.arg
Returns:
True if all conditions match the instruction
"""
if isinstance(opnames, str):
opnames = [opnames]
return instruction.opname in opnames and kwargs == {
k: getattr(instruction, k) for k in kwargs
}
def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
"""
match the ast-node
Parameters:
node_type: type of the node
**kwargs: every `arg` has to be equal `node.arg`
or `node.arg` has to be an instance of `arg` if it is a type.
"""
return isinstance(node, node_type) and all(
isinstance(getattr(node, k), v)
if isinstance(v, type)
else getattr(node, k) == v
for k, v in kwargs.items()
)
if op_name == "CACHE":
return
if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)):
# call to context.__exit__
return
if inst_match(("CALL", "LOAD_FAST")) and node_match(
(ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp)
):
# call to the generator function
return
if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match(
(ast.ClassDef, ast.Call)
):
return
if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match(
ast.Compare
):
return
if inst_match("LOAD_NAME", argval="__annotations__") and node_match(
ast.AnnAssign
):
return
if (
(
inst_match("LOAD_METHOD", argval="join")
or inst_match(("CALL", "BUILD_STRING"))
)
and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod)
and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str)
):
# "..."%(...) uses "".join
return
if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign):
# data: int
return
if self.is_except_cleanup(instruction, node):
return
if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match(
ast.Name, id=instruction.argval, ctx=ast.Del
):
return
if inst_match("BUILD_STRING") and (
node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod)
):
return
if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With):
return
if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match(
ast.Constant
):
# store docstrings
return
if (
inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF"))
and node_match(ast.ExceptHandler)
and instruction.argval == mangled_name(node)
):
# store exception in variable
return
if (
inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL"))
and node_match((ast.Import, ast.ImportFrom))
and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names)
):
# store imported module in variable
return
if (
inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL"))
and (
node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef))
or node_match(
ast.Name,
ctx=ast.Store,
)
)
and instruction.argval == mangled_name(node)
):
return
if False:
# TODO: match expressions are not supported for now
if inst_match(("STORE_FAST", "STORE_NAME")) and node_match(
ast.MatchAs, name=instruction.argval
):
return
if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence):
return
if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue):
return
if inst_match("BINARY_OP") and node_match(
ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")]
):
# a+=5
return
if node_match(ast.Attribute, ctx=ast.Del) and inst_match(
"DELETE_ATTR", argval=mangled_name(node)
):
return
if inst_match(("JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP")) and node_match(
ast.BoolOp
):
# and/or short circuit
return
if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del):
return
if node_match(ast.Name, ctx=ast.Load) and inst_match(
("LOAD_NAME", "LOAD_FAST", "LOAD_GLOBAL"), argval=mangled_name(node)
):
return
if node_match(ast.Name, ctx=ast.Del) and inst_match(
("DELETE_NAME", "DELETE_GLOBAL"), argval=mangled_name(node)
):
return
# old verifier
typ: Type = type(None)
op_type: Type = type(None)
if op_name.startswith(("BINARY_SUBSCR", "SLICE+")):
typ = ast.Subscript
ctx = ast.Load
elif op_name.startswith("BINARY_"):
typ = ast.BinOp
op_type = op_type_map[instruction.argrepr]
extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type)
elif op_name.startswith("UNARY_"):
typ = ast.UnaryOp
op_type = dict(
UNARY_POSITIVE=ast.UAdd,
UNARY_NEGATIVE=ast.USub,
UNARY_NOT=ast.Not,
UNARY_INVERT=ast.Invert,
)[op_name]
extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type)
elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD"):
typ = ast.Attribute
ctx = ast.Load
extra_filter = lambda e: mangled_name(e) == instruction.argval
elif op_name in (
"LOAD_NAME",
"LOAD_GLOBAL",
"LOAD_FAST",
"LOAD_DEREF",
"LOAD_CLASSDEREF",
):
typ = ast.Name
ctx = ast.Load
extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval
elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"):
typ = ast.Compare
extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1
elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")):
ctx = ast.Store
typ = ast.Subscript
elif op_name.startswith("STORE_ATTR"):
ctx = ast.Store
typ = ast.Attribute
extra_filter = lambda e: mangled_name(e) == instruction.argval
node_ctx = getattr(node, "ctx", None)
ctx_match = (
ctx is not type(None)
or not hasattr(node, "ctx")
or isinstance(node_ctx, ctx)
)
# check for old verifier
if isinstance(node, typ) and ctx_match and extra_filter(node):
return
# generate error
title = "ast.%s is not created from %s" % (
type(node).__name__,
instruction.opname,
)
> raise VerifierFailure(title, node, instruction)
E executing._exceptions.VerifierFailure: ast.Name is not created from LOAD_FAST_CHECK
executing/_position_node_finder.py:545: VerifierFailure
___________________________ test_global_tester_calls ___________________________
def test_global_tester_calls():
# tester calls should be tested at global scope
> from . import global_tester_calls
tests/test_main.py:1397:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/global_tester_calls.py:13: in <module>
assert -tester is +tester is ~tester is tester
tests/utils.py:131: in __invert__
node = self.get_node(ast.UnaryOp)
tests/utils.py:35: in get_node
ex = self.get_executing(inspect.currentframe().f_back.f_back)
tests/utils.py:42: in get_executing
return Source.executing(frame)
executing/executing.py:368: in executing
node_finder = NodeFinder(frame, stmts, tree, lasti, source)
executing/_position_node_finder.py:158: in __init__
self.verify(self.result, self.instruction(lasti))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <executing._position_node_finder.PositionNodeFinder object at 0x7f702c84ede0>
node = <ast.UnaryOp object at 0x7f7029326590>
instruction = Instruction(opname='CALL_INTRINSIC_1', opcode=173, arg=5, argval=5, argrepr='', offset=178, starts_line=None, is_jump_target=False, positions=Positions(lineno=13, end_lineno=13, col_offset=18, end_col_offset=25))
def verify(self, node: EnhancedAST, instruction: dis.Instruction) -> None:
"""
checks if this node could gererate this instruction
"""
op_name = instruction.opname
extra_filter: Callable[[EnhancedAST], bool] = lambda e: True
ctx: Type = type(None)
def inst_match(opnames: Union[str, Sequence[str]], **kwargs: Any) -> bool:
"""
match instruction
Parameters:
opnames: (str|Seq[str]): inst.opname has to be equal to or in `opname`
**kwargs: every arg has to match inst.arg
Returns:
True if all conditions match the instruction
"""
if isinstance(opnames, str):
opnames = [opnames]
return instruction.opname in opnames and kwargs == {
k: getattr(instruction, k) for k in kwargs
}
def node_match(node_type: Union[Type, Tuple[Type, ...]], **kwargs: Any) -> bool:
"""
match the ast-node
Parameters:
node_type: type of the node
**kwargs: every `arg` has to be equal `node.arg`
or `node.arg` has to be an instance of `arg` if it is a type.
"""
return isinstance(node, node_type) and all(
isinstance(getattr(node, k), v)
if isinstance(v, type)
else getattr(node, k) == v
for k, v in kwargs.items()
)
if op_name == "CACHE":
return
if inst_match("CALL") and node_match((ast.With, ast.AsyncWith)):
# call to context.__exit__
return
if inst_match(("CALL", "LOAD_FAST")) and node_match(
(ast.ListComp, ast.GeneratorExp, ast.SetComp, ast.DictComp)
):
# call to the generator function
return
if inst_match(("CALL", "CALL_FUNCTION_EX")) and node_match(
(ast.ClassDef, ast.Call)
):
return
if inst_match(("COMPARE_OP", "IS_OP", "CONTAINS_OP")) and node_match(
ast.Compare
):
return
if inst_match("LOAD_NAME", argval="__annotations__") and node_match(
ast.AnnAssign
):
return
if (
(
inst_match("LOAD_METHOD", argval="join")
or inst_match(("CALL", "BUILD_STRING"))
)
and node_match(ast.BinOp, left=ast.Constant, op=ast.Mod)
and isinstance(cast(ast.Constant, cast(ast.BinOp, node).left).value, str)
):
# "..."%(...) uses "".join
return
if inst_match("STORE_SUBSCR") and node_match(ast.AnnAssign):
# data: int
return
if self.is_except_cleanup(instruction, node):
return
if inst_match(("DELETE_NAME", "DELETE_FAST")) and node_match(
ast.Name, id=instruction.argval, ctx=ast.Del
):
return
if inst_match("BUILD_STRING") and (
node_match(ast.JoinedStr) or node_match(ast.BinOp, op=ast.Mod)
):
return
if inst_match(("BEFORE_WITH","WITH_EXCEPT_START")) and node_match(ast.With):
return
if inst_match(("STORE_NAME", "STORE_GLOBAL"), argval="__doc__") and node_match(
ast.Constant
):
# store docstrings
return
if (
inst_match(("STORE_NAME", "STORE_FAST", "STORE_GLOBAL", "STORE_DEREF"))
and node_match(ast.ExceptHandler)
and instruction.argval == mangled_name(node)
):
# store exception in variable
return
if (
inst_match(("STORE_NAME", "STORE_FAST", "STORE_DEREF", "STORE_GLOBAL"))
and node_match((ast.Import, ast.ImportFrom))
and any(mangled_name(cast(EnhancedAST, alias)) == instruction.argval for alias in cast(ast.Import, node).names)
):
# store imported module in variable
return
if (
inst_match(("STORE_FAST", "STORE_DEREF", "STORE_NAME", "STORE_GLOBAL"))
and (
node_match((ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef))
or node_match(
ast.Name,
ctx=ast.Store,
)
)
and instruction.argval == mangled_name(node)
):
return
if False:
# TODO: match expressions are not supported for now
if inst_match(("STORE_FAST", "STORE_NAME")) and node_match(
ast.MatchAs, name=instruction.argval
):
return
if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchSequence):
return
if inst_match("COMPARE_OP", argval="==") and node_match(ast.MatchValue):
return
if inst_match("BINARY_OP") and node_match(
ast.AugAssign, op=op_type_map[instruction.argrepr.removesuffix("=")]
):
# a+=5
return
if node_match(ast.Attribute, ctx=ast.Del) and inst_match(
"DELETE_ATTR", argval=mangled_name(node)
):
return
if inst_match(("JUMP_IF_TRUE_OR_POP", "JUMP_IF_FALSE_OR_POP")) and node_match(
ast.BoolOp
):
# and/or short circuit
return
if inst_match("DELETE_SUBSCR") and node_match(ast.Subscript, ctx=ast.Del):
return
if node_match(ast.Name, ctx=ast.Load) and inst_match(
("LOAD_NAME", "LOAD_FAST", "LOAD_GLOBAL"), argval=mangled_name(node)
):
return
if node_match(ast.Name, ctx=ast.Del) and inst_match(
("DELETE_NAME", "DELETE_GLOBAL"), argval=mangled_name(node)
):
return
# old verifier
typ: Type = type(None)
op_type: Type = type(None)
if op_name.startswith(("BINARY_SUBSCR", "SLICE+")):
typ = ast.Subscript
ctx = ast.Load
elif op_name.startswith("BINARY_"):
typ = ast.BinOp
op_type = op_type_map[instruction.argrepr]
extra_filter = lambda e: isinstance(cast(ast.BinOp, e).op, op_type)
elif op_name.startswith("UNARY_"):
typ = ast.UnaryOp
op_type = dict(
UNARY_POSITIVE=ast.UAdd,
UNARY_NEGATIVE=ast.USub,
UNARY_NOT=ast.Not,
UNARY_INVERT=ast.Invert,
)[op_name]
extra_filter = lambda e: isinstance(cast(ast.UnaryOp, e).op, op_type)
elif op_name in ("LOAD_ATTR", "LOAD_METHOD", "LOOKUP_METHOD"):
typ = ast.Attribute
ctx = ast.Load
extra_filter = lambda e: mangled_name(e) == instruction.argval
elif op_name in (
"LOAD_NAME",
"LOAD_GLOBAL",
"LOAD_FAST",
"LOAD_DEREF",
"LOAD_CLASSDEREF",
):
typ = ast.Name
ctx = ast.Load
extra_filter = lambda e: cast(ast.Name, e).id == instruction.argval
elif op_name in ("COMPARE_OP", "IS_OP", "CONTAINS_OP"):
typ = ast.Compare
extra_filter = lambda e: len(cast(ast.Compare, e).ops) == 1
elif op_name.startswith(("STORE_SLICE", "STORE_SUBSCR")):
ctx = ast.Store
typ = ast.Subscript
elif op_name.startswith("STORE_ATTR"):
ctx = ast.Store
typ = ast.Attribute
extra_filter = lambda e: mangled_name(e) == instruction.argval
node_ctx = getattr(node, "ctx", None)
ctx_match = (
ctx is not type(None)
or not hasattr(node, "ctx")
or isinstance(node_ctx, ctx)
)
# check for old verifier
if isinstance(node, typ) and ctx_match and extra_filter(node):
return
# generate error
title = "ast.%s is not created from %s" % (
type(node).__name__,
instruction.opname,
)
> raise VerifierFailure(title, node, instruction)
E executing._exceptions.VerifierFailure: ast.UnaryOp is not created from CALL_INTRINSIC_1
executing/_position_node_finder.py:545: VerifierFailure
=========================== short test summary info ============================
FAILED tests/test_main.py::TestStuff::test_decorator - AssertionError: ([7, 8...
FAILED tests/test_main.py::TestStuff::test_decorator_cache_instruction - exec...
FAILED tests/test_main.py::TestStuff::test_names - executing._exceptions.Veri...
FAILED tests/test_main.py::test_global_tester_calls - executing._exceptions.V...
=================== 4 failed, 41 passed, 15 skipped in 3.02s ===================