diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index f22b7711a7..6b2426d704 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -3028,8 +3028,6 @@ class ElementIterTest(unittest.TestCase): self.assertEqual(summarize_list(doc.getiterator(None)), all_tags) self.assertEqual(summarize_list(doc.getiterator('*')), all_tags) - # TODO: RUSTPYTHON - @unittest.expectedFailure def test_copy(self): a = ET.Element('a') it = a.iter() diff --git a/extra_tests/snippets/forbidden_instantiation.py b/extra_tests/snippets/forbidden_instantiation.py index 386c894c06..e5a178e8ae 100644 --- a/extra_tests/snippets/forbidden_instantiation.py +++ b/extra_tests/snippets/forbidden_instantiation.py @@ -1,4 +1,9 @@ from typing import Type +from types import ( + GeneratorType, CoroutineType, AsyncGeneratorType, BuiltinFunctionType, + BuiltinMethodType, WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, + ClassMethodDescriptorType, FrameType, GetSetDescriptorType, MemberDescriptorType +) from testutils import assert_raises def check_forbidden_instantiation(typ, reverse=False): @@ -11,8 +16,26 @@ dict_values, dict_items = lambda: {}.values(), lambda: {}.items() iter_types = [list, set, str, bytearray, bytes, dict, tuple, lambda: range(0), dict_items, dict_values] # types with custom backwards iterators reviter_types = [list, dict, lambda: range(0), dict_values, dict_items] +# internal types: +internal_types = [ + GeneratorType, + CoroutineType, + AsyncGeneratorType, + BuiltinFunctionType, + BuiltinMethodType, # same as MethodWrapperType + WrapperDescriptorType, + MethodWrapperType, + MethodDescriptorType, + ClassMethodDescriptorType, + FrameType, + GetSetDescriptorType, # same as MemberDescriptorType + MemberDescriptorType +] for typ in iter_types: check_forbidden_instantiation(typ) for typ in reviter_types: check_forbidden_instantiation(typ, reverse=True) +for typ in internal_types: + with assert_raises(TypeError): + typ() \ No newline at end of file diff --git a/vm/src/builtins/asyncgenerator.rs b/vm/src/builtins/asyncgenerator.rs index 09a967445c..e17648cfb7 100644 --- a/vm/src/builtins/asyncgenerator.rs +++ b/vm/src/builtins/asyncgenerator.rs @@ -5,7 +5,7 @@ use crate::{ frame::FrameRef, function::OptionalArg, protocol::PyIterReturn, - types::{IterNext, IterNextIterable}, + types::{Constructor, IterNext, IterNextIterable, Unconstructible}, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine, }; @@ -26,7 +26,7 @@ impl PyValue for PyAsyncGen { } } -#[pyimpl] +#[pyimpl(with(Constructor))] impl PyAsyncGen { pub fn as_coro(&self) -> &Coro { &self.inner @@ -124,6 +124,7 @@ impl PyAsyncGen { self.inner.frame().code.clone() } } +impl Unconstructible for PyAsyncGen {} #[pyclass(module = false, name = "async_generator_wrapped_value")] #[derive(Debug)] diff --git a/vm/src/builtins/builtinfunc.rs b/vm/src/builtins/builtinfunc.rs index 75016a423a..f65d346b00 100644 --- a/vm/src/builtins/builtinfunc.rs +++ b/vm/src/builtins/builtinfunc.rs @@ -2,7 +2,7 @@ use super::{pytype, PyClassMethod, PyStr, PyStrRef, PyTypeRef}; use crate::{ builtins::PyBoundMethod, function::{FuncArgs, IntoPyNativeFunc, PyNativeFunc}, - types::{Callable, GetDescriptor}, + types::{Callable, Constructor, GetDescriptor, Unconstructible}, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine, }; use std::fmt; @@ -99,7 +99,7 @@ impl Callable for PyBuiltinFunction { } } -#[pyimpl(with(Callable), flags(HAS_DICT))] +#[pyimpl(with(Callable, Constructor), flags(HAS_DICT))] impl PyBuiltinFunction { #[pyproperty(magic)] fn module(&self, vm: &VirtualMachine) -> PyObjectRef { @@ -142,6 +142,7 @@ impl PyBuiltinFunction { }) } } +impl Unconstructible for PyBuiltinFunction {} // `PyBuiltinMethod` is similar to both `PyMethodDescrObject` in // https://github.com/python/cpython/blob/main/Include/descrobject.h @@ -207,7 +208,7 @@ impl PyBuiltinMethod { } } -#[pyimpl(with(GetDescriptor, Callable), flags(METHOD_DESCR))] +#[pyimpl(with(GetDescriptor, Callable, Constructor), flags(METHOD_DESCR))] impl PyBuiltinMethod { #[pyproperty(magic)] fn name(&self) -> PyStrRef { @@ -237,6 +238,7 @@ impl PyBuiltinMethod { ) } } +impl Unconstructible for PyBuiltinMethod {} pub fn init(context: &PyContext) { PyBuiltinFunction::extend_class(context, &context.types.builtin_function_or_method_type); diff --git a/vm/src/builtins/coroutine.rs b/vm/src/builtins/coroutine.rs index 04b5e9633e..3d5619ffda 100644 --- a/vm/src/builtins/coroutine.rs +++ b/vm/src/builtins/coroutine.rs @@ -4,7 +4,7 @@ use crate::{ frame::FrameRef, function::OptionalArg, protocol::PyIterReturn, - types::{IterNext, IterNextIterable}, + types::{Constructor, IterNext, IterNextIterable, Unconstructible}, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine, }; @@ -21,7 +21,7 @@ impl PyValue for PyCoroutine { } } -#[pyimpl(with(IterNext))] +#[pyimpl(with(Constructor, IterNext))] impl PyCoroutine { pub fn as_coro(&self) -> &Coro { &self.inner @@ -103,6 +103,7 @@ impl PyCoroutine { None } } +impl Unconstructible for PyCoroutine {} impl IterNextIterable for PyCoroutine {} impl IterNext for PyCoroutine { diff --git a/vm/src/builtins/frame.rs b/vm/src/builtins/frame.rs index 3503eee5fd..1655f857af 100644 --- a/vm/src/builtins/frame.rs +++ b/vm/src/builtins/frame.rs @@ -2,10 +2,10 @@ */ -use super::{PyCode, PyDictRef, PyStrRef, PyTypeRef}; +use super::{PyCode, PyDictRef, PyStrRef}; use crate::{ frame::{Frame, FrameRef}, - function::FuncArgs, + types::{Constructor, Unconstructible}, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, VirtualMachine, }; @@ -13,16 +13,12 @@ pub fn init(context: &PyContext) { FrameRef::extend_class(context, &context.types.frame_type); } -#[pyimpl(with(PyRef))] +#[pyimpl(with(Constructor, PyRef))] impl Frame {} +impl Unconstructible for Frame {} #[pyimpl] impl FrameRef { - #[pyslot] - fn slot_new(_cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { - Err(vm.new_type_error("Cannot directly create frame object".to_owned())) - } - #[pymethod(magic)] fn repr(self) -> String { "".to_owned() diff --git a/vm/src/builtins/generator.rs b/vm/src/builtins/generator.rs index 65863d4a85..1769435a3a 100644 --- a/vm/src/builtins/generator.rs +++ b/vm/src/builtins/generator.rs @@ -8,7 +8,7 @@ use crate::{ frame::FrameRef, function::OptionalArg, protocol::PyIterReturn, - types::{IterNext, IterNextIterable}, + types::{Constructor, IterNext, IterNextIterable, Unconstructible}, IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine, }; @@ -24,7 +24,7 @@ impl PyValue for PyGenerator { } } -#[pyimpl(with(IterNext))] +#[pyimpl(with(Constructor, IterNext))] impl PyGenerator { pub fn as_coro(&self) -> &Coro { &self.inner @@ -95,6 +95,7 @@ impl PyGenerator { self.inner.frame().yield_from_target() } } +impl Unconstructible for PyGenerator {} impl IterNextIterable for PyGenerator {} impl IterNext for PyGenerator { diff --git a/vm/src/builtins/getset.rs b/vm/src/builtins/getset.rs index 4479544b8a..ded3724544 100644 --- a/vm/src/builtins/getset.rs +++ b/vm/src/builtins/getset.rs @@ -4,7 +4,7 @@ use super::PyTypeRef; use crate::{ function::{IntoPyResult, OwnedParam, RefParam}, - types::GetDescriptor, + types::{Constructor, GetDescriptor, Unconstructible}, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyThreadingConstraint, PyValue, TryFromObject, TypeProtocol, VirtualMachine, }; @@ -300,7 +300,7 @@ impl PyGetSet { } } -#[pyimpl(with(GetDescriptor))] +#[pyimpl(with(GetDescriptor, Constructor))] impl PyGetSet { // Descriptor methods @@ -361,6 +361,7 @@ impl PyGetSet { format!("{}.{}", self.class.slot_name(), self.name.clone()) } } +impl Unconstructible for PyGetSet {} pub(crate) fn init(context: &PyContext) { PyGetSet::extend_class(context, &context.types.getset_type);