Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-astroid for openSUSE:Factory 
checked in at 2026-01-05 14:50:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-astroid (Old)
 and      /work/SRC/openSUSE:Factory/.python-astroid.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-astroid"

Mon Jan  5 14:50:15 2026 rev:63 rq:1325245 version:4.0.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-astroid/python-astroid.changes    
2025-11-18 15:29:17.048716491 +0100
+++ /work/SRC/openSUSE:Factory/.python-astroid.new.1928/python-astroid.changes  
2026-01-05 14:50:28.951587996 +0100
@@ -1,0 +2,10 @@
+Sun Jan  4 08:45:22 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 4.0.3:
+  * Fix inference of ``IfExp`` (ternary expression) nodes to
+    avoid prematurely narrowing results in the face of inference
+    ambiguity.
+  * Fix base class inference for dataclasses using the PEP 695
+    typing syntax.
+
+-------------------------------------------------------------------

Old:
----
  astroid-4.0.2-gh.tar.gz

New:
----
  astroid-4.0.3-gh.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-astroid.spec ++++++
--- /var/tmp/diff_new_pack.PcYttd/_old  2026-01-05 14:50:32.999756596 +0100
+++ /var/tmp/diff_new_pack.PcYttd/_new  2026-01-05 14:50:33.031757929 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-astroid
 #
-# Copyright (c) 2025 SUSE LLC and contributors
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-astroid
-Version:        4.0.2
+Version:        4.0.3
 Release:        0
 Summary:        Representation of Python source as an AST for pylint
 License:        LGPL-2.1-or-later

++++++ astroid-4.0.2-gh.tar.gz -> astroid-4.0.3-gh.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/.github/workflows/ci.yaml 
new/astroid-4.0.3/.github/workflows/ci.yaml
--- old/astroid-4.0.2/.github/workflows/ci.yaml 2025-11-09 22:19:11.000000000 
+0100
+++ new/astroid-4.0.3/.github/workflows/ci.yaml 2026-01-03 23:11:10.000000000 
+0100
@@ -156,7 +156,7 @@
         run: >-
           echo "key=${{ env.KEY_PREFIX }}-${{ env.CACHE_VERSION }}-${{
             hashFiles('pyproject.toml', 'requirements_dev.txt',
-          'requirements_full.txt', 'requirements_minimal.txt') }}" >> 
$GITHUB_OUTPUT
+          'requirements_full.txt', 'requirements_minimal.txt') }}" >> 
$env:GITHUB_OUTPUT
       - *cache-python
       - name: Create Python virtual environment
         if: steps.cache-venv.outputs.cache-hit != 'true'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/ChangeLog new/astroid-4.0.3/ChangeLog
--- old/astroid-4.0.2/ChangeLog 2025-11-09 22:19:11.000000000 +0100
+++ new/astroid-4.0.3/ChangeLog 2026-01-03 23:11:10.000000000 +0100
@@ -9,12 +9,26 @@
 
 
 
-What's New in astroid 4.0.3?
+What's New in astroid 4.0.4?
 ============================
 Release date: TBA
 
 
 
+What's New in astroid 4.0.3?
+============================
+Release date: 2026-01-03
+
+* Fix inference of ``IfExp`` (ternary expression) nodes to avoid prematurely 
narrowing
+  results in the face of inference ambiguity.
+
+  Closes #2899
+
+* Fix base class inference for dataclasses using the PEP 695 typing syntax.
+
+  Refs pylint-dev/pylint#10788
+
+
 What's New in astroid 4.0.2?
 ============================
 Release date: 2025-11-09
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/astroid/__pkginfo__.py 
new/astroid-4.0.3/astroid/__pkginfo__.py
--- old/astroid-4.0.2/astroid/__pkginfo__.py    2025-11-09 22:19:11.000000000 
+0100
+++ new/astroid-4.0.3/astroid/__pkginfo__.py    2026-01-03 23:11:10.000000000 
+0100
@@ -2,5 +2,5 @@
 # For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE
 # Copyright (c) 
https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt
 
-__version__ = "4.0.2"
+__version__ = "4.0.3"
 version = __version__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/astroid/brain/brain_dataclasses.py 
new/astroid-4.0.3/astroid/brain/brain_dataclasses.py
--- old/astroid-4.0.2/astroid/brain/brain_dataclasses.py        2025-11-09 
22:19:11.000000000 +0100
+++ new/astroid-4.0.3/astroid/brain/brain_dataclasses.py        2026-01-03 
23:11:10.000000000 +0100
@@ -54,7 +54,7 @@
     )
 
 
-def dataclass_transform(node: nodes.ClassDef) -> None:
+def dataclass_transform(node: nodes.ClassDef) -> nodes.ClassDef | None:
     """Rewrite a dataclass to be easily understood by pylint."""
     node.is_dataclass = True
 
@@ -70,7 +70,7 @@
         node.instance_attrs[name] = [rhs_node]
 
     if not _check_generate_dataclass_init(node):
-        return
+        return None
 
     kw_only_decorated = False
     if node.decorators.nodes:
@@ -102,6 +102,7 @@
             new_assign = parse(f"{DEFAULT_FACTORY} = object()").body[0]
             new_assign.parent = root
             root.locals[DEFAULT_FACTORY] = [new_assign.targets[0]]
