Bug 2323166 - python-astroid fails to build with Python 3.14: astroid.exceptions.InferenceError: StopIteration raised without any error information.
Summary: python-astroid fails to build with Python 3.14: astroid.exceptions.InferenceE...
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: python-astroid
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Gwyn Ciesla
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: PYTHON3.14
TreeView+ depends on / blocked
 
Reported: 2024-11-01 14:49 UTC by Karolina Surma
Modified: 2025-06-15 18:30 UTC (History)
4 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2025-06-15 18:30:32 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Github pylint-dev astroid issues 2641 0 None open Test failure on 3.14 2024-11-21 19:50:12 UTC

Description Karolina Surma 2024-11-01 14:49:12 UTC
python-astroid fails to build with Python 3.14.0a1.

=================================== FAILURES ===================================
___________ CollectionsBrain.test_collections_object_subscriptable_3 ___________

args = (<Attribute.ByteString l.3 at 0x7f75c592dbd0>,)
kwargs = {'context': <astroid.context.InferenceContext object at 0x7f75c59adae0>}
generator = <generator object Attribute._infer at 0x7f75c591cbf0>

    def inner(*args: _P.args, **kwargs: _P.kwargs) -> Generator[InferenceResult]:
        generator = func(*args, **kwargs)
        try:
>           yield next(generator)
E           StopIteration

astroid/decorators.py:86: StopIteration

The above exception was the direct cause of the following exception:

self = <tests.brain.test_brain.CollectionsBrain testMethod=test_collections_object_subscriptable_3>

    def test_collections_object_subscriptable_3(self):
        """With Python 3.9 the ByteString class of the collections module is subscriptable
        (but not the same class from typing module)"""
        right_node = builder.extract_node(
            """
        import collections.abc
        collections.abc.ByteString[int]
        """
        )
>       inferred = next(right_node.infer())

tests/brain/test_brain.py:331: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
astroid/nodes/node_ng.py:168: in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
astroid/decorators.py:86: in inner
    yield next(generator)
astroid/decorators.py:49: in wrapped
    for res in _func(node, context, **kwargs):
astroid/nodes/node_classes.py:3724: in _infer_subscript
    for value in self.value.infer(context):
astroid/nodes/node_ng.py:168: in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (<Attribute.ByteString l.3 at 0x7f75c592dbd0>,)
kwargs = {'context': <astroid.context.InferenceContext object at 0x7f75c59adae0>}
generator = <generator object Attribute._infer at 0x7f75c591cbf0>

    def inner(*args: _P.args, **kwargs: _P.kwargs) -> Generator[InferenceResult]:
        generator = func(*args, **kwargs)
        try:
            yield next(generator)
        except StopIteration as error:
            # generator is empty
            if error.args:
                raise InferenceError(**error.args[0]) from error
>           raise InferenceError(
                "StopIteration raised without any error information."
            ) from error
E           astroid.exceptions.InferenceError: StopIteration raised without any error information.

astroid/decorators.py:91: InferenceError
______________ TypingBrain.test_typing_object_notsubscriptable_3 _______________

args = (<Attribute.ByteString l.3 at 0x7f75c586d630>,)
kwargs = {'context': <astroid.context.InferenceContext object at 0x7f75c6386260>}
generator = <generator object Attribute._infer at 0x7f75c509d030>

    def inner(*args: _P.args, **kwargs: _P.kwargs) -> Generator[InferenceResult]:
        generator = func(*args, **kwargs)
        try:
>           yield next(generator)
E           StopIteration

astroid/decorators.py:86: StopIteration

The above exception was the direct cause of the following exception:

self = <tests.brain.test_brain.TypingBrain testMethod=test_typing_object_notsubscriptable_3>

    def test_typing_object_notsubscriptable_3(self):
        """Until python39 ByteString class of the typing module is not
        subscriptable (whereas it is in the collections' module)"""
        right_node = builder.extract_node(
            """
        import typing
        typing.ByteString
        """
        )
>       inferred = next(right_node.infer())

tests/brain/test_brain.py:914: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
astroid/nodes/node_ng.py:168: in infer
    for i, result in enumerate(self._infer(context=context, **kwargs)):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (<Attribute.ByteString l.3 at 0x7f75c586d630>,)
