Package: src:python-executing
Version: 2.0.1-0.1
Severity: serious
Tags: ftbfs
Dear maintainer:
During a rebuild of all packages in unstable, your package failed to build:
--------------------------------------------------------------------------------
[...]
debian/rules binary
dh binary --buildsystem=pybuild
dh_update_autotools_config -O--buildsystem=pybuild
dh_autoreconf -O--buildsystem=pybuild
dh_auto_configure -O--buildsystem=pybuild
dh_auto_build -O--buildsystem=pybuild
I: pybuild plugin_pyproject:129: Building wheel for python3.12 with "build"
module
I: pybuild base:311: python3.12 -m build --skip-dependency-check --no-isolation --wheel
--outdir /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12
* Building wheel...
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/executing
copying executing/_exceptions.py -> build/lib/executing
copying executing/version.py -> build/lib/executing
copying executing/__init__.py -> build/lib/executing
copying executing/executing.py -> build/lib/executing
copying executing/_position_node_finder.py -> build/lib/executing
running egg_info
creating executing.egg-info
writing executing.egg-info/PKG-INFO
writing dependency_links to executing.egg-info/dependency_links.txt
writing requirements to executing.egg-info/requires.txt
writing top-level names to executing.egg-info/top_level.txt
writing manifest file 'executing.egg-info/SOURCES.txt'
reading manifest file 'executing.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
adding license file 'LICENSE.txt'
writing manifest file 'executing.egg-info/SOURCES.txt'
copying executing/py.typed -> build/lib/executing
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/executing
copying build/lib/executing/_exceptions.py ->
build/bdist.linux-x86_64/wheel/executing
copying build/lib/executing/version.py ->
build/bdist.linux-x86_64/wheel/executing
copying build/lib/executing/__init__.py ->
build/bdist.linux-x86_64/wheel/executing
copying build/lib/executing/executing.py ->
build/bdist.linux-x86_64/wheel/executing
copying build/lib/executing/_position_node_finder.py ->
build/bdist.linux-x86_64/wheel/executing
copying build/lib/executing/py.typed -> build/bdist.linux-x86_64/wheel/executing
running install_egg_info
Copying executing.egg-info to
build/bdist.linux-x86_64/wheel/executing-2.0.1.egg-info
running install_scripts
creating build/bdist.linux-x86_64/wheel/executing-2.0.1.dist-info/WHEEL
creating
'/<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/.tmp-hk80yuhq/executing-2.0.1-py2.py3-none-any.whl'
and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'executing/__init__.py'
adding 'executing/_exceptions.py'
adding 'executing/_position_node_finder.py'
adding 'executing/executing.py'
adding 'executing/py.typed'
adding 'executing/version.py'
adding 'executing-2.0.1.dist-info/LICENSE.txt'
adding 'executing-2.0.1.dist-info/METADATA'
adding 'executing-2.0.1.dist-info/WHEEL'
adding 'executing-2.0.1.dist-info/top_level.txt'
adding 'executing-2.0.1.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
Successfully built executing-2.0.1-py2.py3-none-any.whl
I: pybuild plugin_pyproject:144: Unpacking wheel built for python3.12 with
"installer" module
dh_auto_test -O--buildsystem=pybuild
I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build;
python3.12 -m pytest tests
============================= test session starts ==============================
platform linux -- Python 3.12.4, pytest-8.2.2, pluggy-1.5.0
rootdir: /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build
configfile: pyproject.toml
collected 199 items
tests/test_ipython.py .. [ 1%]
tests/test_main.py ...............F..................................... [ 27%]
........................................................................ [ 63%]
............................................sssssssssssssss. [ 93%]
tests/test_pytest.py ............ [100%]
=================================== FAILURES ===================================
_____________________________ TestStuff.test_iter ______________________________
self = <tests.test_main.TestStuff testMethod=test_iter>
def test_iter(self):
class iter_test:
def __init__(self, typ):
self.typ = typ
self.it = iter([1, 2])
def __iter__(self):
assert isinstance(calling_expression(), self.typ)
return self
def __next__(self):
assert isinstance(calling_expression(), self.typ)
return next(self.it)
assert list(iter_test(ast.Call)) == [1, 2]
assert next(iter(iter_test(ast.Call))) == 1
if sys.version_info >= (3, 11):
assert [i for i in iter_test(ast.ListComp)] == [1, 2]
assert {i for i in iter_test(ast.SetComp)} == {1, 2}
assert {i: i for i in iter_test(ast.DictComp)} == {1: 1, 2: 2}
assert list(i for i in iter_test(ast.GeneratorExp)) == [1, 2]
for i in iter_test(ast.For):
tests/test_main.py:604:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_main.py:587: in __iter__
assert isinstance(calling_expression(), self.typ)
tests/test_main.py:48: in calling_expression
return Source.executing(frame).node
executing/executing.py:273: in executing
node_finder = NodeFinder(frame, stmts, tree, lasti, source)
executing/_position_node_finder.py:165: in __init__
self.verify(self.result, self.instruction(lasti))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <executing._position_node_finder.PositionNodeFinder object at
0x7f710437fbf0>
node = <ast.Call object at 0x7f71040b4790>
instruction = Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None,
argrepr='', offset=620, starts_line=None, is_jump_target=False,
positions=Positions(lineno=604, end_lineno=604, col_offset=21,
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 (
sys.version_info >= (3, 12)
and inst_match(("LOAD_FAST_AND_CLEAR", "STORE_FAST"))
and node_match((ast.ListComp, ast.SetComp, ast.DictComp))
):
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("LOAD_ATTR", argval="join") # 3.12
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 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",
"POP_JUMP_IF_TRUE",
"POP_JUMP_IF_FALSE",
)
) 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)
or (
node_match(ast.Name, ctx=ast.Store)
and isinstance(node.parent, ast.AugAssign)
)
) and inst_match(
(
"LOAD_NAME",
"LOAD_FAST",
"LOAD_FAST_CHECK",
"LOAD_GLOBAL",
"LOAD_DEREF",
"LOAD_FROM_DICT_OR_DEREF",
),
argval=mangled_name(node),
):
return
if node_match(ast.Name, ctx=ast.Del) and inst_match(
("DELETE_NAME", "DELETE_GLOBAL", "DELETE_DEREF"),
argval=mangled_name(node)
):
return
if node_match(ast.Constant) and inst_match(
"LOAD_CONST", argval=cast(ast.Constant, node).value
):
return
if node_match(
(ast.ListComp, ast.SetComp, ast.DictComp, ast.GeneratorExp, ast.For)
) and inst_match(("GET_ITER", "FOR_ITER")):
return
if sys.version_info >= (3, 12):
if node_match(ast.UnaryOp, op=ast.UAdd) and inst_match(
"CALL_INTRINSIC_1", argrepr="INTRINSIC_UNARY_POSITIVE"
):
return
if node_match(ast.Subscript) and inst_match("BINARY_SLICE"):
return
if node_match(ast.ImportFrom) and inst_match(
"CALL_INTRINSIC_1", argrepr="INTRINSIC_IMPORT_STAR"
):
return
if (
node_match(ast.Yield) or isinstance(node.parent,
ast.GeneratorExp)
) and inst_match("CALL_INTRINSIC_1",
argrepr="INTRINSIC_ASYNC_GEN_WRAP"):
return
if node_match(ast.Name) and inst_match("LOAD_DEREF",argval="__classdict__"):
return
if node_match(ast.TypeVar) and (
inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVAR")
or inst_match(
"CALL_INTRINSIC_2", argrepr="INTRINSIC_TYPEVAR_WITH_BOUND"
)
or inst_match(
"CALL_INTRINSIC_2",
argrepr="INTRINSIC_TYPEVAR_WITH_CONSTRAINTS"
)
or inst_match(("STORE_FAST", "STORE_DEREF"),
argrepr=mangled_name(node))
):
return
if node_match(ast.TypeVarTuple) and (
inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_TYPEVARTUPLE")
or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)
):
return
if node_match(ast.ParamSpec) and (
inst_match("CALL_INTRINSIC_1", argrepr="INTRINSIC_PARAMSPEC")
or inst_match(("STORE_FAST", "STORE_DEREF"), argrepr=node.name)):
return
if node_match(ast.TypeAlias):
if(
inst_match("CALL_INTRINSIC_1",
argrepr="INTRINSIC_TYPEALIAS")
or inst_match(
("STORE_NAME", "STORE_FAST", "STORE_DEREF"),
argrepr=node.name.id
)
or inst_match("CALL")
):
return
if node_match(ast.ClassDef) and node.type_params:
if inst_match(
("STORE_DEREF", "LOAD_DEREF", "LOAD_FROM_DICT_OR_DEREF"),
argrepr=".type_params",
):
return
if inst_match(("STORE_FAST", "LOAD_FAST"), argrepr=".generic_base"):
return
if inst_match(
"CALL_INTRINSIC_1", argrepr="INTRINSIC_SUBSCRIPT_GENERIC"
):
return
if inst_match("LOAD_DEREF",argval="__classdict__"):
return
if node_match((ast.FunctionDef,ast.AsyncFunctionDef)) and node.type_params:
if inst_match("CALL"):
return
if inst_match(
"CALL_INTRINSIC_2",
argrepr="INTRINSIC_SET_FUNCTION_TYPE_PARAMS"
):
return
if inst_match("LOAD_FAST",argval=".defaults"):
return
if inst_match("LOAD_FAST",argval=".kwdefaults"):
return
if inst_match("STORE_NAME", argval="__classdictcell__"):
# this is a general thing
return
# f-strings
if node_match(ast.JoinedStr) and (
inst_match("LOAD_ATTR", argval="join")
or inst_match(("LIST_APPEND", "CALL"))
):
return
if node_match(ast.FormattedValue) and inst_match("FORMAT_VALUE"):
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","LOAD_SUPER_ATTR"):
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.Call is not created from
GET_ITER
executing/_position_node_finder.py:772: VerifierFailure
=============================== warnings summary ===============================
tests/test_main.py::test_small_samples[4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5.py]
/<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build/tests/small_samples/4851dc1b626a95e97dbe0c53f96099d165b755dd1bd552c6ca771f7bca6d30f5.py:16:
SyntaxWarning: "is" with 'int' literal. Did you mean "=="?
if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1:
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_main.py::TestStuff::test_iter - executing._exceptions.Verif...
============= 1 failed, 183 passed, 15 skipped, 1 warning in 5.19s =============
E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd
/<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build; python3.12 -m pytest tests
dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p 3.12
returned exit code 13
make: *** [debian/rules:8: binary] Error 25
dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2
--------------------------------------------------------------------------------
The above is just how the build ends and not necessarily the most relevant part.
If required, the full build log is available here:
https://people.debian.org/~sanvila/build-logs/202407/
About the archive rebuild: The build was made on virtual machines
of type m6a.large and r6a.large from AWS, using sbuild and a
reduced chroot with only build-essential packages.
If you could not reproduce the bug please contact me privately, as I
am willing to provide ssh access to a virtual machine where the bug is
fully reproducible.
If this is really a bug in one of the build-depends, please use
reassign and affects, so that this is still visible in the BTS web
page for this package.
Thanks.