Skip to content

typing upgrade to 3.13.2 #5590

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Apr 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Lib/_py_abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class ABCMeta(type):
_abc_invalidation_counter = 0

def __new__(mcls, name, bases, namespace, /, **kwargs):
# TODO: RUSTPYTHON remove this line (prevents duplicate bases)
bases = tuple(dict.fromkeys(bases))
cls = super().__new__(mcls, name, bases, namespace, **kwargs)
# Compute set of abstract method names
abstracts = {name
Expand Down Expand Up @@ -98,8 +100,8 @@ def __instancecheck__(cls, instance):
subtype = type(instance)
if subtype is subclass:
if (cls._abc_negative_cache_version ==
ABCMeta._abc_invalidation_counter and
subclass in cls._abc_negative_cache):
ABCMeta._abc_invalidation_counter and
subclass in cls._abc_negative_cache):
return False
# Fall back to the subclass check.
return cls.__subclasscheck__(subclass)
Expand Down
57 changes: 57 additions & 0 deletions Lib/test/support/testcase.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,63 @@
from math import copysign, isnan


class ExtraAssertions:

def assertIsSubclass(self, cls, superclass, msg=None):
if issubclass(cls, superclass):
return
standardMsg = f'{cls!r} is not a subclass of {superclass!r}'
self.fail(self._formatMessage(msg, standardMsg))

def assertNotIsSubclass(self, cls, superclass, msg=None):
if not issubclass(cls, superclass):
return
standardMsg = f'{cls!r} is a subclass of {superclass!r}'
self.fail(self._formatMessage(msg, standardMsg))

def assertHasAttr(self, obj, name, msg=None):
if not hasattr(obj, name):
if isinstance(obj, types.ModuleType):
standardMsg = f'module {obj.__name__!r} has no attribute {name!r}'
elif isinstance(obj, type):
standardMsg = f'type object {obj.__name__!r} has no attribute {name!r}'
else:
standardMsg = f'{type(obj).__name__!r} object has no attribute {name!r}'
self.fail(self._formatMessage(msg, standardMsg))

def assertNotHasAttr(self, obj, name, msg=None):
if hasattr(obj, name):
if isinstance(obj, types.ModuleType):
standardMsg = f'module {obj.__name__!r} has unexpected attribute {name!r}'
elif isinstance(obj, type):
standardMsg = f'type object {obj.__name__!r} has unexpected attribute {name!r}'
else:
standardMsg = f'{type(obj).__name__!r} object has unexpected attribute {name!r}'
self.fail(self._formatMessage(msg, standardMsg))

def assertStartsWith(self, s, prefix, msg=None):
if s.startswith(prefix):
return
standardMsg = f"{s!r} doesn't start with {prefix!r}"
self.fail(self._formatMessage(msg, standardMsg))

def assertNotStartsWith(self, s, prefix, msg=None):
if not s.startswith(prefix):
return
self.fail(self._formatMessage(msg, f"{s!r} starts with {prefix!r}"))

def assertEndsWith(self, s, suffix, msg=None):
if s.endswith(suffix):
return
standardMsg = f"{s!r} doesn't end with {suffix!r}"
self.fail(self._formatMessage(msg, standardMsg))

def assertNotEndsWith(self, s, suffix, msg=None):
if not s.endswith(suffix):
return
self.fail(self._formatMessage(msg, f"{s!r} ends with {suffix!r}"))