kwargs = {'context': <astroid.context.InferenceContext object at 0x7f75c6386260>}
generator = <generator object Attribute._infer at 0x7f75c509d030>

    def inner(*args: _P.args, **kwargs: _P.kwargs) -> Generator[InferenceResult]:
        generator = func(*args, **kwargs)
        try:
            yield next(generator)
        except StopIteration as error:
            # generator is empty
            if error.args:
                raise InferenceError(**error.args[0]) from error
>           raise InferenceError(
                "StopIteration raised without any error information."
            ) from error
E           astroid.exceptions.InferenceError: StopIteration raised without any error information.

astroid/decorators.py:91: InferenceError
=========================== short test summary info ============================
FAILED tests/brain/test_brain.py::CollectionsBrain::test_collections_object_subscriptable_3
FAILED tests/brain/test_brain.py::TypingBrain::test_typing_object_notsubscriptable_3
==== 2 failed, 1601 passed, 78 skipped, 7 deselected, 15 xfailed in 41.07s =====

https://docs.python.org/3.14/whatsnew/3.14.html

For the build logs, see:
https://copr-be.cloud.fedoraproject.org/results/@python/python3.14/fedora-rawhide-x86_64/08189180-python-astroid/

For all our attempts to build python-astroid with Python 3.14, see:
https://copr.fedorainfracloud.org/coprs/g/python/python3.14/package/python-astroid/

Testing and mass rebuild of packages is happening in copr.
You can follow these instructions to test locally in mock if your package builds with Python 3.14:
https://copr.fedorainfracloud.org/coprs/g/python/python3.14/

Let us know here if you have any questions.

Python 3.14 is planned to be included in Fedora 43.
To make that update smoother, we're building Fedora packages with all pre-releases of Python 3.14.
A build failure prevents us from testing all dependent packages (transitive [Build]Requires),
so if this package is required a lot, it's important for us to get it fixed soon.

We'd appreciate help from the people who know this package best,
but if you don't want to work on this now, let us know so we can try to work around it on our side.

Comment 1 Karolina Surma 2025-02-13 09:29:51 UTC
I know upstream is not interested in alpha releases, but noting three new failures with Python 3.14.0a5 related to Path objects:

=================================== FAILURES ===================================
____________________________ 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)
E       AssertionError: assert False
E        +  where False = isinstance(Uninferable, <class 'astroid.bases.Instance'>)
E        +    where <class 'astroid.bases.Instance'> = bases.Instance

tests/brain/test_pathlib.py:25: AssertionError
____________________ test_inference_parents_subscript_index ____________________

    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()
        assert len(inferred) == 1
>       assert isinstance(inferred[0], bases.Instance)
E       AssertionError: assert False
E        +  where False = isinstance(Uninferable, <class 'astroid.bases.Instance'>)
E        +    where <class 'astroid.bases.Instance'> = bases.Instance

tests/brain/test_pathlib.py:45: AssertionError
____________________ test_inference_parents_subscript_slice ____________________

    def test_inference_parents_subscript_slice() -> None:
        """Test inference of ``pathlib.Path.parents``, accessed by slice."""
        name_node = astroid.extract_node(
            """
        from pathlib import Path
    
        current_path = Path().resolve()
        parent_path = current_path.parents[:2]
        parent_path
        """
        )
        inferred = name_node.inferred()
        assert len(inferred) == 1
        if PY310_PLUS:
>           assert isinstance(inferred[0], bases.Instance)
E           AssertionError: assert False
E            +  where False = isinstance(Uninferable, <class 'astroid.bases.Instance'>)
E            +    where <class 'astroid.bases.Instance'> = bases.Instance

tests/brain/test_pathlib.py:66: AssertionError

Comment 2 Aoife Moloney 2025-02-26 13:14:20 UTC
This bug appears to have been reported against 'rawhide' during the Fedora Linux 42 development cycle.
Changing version to 42.

Comment 3 Karolina Surma 2025-05-20 11:32:41 UTC
With b1 there is 185 failures with 

_____________________ ClassNodeTest.test_without_docstring _____________________

