Source: astroid Version: 3.2.2-1 Severity: normal User: [email protected] Usertags: python3.13 Forwarded: https://github.com/pylint-dev/astroid/issues/2349
This package failed build from source when test-built against a version of python3-defaults that includes 3.13 as a supported version. To reproduce this issue, build against python3-defaults (python3-all-dev etc.) from Debian experimental. Looks like 3.3.0 upstream should add support. What's new in Python 3.13: https://docs.python.org/3.13/whatsnew/3.13.html Log snippet: I: pybuild plugin_pyproject:144: Unpacking wheel built for python3.12 with "installer" module dh_auto_test -O--buildsystem=pybuild I: pybuild pybuild:308: cp -r /<<PKGBUILDDIR>>/tests /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_astroid/build/astroid/ I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_astroid/build; python3.13 -m pytest tests ============================= test session starts ============================== platform linux -- Python 3.13.0rc2, pytest-8.3.2, pluggy-1.5.0 rootdir: /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_astroid/build configfile: pyproject.toml plugins: typeguard-4.3.0 collected 1689 items tests/brain/numpy/test_core_einsumfunc.py ss [ 0%] tests/brain/numpy/test_core_fromnumeric.py s [ 0%] tests/brain/numpy/test_core_function_base.py s [ 0%] tests/brain/numpy/test_core_multiarray.py sssss [ 0%] tests/brain/numpy/test_core_numeric.py sssss [ 0%] tests/brain/numpy/test_core_numerictypes.py sssssss.. [ 1%] tests/brain/numpy/test_core_umath.py ssssssss [ 1%] tests/brain/numpy/test_ma.py ssss [ 2%] tests/brain/numpy/test_ndarray.py sss [ 2%] tests/brain/numpy/test_random_mtrand.py ss [ 2%] tests/brain/test_argparse.py . [ 2%] tests/brain/test_attr.py sssss [ 2%] tests/brain/test_brain.py .s.....s....ss........................F....... [ 5%] ............s..........................................................x [ 9%] ...............s...... [ 11%] tests/brain/test_builtin.py .................. [ 12%] tests/brain/test_ctypes.py ....x........................ [ 13%] tests/brain/test_dataclasses.py ........................................ [ 16%] ......................................x... [ 18%] tests/brain/test_dateutil.py s [ 18%] tests/brain/test_enum.py ............................. [ 20%] tests/brain/test_hashlib.py ... [ 20%] tests/brain/test_multiprocessing.py ... [ 20%] tests/brain/test_named_tuple.py ....................... [ 22%] tests/brain/test_nose.py s [ 22%] tests/brain/test_pathlib.py FF.. [ 22%] tests/brain/test_pytest.py . [ 22%] tests/brain/test_qt.py sss [ 22%] tests/brain/test_regex.py ss [ 22%] tests/brain/test_signal.py ... [ 22%] tests/brain/test_six.py ....... [ 23%] tests/brain/test_ssl.py . [ 23%] tests/brain/test_threading.py .... [ 23%] tests/brain/test_typing.py . [ 23%] tests/brain/test_typing_extensions.py . [ 23%] tests/brain/test_unittest.py . [ 23%] tests/test_builder.py .................................................. [ 26%] .....x.. [ 27%] tests/test_constraint.py ................................... [ 29%] tests/test_decorators.py ... [ 29%] tests/test_filter_statements.py . [ 29%] tests/test_group_exceptions.py ... [ 29%] tests/test_helpers.py ............... [ 30%] tests/test_inference.py ................................................ [ 33%] ..........................................x...........x.....x.....F..... [ 37%] ..............................................x......................... [ 42%] ........................................................................ [ 46%] ........................................x........xx..................... [ 50%] x...x..........................................sF.....x................. [ 54%] ....................... [ 56%] tests/test_inference_calls.py ........................ [ 57%] tests/test_lookup.py ................................................... [ 60%] .... [ 60%] tests/test_manager.py ............................................ [ 63%] tests/test_modutils.py ................................................. [ 66%] ................s. [ 67%] tests/test_nodes.py .................................................... [ 70%] ........................................................................ [ 74%] ................................................................ [ 78%] tests/test_nodes_lineno.py s....................... [ 79%] tests/test_nodes_position.py ... [ 80%] tests/test_object_model.py x...............x.........s......... [ 82%] tests/test_objects.py ...................... [ 83%] tests/test_protocols.py ..................... [ 84%] tests/test_python3.py .......................... [ 86%] tests/test_raw_building.py ............. [ 87%] tests/test_regrtest.py .............ss........... [ 88%] tests/test_scoped_nodes.py ............................................. [ 91%] ........................................................................ [ 95%] .................................................. [ 98%] tests/test_stdlib.py .. [ 98%] tests/test_transforms.py ......... [ 99%] tests/test_type_params.py ..... [ 99%] tests/test_utils.py ........ [100%] =================================== FAILURES =================================== _______________ TypingBrain.test_typing_annotated_subscriptable ________________ self = <tests.brain.test_brain.TypingBrain testMethod=test_typing_annotated_subscriptable> @test_utils.require_version(minver="3.9") def test_typing_annotated_subscriptable(self): """Test typing.Annotated is subscriptable with __class_getitem__""" node = builder.extract_node( """ import typing typing.Annotated[str, "data"] """ ) inferred = next(node.infer()) assert isinstance(inferred, nodes.ClassDef) > assert isinstance(inferred.getattr("__class_getitem__")[0], > nodes.FunctionDef) tests/brain/test_brain.py:659: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <ClassDef.Annotated l.10 at 0xffffb01be5d0>, name = '__class_getitem__' context = None, class_context = True def getattr( self, name: str, context: InferenceContext | None = None, class_context: bool = True, ) -> list[InferenceResult]: """Get an attribute from this class, using Python's attribute semantic. This method doesn't look in the :attr:`instance_attrs` dictionary since it is done by an :class:`Instance` proxy at inference time. It may return an :class:`Uninferable` object if the attribute has not been found, but a ``__getattr__`` or ``__getattribute__`` method is defined. If ``class_context`` is given, then it is considered that the attribute is accessed from a class context, e.g. ClassDef.attribute, otherwise it might have been accessed from an instance as well. If ``class_context`` is used in that case, then a lookup in the implicit metaclass and the explicit metaclass will be done. :param name: The attribute to look for. :param class_context: Whether the attribute can be accessed statically. :returns: The attribute. :raises AttributeInferenceError: If the attribute cannot be inferred. """ if not name: raise AttributeInferenceError(target=self, attribute=name, context=context) # don't modify the list in self.locals! values: list[InferenceResult] = list(self.locals.get(name, [])) for classnode in self.ancestors(recurs=True, context=context): values += classnode.locals.get(name, []) if name in self.special_attributes and class_context and not values: result = [self.special_attributes.lookup(name)] if name == "__bases__": # Need special treatment, since they are mutable # and we need to return all the values. result += values return result if class_context: values += self._metaclass_lookup_attribute(name, context) # Remove AnnAssigns without value, which are not attributes in the purest sense. for value in values.copy(): if isinstance(value, node_classes.AssignName): stmt = value.statement() if isinstance(stmt, node_classes.AnnAssign) and stmt.value is None: values.pop(values.index(value)) if not values: > raise AttributeInferenceError(target=self, attribute=name, > context=context) E astroid.exceptions.AttributeInferenceError: '__class_getitem__' not found on <ClassDef.Annotated l.10 at 0xffffb01be5d0>. astroid/nodes/scoped_nodes/scoped_nodes.py:2441: AttributeInferenceError ____________________________ test_inference_parents ____________________________ def test_inference_parents() -> None: """Test inference of ``pathlib.Path.parents``.""" name_node = astroid.extract_node( """ from pathlib import Path current_path = Path().resolve() path_parents = current_path.parents path_parents """ ) inferred = name_node.inferred() assert len(inferred) == 1 assert isinstance(inferred[0], bases.Instance) > assert inferred[0].qname() == "pathlib._PathParents" E AssertionError: assert 'builtins.tuple' == 'pathlib._PathParents' E E - pathlib._PathParents E + builtins.tuple tests/brain/test_pathlib.py:26: AssertionError ____________________ test_inference_parents_subscript_index ____________________ instance = <Tuple.tuple l.349 at 0xffffae6d1bd0>, elts = [] index = <Const.int l.5 at 0xffffae573380> context = <astroid.context.InferenceContext object at 0xffffafc94100> def _container_getitem(instance, elts, index, context: InferenceContext | None = None): """Get a slice or an item, using the given *index*, for the given sequence.""" try: if isinstance(index, Slice): index_slice = _infer_slice(index, context=context) new_cls = instance.__class__() new_cls.elts = elts[index_slice] new_cls.parent = instance.parent return new_cls if isinstance(index, Const): > return elts[index.value] E IndexError: list index out of range astroid/nodes/node_classes.py:252: IndexError The above exception was the direct cause of the following exception: self = <Subscript l.5 at 0xffffae6d19f0> context = <astroid.context.InferenceContext object at 0xffffafc94100> kwargs = {} helpers = <module 'astroid.helpers' from '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_astroid/build/astroid/helpers.py'> found_one = False, value = <Tuple.tuple l.349 at 0xffffae6d1bd0> index = <Const.int l.5 at 0xffffae573380> index_value = <Const.int l.5 at 0xffffae573380> def _infer_subscript( self, context: InferenceContext | None = None, **kwargs: Any ) -> Generator[InferenceResult, None, InferenceErrorInfo | None]: """Inference for subscripts. We're understanding if the index is a Const or a slice, passing the result of inference to the value's `getitem` method, which should handle each supported index type accordingly. """ from astroid import helpers # pylint: disable=import-outside-toplevel found_one = False for value in self.value.infer(context): if isinstance(value, util.UninferableBase): yield util.Uninferable return None for index in self.slice.infer(context): if isinstance(index, util.UninferableBase): yield util.Uninferable return None # Try to deduce the index value. index_value = self._SUBSCRIPT_SENTINEL if value.__class__ == Instance: index_value = index elif index.__class__ == Instance: instance_as_index = helpers.class_instance_as_index(index) if instance_as_index: index_value = instance_as_index else: index_value = index if index_value is self._SUBSCRIPT_SENTINEL: raise InferenceError(node=self, context=context) try: > assigned = value.getitem(index_value, context) astroid/nodes/node_classes.py:3743: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ astroid/nodes/node_classes.py:4062: in getitem return _container_getitem(self, self.elts, index, context=context) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ instance = <Tuple.tuple l.349 at 0xffffae6d1bd0>, elts = [] index = <Const.int l.5 at 0xffffae573380> context = <astroid.context.InferenceContext object at 0xffffafc94100> def _container_getitem(instance, elts, index, context: InferenceContext | None = None): """Get a slice or an item, using the given *index*, for the given sequence.""" try: if isinstance(index, Slice): index_slice = _infer_slice(index, context=context) new_cls = instance.__class__() new_cls.elts = elts[index_slice] new_cls.parent = instance.parent return new_cls if isinstance(index, Const): return elts[index.value] except ValueError as exc: raise AstroidValueError( message="Slice {index!r} cannot index container", node=instance, index=index, context=context, ) from exc except IndexError as exc: > raise AstroidIndexError( message="Index {index!s} out of range", node=instance, index=index, context=context, ) from exc E astroid.exceptions.AstroidIndexError: Index Const.int(value=2, E kind=None) out of range astroid/nodes/node_classes.py:261: AstroidIndexError The above exception was the direct cause of the following exception: def test_inference_parents_subscript_index() -> None: """Test inference of ``pathlib.Path.parents``, accessed by index.""" path = astroid.extract_node( """ from pathlib import Path current_path = Path().resolve() current_path.parents[2] #@ """ ) > inferred = path.inferred() tests/brain/test_pathlib.py:40: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ astroid/nodes/node_ng.py:586: in inferred return list(self.infer()) astroid/nodes/node_ng.py:170: in infer for i, result in enumerate(self._infer(context=context, **kwargs)): astroid/decorators.py:90: in inner yield next(generator) astroid/decorators.py:49: in wrapped for res in _func(node, context, **kwargs): _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <Subscript l.5 at 0xffffae6d19f0> context = <astroid.context.InferenceContext object at 0xffffafc94100> kwargs = {} helpers = <module 'astroid.helpers' from '/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_astroid/build/astroid/helpers.py'> found_one = False, value = <Tuple.tuple l.349 at 0xffffae6d1bd0> index = <Const.int l.5 at 0xffffae573380> index_value = <Const.int l.5 at 0xffffae573380> def _infer_subscript( self, context: InferenceContext | None = None, **kwargs: Any ) -> Generator[InferenceResult, None, InferenceErrorInfo | None]: """Inference for subscripts. We're understanding if the index is a Const or a slice, passing the result of inference to the value's `getitem` method, which should handle each supported index type accordingly. """ from astroid import helpers # pylint: disable=import-outside-toplevel found_one = False for value in self.value.infer(context): if isinstance(value, util.UninferableBase): yield util.Uninferable return None for index in self.slice.infer(context): if isinstance(index, util.UninferableBase): yield util.Uninferable return None # Try to deduce the index value. index_value = self._SUBSCRIPT_SENTINEL if value.__class__ == Instance: index_value = index elif index.__class__ == Instance: instance_as_index = helpers.class_instance_as_index(index) if instance_as_index: index_value = instance_as_index else: index_value = index if index_value is self._SUBSCRIPT_SENTINEL: raise InferenceError(node=self, context=context) try: assigned = value.getitem(index_value, context) except ( AstroidTypeError, AstroidIndexError, AstroidValueError, AttributeInferenceError, AttributeError, ) as exc: > raise InferenceError(node=self, context=context) from exc E astroid.exceptions.InferenceError: Inference failed for <Subscript l.5 at 0xffffae6d19f0>. astroid/nodes/node_classes.py:3751: InferenceError ____________ InferenceTest.test_getitem_of_class_raised_type_error _____________ self = <tests.test_inference.InferenceTest testMethod=test_getitem_of_class_raised_type_error> def test_getitem_of_class_raised_type_error(self) -> None: # Test that we wrap an AttributeInferenceError # and reraise it as a TypeError in Class.getitem node = extract_node( """ def test(): yield test() """ ) inferred = next(node.infer()) > with self.assertRaises(AstroidTypeError): E AssertionError: AstroidTypeError not raised tests/test_inference.py:4467: AssertionError ___________ test_dataclasses_subscript_inference_recursion_error_39 ____________ @pytest.mark.skipif( not PY39_PLUS, reason="Exact inference with dataclasses (replace function) in python3.9", ) def test_dataclasses_subscript_inference_recursion_error_39(): code = """ from dataclasses import dataclass, replace @dataclass class ProxyConfig: auth: str = "/auth" a = ProxyConfig("") test_dict = {"proxy" : {"auth" : "", "bla" : "f"}} foo = test_dict['proxy'] replace(a, **test_dict['proxy']) # This fails """ node = extract_node(code) infer_val = util.safe_infer(node) > assert isinstance(infer_val, Instance) E assert False E + where False = isinstance(Uninferable, Instance) tests/test_inference.py:6790: AssertionError =========================== short test summary info ============================ FAILED tests/brain/test_brain.py::TypingBrain::test_typing_annotated_subscriptable FAILED tests/brain/test_pathlib.py::test_inference_parents - AssertionError: ... FAILED tests/brain/test_pathlib.py::test_inference_parents_subscript_index - ... FAILED tests/test_inference.py::InferenceTest::test_getitem_of_class_raised_type_error FAILED tests/test_inference.py::test_dataclasses_subscript_inference_recursion_error_39 =========== 5 failed, 1606 passed, 62 skipped, 16 xfailed in 55.32s ============ E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_astroid/build; python3.13 -m pytest tests If required, the full build log is available here (for the next 30 days): https://debusine.debian.net/artifact/715688/ This bug has been filed at "normal" severity, as we haven't started the transition to add 3.13 as a supported version, yet. This will be raised to RC as soon as that happens, hopefully well before trixie. Thanks, Stefano

