mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
type.__type_params__
This commit is contained in:
1 parent
e25c2856ad
commit
fa7af0e5ea
5 files changed
+57
-38
No files matched your search
Vendored
-2
@@ -3246,8 +3246,6 @@ class TestStringAnnotations(unittest.TestCase):
|
||||
# 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
|
||||
|
||||
|
||||
Vendored
-35
@@ -1605,8 +1605,6 @@ class TypeVarTupleTests(BaseTestCase):
|
||||
self.assertIs(D[T].__origin__, D)
|
||||
self.assertIs(D[Unpack[Ts]].__origin__, D)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_get_type_hints_on_unpack_args(self):
|
||||
Ts = TypeVarTuple('Ts')
|
||||
|
||||
@@ -1809,8 +1807,6 @@ class TypeVarTupleTests(BaseTestCase):
|
||||
F[int, str, float]
|
||||
F[int, str, float, bool]
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_variadic_args_annotations_are_correct(self):
|
||||
Ts = TypeVarTuple('Ts')
|
||||
|
||||
@@ -2494,7 +2490,6 @@ class BaseCallableTests:
|
||||
self.assertEqual(C5[int, str, float],
|
||||
Callable[[typing.List[int], tuple[str, int], float], int])
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON")
|
||||
def test_type_subst_error(self):
|
||||
Callable = self.Callable
|
||||
P = ParamSpec('P')
|
||||
@@ -3859,8 +3854,6 @@ class GenericTests(BaseTestCase):
|
||||
def barfoo2(x: CT): ...
|
||||
self.assertIs(get_type_hints(barfoo2, globals(), locals())['x'], CT)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_generic_pep585_forward_ref(self):
|
||||
# See https://bugs.python.org/issue41370
|
||||
|
||||
@@ -5189,8 +5182,6 @@ class ForwardRefTests(BaseTestCase):
|
||||
self.assertIsNot(r1, r2)
|
||||
self.assertRaises(RecursionError, cmp, r1, r2)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_union_forward_recursion(self):
|
||||
ValueList = List['Value']
|
||||
Value = Union[str, ValueList]
|
||||
@@ -5239,8 +5230,6 @@ class ForwardRefTests(BaseTestCase):
|
||||
self.assertEqual(get_type_hints(foo, globals(), locals()),
|
||||
{'a': Callable[..., T]})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_special_forms_forward(self):
|
||||
|
||||
class C:
|
||||
@@ -5323,8 +5312,6 @@ class ForwardRefTests(BaseTestCase):
|
||||
|
||||
self.assertEqual(get_type_hints(Child.foo), {'x': int})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_no_type_check_nested_types(self):
|
||||
# See https://bugs.python.org/issue46571
|
||||
class Other:
|
||||
@@ -5409,8 +5396,6 @@ class ForwardRefTests(BaseTestCase):
|
||||
# `TypeError: can't set attributes of built-in/extension type 'dict'`
|
||||
no_type_check(dict)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_no_type_check_forward_ref_as_string(self):
|
||||
class C:
|
||||
foo: typing.ClassVar[int] = 7
|
||||
@@ -5465,8 +5450,6 @@ class ForwardRefTests(BaseTestCase):
|
||||
hints = get_type_hints(ns['C'].foo)
|
||||
self.assertEqual(hints, {'a': ns['C'], 'return': ns['D']})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_final_forward_ref(self):
|
||||
self.assertEqual(gth(Loop, globals())['attr'], Final[Loop])
|
||||
self.assertNotEqual(gth(Loop, globals())['attr'], Final[int])
|
||||
@@ -5832,8 +5815,6 @@ class GetTypeHintTests(BaseTestCase):
|
||||
'my_inner_a2': mod_generics_cache.B.A,
|
||||
'my_outer_a': mod_generics_cache.A})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_get_type_hints_classes_no_implicit_optional(self):
|
||||
class WithNoneDefault:
|
||||
field: int = None # most type-checkers won't be happy with it
|
||||
@@ -5878,8 +5859,6 @@ class GetTypeHintTests(BaseTestCase):
|
||||
b.__annotations__ = {'x': 'A'}
|
||||
self.assertEqual(gth(b, locals()), {'x': A})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_get_type_hints_ClassVar(self):
|
||||
self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__),
|
||||
{'var': typing.ClassVar[ann_module2.CV]})
|
||||
@@ -6006,8 +5985,6 @@ class GetTypeHintTests(BaseTestCase):
|
||||
{'x': Annotated[int, 'data']},
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_get_type_hints_classes_str_annotations(self):
|
||||
class Foo:
|
||||
y = str
|
||||
@@ -6023,8 +6000,6 @@ class GetTypeHintTests(BaseTestCase):
|
||||
self.assertNotIn('bad', sys.modules)
|
||||
self.assertEqual(get_type_hints(BadModule), {})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_get_type_hints_annotated_bad_module(self):
|
||||
# See https://bugs.python.org/issue44468
|
||||
class BadBase:
|
||||
@@ -6035,8 +6010,6 @@ class GetTypeHintTests(BaseTestCase):
|
||||
self.assertNotIn('bad', sys.modules)
|
||||
self.assertEqual(get_type_hints(BadType), {'foo': tuple, 'bar': list})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_forward_ref_and_final(self):
|
||||
# https://bugs.python.org/issue45166
|
||||
hints = get_type_hints(ann_module5)
|
||||
@@ -8274,8 +8247,6 @@ class AnnotatedTests(BaseTestCase):
|
||||
A.x = 5
|
||||
self.assertEqual(C.x, 5)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_special_form_containment(self):
|
||||
class C:
|
||||
classvar: Annotated[ClassVar[int], "a decoration"] = 4
|
||||
@@ -8284,8 +8255,6 @@ class AnnotatedTests(BaseTestCase):
|
||||
self.assertEqual(get_type_hints(C, globals())['classvar'], ClassVar[int])
|
||||
self.assertEqual(get_type_hints(C, globals())['const'], Final[int])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_special_forms_nesting(self):
|
||||
# These are uncommon types and are to ensure runtime
|
||||
# is lax on validation. See gh-89547 for more context.
|
||||
@@ -8563,8 +8532,6 @@ class TypeAliasTests(BaseTestCase):
|
||||
with self.assertRaises(TypeError):
|
||||
isinstance(42, TypeAlias)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_stringized_usage(self):
|
||||
class A:
|
||||
a: "TypeAlias"
|
||||
@@ -8652,8 +8619,6 @@ class ParamSpecTests(BaseTestCase):
|
||||
self.assertEqual(repr(P.kwargs), "P.kwargs")
|
||||
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_stringized(self):
|
||||
P = ParamSpec('P')
|
||||
class C(Generic[P]):
|
||||
|
||||
@@ -2901,7 +2901,20 @@ impl Compiler<'_> {
|
||||
} else {
|
||||
let was_in_annotation = self.in_annotation;
|
||||
self.in_annotation = true;
|
||||
let result = self.compile_expression(annotation);
|
||||
|
||||
// Special handling for starred annotations (*Ts -> Unpack[Ts])
|
||||
let result = match annotation {
|
||||
Expr::Starred(ExprStarred { value, .. }) => {
|
||||
// Following CPython's approach:
|
||||
// *args: *Ts (where Ts is a TypeVarTuple).
|
||||
// Do [annotation_value] = [*Ts].
|
||||
self.compile_expression(value)?;
|
||||
emit!(self, Instruction::UnpackSequence { size: 1 });
|
||||
Ok(())
|
||||
}
|
||||
_ => self.compile_expression(annotation),
|
||||
};
|
||||
|
||||
self.in_annotation = was_in_annotation;
|
||||
result?;
|
||||
}
|
||||
|
||||
@@ -849,6 +849,48 @@ impl PyType {
|
||||
.and_then(|doc| get_text_signature_from_internal_doc(&self.name(), doc))
|
||||
.map(|signature| signature.to_string())
|
||||
}
|
||||
|
||||
#[pygetset]
|
||||
fn __type_params__(&self, vm: &VirtualMachine) -> PyTupleRef {
|
||||
let attrs = self.attributes.read();
|
||||
let key = identifier!(vm, __type_params__);
|
||||
if let Some(params) = attrs.get(&key) {
|
||||
if let Ok(tuple) = params.clone().downcast::<PyTuple>() {
|
||||
return tuple;
|
||||
}
|
||||
}
|
||||
// Return empty tuple if not found or not a tuple
|
||||
vm.ctx.empty_tuple.clone()
|
||||
}
|
||||
|
||||
#[pygetset(setter)]
|
||||
fn set___type_params__(
|
||||
&self,
|
||||
value: PySetterValue<PyTupleRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
match value {
|
||||
PySetterValue::Assign(ref val) => {
|
||||
let key = identifier!(vm, __type_params__);
|
||||
self.check_set_special_type_attr(val.as_ref(), key, vm)?;
|
||||
let mut attrs = self.attributes.write();
|
||||
attrs.insert(key, val.clone().into());
|
||||
}
|
||||
PySetterValue::Delete => {
|
||||
// For delete, we still need to check if the type is immutable
|
||||
if self.slots.flags.has_feature(PyTypeFlags::IMMUTABLETYPE) {
|
||||
return Err(vm.new_type_error(format!(
|
||||
"cannot delete '__type_params__' attribute of immutable type '{}'",
|
||||
self.slot_name()
|
||||
)));
|
||||
}
|
||||
let mut attrs = self.attributes.write();
|
||||
let key = identifier!(vm, __type_params__);
|
||||
attrs.shift_remove(&key);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Constructor for PyType {
|
||||
|
||||
@@ -223,6 +223,7 @@ declare_const_name! {
|
||||
__sizeof__,
|
||||
__truediv__,
|
||||
__trunc__,
|
||||
__type_params__,
|
||||
__typing_subst__,
|
||||
__typing_is_unpacked_typevartuple__,
|
||||
__typing_prepare_subst__,
|
||||
|
||||
Reference in new issue
Block a user