self = <astroid.builder.AstroidBuilder object at 0x7fece59dc360>
data = '"""test module for astroid\n"""\n\n__revision__ = \'$Id: module.py,v 1.2 2005-11-02 11:56:54 syt Exp $\'\nfrom astroi...= a and (b or c)\n    else:\n        c = a and b or d\n    list(map(lambda x, y: (y, x), a))\nredirect = four_args\n\n'
modname = 'data.module'
path = '/builddir/build/BUILD/python-astroid-3.3.8-build/astroid-3.3.8/tests/testdata/python3/data/module.py'

    def _data_build(
        self, data: str, modname: str, path: str | None
    ) -> tuple[nodes.Module, rebuilder.TreeRebuilder]:
        """Build tree node from data and add some informations."""
        try:
>           node, parser_module = _parse_string(
                data, type_comments=True, modname=modname
            )

astroid/builder.py:181: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
astroid/builder.py:477: in _parse_string
    parsed = parser_module.parse(
astroid/_ast.py:29: in parse
    return ast.parse(string, filename=filename, type_comments=type_comments)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

source = '"""test module for astroid\n"""\n\n__revision__ = \'$Id: module.py,v 1.2 2005-11-02 11:56:54 syt Exp $\'\nfrom astroi...a and (b or c)\n    else:\n        c = a and b or d\n    list(map(lambda x, y: (y, x), a))\nredirect = four_args\n\n\n'
filename = 'data.module', mode = 'exec'

    def parse(source, filename='<unknown>', mode='exec', *,
              type_comments=False, feature_version=None, optimize=-1):
        """
        Parse the source into an AST node.
        Equivalent to compile(source, filename, mode, PyCF_ONLY_AST).
        Pass type_comments=True to get back type comments where the syntax allows.
        """
        flags = PyCF_ONLY_AST
        if optimize > 0:
            flags |= PyCF_OPTIMIZED_AST
        if type_comments:
            flags |= PyCF_TYPE_COMMENTS
        if feature_version is None:
            feature_version = -1
        elif isinstance(feature_version, tuple):
            major, minor = feature_version  # Should be a 2-tuple.
            if major != 3:
                raise ValueError(f"Unsupported major version: {major}")
            feature_version = minor
        # Else it should be an int giving the minor version for 3.x.
>       return compile(source, filename, mode, flags,
                       _feature_version=feature_version, optimize=optimize)
E         File "data.module", line 62
E       SyntaxError: 'return' in a 'finally' block

/usr/lib64/python3.14/ast.py:46: SyntaxError

The above exception was the direct cause of the following exception:

self = <tests.test_scoped_nodes.ClassNodeTest testMethod=test_without_docstring>

    def setUp(self) -> None:
        super().setUp()
>       self.module = resources.build_file("data/module.py", "data.module")

tests/test_scoped_nodes.py:73: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/resources.py:23: in build_file
    return builder.AstroidBuilder().file_build(find(path), modname)
astroid/builder.py:144: in file_build
    module, builder = self._data_build(data, modname, path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <astroid.builder.AstroidBuilder object at 0x7fece59dc360>
data = '"""test module for astroid\n"""\n\n__revision__ = \'$Id: module.py,v 1.2 2005-11-02 11:56:54 syt Exp $\'\nfrom astroi...= a and (b or c)\n    else:\n        c = a and b or d\n    list(map(lambda x, y: (y, x), a))\nredirect = four_args\n\n'
modname = 'data.module'
path = '/builddir/build/BUILD/python-astroid-3.3.8-build/astroid-3.3.8/tests/testdata/python3/data/module.py'

    def _data_build(
        self, data: str, modname: str, path: str | None
    ) -> tuple[nodes.Module, rebuilder.TreeRebuilder]:
        """Build tree node from data and add some informations."""
        try:
            node, parser_module = _parse_string(
                data, type_comments=True, modname=modname
            )
        except (TypeError, ValueError, SyntaxError) as exc:
>           raise AstroidSyntaxError(
                "Parsing Python code failed:\n{error}",
                source=data,
                modname=modname,
                path=path,
                error=exc,
            ) from exc
E           astroid.exceptions.AstroidSyntaxError: Parsing Python code failed:
E           'return' in a 'finally' block (data.module, line 62)


Note You need to log in before you can comment on or make changes to this bug.