diff --git a/derive-impl/src/pyclass.rs b/derive-impl/src/pyclass.rs index a8371d889be..38f5bad613a 100644 --- a/derive-impl/src/pyclass.rs +++ b/derive-impl/src/pyclass.rs @@ -1453,29 +1453,37 @@ fn extract_impl_attrs(attr: AttributeArgs, item: &Ident) -> Result { if path.is_ident("with") { for meta in nested { - let NestedMeta::Meta(Meta::Path(path)) = meta else { - bail_span!(meta, "#[pyclass(with(...))] arguments should be paths") + let NestedMeta::Meta(Meta::Path(path)) = &meta else { + bail_span!(meta, "#[pyclass(with(...))] arguments must be paths") + }; + let (extend_class, method_defs, extend_slots) = if path.is_ident("PyRef") + || path.is_ident("Py") + { + // special handling for PyRef + ( + quote!(#path::::__extend_py_class), + quote!(#path::::__OWN_METHOD_DEFS), + quote!(#path::::__extend_slots), + ) + } else { + if path.is_ident("DefaultConstructor") { + bail_span!(meta, "Try `#[pyclass(with(Constructor, ...))]` instead of `#[pyclass(with(DefaultConstructor, ...))]`. DefaultConstructor implicitly implements Constructor.") + } + if path.is_ident("Constructor") || path.is_ident("Unconstructible") { + has_constructor = true; + } + ( + quote!(::__extend_py_class), + quote!(::__OWN_METHOD_DEFS), + quote!(::__extend_slots), + ) }; - let (extend_class, method_defs, extend_slots) = - if path.is_ident("PyRef") || path.is_ident("Py") { - // special handling for PyRef - ( - quote!(#path::::__extend_py_class), - quote!(#path::::__OWN_METHOD_DEFS), - quote!(#path::::__extend_slots), - ) - } else { - ( - quote!(::__extend_py_class), - quote!(::__OWN_METHOD_DEFS), - quote!(::__extend_slots), - ) - }; let item_span = item.span().resolved_at(Span::call_site()); withs.push(quote_spanned! { path.span() => #extend_class(ctx, class); @@ -1518,6 +1526,11 @@ fn extract_impl_attrs(attr: AttributeArgs, item: &Ident) -> Result bail_span!(attr, "Unknown pyimpl attribute"), } } + // TODO: DISALLOW_INSTANTIATION check is required + let _ = has_constructor; + // if !withs.is_empty() && !has_constructor { + // bail_span!(item, "#[pyclass(with(...))] does not have a Constructor. Either #[pyclass(with(Constructor, ...))] or #[pyclass(with(Unconstructible, ...))] is mandatory. Consider to add `impl DefaultConstructor for T {{}}` or `impl Unconstructible for T {{}}`.") + // } Ok(ExtractedImplAttrs { payload, diff --git a/stdlib/src/socket.rs b/stdlib/src/socket.rs index f3a86141e2f..1c99e3d5f68 100644 --- a/stdlib/src/socket.rs +++ b/stdlib/src/socket.rs @@ -16,7 +16,7 @@ mod _socket { common::os::ErrorExt, convert::{IntoPyException, ToPyObject, TryFromBorrowedObject, TryFromObject}, function::{ArgBytesLike, ArgMemoryBuffer, Either, FsPath, OptionalArg, OptionalOption}, - types::{DefaultConstructor, Initializer, Representable}, + types::{Constructor, DefaultConstructor, Initializer, Representable}, utils::ToCString, AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; @@ -1062,7 +1062,7 @@ mod _socket { } } - #[pyclass(with(DefaultConstructor, Initializer, Representable), flags(BASETYPE))] + #[pyclass(with(Constructor, Initializer, Representable), flags(BASETYPE))] impl PySocket { fn _init( zelf: PyRef, diff --git a/vm/src/builtins/asyncgenerator.rs b/vm/src/builtins/asyncgenerator.rs index d58744da0ad..4efb41b450b 100644 --- a/vm/src/builtins/asyncgenerator.rs +++ b/vm/src/builtins/asyncgenerator.rs @@ -6,7 +6,7 @@ use crate::{ frame::FrameRef, function::OptionalArg, protocol::PyIterReturn, - types::{Constructor, IterNext, Iterable, Representable, SelfIter, Unconstructible}, + types::{IterNext, Iterable, Representable, SelfIter, Unconstructible}, AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; @@ -26,7 +26,7 @@ impl PyPayload for PyAsyncGen { } } -#[pyclass(with(PyRef, Constructor, Representable))] +#[pyclass(with(PyRef, Unconstructible, Representable))] impl PyAsyncGen { pub fn as_coro(&self) -> &Coro { &self.inner diff --git a/vm/src/builtins/builtin_func.rs b/vm/src/builtins/builtin_func.rs index 515ae7d726d..b0b3492ea9f 100644 --- a/vm/src/builtins/builtin_func.rs +++ b/vm/src/builtins/builtin_func.rs @@ -3,7 +3,7 @@ use crate::{ class::PyClassImpl, convert::TryFromObject, function::{FuncArgs, PyComparisonValue, PyMethodDef, PyMethodFlags, PyNativeFn}, - types::{Callable, Comparable, Constructor, PyComparisonOp, Representable, Unconstructible}, + types::{Callable, Comparable, PyComparisonOp, Representable, Unconstructible}, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use std::fmt; @@ -65,7 +65,7 @@ impl Callable for PyNativeFunction { } } -#[pyclass(with(Callable, Constructor), flags(HAS_DICT))] +#[pyclass(with(Callable, Unconstructible), flags(HAS_DICT))] impl PyNativeFunction { #[pygetset(magic)] fn module(zelf: NativeFunctionOrMethod) -> Option<&'static PyStrInterned> { @@ -138,7 +138,10 @@ pub struct PyNativeMethod { pub(crate) class: &'static Py, // TODO: the actual life is &'self } -#[pyclass(with(Callable, Comparable, Representable), flags(HAS_DICT))] +#[pyclass( + with(Unconstructible, Callable, Comparable, Representable), + flags(HAS_DICT) +)] impl PyNativeMethod { #[pygetset(magic)] fn qualname(zelf: PyRef, vm: &VirtualMachine) -> PyResult { diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 9ac0fb54f23..40e6cf7b5cb 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -21,8 +21,7 @@ use crate::{ }, convert::{ToPyObject, ToPyResult}, function::{ - ArgBytesLike, ArgIterable, ArgSize, Either, FuncArgs, OptionalArg, OptionalOption, - PyComparisonValue, + ArgBytesLike, ArgIterable, ArgSize, Either, OptionalArg, OptionalOption, PyComparisonValue, }, protocol::{ BufferDescriptor, BufferMethods, BufferResizeGuard, PyBuffer, PyIterReturn, @@ -30,8 +29,9 @@ use crate::{ }, sliceable::{SequenceIndex, SliceableSequenceMutOp, SliceableSequenceOp}, types::{ - AsBuffer, AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, Initializer, - IterNext, Iterable, PyComparisonOp, Representable, SelfIter, Unconstructible, + AsBuffer, AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, + DefaultConstructor, Initializer, IterNext, Iterable, PyComparisonOp, Representable, + SelfIter, Unconstructible, }, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, @@ -696,15 +696,7 @@ impl PyRef { } } -impl Constructor for PyByteArray { - type Args = FuncArgs; - - fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult { - PyByteArray::default() - .into_ref_with_type(vm, cls) - .map(Into::into) - } -} +impl DefaultConstructor for PyByteArray {} impl Initializer for PyByteArray { type Args = ByteInnerNewOptions; @@ -891,7 +883,7 @@ impl PyPayload for PyByteArrayIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyByteArrayIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { diff --git a/vm/src/builtins/bytes.rs b/vm/src/builtins/bytes.rs index 351eb7ba8a3..1db64178368 100644 --- a/vm/src/builtins/bytes.rs +++ b/vm/src/builtins/bytes.rs @@ -688,7 +688,7 @@ impl PyPayload for PyBytesIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyBytesIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { diff --git a/vm/src/builtins/coroutine.rs b/vm/src/builtins/coroutine.rs index 2454e27e2c2..ce6b160fd17 100644 --- a/vm/src/builtins/coroutine.rs +++ b/vm/src/builtins/coroutine.rs @@ -5,7 +5,7 @@ use crate::{ frame::FrameRef, function::OptionalArg, protocol::PyIterReturn, - types::{Constructor, IterNext, Iterable, Representable, SelfIter, Unconstructible}, + types::{IterNext, Iterable, Representable, SelfIter, Unconstructible}, AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; @@ -22,7 +22,7 @@ impl PyPayload for PyCoroutine { } } -#[pyclass(with(Constructor, IterNext, Representable))] +#[pyclass(with(Unconstructible, IterNext, Representable))] impl PyCoroutine { pub fn as_coro(&self) -> &Coro { &self.inner diff --git a/vm/src/builtins/descriptor.rs b/vm/src/builtins/descriptor.rs index ffce4db5e7e..6f0705e8ecc 100644 --- a/vm/src/builtins/descriptor.rs +++ b/vm/src/builtins/descriptor.rs @@ -3,7 +3,7 @@ use crate::{ builtins::{builtin_func::PyNativeMethod, type_}, class::PyClassImpl, function::{FuncArgs, PyMethodDef, PyMethodFlags, PySetterValue}, - types::{Callable, Constructor, GetDescriptor, Representable, Unconstructible}, + types::{Callable, GetDescriptor, Representable, Unconstructible}, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; use rustpython_common::lock::PyRwLock; @@ -103,7 +103,7 @@ impl PyMethodDescriptor { } #[pyclass( - with(GetDescriptor, Callable, Constructor, Representable), + with(GetDescriptor, Callable, Unconstructible, Representable), flags(METHOD_DESCRIPTOR) )] impl PyMethodDescriptor { @@ -237,7 +237,7 @@ fn calculate_qualname(descr: &PyDescriptorOwned, vm: &VirtualMachine) -> PyResul } } -#[pyclass(with(GetDescriptor, Constructor, Representable), flags(BASETYPE))] +#[pyclass(with(GetDescriptor, Unconstructible, Representable), flags(BASETYPE))] impl PyMemberDescriptor { #[pygetset(magic)] fn doc(&self) -> Option { diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index f5a1abdee22..39ae0710454 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -12,15 +12,13 @@ use crate::{ class::{PyClassDef, PyClassImpl}, common::ascii, dictdatatype::{self, DictKey}, - function::{ - ArgIterable, FuncArgs, KwArgs, OptionalArg, PyArithmeticValue::*, PyComparisonValue, - }, + function::{ArgIterable, KwArgs, OptionalArg, PyArithmeticValue::*, PyComparisonValue}, iter::PyExactSizeIterator, protocol::{PyIterIter, PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods}, recursion::ReprGuard, types::{ - AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, Initializer, IterNext, - Iterable, PyComparisonOp, Representable, SelfIter, Unconstructible, + AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, DefaultConstructor, + Initializer, IterNext, Iterable, PyComparisonOp, Representable, SelfIter, Unconstructible, }, vm::VirtualMachine, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, @@ -410,15 +408,7 @@ impl PyRef { } } -impl Constructor for PyDict { - type Args = FuncArgs; - - fn py_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { - PyDict::default() - .into_ref_with_type(vm, cls) - .map(Into::into) - } -} +impl DefaultConstructor for PyDict {} impl Initializer for PyDict { type Args = (OptionalArg, KwArgs); @@ -835,7 +825,7 @@ macro_rules! dict_view { } } - #[pyclass(with(Constructor, IterNext, Iterable))] + #[pyclass(with(Unconstructible, IterNext, Iterable))] impl $iter_name { fn new(dict: PyDictRef) -> Self { $iter_name { @@ -908,7 +898,7 @@ macro_rules! dict_view { } } - #[pyclass(with(Constructor, IterNext, Iterable))] + #[pyclass(with(Unconstructible, IterNext, Iterable))] impl $reverse_iter_name { fn new(dict: PyDictRef) -> Self { let size = dict.size(); @@ -1114,7 +1104,7 @@ trait ViewSetOps: DictView { impl ViewSetOps for PyDictKeys {} #[pyclass(with( DictView, - Constructor, + Unconstructible, Comparable, Iterable, ViewSetOps, @@ -1178,7 +1168,7 @@ impl AsNumber for PyDictKeys { impl ViewSetOps for PyDictItems {} #[pyclass(with( DictView, - Constructor, + Unconstructible, Comparable, Iterable, ViewSetOps, @@ -1253,7 +1243,7 @@ impl AsNumber for PyDictItems { } } -#[pyclass(with(DictView, Constructor, Iterable, AsSequence, Representable))] +#[pyclass(with(DictView, Unconstructible, Iterable, AsSequence, Representable))] impl PyDictValues { #[pygetset] fn mapping(zelf: PyRef) -> PyMappingProxy { diff --git a/vm/src/builtins/frame.rs b/vm/src/builtins/frame.rs index d93799db92f..3cc7d788fb4 100644 --- a/vm/src/builtins/frame.rs +++ b/vm/src/builtins/frame.rs @@ -7,7 +7,7 @@ use crate::{ class::PyClassImpl, frame::{Frame, FrameRef}, function::PySetterValue, - types::{Constructor, Representable, Unconstructible}, + types::{Representable, Unconstructible}, AsObject, Context, Py, PyObjectRef, PyRef, PyResult, VirtualMachine, }; use num_traits::Zero; @@ -31,7 +31,7 @@ impl Representable for Frame { } } -#[pyclass(with(Constructor, Py))] +#[pyclass(with(Unconstructible, Py))] impl Frame { #[pymethod] fn clear(&self) { diff --git a/vm/src/builtins/generator.rs b/vm/src/builtins/generator.rs index eceac5ba935..e0ec77006d1 100644 --- a/vm/src/builtins/generator.rs +++ b/vm/src/builtins/generator.rs @@ -9,7 +9,7 @@ use crate::{ frame::FrameRef, function::OptionalArg, protocol::PyIterReturn, - types::{Constructor, IterNext, Iterable, Representable, SelfIter, Unconstructible}, + types::{IterNext, Iterable, Representable, SelfIter, Unconstructible}, AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; @@ -25,7 +25,7 @@ impl PyPayload for PyGenerator { } } -#[pyclass(with(Py, Constructor, IterNext, Iterable))] +#[pyclass(with(Py, Unconstructible, IterNext, Iterable))] impl PyGenerator { pub fn as_coro(&self) -> &Coro { &self.inner diff --git a/vm/src/builtins/getset.rs b/vm/src/builtins/getset.rs index 2516fcd5660..2fa1e414838 100644 --- a/vm/src/builtins/getset.rs +++ b/vm/src/builtins/getset.rs @@ -5,7 +5,7 @@ use super::PyType; use crate::{ class::PyClassImpl, function::{IntoPyGetterFunc, IntoPySetterFunc, PyGetterFunc, PySetterFunc, PySetterValue}, - types::{Constructor, GetDescriptor, Unconstructible}, + types::{GetDescriptor, Unconstructible}, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyResult, VirtualMachine, }; @@ -94,7 +94,7 @@ impl PyGetSet { } } -#[pyclass(with(GetDescriptor, Constructor))] +#[pyclass(with(GetDescriptor, Unconstructible))] impl PyGetSet { // Descriptor methods diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index 29be635de22..e9de8e5f041 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -538,7 +538,7 @@ impl PyPayload for PyListIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyListIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { @@ -583,7 +583,7 @@ impl PyPayload for PyListReverseIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyListReverseIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { diff --git a/vm/src/builtins/memory.rs b/vm/src/builtins/memory.rs index aca2114bf02..dfbbdc5aaf5 100644 --- a/vm/src/builtins/memory.rs +++ b/vm/src/builtins/memory.rs @@ -1137,7 +1137,7 @@ impl PyPayload for PyMemoryViewIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyMemoryViewIterator { #[pymethod(magic)] fn reduce(&self, vm: &VirtualMachine) -> PyTupleRef { diff --git a/vm/src/builtins/namespace.rs b/vm/src/builtins/namespace.rs index 4a08dddc9ad..441fd014f03 100644 --- a/vm/src/builtins/namespace.rs +++ b/vm/src/builtins/namespace.rs @@ -1,10 +1,12 @@ -use super::{tuple::IntoPyTuple, PyTupleRef, PyType, PyTypeRef}; +use super::{tuple::IntoPyTuple, PyTupleRef, PyType}; use crate::{ builtins::PyDict, class::PyClassImpl, function::{FuncArgs, PyComparisonValue}, recursion::ReprGuard, - types::{Comparable, Constructor, Initializer, PyComparisonOp, Representable}, + types::{ + Comparable, Constructor, DefaultConstructor, Initializer, PyComparisonOp, Representable, + }, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, }; @@ -12,7 +14,7 @@ use crate::{ /// /// SimpleNamespace(**kwargs) #[pyclass(module = "types", name = "SimpleNamespace")] -#[derive(Debug)] +#[derive(Debug, Default)] pub struct PyNamespace {} impl PyPayload for PyNamespace { @@ -21,13 +23,7 @@ impl PyPayload for PyNamespace { } } -impl Constructor for PyNamespace { - type Args = FuncArgs; - - fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult { - PyNamespace {}.into_ref_with_type(vm, cls).map(Into::into) - } -} +impl DefaultConstructor for PyNamespace {} impl PyNamespace { pub fn new_ref(ctx: &Context) -> PyRef { diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index 348924a7a97..23a3a7e81c8 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -8,8 +8,8 @@ use crate::{ function::{ArgIndex, FuncArgs, OptionalArg, PyComparisonValue}, protocol::{PyIterReturn, PyMappingMethods, PySequenceMethods}, types::{ - AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, Iterable, - PyComparisonOp, Representable, SelfIter, Unconstructible, + AsMapping, AsSequence, Comparable, Hashable, IterNext, Iterable, PyComparisonOp, + Representable, SelfIter, Unconstructible, }, AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, @@ -537,7 +537,7 @@ impl PyPayload for PyLongRangeIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyLongRangeIterator { #[pymethod(magic)] fn length_hint(&self) -> BigInt { @@ -602,7 +602,7 @@ impl PyPayload for PyRangeIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyRangeIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index 9672b467ec4..65f4338bc60 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -11,13 +11,13 @@ use crate::{ common::{ascii, hash::PyHash, lock::PyMutex, rc::PyRc}, convert::ToPyResult, dictdatatype::{self, DictSize}, - function::{ArgIterable, FuncArgs, OptionalArg, PosArgs, PyArithmeticValue, PyComparisonValue}, + function::{ArgIterable, OptionalArg, PosArgs, PyArithmeticValue, PyComparisonValue}, protocol::{PyIterReturn, PyNumberMethods, PySequenceMethods}, recursion::ReprGuard, types::AsNumber, types::{ - AsSequence, Comparable, Constructor, Hashable, Initializer, IterNext, Iterable, - PyComparisonOp, Representable, SelfIter, Unconstructible, + AsSequence, Comparable, Constructor, DefaultConstructor, Hashable, Initializer, IterNext, + Iterable, PyComparisonOp, Representable, SelfIter, Unconstructible, }, utils::collection_repr, vm::VirtualMachine, @@ -765,13 +765,7 @@ impl PySet { } } -impl Constructor for PySet { - type Args = FuncArgs; - - fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult { - PySet::default().into_ref_with_type(vm, cls).map(Into::into) - } -} +impl DefaultConstructor for PySet {} impl Initializer for PySet { type Args = OptionalArg; @@ -1253,7 +1247,7 @@ impl PyPayload for PySetIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PySetIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { diff --git a/vm/src/builtins/str.rs b/vm/src/builtins/str.rs index 03207aa53ed..9cc3397cade 100644 --- a/vm/src/builtins/str.rs +++ b/vm/src/builtins/str.rs @@ -204,7 +204,7 @@ impl PyPayload for PyStrIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyStrIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { diff --git a/vm/src/builtins/tuple.rs b/vm/src/builtins/tuple.rs index cf267a63b87..e9e85d1fe89 100644 --- a/vm/src/builtins/tuple.rs +++ b/vm/src/builtins/tuple.rs @@ -434,7 +434,7 @@ impl PyPayload for PyTupleIterator { } } -#[pyclass(with(Constructor, IterNext, Iterable))] +#[pyclass(with(Unconstructible, IterNext, Iterable))] impl PyTupleIterator { #[pymethod(magic)] fn length_hint(&self) -> usize { diff --git a/vm/src/class.rs b/vm/src/class.rs index d6893bf1522..3b7f1bffcb9 100644 --- a/vm/src/class.rs +++ b/vm/src/class.rs @@ -70,7 +70,10 @@ pub trait PyClassDef { pub trait PyClassImpl: PyClassDef { const TP_FLAGS: PyTypeFlags = PyTypeFlags::DEFAULT; - fn extend_class(ctx: &Context, class: &'static Py) { + fn extend_class(ctx: &Context, class: &'static Py) + where + Self: Sized, + { #[cfg(debug_assertions)] { assert!(class.slots.flags.is_created_with_flags()); @@ -120,7 +123,7 @@ pub trait PyClassImpl: PyClassDef { fn make_class(ctx: &Context) -> PyTypeRef where - Self: StaticType, + Self: StaticType + Sized, { (*Self::static_cell().get_or_init(|| { let typ = Self::create_static_type(); diff --git a/vm/src/protocol/buffer.rs b/vm/src/protocol/buffer.rs index 820a7c7124e..3783ccf4b6a 100644 --- a/vm/src/protocol/buffer.rs +++ b/vm/src/protocol/buffer.rs @@ -8,7 +8,7 @@ use crate::{ }, object::PyObjectPayload, sliceable::SequenceIndexOp, - types::{Constructor, Unconstructible}, + types::Unconstructible, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromBorrowedObject, VirtualMachine, }; use itertools::Itertools; @@ -404,7 +404,7 @@ pub struct VecBuffer { data: PyMutex>, } -#[pyclass(flags(BASETYPE), with(Constructor))] +#[pyclass(flags(BASETYPE), with(Unconstructible))] impl VecBuffer { pub fn take(&self) -> Vec { std::mem::take(&mut self.data.lock()) diff --git a/vm/src/stdlib/collections.rs b/vm/src/stdlib/collections.rs index e416792d05e..00eaaca0209 100644 --- a/vm/src/stdlib/collections.rs +++ b/vm/src/stdlib/collections.rs @@ -9,15 +9,15 @@ mod _collections { PositionIterInternal, PyGenericAlias, PyInt, PyTypeRef, }, common::lock::{PyMutex, PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard}, - function::{FuncArgs, KwArgs, OptionalArg, PyComparisonValue}, + function::{KwArgs, OptionalArg, PyComparisonValue}, iter::PyExactSizeIterator, protocol::{PyIterReturn, PySequenceMethods}, recursion::ReprGuard, sequence::{MutObjectSequenceOp, OptionalRangeArgs}, sliceable::SequenceIndexOp, types::{ - AsSequence, Comparable, Constructor, Initializer, IterNext, Iterable, PyComparisonOp, - Representable, SelfIter, + AsSequence, Comparable, Constructor, DefaultConstructor, Initializer, IterNext, + Iterable, PyComparisonOp, Representable, SelfIter, }, utils::collection_repr, AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine, @@ -427,15 +427,7 @@ mod _collections { } } - impl Constructor for PyDeque { - type Args = FuncArgs; - - fn py_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { - PyDeque::default() - .into_ref_with_type(vm, cls) - .map(Into::into) - } - } + impl DefaultConstructor for PyDeque {} impl Initializer for PyDeque { type Args = PyDequeOptions; diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index 11d2ab8a5bb..2478566e691 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -1694,7 +1694,7 @@ mod _io { } #[pyclass( - with(DefaultConstructor, BufferedMixin, BufferedReadable), + with(Constructor, BufferedMixin, BufferedReadable), flags(BASETYPE, HAS_DICT) )] impl BufferedReader {} @@ -1744,7 +1744,7 @@ mod _io { } #[pyclass( - with(DefaultConstructor, BufferedMixin, BufferedWritable), + with(Constructor, BufferedMixin, BufferedWritable), flags(BASETYPE, HAS_DICT) )] impl BufferedWriter {} @@ -1780,7 +1780,7 @@ mod _io { } #[pyclass( - with(DefaultConstructor, BufferedMixin, BufferedReadable, BufferedWritable), + with(Constructor, BufferedMixin, BufferedReadable, BufferedWritable), flags(BASETYPE, HAS_DICT) )] impl BufferedRandom {} @@ -1824,7 +1824,7 @@ mod _io { } #[pyclass( - with(DefaultConstructor, Initializer, BufferedReadable, BufferedWritable), + with(Constructor, Initializer, BufferedReadable, BufferedWritable), flags(BASETYPE, HAS_DICT) )] impl BufferedRWPair { @@ -2292,7 +2292,7 @@ mod _io { } } - #[pyclass(with(DefaultConstructor, Initializer), flags(BASETYPE))] + #[pyclass(with(Constructor, Initializer), flags(BASETYPE))] impl TextIOWrapper { #[pymethod] fn seekable(&self, vm: &VirtualMachine) -> PyResult { @@ -3724,7 +3724,7 @@ mod fileio { function::{ArgBytesLike, ArgMemoryBuffer, OptionalArg, OptionalOption}, ospath::{IOErrorBuilder, OsPath, OsPathOrFd}, stdlib::os, - types::{DefaultConstructor, Initializer, Representable}, + types::{Constructor, DefaultConstructor, Initializer, Representable}, AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine, }; use crossbeam_utils::atomic::AtomicCell; @@ -3987,7 +3987,7 @@ mod fileio { } #[pyclass( - with(DefaultConstructor, Initializer, Representable), + with(Constructor, Initializer, Representable), flags(BASETYPE, HAS_DICT) )] impl FileIO { diff --git a/vm/src/types/slot.rs b/vm/src/types/slot.rs index 04047eafd06..58b5a013459 100644 --- a/vm/src/types/slot.rs +++ b/vm/src/types/slot.rs @@ -767,24 +767,27 @@ pub trait Constructor: PyPayload { fn py_new(cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult; } +pub trait DefaultConstructor: PyPayload + Default {} + +/// For types that cannot be instantiated through Python code. #[pyclass] -pub trait DefaultConstructor: PyPayload + Default { - #[inline] +pub trait Unconstructible: PyPayload { #[pyslot] fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { - Self::default().into_ref_with_type(vm, cls).map(Into::into) + Err(vm.new_type_error(format!("cannot create {} instances", cls.slot_name()))) } } -/// For types that cannot be instantiated through Python code. -pub trait Unconstructible: PyPayload {} - impl Constructor for T where - T: Unconstructible, + T: DefaultConstructor, { type Args = FuncArgs; + fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult { + Self::default().into_ref_with_type(vm, cls).map(Into::into) + } + fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult { Err(vm.new_type_error(format!("cannot create {} instances", cls.slot_name()))) }