class ExceptionIsLikeMixin:
def assertExceptionIsLike(self, exc, template):
"""
Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,8 @@ def new_method(self):
c = Alias(10, 1.0)
self.assertEqual(c.new_method(), 1.0)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_generic_dynamic(self):
T = TypeVar('T')

Expand Down Expand Up @@ -3250,6 +3252,8 @@ def test_classvar_module_level_import(self):
# won't exist on the instance.
self.assertNotIn('not_iv4', c.__dict__)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_text_annotations(self):
from test import dataclass_textanno

Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_exception_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ def test_exception_is_not_generic_type(self):
with self.assertRaisesRegex(TypeError, 'Exception'):
Exception[OSError]

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_exception_group_is_generic_type(self):
E = OSError
self.assertIsInstance(ExceptionGroup[E], types.GenericAlias)
Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_future_stmt/test_future.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,8 +442,6 @@ def foo():
def bar(arg: (yield)): pass
"""))

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_get_type_hints_on_func_with_variadic_arg(self):
# `typing.get_type_hints` might break on a function with a variadic
# annotation (e.g. `f(*args: *Ts)`) if `from __future__ import
Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_genericalias.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ def test_exposed_type(self):
self.assertEqual(a.__args__, (int,))
self.assertEqual(a.__parameters__, ())

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_parameters(self):
from typing import List, Dict, Callable
D0 = dict[str, int]
Expand Down Expand Up @@ -212,6 +214,8 @@ def test_parameters(self):
self.assertEqual(L5.__args__, (Callable[[K, V], K],))
self.assertEqual(L5.__parameters__, (K, V))

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_parameter_chaining(self):
from typing import List, Dict, Union, Callable
self.assertEqual(list[T][int], list[int])
Expand Down Expand Up @@ -271,6 +275,8 @@ class MyType(type):
with self.assertRaises(TypeError):
MyType[int]

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_pickle(self):
alias = GenericAlias(list, T)
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Expand All @@ -280,6 +286,8 @@ def test_pickle(self):
self.assertEqual(loaded.__args__, alias.__args__)
self.assertEqual(loaded.__parameters__, alias.__parameters__)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_copy(self):
class X(list):
def __copy__(self):
Expand All @@ -303,6 +311,8 @@ def test_union(self):
self.assertEqual(a.__args__, (list[int], list[str]))
self.assertEqual(a.__parameters__, ())

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_union_generic(self):
a = typing.Union[list[T], tuple[T, ...]]
self.assertEqual(a.__args__, (list[T], tuple[T, ...]))
Expand Down
16 changes: 16 additions & 0 deletions Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,8 @@ def test_instancecheck_and_subclasscheck(self):
self.assertTrue(issubclass(dict, x))
self.assertFalse(issubclass(list, x))

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_instancecheck_and_subclasscheck_order(self):
T = typing.TypeVar('T')

Expand Down Expand Up @@ -788,13 +790,17 @@ def __subclasscheck__(cls, sub):
self.assertTrue(issubclass(int, x))
self.assertRaises(ZeroDivisionError, issubclass, list, x)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_or_type_operator_with_TypeVar(self):
TV = typing.TypeVar('T')
assert TV | str == typing.Union[TV, str]
assert str | TV == typing.Union[str, TV]
self.assertIs((int | TV)[int], int)
self.assertIs((TV | int)[int], int)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_union_args(self):
def check(arg, expected):
clear_typing_caches()
Expand Down Expand Up @@ -825,6 +831,8 @@ def check(arg, expected):
check(x | None, (x, type(None)))
check(None | x, (type(None), x))

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_union_parameter_chaining(self):
T = typing.TypeVar("T")
S = typing.TypeVar("S")
Expand Down Expand Up @@ -869,6 +877,8 @@ def eq(actual, expected, typed=True):
eq(x[NT], int | NT | bytes)
eq(x[S], int | S | bytes)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_union_pickle(self):
orig = list[T] | int
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
Expand All @@ -878,19 +888,25 @@ def test_union_pickle(self):
self.assertEqual(loaded.__args__, orig.__args__)
self.assertEqual(loaded.__parameters__, orig.__parameters__)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_union_copy(self):
orig = list[T] | int
for copied in (copy.copy(orig), copy.deepcopy(orig)):
self.assertEqual(copied, orig)
self.assertEqual(copied.__args__, orig.__args__)
self.assertEqual(copied.__parameters__, orig.__parameters__)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_union_parameter_substitution_errors(self):
T = typing.TypeVar("T")
x = int | T
with self.assertRaises(TypeError):
x[int, str]

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_or_type_operator_with_forward(self):
T = typing.TypeVar('T')
ForwardAfter = T | 'Forward'
Expand Down
Loading
Loading