Skip to content

Commit 52aad1e

Browse files
committed
DefaultConstructor impls Constructor; Unconstructible is not anymore
1 parent 5f0d125 commit 52aad1e

File tree

24 files changed

+115
-129
lines changed

24 files changed

+115
-129
lines changed

derive-impl/src/pyclass.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1453,29 +1453,37 @@ fn extract_impl_attrs(attr: AttributeArgs, item: &Ident) -> Result<ExtractedImpl
14531453
}];
14541454
let mut payload = None;
14551455

1456+
let mut has_constructor = false;
14561457
for attr in attr {
14571458
match attr {
14581459
NestedMeta::Meta(Meta::List(syn::MetaList { path, nested, .. })) => {
14591460
if path.is_ident("with") {
14601461
for meta in nested {
1461-
let NestedMeta::Meta(Meta::Path(path)) = meta else {
1462-
bail_span!(meta, "#[pyclass(with(...))] arguments should be paths")
1462+
let NestedMeta::Meta(Meta::Path(path)) = &meta else {
1463+
bail_span!(meta, "#[pyclass(with(...))] arguments must be paths")
1464+
};
1465+
let (extend_class, method_defs, extend_slots) = if path.is_ident("PyRef")
1466+
|| path.is_ident("Py")
1467+
{
1468+
// special handling for PyRef
1469+
(
1470+
quote!(#path::<Self>::__extend_py_class),
1471+
quote!(#path::<Self>::__OWN_METHOD_DEFS),
1472+
quote!(#path::<Self>::__extend_slots),
1473+
)
1474+
} else {
1475+
if path.is_ident("DefaultConstructor") {
1476+
bail_span!(meta, "Try `#[pyclass(with(Constructor, ...))]` instead of `#[pyclass(with(DefaultConstructor, ...))]`. DefaultConstructor implicitly implements Constructor.")
1477+
}
1478+
if path.is_ident("Constructor") || path.is_ident("Unconstructible") {
1479+
has_constructor = true;
1480+
}
1481+
(
1482+
quote!(<Self as #path>::__extend_py_class),
1483+
quote!(<Self as #path>::__OWN_METHOD_DEFS),
1484+
quote!(<Self as #path>::__extend_slots),
1485+
)
14631486
};
1464-
let (extend_class, method_defs, extend_slots) =
1465-
if path.is_ident("PyRef") || path.is_ident("Py") {
1466-
// special handling for PyRef
1467-
(
1468-
quote!(#path::<Self>::__extend_py_class),
1469-
quote!(#path::<Self>::__OWN_METHOD_DEFS),
1470-
quote!(#path::<Self>::__extend_slots),
1471-
)
1472-
} else {
1473-
(
1474-
quote!(<Self as #path>::__extend_py_class),
1475-
quote!(<Self as #path>::__OWN_METHOD_DEFS),
1476-
quote!(<Self as #path>::__extend_slots),
1477-
)
1478-
};
14791487
let item_span = item.span().resolved_at(Span::call_site());
14801488
withs.push(quote_spanned! { path.span() =>
14811489
#extend_class(ctx, class);
@@ -1518,6 +1526,11 @@ fn extract_impl_attrs(attr: AttributeArgs, item: &Ident) -> Result<ExtractedImpl
15181526
attr => bail_span!(attr, "Unknown pyimpl attribute"),
15191527
}
15201528
}
1529+
// TODO: DISALLOW_INSTANTIATION check is required
1530+
let _ = has_constructor;
1531+
// if !withs.is_empty() && !has_constructor {
1532+
// 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 {{}}`.")
1533+
// }
15211534

15221535
Ok(ExtractedImplAttrs {
15231536
payload,

stdlib/src/socket.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ mod _socket {
1616
common::os::ErrorExt,
1717
convert::{IntoPyException, ToPyObject, TryFromBorrowedObject, TryFromObject},
1818
function::{ArgBytesLike, ArgMemoryBuffer, Either, FsPath, OptionalArg, OptionalOption},
19-
types::{DefaultConstructor, Initializer, Representable},
19+
types::{Constructor, DefaultConstructor, Initializer, Representable},
2020
utils::ToCString,
2121
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
2222
};
@@ -1062,7 +1062,7 @@ mod _socket {
10621062
}
10631063
}
10641064

1065-
#[pyclass(with(DefaultConstructor, Initializer, Representable), flags(BASETYPE))]
1065+
#[pyclass(with(Constructor, Initializer, Representable), flags(BASETYPE))]
10661066
impl PySocket {
10671067
fn _init(
10681068
zelf: PyRef<Self>,

vm/src/builtins/asyncgenerator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
frame::FrameRef,
77
function::OptionalArg,
88
protocol::PyIterReturn,
9-
types::{Constructor, IterNext, Iterable, Representable, SelfIter, Unconstructible},
9+
types::{IterNext, Iterable, Representable, SelfIter, Unconstructible},
1010
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
1111
};
1212

@@ -26,7 +26,7 @@ impl PyPayload for PyAsyncGen {
2626
}
2727
}
2828

29-
#[pyclass(with(PyRef, Constructor, Representable))]
29+
#[pyclass(with(PyRef, Unconstructible, Representable))]
3030
impl PyAsyncGen {
3131
pub fn as_coro(&self) -> &Coro {
3232
&self.inner

vm/src/builtins/builtin_func.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
class::PyClassImpl,
44
convert::TryFromObject,
55
function::{FuncArgs, PyComparisonValue, PyMethodDef, PyMethodFlags, PyNativeFn},
6-
types::{Callable, Comparable, Constructor, PyComparisonOp, Representable, Unconstructible},
6+
types::{Callable, Comparable, PyComparisonOp, Representable, Unconstructible},
77
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
88
};
99
use std::fmt;
@@ -65,7 +65,7 @@ impl Callable for PyNativeFunction {
6565
}
6666
}
6767

68-
#[pyclass(with(Callable, Constructor), flags(HAS_DICT))]
68+
#[pyclass(with(Callable, Unconstructible), flags(HAS_DICT))]
6969
impl PyNativeFunction {
7070
#[pygetset(magic)]
7171
fn module(zelf: NativeFunctionOrMethod) -> Option<&'static PyStrInterned> {
@@ -138,7 +138,10 @@ pub struct PyNativeMethod {
138138
pub(crate) class: &'static Py<PyType>, // TODO: the actual life is &'self
139139
}
140140

141-
#[pyclass(with(Callable, Comparable, Representable), flags(HAS_DICT))]
141+
#[pyclass(
142+
with(Unconstructible, Callable, Comparable, Representable),
143+
flags(HAS_DICT)
144+
)]
142145
impl PyNativeMethod {
143146
#[pygetset(magic)]
144147
fn qualname(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<PyStrRef> {

vm/src/builtins/bytearray.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ use crate::{
2121
},
2222
convert::{ToPyObject, ToPyResult},
2323
function::{
24-
ArgBytesLike, ArgIterable, ArgSize, Either, FuncArgs, OptionalArg, OptionalOption,
25-
PyComparisonValue,
24+
ArgBytesLike, ArgIterable, ArgSize, Either, OptionalArg, OptionalOption, PyComparisonValue,
2625
},
2726
protocol::{
2827
BufferDescriptor, BufferMethods, BufferResizeGuard, PyBuffer, PyIterReturn,
2928
PyMappingMethods, PyNumberMethods, PySequenceMethods,
3029
},
3130
sliceable::{SequenceIndex, SliceableSequenceMutOp, SliceableSequenceOp},
3231
types::{
33-
AsBuffer, AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, Initializer,
34-
IterNext, Iterable, PyComparisonOp, Representable, SelfIter, Unconstructible,
32+
AsBuffer, AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor,
33+
DefaultConstructor, Initializer, IterNext, Iterable, PyComparisonOp, Representable,
34+
SelfIter, Unconstructible,
3535
},
3636
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject,
3737
VirtualMachine,
@@ -696,15 +696,7 @@ impl PyRef<PyByteArray> {
696696
}
697697
}
698698

699-
impl Constructor for PyByteArray {
700-
type Args = FuncArgs;
701-
702-
fn py_new(cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult {
703-
PyByteArray::default()
704-
.into_ref_with_type(vm, cls)
705-
.map(Into::into)
706-
}
707-
}
699+
impl DefaultConstructor for PyByteArray {}
708700

709701
impl Initializer for PyByteArray {
710702
type Args = ByteInnerNewOptions;
@@ -891,7 +883,7 @@ impl PyPayload for PyByteArrayIterator {
891883
}
892884
}
893885

894-
#[pyclass(with(Constructor, IterNext, Iterable))]
886+
#[pyclass(with(Unconstructible, IterNext, Iterable))]
895887
impl PyByteArrayIterator {
896888
#[pymethod(magic)]
897889
fn length_hint(&self) -> usize {

vm/src/builtins/bytes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ impl PyPayload for PyBytesIterator {
688688
}
689689
}
690690

691-
#[pyclass(with(Constructor, IterNext, Iterable))]
691+
#[pyclass(with(Unconstructible, IterNext, Iterable))]
692692
impl PyBytesIterator {
693693
#[pymethod(magic)]
694694
fn length_hint(&self) -> usize {

vm/src/builtins/coroutine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::{
55
frame::FrameRef,
66
function::OptionalArg,
77
protocol::PyIterReturn,
8-
types::{Constructor, IterNext, Iterable, Representable, SelfIter, Unconstructible},
8+
types::{IterNext, Iterable, Representable, SelfIter, Unconstructible},
99
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
1010
};
1111

@@ -22,7 +22,7 @@ impl PyPayload for PyCoroutine {
2222
}
2323
}
2424

25-
#[pyclass(with(Constructor, IterNext, Representable))]
25+
#[pyclass(with(Unconstructible, IterNext, Representable))]
2626
impl PyCoroutine {
2727
pub fn as_coro(&self) -> &Coro {
2828
&self.inner

vm/src/builtins/descriptor.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::{
33
builtins::{builtin_func::PyNativeMethod, type_},
44
class::PyClassImpl,
55
function::{FuncArgs, PyMethodDef, PyMethodFlags, PySetterValue},
6-
types::{Callable, Constructor, GetDescriptor, Representable, Unconstructible},
6+
types::{Callable, GetDescriptor, Representable, Unconstructible},
77
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
88
};
99
use rustpython_common::lock::PyRwLock;
@@ -103,7 +103,7 @@ impl PyMethodDescriptor {
103103
}
104104

105105
#[pyclass(
106-
with(GetDescriptor, Callable, Constructor, Representable),
106+
with(GetDescriptor, Callable, Unconstructible, Representable),
107107
flags(METHOD_DESCRIPTOR)
108108
)]
109109
impl PyMethodDescriptor {
@@ -237,7 +237,7 @@ fn calculate_qualname(descr: &PyDescriptorOwned, vm: &VirtualMachine) -> PyResul
237237
}
238238
}
239239

240-
#[pyclass(with(GetDescriptor, Constructor, Representable), flags(BASETYPE))]
240+
#[pyclass(with(GetDescriptor, Unconstructible, Representable), flags(BASETYPE))]
241241
impl PyMemberDescriptor {
242242
#[pygetset(magic)]
243243
fn doc(&self) -> Option<String> {

vm/src/builtins/dict.rs

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@ use crate::{
1212
class::{PyClassDef, PyClassImpl},
1313
common::ascii,
1414
dictdatatype::{self, DictKey},
15-
function::{
16-
ArgIterable, FuncArgs, KwArgs, OptionalArg, PyArithmeticValue::*, PyComparisonValue,
17-
},
15+
function::{ArgIterable, KwArgs, OptionalArg, PyArithmeticValue::*, PyComparisonValue},
1816
iter::PyExactSizeIterator,
1917
protocol::{PyIterIter, PyIterReturn, PyMappingMethods, PyNumberMethods, PySequenceMethods},
2018
recursion::ReprGuard,
2119
types::{
22-
AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, Initializer, IterNext,
23-
Iterable, PyComparisonOp, Representable, SelfIter, Unconstructible,
20+
AsMapping, AsNumber, AsSequence, Callable, Comparable, Constructor, DefaultConstructor,
21+
Initializer, IterNext, Iterable, PyComparisonOp, Representable, SelfIter, Unconstructible,
2422
},
2523
vm::VirtualMachine,
2624
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
@@ -410,15 +408,7 @@ impl PyRef<PyDict> {
410408
}
411409
}
412410

413-
impl Constructor for PyDict {
414-
type Args = FuncArgs;
415-
416-
fn py_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
417-
PyDict::default()
418-
.into_ref_with_type(vm, cls)
419-
.map(Into::into)
420-
}
421-
}
411+
impl DefaultConstructor for PyDict {}
422412

423413
impl Initializer for PyDict {
424414
type Args = (OptionalArg<PyObjectRef>, KwArgs);
@@ -835,7 +825,7 @@ macro_rules! dict_view {
835825
}
836826
}
837827

838-
#[pyclass(with(Constructor, IterNext, Iterable))]
828+
#[pyclass(with(Unconstructible, IterNext, Iterable))]
839829
impl $iter_name {
840830
fn new(dict: PyDictRef) -> Self {
841831
$iter_name {
@@ -908,7 +898,7 @@ macro_rules! dict_view {
908898
}
909899
}
910900

911-
#[pyclass(with(Constructor, IterNext, Iterable))]
901+
#[pyclass(with(Unconstructible, IterNext, Iterable))]
912902
impl $reverse_iter_name {
913903
fn new(dict: PyDictRef) -> Self {
914904
let size = dict.size();
@@ -1114,7 +1104,7 @@ trait ViewSetOps: DictView {
11141104
impl ViewSetOps for PyDictKeys {}
11151105
#[pyclass(with(
11161106
DictView,
1117-
Constructor,
1107+
Unconstructible,
11181108
Comparable,
11191109
Iterable,
11201110
ViewSetOps,
@@ -1178,7 +1168,7 @@ impl AsNumber for PyDictKeys {
11781168
impl ViewSetOps for PyDictItems {}
11791169
#[pyclass(with(
11801170
DictView,
1181-
Constructor,
1171+
Unconstructible,
11821172
Comparable,
11831173
Iterable,
11841174
ViewSetOps,
@@ -1253,7 +1243,7 @@ impl AsNumber for PyDictItems {
12531243
}
12541244
}
12551245

1256-
#[pyclass(with(DictView, Constructor, Iterable, AsSequence, Representable))]
1246+
#[pyclass(with(DictView, Unconstructible, Iterable, AsSequence, Representable))]
12571247
impl PyDictValues {
12581248
#[pygetset]
12591249
fn mapping(zelf: PyRef<Self>) -> PyMappingProxy {

vm/src/builtins/frame.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::{
77
class::PyClassImpl,
88
frame::{Frame, FrameRef},
99
function::PySetterValue,
10-
types::{Constructor, Representable, Unconstructible},
10+
types::{Representable, Unconstructible},
1111
AsObject, Context, Py, PyObjectRef, PyRef, PyResult, VirtualMachine,
1212
};
1313
use num_traits::Zero;
@@ -31,7 +31,7 @@ impl Representable for Frame {
3131
}
3232
}
3333

34-
#[pyclass(with(Constructor, Py))]
34+
#[pyclass(with(Unconstructible, Py))]
3535
impl Frame {
3636
#[pymethod]
3737
fn clear(&self) {

0 commit comments

Comments
 (0)