Skip to content

Commit 20b8987

Browse files
Parameter qualname is added to TypeAliasType constructor
1 parent ef9609a commit 20b8987

File tree

8 files changed

+53
-14
lines changed

8 files changed

+53
-14
lines changed

Doc/library/typing.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2243,7 +2243,7 @@ without the dedicated syntax, as documented below.
22432243
.. versionadded:: 3.10
22442244

22452245

2246-
.. class:: TypeAliasType(name, value, *, type_params=())
2246+
.. class:: TypeAliasType(name, value, *, type_params=(), qualname=None)
22472247

22482248
The type of type aliases created through the :keyword:`type` statement.
22492249

Include/internal/pycore_global_objects_fini_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,7 @@ struct _Py_global_strings {
696696
STRUCT_FOR_ID(ps1)
697697
STRUCT_FOR_ID(ps2)
698698
STRUCT_FOR_ID(qid)
699+
STRUCT_FOR_ID(qualname)
699700
STRUCT_FOR_ID(query)
700701
STRUCT_FOR_ID(queuetype)
701702
STRUCT_FOR_ID(quotetabs)

Include/internal/pycore_runtime_init_generated.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_type_aliases.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,15 +234,25 @@ class TypeAliasConstructorTest(unittest.TestCase):
234234
def test_basic(self):
235235
TA = TypeAliasType("TA", int)
236236
self.assertEqual(TA.__name__, "TA")
237+
self.assertEqual(TA.__qualname__, "TA")
237238
self.assertIs(TA.__value__, int)
238239
self.assertEqual(TA.__type_params__, ())
239240
self.assertEqual(TA.__module__, __name__)
240241

242+
def test_with_qualname(self):
243+
TA = TypeAliasType("TA", str, qualname="Class.TA")
244+
self.assertEqual(TA.__name__, "TA")
245+
self.assertEqual(TA.__qualname__, "Class.TA")
246+
self.assertIs(TA.__value__, str)
247+
self.assertEqual(TA.__type_params__, ())
248+
self.assertEqual(TA.__module__, __name__)
249+
241250
def test_attributes_with_exec(self):
242251
ns = {}
243252
exec("type TA = int", ns, ns)
244253
TA = ns["TA"]
245254
self.assertEqual(TA.__name__, "TA")
255+
self.assertEqual(TA.__qualname__, "TA")
246256
self.assertIs(TA.__value__, int)
247257
self.assertEqual(TA.__type_params__, ())
248258
self.assertIs(TA.__module__, None)
@@ -251,6 +261,7 @@ def test_generic(self):
251261
T = TypeVar("T")
252262
TA = TypeAliasType("TA", list[T], type_params=(T,))
253263
self.assertEqual(TA.__name__, "TA")
264+
self.assertEqual(TA.__qualname__, "TA")
254265
self.assertEqual(TA.__value__, list[T])
255266
self.assertEqual(TA.__type_params__, (T,))
256267
self.assertEqual(TA.__module__, __name__)
@@ -259,6 +270,7 @@ def test_generic(self):
259270
def test_not_generic(self):
260271
TA = TypeAliasType("TA", list[int], type_params=())
261272
self.assertEqual(TA.__name__, "TA")
273+
self.assertEqual(TA.__qualname__, "TA")
262274
self.assertEqual(TA.__value__, list[int])
263275
self.assertEqual(TA.__type_params__, ())
264276
self.assertEqual(TA.__module__, __name__)
@@ -311,6 +323,7 @@ def test_expects_type_like(self):
311323
def test_keywords(self):
312324
TA = TypeAliasType(name="TA", value=int)
313325
self.assertEqual(TA.__name__, "TA")
326+
self.assertEqual(TA.__qualname__, "TA")
314327
self.assertIs(TA.__value__, int)
315328
self.assertEqual(TA.__type_params__, ())
316329
self.assertEqual(TA.__module__, __name__)
@@ -324,6 +337,8 @@ def test_errors(self):
324337
TypeAliasType("TA", list, ())
325338
with self.assertRaises(TypeError):
326339
TypeAliasType("TA", list, type_params=42)
340+
with self.assertRaises(TypeError):
341+
TypeAliasType("TA", list, qualname=range(5))
327342

328343

329344
class TypeAliasTypeTest(unittest.TestCase):

Objects/clinic/typevarobject.c.h

Lines changed: 16 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Objects/typevarobject.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,14 +2092,15 @@ typealias.__new__ as typealias_new
20922092
value: object
20932093
*
20942094
type_params: object = NULL
2095+
qualname: object(c_default="NULL") = None
20952096
20962097
Create a TypeAliasType.
20972098
[clinic start generated code]*/
20982099

20992100
static PyObject *
21002101
typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value,
2101-
PyObject *type_params)
2102-
/*[clinic end generated code: output=8920ce6bdff86f00 input=df163c34e17e1a35]*/
2102+
PyObject *type_params, PyObject *qualname)
2103+
/*[clinic end generated code: output=b7f6d9f1c577cd9c input=cbec290f8c4886ef]*/
21032104
{
21042105
if (type_params != NULL && !PyTuple_Check(type_params)) {
21052106
PyErr_SetString(PyExc_TypeError, "type_params must be a tuple");
@@ -2117,9 +2118,18 @@ typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value,
21172118
return NULL;
21182119
}
21192120

2120-
// It's impossible to determine qualname, so we use name instead.
2121+
if (qualname == NULL || qualname == Py_None) {
2122+
// If qualname was not set directly, we use name instead.
2123+
qualname = name;
2124+
} else {
2125+
if (!PyUnicode_Check(qualname)) {
2126+
PyErr_SetString(PyExc_TypeError, "qualname must be a string");
2127+
return NULL;
2128+
}
2129+
}
2130+
21212131
PyObject *ta = (PyObject *)typealias_alloc(
2122-
name, name, checked_params, NULL, value, module);
2132+
name, qualname, checked_params, NULL, value, module);
21232133
Py_DECREF(module);
21242134
return ta;
21252135
}

0 commit comments

Comments
 (0)