+    return node
 
 
 def _get_dataclass_attributes(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/astroid/nodes/node_classes.py 
new/astroid-4.0.3/astroid/nodes/node_classes.py
--- old/astroid-4.0.2/astroid/nodes/node_classes.py     2025-11-09 
22:19:11.000000000 +0100
+++ new/astroid-4.0.3/astroid/nodes/node_classes.py     2026-01-03 
23:11:10.000000000 +0100
@@ -1022,7 +1022,7 @@
 
     @decorators.raise_if_nothing_inferred
     def _infer(
-        self: nodes.Arguments, context: InferenceContext | None = None, 
**kwargs: Any
+        self, context: InferenceContext | None = None, **kwargs: Any
     ) -> Generator[InferenceResult]:
         # pylint: disable-next=import-outside-toplevel
         from astroid.protocols import _arguments_infer_argname
@@ -1441,7 +1441,7 @@
     @decorators.raise_if_nothing_inferred
     @decorators.path_wrapper
     def _infer(
-        self: nodes.AugAssign, context: InferenceContext | None = None, 
**kwargs: Any
+        self, context: InferenceContext | None = None, **kwargs: Any
     ) -> Generator[InferenceResult]:
         return self._filter_operation_errors(
             self._infer_augassign, context, util.BadBinaryOperationMessage
@@ -1556,7 +1556,7 @@
     @decorators.yes_if_nothing_inferred
     @decorators.path_wrapper
     def _infer(
-        self: nodes.BinOp, context: InferenceContext | None = None, **kwargs: 
Any
+        self, context: InferenceContext | None = None, **kwargs: Any
     ) -> Generator[InferenceResult]:
         return self._filter_operation_errors(
             self._infer_binop, context, util.BadBinaryOperationMessage
@@ -1633,7 +1633,7 @@
     @decorators.raise_if_nothing_inferred
     @decorators.path_wrapper
     def _infer(
-        self: nodes.BoolOp, context: InferenceContext | None = None, **kwargs: 
Any
+        self, context: InferenceContext | None = None, **kwargs: Any
     ) -> Generator[InferenceResult, None, InferenceErrorInfo | None]:
         """Infer a boolean operation (and / or / not).
 
@@ -3108,31 +3108,37 @@
         to inferring both branches. Otherwise, we infer either branch
         depending on the condition.
         """
-        both_branches = False
+
         # We use two separate contexts for evaluating lhs and rhs because
         # evaluating lhs may leave some undesired entries in context.path
         # which may not let us infer right value of rhs.
-
         context = context or InferenceContext()
         lhs_context = copy_context(context)
         rhs_context = copy_context(context)
+
+        # Infer bool condition. Stop inferring if in doubt and fallback to
+        # evaluating both branches.
+        condition: bool | None = None
         try:
-            test = next(self.test.infer(context=context.clone()))
-        except (InferenceError, StopIteration):
-            both_branches = True
-        else:
-            test_bool_value = test.bool_value()
-            if not isinstance(test, util.UninferableBase) and not isinstance(
-                test_bool_value, util.UninferableBase
-            ):
-                if test_bool_value:
-                    yield from self.body.infer(context=lhs_context)
-                else:
-                    yield from self.orelse.infer(context=rhs_context)
-            else:
-                both_branches = True
-        if both_branches:
+            for test in self.test.infer(context=context.clone()):
+                if isinstance(test, util.UninferableBase):
+                    condition = None
+                    break
+                test_bool_value = test.bool_value()
+                if isinstance(test_bool_value, util.UninferableBase):
+                    condition = None
+                    break
+                if condition is None:
+                    condition = test_bool_value
+                elif test_bool_value != condition:
+                    condition = None
+                    break
+        except InferenceError:
+            condition = None
+
+        if condition is True or condition is None:
             yield from self.body.infer(context=lhs_context)
+        if condition is False or condition is None:
             yield from self.orelse.infer(context=rhs_context)
 
 
@@ -4318,7 +4324,7 @@
         return super().op_precedence()
 
     def _infer_unaryop(
-        self: nodes.UnaryOp, context: InferenceContext | None = None, 
**kwargs: Any
+        self, context: InferenceContext | None = None, **kwargs: Any
     ) -> Generator[
         InferenceResult | util.BadUnaryOperationMessage, None, 
InferenceErrorInfo
     ]:
@@ -4384,7 +4390,7 @@
     @decorators.raise_if_nothing_inferred
     @decorators.path_wrapper
     def _infer(
-        self: nodes.UnaryOp, context: InferenceContext | None = None, 
**kwargs: Any
+        self, context: InferenceContext | None = None, **kwargs: Any
     ) -> Generator[InferenceResult, None, InferenceErrorInfo]:
         """Infer what an UnaryOp should return when evaluated."""
         yield from self._filter_operation_errors(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/astroid/nodes/scoped_nodes/mixin.py 
new/astroid-4.0.3/astroid/nodes/scoped_nodes/mixin.py
--- old/astroid-4.0.2/astroid/nodes/scoped_nodes/mixin.py       2025-11-09 
22:19:11.000000000 +0100
+++ new/astroid-4.0.3/astroid/nodes/scoped_nodes/mixin.py       2026-01-03 
23:11:10.000000000 +0100
@@ -6,7 +6,8 @@
 
 from __future__ import annotations
 
-from typing import TYPE_CHECKING, TypeVar, overload
+import sys
+from typing import TYPE_CHECKING, overload
 
 from astroid.exceptions import ParentMissingError
 from astroid.filter_statements import _filter_stmts
@@ -14,11 +15,13 @@
 from astroid.nodes.scoped_nodes.utils import builtin_lookup
 from astroid.typing import InferenceResult, SuccessfulInferenceResult
 
+if sys.version_info >= (3, 11):
+    from typing import Self
+else:
+    from typing_extensions import Self
 if TYPE_CHECKING:
     from astroid import nodes
 
-_T = TypeVar("_T")
-
 
 class LocalsDictNodeNG(_base_nodes.LookupMixIn):
     """this class provides locals handling common to Module, FunctionDef
@@ -46,7 +49,7 @@
         except ParentMissingError:
             return self.name
 
-    def scope(self: _T) -> _T:
+    def scope(self) -> Self:
         """The first parent node defining a new scope.
 
         :returns: The first parent scope node.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/astroid-4.0.2/astroid/nodes/scoped_nodes/scoped_nodes.py 
new/astroid-4.0.3/astroid/nodes/scoped_nodes/scoped_nodes.py
--- old/astroid-4.0.2/astroid/nodes/scoped_nodes/scoped_nodes.py        
2025-11-09 22:19:11.000000000 +0100
+++ new/astroid-4.0.3/astroid/nodes/scoped_nodes/scoped_nodes.py        
2026-01-03 23:11:10.000000000 +0100
@@ -13,9 +13,10 @@
 import io
 import itertools
 import os
+import sys
 from collections.abc import Generator, Iterable, Iterator, Sequence
 from functools import cached_property, lru_cache
-from typing import TYPE_CHECKING, Any, ClassVar, Literal, NoReturn, TypeVar
+from typing import TYPE_CHECKING, Any, ClassVar, Literal, NoReturn
 
 from astroid import bases, protocols, util
 from astroid.context import (
@@ -50,6 +51,11 @@
     SuccessfulInferenceResult,
 )
 
+if sys.version_info >= (3, 11):
+    from typing import Self
+else:
+    from typing_extensions import Self
+
 if TYPE_CHECKING:
     from astroid import nodes, objects
     from astroid.nodes import Arguments, Const, NodeNG
@@ -62,8 +68,6 @@
     {"classmethod", "staticmethod", "builtins.classmethod", 
"builtins.staticmethod"}
 )
 
-_T = TypeVar("_T")
-
 
 def _c3_merge(sequences, cls, context):
     """Merges MROs in *sequences* to a single MRO using the C3 algorithm.
@@ -587,7 +591,7 @@
     def get_children(self):
         yield from self.body
 
-    def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
+    def frame(self, *, future: Literal[None, True] = None) -> Self:
         """The node's frame node.
 
         A frame node is a :class:`Module`, :class:`FunctionDef`,
@@ -1030,7 +1034,7 @@
         yield self.args
         yield self.body
 
-    def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
+    def frame(self, *, future: Literal[None, True] = None) -> Self:
         """The node's frame node.
 
         A frame node is a :class:`Module`, :class:`FunctionDef`,
@@ -1677,7 +1681,7 @@
             frame = self
         return frame._scope_lookup(node, name, offset)
 
-    def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
+    def frame(self, *, future: Literal[None, True] = None) -> Self:
         """The node's frame node.
 
         A frame node is a :class:`Module`, :class:`FunctionDef`,
@@ -2884,7 +2888,7 @@
         )
         return list(itertools.chain.from_iterable(children_assign_nodes))
 
-    def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
+    def frame(self, *, future: Literal[None, True] = None) -> Self:
         """The node's frame node.
 
         A frame node is a :class:`Module`, :class:`FunctionDef`,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/astroid/objects.py 
new/astroid-4.0.3/astroid/objects.py
--- old/astroid-4.0.2/astroid/objects.py        2025-11-09 22:19:11.000000000 
+0100
+++ new/astroid-4.0.3/astroid/objects.py        2026-01-03 23:11:10.000000000 
+0100
@@ -13,9 +13,10 @@
 
 from __future__ import annotations
 
+import sys
 from collections.abc import Generator, Iterator
 from functools import cached_property
-from typing import Any, Literal, NoReturn, TypeVar
+from typing import Any, Literal, NoReturn
 
 from astroid import bases, util
 from astroid.context import InferenceContext
@@ -30,7 +31,10 @@
 from astroid.nodes import node_classes, scoped_nodes
 from astroid.typing import InferenceResult, SuccessfulInferenceResult
 
-_T = TypeVar("_T")
+if sys.version_info >= (3, 11):
+    from typing import Self
+else:
+    from typing_extensions import Self
 
 
 class FrozenSet(node_classes.BaseContainer):
@@ -355,6 +359,6 @@
         raise InferenceError("Properties are not callable")
 
     def _infer(
-        self: _T, context: InferenceContext | None = None, **kwargs: Any
-    ) -> Generator[_T]:
+        self, context: InferenceContext | None = None, **kwargs: Any
+    ) -> Generator[Self]:
         yield self
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/requirements_minimal.txt 
new/astroid-4.0.3/requirements_minimal.txt
--- old/astroid-4.0.2/requirements_minimal.txt  2025-11-09 22:19:11.000000000 
+0100
+++ new/astroid-4.0.3/requirements_minimal.txt  2026-01-03 23:11:10.000000000 
+0100
@@ -6,4 +6,4 @@
 coverage~=7.10
 pytest
 pytest-cov~=7.0
-mypy
+mypy; platform_python_implementation!="PyPy"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/tbump.toml new/astroid-4.0.3/tbump.toml
--- old/astroid-4.0.2/tbump.toml        2025-11-09 22:19:11.000000000 +0100
+++ new/astroid-4.0.3/tbump.toml        2026-01-03 23:11:10.000000000 +0100
@@ -1,7 +1,7 @@
 github_url = "https://github.com/pylint-dev/astroid";
 
 [version]
-current = "4.0.2"
+current = "4.0.3"
 regex = '''
 ^(?P<major>0|[1-9]\d*)
 \.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/tests/test_inference.py 
new/astroid-4.0.3/tests/test_inference.py
--- old/astroid-4.0.2/tests/test_inference.py   2025-11-09 22:19:11.000000000 
+0100
+++ new/astroid-4.0.3/tests/test_inference.py   2026-01-03 23:11:10.000000000 
+0100
@@ -6442,6 +6442,98 @@
     assert [third[0].value, third[1].value] == [1, 2]
 
 
+def test_ifexp_with_default_arguments() -> None:
+    code = """
+    def with_default(foo: str | None = None):
+        a = 1 if foo else "bar" #@
+
+    def without_default(foo: str):
+        a = 1 if foo else "bar" #@
+
+    def some_ifexps(foo: str | None = None):
+        a = 1 if foo else 2
+        b = 3 if a else 4 #@
+        c = 4 if b else 5 #@
+        d = 5 if not foo else foo #@
+        e = d if not foo else foo #@
+    """
+
+    ast_nodes = extract_node(code)
+
+    first = ast_nodes[0].value.inferred()
+    second = ast_nodes[1].value.inferred()
+    third = ast_nodes[2].value.inferred()
+    fourth = ast_nodes[3].value.inferred()
+    fifth = ast_nodes[4].value.inferred()
+    sixth = ast_nodes[5].value.inferred()
+
+    assert len(first) == 2
+    assert [first[0].value, first[1].value] == [1, "bar"]
+
+    assert len(second) == 2
+    assert [second[0].value, second[1].value] == [1, "bar"]
+
+    assert len(third) == 1
+    assert third[0].value == 3
+
+    assert len(fourth) == 1
+    assert fourth[0].value == 4
+
+    assert len(fifth) == 2
+    assert [fifth[0].value, fifth[1].value] == [5, Uninferable]
+
+    assert len(sixth) == 3
+    assert [sixth[0].value, sixth[1].value, sixth[2].value] == [
+        5,
+        Uninferable,
+        Uninferable,
+    ]
+
+
+def test_ifexp_with_uninferables() -> None:
+    code = """
+    def truthy_and_falsy():
+        return False if unknown() else True
+
+    def truthy_and_uninferable():
+        return False if unknown() else unknown()
+
+    def calls_truthy_and_falsy():
+        return 1 if truthy_and_falsy() else 2
+
+    def calls_truthy_and_uninferable():
+        return 1 if range(10) else truthy_and_uninferable()
+
+    truthy_and_falsy() #@
+    truthy_and_uninferable() #@
+    calls_truthy_and_falsy() #@
+    calls_truthy_and_uninferable() #@
+    """
+
+    ast_nodes = extract_node(code)
+
+    first = ast_nodes[0].inferred()
+    second = ast_nodes[1].inferred()
+    third = ast_nodes[2].inferred()
+    fourth = ast_nodes[3].inferred()
+
+    assert len(first) == 2
+    assert [first[0].value, first[1].value] == [False, True]
+
+    assert len(second) == 2
+    assert [second[0].value, second[1].value] == [False, Uninferable]
+
+    assert len(third) == 2
+    assert [third[0].value, third[1].value] == [1, 2]
+
+    assert len(fourth) == 3
+    assert [fourth[0].value, fourth[1].value, fourth[2].value] == [
+        1,
+        False,
+        Uninferable,
+    ]
+
+
 def test_assert_last_function_returns_none_on_inference() -> None:
     code = """
     def check_equal(a, b):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/tests/test_raw_building.py 
new/astroid-4.0.3/tests/test_raw_building.py
--- old/astroid-4.0.2/tests/test_raw_building.py        2025-11-09 
22:19:11.000000000 +0100
+++ new/astroid-4.0.3/tests/test_raw_building.py        2026-01-03 
23:11:10.000000000 +0100
@@ -19,7 +19,6 @@
 from typing import Any
 from unittest import mock
 
-import mypy.build
 import pytest
 
 import tests.testdata.python3.data.fake_module_with_broken_getattr as 
fm_getattr
@@ -37,6 +36,13 @@
     object_build_class,
 )
 
+try:
+    import mypy.build
+
+    HAS_MYPY = True
+except ImportError:
+    HAS_MYPY = False
+
 DUMMY_MOD = build_module("DUMMY")
 
 
@@ -173,6 +179,7 @@
     assert not err
 
 
[email protected](not HAS_MYPY, reason="This test requires mypy")
 def test_missing__dict__():
     # This shouldn't raise an exception.
     object_build_class(DUMMY_MOD, mypy.build.ModuleNotFound)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/astroid-4.0.2/tests/test_scoped_nodes.py 
new/astroid-4.0.3/tests/test_scoped_nodes.py
--- old/astroid-4.0.2/tests/test_scoped_nodes.py        2025-11-09 
22:19:11.000000000 +0100
+++ new/astroid-4.0.3/tests/test_scoped_nodes.py        2026-01-03 
23:11:10.000000000 +0100
@@ -29,7 +29,7 @@
     util,
 )
 from astroid.bases import BoundMethod, Generator, Instance, UnboundMethod
