Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
impl TypeVarTuple iter
  • Loading branch information
youknowone committed Jun 26, 2025
commit af2d36c1d396fd884cefef503101c30ce1abab3a
26 changes: 0 additions & 26 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,6 @@ class X(Generic[*Ts, T]): ...
with self.assertRaises(TypeError):
class Y(Generic[*Ts_default, T]): ...

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_allow_default_after_non_default_in_alias(self):
T_default = TypeVar('T_default', default=int)
T = TypeVar('T')
Expand Down Expand Up @@ -1298,8 +1296,6 @@ def test_cannot_call_instance(self):
with self.assertRaises(TypeError):
Ts()

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_unpacked_typevartuple_is_equal_to_itself(self):
Ts = TypeVarTuple('Ts')
self.assertEqual((*Ts,)[0], (*Ts,)[0])
Expand All @@ -1310,8 +1306,6 @@ def test_parameterised_tuple_is_equal_to_itself(self):
# self.assertEqual(tuple[*Ts], tuple[*Ts])
self.assertEqual(Tuple[Unpack[Ts]], Tuple[Unpack[Ts]])

# TODO: RUSTPYTHON
@unittest.expectedFailure
def tests_tuple_arg_ordering_matters(self):
Ts1 = TypeVarTuple('Ts1')
Ts2 = TypeVarTuple('Ts2')
Expand Down Expand Up @@ -1673,8 +1667,6 @@ def func2(*args: '*tuple[int, str]'): pass
# {'args': Unpack[CustomVariadic[int, str]]})


# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_tuple_args_are_correct(self):
Ts = TypeVarTuple('Ts')

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

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_callable_args_are_correct(self):
Ts = TypeVarTuple('Ts')
Ts1 = TypeVarTuple('Ts1')
Expand Down Expand Up @@ -1772,8 +1762,6 @@ class E(Generic[*Ts1, *Ts2, *Ts1]): pass
with self.assertRaises(TypeError):
class F(Generic[Unpack[Ts1], Unpack[Ts2], Unpack[Ts1]]): pass

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_type_concatenation_in_variadic_class_argument_list_succeeds(self):
Ts = TypeVarTuple('Ts')
class C(Generic[Unpack[Ts]]): pass
Expand All @@ -1790,8 +1778,6 @@ class C(Generic[Unpack[Ts]]): pass
C[int, bool, *Ts, float, str]
C[int, bool, Unpack[Ts], float, str]

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_type_concatenation_in_tuple_argument_list_succeeds(self):
Ts = TypeVarTuple('Ts')

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

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_variadic_class_with_2_typevars_accepts_2_or_more_args(self):
Ts = TypeVarTuple('Ts')
T1 = TypeVar('T1')
Expand Down Expand Up @@ -2022,8 +2006,6 @@ def test_pickling_then_unpickling_results_in_same_identity(self, proto):
global_Ts2 = pickle.loads(pickle.dumps(global_Ts1, proto))
self.assertIs(global_Ts1, global_Ts2)

# TODO: RUSTPYTHON
@unittest.expectedFailure
@all_pickle_protocols
def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto):
global global_Ts # See explanation at start of class.
Expand All @@ -2037,8 +2019,6 @@ def test_pickling_then_unpickling_unpacked_results_in_same_identity(self, proto)
unpacked4 = pickle.loads(pickle.dumps(unpacked3, proto))
self.assertIs(unpacked3, unpacked4)

# TODO: RUSTPYTHON
@unittest.expectedFailure
@all_pickle_protocols
def test_pickling_then_unpickling_tuple_with_typevartuple_equality(
self, proto
Expand Down Expand Up @@ -2499,8 +2479,6 @@ def test_weakref(self):
alias = Callable[[int, str], float]
self.assertEqual(weakref.ref(alias)(), alias)

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_pickle(self):
global T_pickle, P_pickle, TS_pickle # needed for pickling
Callable = self.Callable
Expand Down Expand Up @@ -4009,8 +3987,6 @@ def test_pep695_generic_class_with_future_annotations_name_clash_with_global_var
set(ann_module695.C.__type_params__)
)

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


class GetUtilitiesTestCase(TestCase):
# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_get_origin(self):
T = TypeVar('T')
Ts = TypeVarTuple('Ts')
Expand Down
20 changes: 17 additions & 3 deletions vm/src/stdlib/typing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
#[pymodule(name = "_typing")]
pub(crate) mod decl {
use crate::{
AsObject, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
AsObject, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
builtins::{PyTupleRef, PyTypeRef, pystr::AsPyStr},
function::{FuncArgs, IntoFuncArgs, PyComparisonValue},
protocol::PyNumberMethods,
types::{AsNumber, Comparable, Constructor, PyComparisonOp, Representable},
types::{AsNumber, Comparable, Constructor, Iterable, PyComparisonOp, Representable},
};

pub(crate) fn _call_typing_func_object<'a>(
Expand Down Expand Up @@ -607,7 +607,7 @@ pub(crate) mod decl {
default_value: parking_lot::Mutex<PyObjectRef>,
evaluate_default: PyObjectRef,
}
#[pyclass(flags(HAS_DICT), with(Constructor, Representable))]
#[pyclass(flags(HAS_DICT), with(Constructor, Representable, Iterable))]
impl TypeVarTuple {
#[pygetset(magic)]
fn name(&self) -> PyObjectRef {
Expand Down Expand Up @@ -667,6 +667,20 @@ pub(crate) mod decl {
}
}

impl Iterable for TypeVarTuple {
fn iter(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
// When unpacking TypeVarTuple with *, return [Unpack[self]]
// This is how CPython handles Generic[*Ts]
let typing = vm.import("typing", 0)?;
let unpack = typing.get_attr("Unpack", vm)?;
let zelf_obj: PyObjectRef = zelf.into();
let unpacked = vm.call_method(&unpack, "__getitem__", (zelf_obj,))?;
let list = vm.ctx.new_list(vec![unpacked]);
let list_obj: PyObjectRef = list.into();
vm.call_method(&list_obj, "__iter__", ())
}
}

impl Constructor for TypeVarTuple {
type Args = FuncArgs;

Expand Down
Loading