Skip to content

Commit af2d36c

Browse files
committed
impl TypeVarTuple iter
1 parent 6161d13 commit af2d36c

File tree

2 files changed

+17
-29
lines changed

2 files changed

+17
-29
lines changed

Lib/test/test_typing.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -715,8 +715,6 @@ class X(Generic[*Ts, T]): ...
715715
with self.assertRaises(TypeError):
716716
class Y(Generic[*Ts_default, T]): ...
717717

718-
# TODO: RUSTPYTHON
719-
@unittest.expectedFailure
720718
def test_allow_default_after_non_default_in_alias(self):
721719
T_default = TypeVar('T_default', default=int)
722720
T = TypeVar('T')
@@ -1298,8 +1296,6 @@ def test_cannot_call_instance(self):
12981296
with self.assertRaises(TypeError):
12991297
Ts()
13001298

1301-
# TODO: RUSTPYTHON
1302-
@unittest.expectedFailure
13031299
def test_unpacked_typevartuple_is_equal_to_itself(self):
13041300
Ts = TypeVarTuple('Ts')
13051301
self.assertEqual((*Ts,)[0], (*Ts,)[0])
@@ -1310,8 +1306,6 @@ def test_parameterised_tuple_is_equal_to_itself(self):
13101306
# self.assertEqual(tuple[*Ts], tuple[*Ts])
13111307
self.assertEqual(Tuple[Unpack[Ts]], Tuple[Unpack[Ts]])
13121308

1313-
# TODO: RUSTPYTHON
1314-
@unittest.expectedFailure
13151309
def tests_tuple_arg_ordering_matters(self):
13161310
Ts1 = TypeVarTuple('Ts1')
13171311
Ts2 = TypeVarTuple('Ts2')
@@ -1673,8 +1667,6 @@ def func2(*args: '*tuple[int, str]'): pass
16731667
# {'args': Unpack[CustomVariadic[int, str]]})
16741668

16751669

1676-
# TODO: RUSTPYTHON
1677-
@unittest.expectedFailure
16781670
def test_tuple_args_are_correct(self):
16791671
Ts = TypeVarTuple('Ts')
16801672

@@ -1695,8 +1687,6 @@ def test_tuple_args_are_correct(self):
16951687
self.assertEqual(tuple[*Ts, int].__args__, (*Ts, int))
16961688
self.assertEqual(Tuple[Unpack[Ts]].__args__, (Unpack[Ts],))
16971689

1698-
# TODO: RUSTPYTHON
1699-
@unittest.expectedFailure
17001690
def test_callable_args_are_correct(self):
17011691
Ts = TypeVarTuple('Ts')
17021692
Ts1 = TypeVarTuple('Ts1')
@@ -1772,8 +1762,6 @@ class E(Generic[*Ts1, *Ts2, *Ts1]): pass
17721762
with self.assertRaises(TypeError):
17731763
class F(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass
17741764

1775-
# TODO: RUSTPYTHON
1776-
@unittest.expectedFailure
17771765
def test_type_concatenation_in_variadic_class_argument_list_succeeds(self):
17781766
Ts = TypeVarTuple('Ts')
17791767
class C(Generic[Unpack[Ts]]): pass
@@ -1790,8 +1778,6 @@ class C(Generic[Unpack[Ts]]): pass
17901778
C[int, bool, *Ts, float, str]
17911779
C[int, bool, Unpack[Ts], float, str]
17921780

1793-
# TODO: RUSTPYTHON
1794-
@unittest.expectedFailure
17951781
def test_type_concatenation_in_tuple_argument_list_succeeds(self):
17961782
Ts = TypeVarTuple('Ts')
17971783

@@ -1817,8 +1803,6 @@ class F(Generic[*Ts, int]): pass
18171803
with self.assertRaises(TypeError):
18181804
class E(Generic[Unpack[Ts], int]): pass
18191805

1820-
# TODO: RUSTPYTHON
1821-
@unittest.expectedFailure
18221806
def test_variadic_class_with_2_typevars_accepts_2_or_more_args(self):
18231807
Ts = TypeVarTuple('Ts')
18241808
T1 = TypeVar('T1')
@@ -2022,8 +2006,6 @@ def test_pickling_then_unpickling_results_in_same_identity(self, proto):
20222006
global_Ts2 = pickle.loads(pickle.dumps(global_Ts1, proto))
20232007
self.assertIs(global_Ts1, global_Ts2)
20242008

2025-
# TODO: RUSTPYTHON
2026-
@unittest.expectedFailure
20272009
@all_pickle_protocols
20282010
def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto):
20292011
global global_Ts # See explanation at start of class.
@@ -2037,8 +2019,6 @@ def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto)
20372019
unpacked4 = pickle.loads(pickle.dumps(unpacked3, proto))
20382020
self.assertIs(unpacked3, unpacked4)
20392021