-from astroid.const import WIN32
+from astroid.const import PY312_PLUS, WIN32
 from astroid.exceptions import (
     AstroidBuildingError,
     AttributeInferenceError,
@@ -1967,6 +1967,34 @@
             cls, [".E", ".C", ".A", ".B", "typing.Generic", ".D", 
"builtins.object"]
         )
 
+    @pytest.mark.skipif(not PY312_PLUS, reason="PEP 695 syntax requires Python 
3.12")
+    def test_mro_generic_8(self):
+        cls = builder.extract_node(
+            """
+        class A: ...
+        class B[T]: ...
+        class C[T](A, B[T]): ...
+        """
+        )
+        assert isinstance(cls, nodes.ClassDef)
+        self.assertEqualMroQName(cls, [".C", ".A", ".B", "builtins.object"])
+
+    @pytest.mark.skipif(not PY312_PLUS, reason="PEP 695 syntax requires Python 
3.12")
+    def test_mro_generic_9(self):
+        cls = builder.extract_node(
+            """
+        from dataclasses import dataclass
+        @dataclass
+        class A: ...
+        @dataclass
+        class B[T]: ...
+        @dataclass
+        class C[T](A, B[T]): ...
+        """
+        )
+        assert isinstance(cls, nodes.ClassDef)
+        self.assertEqualMroQName(cls, [".C", ".A", ".B", "builtins.object"])
+
     def test_mro_generic_error_1(self):
         cls = builder.extract_node(
             """

Reply via email to