Skip to content

Commit 2c278ca

Browse files
committed
C is fun PT2 (ignore this)
1 parent 0e849c5 commit 2c278ca

File tree

6 files changed

+65
-0
lines changed

6 files changed

+65
-0
lines changed

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
@@ -93,6 +93,7 @@ struct _Py_global_strings {
9393
STRUCT_FOR_ID(__contains__)
9494
STRUCT_FOR_ID(__copy__)
9595
STRUCT_FOR_ID(__ctypes_from_outparam__)
96+
STRUCT_FOR_ID(__default__)
9697
STRUCT_FOR_ID(__del__)
9798
STRUCT_FOR_ID(__delattr__)
9899
STRUCT_FOR_ID(__delete__)

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: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_types.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,14 @@ def test_union_parameter_chaining(self):
828828
self.assertEqual((list[T] | list[S])[int, T], list[int] | list[T])
829829
self.assertEqual((list[T] | list[S])[int, int], list[int])
830830

831+
def test_union_parameter_default_ordering(self):
832+
T = typing.TypeVar("T")
833+
U = typing.TypeVar("U", default=int)
834+
835+
self.assertEqual((list[U] | list[T]).__parameters__, (U, T))
836+
with self.assertRaises(TypeError):
837+
list[U] | list[T]
838+
831839
def test_union_parameter_substitution(self):
832840
def eq(actual, expected, typed=True):
833841
self.assertEqual(actual, expected)
@@ -967,6 +975,18 @@ def __eq__(self, other):
967975
with self.assertRaises(TypeError):
968976
issubclass(int, type_)
969977

978+
def test_generic_alias_subclass_with_defaults(self):
979+
T = typing.TypeVar("T")
980+
U = typing.TypeVar("U", default=int)
981+
class MyGeneric:
982+
__class_getitem__ = classmethod(types.GenericAlias)
983+
984+
class Fine(MyGeneric[T, U]):
985+
...
986+
987+
with self.assertRaises(TypeError):
988+
class NonDefaultFollows(MyGeneric[U, T]): ...
989+
970990
def test_or_type_operator_with_bad_module(self):
971991
class BadMeta(type):
972992
__qualname__ = 'TypeVar'

Objects/genericaliasobject.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,11 @@ _Py_make_parameters(PyObject *args)
214214
if (parameters == NULL)
215215
return NULL;
216216
Py_ssize_t iparam = 0;
217+
bool seen_default = false;
217218
for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
218219
PyObject *t = PyTuple_GET_ITEM(args, iarg);
219220
PyObject *subst;
221+
220222
// We don't want __parameters__ descriptor of a bare Python class.
221223
if (PyType_Check(t)) {
222224
continue;
@@ -225,7 +227,28 @@ _Py_make_parameters(PyObject *args)
225227
Py_DECREF(parameters);
226228
return NULL;
227229
}
230+
printf("Here\n");
228231
if (subst) {
232+
printf("subst checking contains\n");
233+
PyObject_Print(t, stdout, 0);
234+
PyObject_Print(parameters, stdout, 0);
235+
PyObject *default_;
236+
bool does_not_contain = tuple_index(parameters, nargs, t) == -1;
237+
if (does_not_contain) {
238+
if (_PyObject_LookupAttr(t, &_Py_ID(__default__), &default_) < 0) {
239+
Py_DECREF(default_);
240+
Py_DECREF(subst);
241+
return NULL;
242+
}
243+
PyObject_Print(default_, stdout, 0);
244+
if (default_ && !!Py_IsNone(default_)) {
245+
seen_default = true;
246+
} else if (seen_default) {
247+
PyErr_Format(PyExc_TypeError, "TypeVarLike without a default follows one with a default");
248+
}
249+
printf("\n%d seen default\n", seen_default);
250+
}
251+
229252
iparam += tuple_add(parameters, iparam, t);
230253
Py_DECREF(subst);
231254
}
@@ -248,7 +271,24 @@ _Py_make_parameters(PyObject *args)
248271
}
249272
}
250273
for (Py_ssize_t j = 0; j < len2; j++) {
274+
PyObject *default_;
251275
PyObject *t2 = PyTuple_GET_ITEM(subparams, j);
276+
277+
bool does_not_contain = tuple_index(parameters, nargs, t) == -1;
278+
if (does_not_contain) {
279+
if (_PyObject_LookupAttr(t2, &_Py_ID(__default__), &default_) < 0) {
280+
Py_DECREF(default_);
281+
Py_DECREF(subst);
282+
return NULL;
283+
}
284+
PyObject_Print(default_, stdout, 0);
285+
printf("\n%d seen default\n", seen_default);
286+
if (default_ && !!Py_IsNone(default_)) {
287+
seen_default = true;
288+
} else if (seen_default) {
289+
PyErr_Format(PyExc_TypeError, "TypeVarLike without a default follows one with a default");
290+
}
291+
}
252292
iparam += tuple_add(parameters, iparam, t2);
253293
}
254294
}

0 commit comments

Comments
 (0)