2040-
# TODO: RUSTPYTHON
2041-
@unittest.expectedFailure
20422022
@all_pickle_protocols
20432023
def test_pickling_then_unpickling_tuple_with_typevartuple_equality(
20442024
self, proto
@@ -2499,8 +2479,6 @@ def test_weakref(self):
24992479
alias = Callable[[int, str], float]
25002480
self.assertEqual(weakref.ref(alias)(), alias)
25012481

2502-
# TODO: RUSTPYTHON
2503-
@unittest.expectedFailure
25042482
def test_pickle(self):
25052483
global T_pickle, P_pickle, TS_pickle # needed for pickling
25062484
Callable = self.Callable
@@ -4009,8 +3987,6 @@ def test_pep695_generic_class_with_future_annotations_name_clash_with_global_var
40093987
set(ann_module695.C.__type_params__)
40103988
)
40113989

4012-
# TODO: RUSTPYTHON
4013-
@unittest.expectedFailure
40143990
def test_pep_695_generic_function_with_future_annotations(self):
40153991
hints_for_generic_function = get_type_hints(ann_module695.generic_function)
40163992
func_t_params = ann_module695.generic_function.__type_params__
@@ -6212,8 +6188,6 @@ def h(x: collections.abc.Callable[P, int]): ...
62126188

62136189

62146190
class GetUtilitiesTestCase(TestCase):
6215-
# TODO: RUSTPYTHON
6216-
@unittest.expectedFailure
62176191
def test_get_origin(self):
62186192
T = TypeVar('T')
62196193
Ts = TypeVarTuple('Ts')

vm/src/stdlib/typing.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
1313
#[pymodule(name = "_typing")]
1414
pub(crate) mod decl {
1515
use crate::{
16-
AsObject, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
16+
AsObject, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
1717
builtins::{PyTupleRef, PyTypeRef, pystr::AsPyStr},
1818
function::{FuncArgs, IntoFuncArgs, PyComparisonValue},
1919
protocol::PyNumberMethods,
20-
types::{AsNumber, Comparable, Constructor, PyComparisonOp, Representable},
20+
types::{AsNumber, Comparable, Constructor, Iterable, PyComparisonOp, Representable},
2121
};
2222

2323
pub(crate) fn _call_typing_func_object<'a>(
@@ -607,7 +607,7 @@ pub(crate) mod decl {
607607
default_value: parking_lot::Mutex<PyObjectRef>,
608608
evaluate_default: PyObjectRef,
609609
}
610-
#[pyclass(flags(HAS_DICT), with(Constructor, Representable))]
610+
#[pyclass(flags(HAS_DICT), with(Constructor, Representable, Iterable))]
611611
impl TypeVarTuple {
612612
#[pygetset(magic)]
613613
fn name(&self) -> PyObjectRef {
@@ -667,6 +667,20 @@ pub(crate) mod decl {
667667
}
668668
}
669669

670+
impl Iterable for TypeVarTuple {
671+
fn iter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
672+
// When unpacking TypeVarTuple with *, return [Unpack[self]]
673+
// This is how CPython handles Generic[*Ts]
674+
let typing = vm.import("typing", 0)?;
675+
let unpack = typing.get_attr("Unpack", vm)?;
676+
let zelf_obj: PyObjectRef = zelf.into();
677+
let unpacked = vm.call_method(&unpack, "__getitem__", (zelf_obj,))?;
678+
let list = vm.ctx.new_list(vec![unpacked]);
679+
let list_obj: PyObjectRef = list.into();
680+
vm.call_method(&list_obj, "__iter__", ())
681+
}
682+
}
683+
670684
impl Constructor for TypeVarTuple {
671685
type Args = FuncArgs;
672686

0 commit comments

Comments
 (0)