mirror of https://github.com/python/cpython
gh-105486: Change the `repr` of `ParamSpec` list of args in `GenericAlias` (#105488)
This commit is contained in:
parent
e212618baf
commit
eb7d6e7ad8
|
@ -209,6 +209,9 @@ class BaseTest(unittest.TestCase):
|
|||
def test_repr(self):
|
||||
class MyList(list):
|
||||
pass
|
||||
class MyGeneric:
|
||||
__class_getitem__ = classmethod(GenericAlias)
|
||||
|
||||
self.assertEqual(repr(list[str]), 'list[str]')
|
||||
self.assertEqual(repr(list[()]), 'list[()]')
|
||||
self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]')
|
||||
|
@ -221,6 +224,11 @@ class BaseTest(unittest.TestCase):
|
|||
self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr.<locals>.MyList[int]'))
|
||||
self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr
|
||||
|
||||
# gh-105488
|
||||
self.assertTrue(repr(MyGeneric[int]).endswith('MyGeneric[int]'))
|
||||
self.assertTrue(repr(MyGeneric[[]]).endswith('MyGeneric[[]]'))
|
||||
self.assertTrue(repr(MyGeneric[[int, str]]).endswith('MyGeneric[[int, str]]'))
|
||||
|
||||
def test_exposed_type(self):
|
||||
import types
|
||||
a = types.GenericAlias(list, int)
|
||||
|
|
|
@ -142,7 +142,16 @@ class TypeParamsAliasValueTest(unittest.TestCase):
|
|||
|
||||
def test_repr(self):
|
||||
type Simple = int
|
||||
type VeryGeneric[T, *Ts, **P] = Callable[P, tuple[T, *Ts]]
|
||||
|
||||
self.assertEqual(repr(Simple), "Simple")
|
||||
self.assertEqual(repr(VeryGeneric), "VeryGeneric")
|
||||
self.assertEqual(repr(VeryGeneric[int, bytes, str, [float, object]]),
|
||||
"VeryGeneric[int, bytes, str, [float, object]]")
|
||||
self.assertEqual(repr(VeryGeneric[int, []]),
|
||||
"VeryGeneric[int, []]")
|
||||
self.assertEqual(repr(VeryGeneric[int, [VeryGeneric[int], list[str]]]),
|
||||
"VeryGeneric[int, [VeryGeneric[int], list[str]]]")
|
||||
|
||||
def test_recursive_repr(self):
|
||||
type Recursive = Recursive
|
||||
|
@ -151,6 +160,13 @@ class TypeParamsAliasValueTest(unittest.TestCase):
|
|||
type X = list[Y]
|
||||
type Y = list[X]
|
||||
self.assertEqual(repr(X), "X")
|
||||
self.assertEqual(repr(Y), "Y")
|
||||
|
||||
type GenericRecursive[X] = list[X | GenericRecursive[X]]
|
||||
self.assertEqual(repr(GenericRecursive), "GenericRecursive")
|
||||
self.assertEqual(repr(GenericRecursive[int]), "GenericRecursive[int]")
|
||||
self.assertEqual(repr(GenericRecursive[GenericRecursive[int]]),
|
||||
"GenericRecursive[GenericRecursive[int]]")
|
||||
|
||||
|
||||
class TypeAliasConstructorTest(unittest.TestCase):
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Change the repr of ``ParamSpec`` list of args in ``types.GenericAlias``.
|
|
@ -121,6 +121,36 @@ done:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
ga_repr_items_list(_PyUnicodeWriter *writer, PyObject *p)
|
||||
{
|
||||
assert(PyList_CheckExact(p));
|
||||
|
||||
Py_ssize_t len = PyList_GET_SIZE(p);
|
||||
|
||||
if (_PyUnicodeWriter_WriteASCIIString(writer, "[", 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (Py_ssize_t i = 0; i < len; i++) {
|
||||
if (i > 0) {
|
||||
if (_PyUnicodeWriter_WriteASCIIString(writer, ", ", 2) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
PyObject *item = PyList_GET_ITEM(p, i);
|
||||
if (ga_repr_item(writer, item) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_PyUnicodeWriter_WriteASCIIString(writer, "]", 1) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
ga_repr(PyObject *self)
|
||||
{
|
||||
|
@ -148,7 +178,13 @@ ga_repr(PyObject *self)
|
|||
}
|
||||
}
|
||||
PyObject *p = PyTuple_GET_ITEM(alias->args, i);
|
||||
if (ga_repr_item(&writer, p) < 0) {
|
||||
if (PyList_CheckExact(p)) {
|
||||
// Looks like we are working with ParamSpec's list of type args:
|
||||
if (ga_repr_items_list(&writer, p) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (ga_repr_item(&writer, p) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue