Mailing List Archive

bpo-45664: Fix resolve_bases() and new_class() for GenericAlias instance as a base (GH-29298)
https://github.com/python/cpython/commit/2b318ce1c988b7b6e3caf293d55f289e066b6e0f
commit: 2b318ce1c988b7b6e3caf293d55f289e066b6e0f
branch: main
author: Serhiy Storchaka <storchaka@gmail.com>
committer: serhiy-storchaka <storchaka@gmail.com>
date: 2021-12-05T22:44:01+02:00
summary:

bpo-45664: Fix resolve_bases() and new_class() for GenericAlias instance as a base (GH-29298)

files:
A Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst
M Lib/test/test_types.py
M Lib/types.py

diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index b1218abc8af5e..3dfda5cb95663 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -1236,6 +1236,17 @@ def __mro_entries__(self, bases):
self.assertEqual(D.__orig_bases__, (c,))
self.assertEqual(D.__mro__, (D, A, object))

+ def test_new_class_with_mro_entry_genericalias(self):
+ L1 = types.new_class('L1', (typing.List[int],), {})
+ self.assertEqual(L1.__bases__, (list, typing.Generic))
+ self.assertEqual(L1.__orig_bases__, (typing.List[int],))
+ self.assertEqual(L1.__mro__, (L1, list, typing.Generic, object))
+
+ L2 = types.new_class('L2', (list[int],), {})
+ self.assertEqual(L2.__bases__, (list,))
+ self.assertEqual(L2.__orig_bases__, (list[int],))
+ self.assertEqual(L2.__mro__, (L2, list, object))
+
def test_new_class_with_mro_entry_none(self):
class A: pass
class B: pass
@@ -1351,6 +1362,11 @@ def __mro_entries__(self, bases):
for bases in [x, y, z, t]:
self.assertIs(types.resolve_bases(bases), bases)

+ def test_resolve_bases_with_mro_entry(self):
+ self.assertEqual(types.resolve_bases((typing.List[int],)),
+ (list, typing.Generic))
+ self.assertEqual(types.resolve_bases((list[int],)), (list,))
+
def test_metaclass_derivation(self):
# issue1294232: correct metaclass calculation
new_calls = [] # to check the order of __new__ calls
diff --git a/Lib/types.py b/Lib/types.py
index ce1c28d5625a2..679c7f638b310 100644
--- a/Lib/types.py
+++ b/Lib/types.py
@@ -82,7 +82,7 @@ def resolve_bases(bases):
updated = False
shift = 0
for i, base in enumerate(bases):
- if isinstance(base, type):
+ if isinstance(base, type) and not isinstance(base, GenericAlias):
continue
if not hasattr(base, "__mro_entries__"):
continue
diff --git a/Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst b/Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst
new file mode 100644
index 0000000000000..573a569845a87
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst
@@ -0,0 +1,2 @@
+Fix :func:`types.resolve_bases` and :func:`types.new_class` for
+:class:`types.GenericAlias` instance as a base.

_______________________________________________
Python-checkins mailing list
Python-checkins@python.org
https://mail.python.org/mailman/listinfo/python-checkins
bpo-45664: Fix resolve_bases() and new_class() for GenericAlias instance as a base (GH-29298) [ In reply to ]
https://github.com/python/cpython/commit/cb68c0a3a4aeb4ec58ab1f71b70bc8bfecbceef6
commit: cb68c0a3a4aeb4ec58ab1f71b70bc8bfecbceef6
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
committer: miss-islington <31488909+miss-islington@users.noreply.github.com>
date: 2021-12-05T13:26:37-08:00
summary:

bpo-45664: Fix resolve_bases() and new_class() for GenericAlias instance as a base (GH-29298)

(cherry picked from commit 2b318ce1c988b7b6e3caf293d55f289e066b6e0f)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>

files:
A Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst
M Lib/test/test_types.py
M Lib/types.py

diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py
index b1218abc8af5e..3dfda5cb95663 100644
--- a/Lib/test/test_types.py
+++ b/Lib/test/test_types.py
@@ -1236,6 +1236,17 @@ def __mro_entries__(self, bases):
self.assertEqual(D.__orig_bases__, (c,))
self.assertEqual(D.__mro__, (D, A, object))

+ def test_new_class_with_mro_entry_genericalias(self):
+ L1 = types.new_class('L1', (typing.List[int],), {})
+ self.assertEqual(L1.__bases__, (list, typing.Generic))
+ self.assertEqual(L1.__orig_bases__, (typing.List[int],))
+ self.assertEqual(L1.__mro__, (L1, list, typing.Generic, object))
+
+ L2 = types.new_class('L2', (list[int],), {})
+ self.assertEqual(L2.__bases__, (list,))
+ self.assertEqual(L2.__orig_bases__, (list[int],))
+ self.assertEqual(L2.__mro__, (L2, list, object))
+
def test_new_class_with_mro_entry_none(self):
class A: pass
class B: pass
@@ -1351,6 +1362,11 @@ def __mro_entries__(self, bases):
for bases in [x, y, z, t]:
self.assertIs(types.resolve_bases(bases), bases)

+ def test_resolve_bases_with_mro_entry(self):
+ self.assertEqual(types.resolve_bases((typing.List[int],)),
+ (list, typing.Generic))
+ self.assertEqual(types.resolve_bases((list[int],)), (list,))
+
def test_metaclass_derivation(self):
# issue1294232: correct metaclass calculation
new_calls = [] # to check the order of __new__ calls
diff --git a/Lib/types.py b/Lib/types.py
index c2dc97dd57ae3..62122a994866f 100644
--- a/Lib/types.py
+++ b/Lib/types.py
@@ -82,7 +82,7 @@ def resolve_bases(bases):
updated = False
shift = 0
for i, base in enumerate(bases):
- if isinstance(base, type):
+ if isinstance(base, type) and not isinstance(base, GenericAlias):
continue
if not hasattr(base, "__mro_entries__"):
continue
diff --git a/Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst b/Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst
new file mode 100644
index 0000000000000..573a569845a87
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-10-28-23-40-54.bpo-45664.7dqtxQ.rst
@@ -0,0 +1,2 @@
+Fix :func:`types.resolve_bases` and :func:`types.new_class` for
+:class:`types.GenericAlias` instance as a base.

_______________________________________________
Python-checkins mailing list
Python-checkins@python.org
https://mail.python.org/mailman/listinfo/python-checkins