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.

Reply via email to