Skip to content

Commit 268164e

Browse files
committed
Fix property to take keyword arguments
1 parent eab5d42 commit 268164e

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

tests/snippets/property.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def foo(self):
5959
with assertRaises(TypeError):
6060
property.__new__(object)
6161

62+
# assert p.__doc__ is None
63+
6264

6365
p1 = property("a", "b", "c")
6466

@@ -75,3 +77,7 @@ def foo(self):
7577
assert p1.deleter(None).fdel == "c"
7678

7779
assert p1.__get__(None, object) is p1
80+
# assert p1.__doc__ is 'a'.__doc__
81+
82+
p2 = property('a', doc='pdoc')
83+
# assert p2.__doc__ == 'pdoc'

vm/src/obj/objproperty.rs

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
33
*/
44

5-
use crate::function::IntoPyNativeFunc;
6-
use crate::function::OptionalArg;
7-
use crate::obj::objstr::PyStringRef;
5+
use crate::function::{IntoPyNativeFunc, OptionalArg, PyFuncArgs};
86
use crate::obj::objtype::PyClassRef;
97
use crate::pyobject::{
108
IdProtocol, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
@@ -82,6 +80,7 @@ pub struct PyProperty {
8280
getter: Option<PyObjectRef>,
8381
setter: Option<PyObjectRef>,
8482
deleter: Option<PyObjectRef>,
83+
doc: Option<PyObjectRef>,
8584
}
8685

8786
impl PyValue for PyProperty {
@@ -97,16 +96,31 @@ impl PyProperty {
9796
#[pymethod(name = "__new__")]
9897
fn new_property(
9998
cls: PyClassRef,
100-
fget: OptionalArg<PyObjectRef>,
101-
fset: OptionalArg<PyObjectRef>,
102-
fdel: OptionalArg<PyObjectRef>,
103-
_doc: OptionalArg<PyStringRef>,
99+
args: PyFuncArgs,
104100
vm: &VirtualMachine,
105101
) -> PyResult<PyPropertyRef> {
102+
arg_check!(
103+
vm,
104+
args,
105+
required = [],
106+
optional = [(fget, None), (fset, None), (fdel, None), (doc, None)]
107+
);
108+
109+
fn into_option(vm: &VirtualMachine, arg: Option<&PyObjectRef>) -> Option<PyObjectRef> {
110+
arg.and_then(|arg| {
111+
if vm.ctx.none().is(arg) {
112+
None
113+
} else {
114+
Some(arg.clone())
115+
}
116+
})
117+
}
118+
106119
PyProperty {
107-
getter: fget.into_option(),
108-
setter: fset.into_option(),
109-
deleter: fdel.into_option(),
120+
getter: into_option(vm, fget),
121+
setter: into_option(vm, fset),
122+
deleter: into_option(vm, fdel),
123+
doc: into_option(vm, doc),
110124
}
111125
.into_ref_with_type(vm, cls)
112126
}
@@ -187,6 +201,7 @@ impl PyProperty {
187201
getter: getter.or_else(|| zelf.getter.clone()),
188202
setter: zelf.setter.clone(),
189203
deleter: zelf.deleter.clone(),
204+
doc: None,
190205
}
191206
.into_ref_with_type(vm, TypeProtocol::class(&zelf))
192207
}
@@ -201,6 +216,7 @@ impl PyProperty {
201216
getter: zelf.getter.clone(),
202217
setter: setter.or_else(|| zelf.setter.clone()),
203218
deleter: zelf.deleter.clone(),
219+
doc: None,
204220
}
205221
.into_ref_with_type(vm, TypeProtocol::class(&zelf))
206222
}
@@ -215,6 +231,7 @@ impl PyProperty {
215231
getter: zelf.getter.clone(),
216232
setter: zelf.setter.clone(),
217233
deleter: deleter.or_else(|| zelf.deleter.clone()),
234+
doc: None,
218235
}
219236
.into_ref_with_type(vm, TypeProtocol::class(&zelf))
220237
}
@@ -259,6 +276,7 @@ impl<'a> PropertyBuilder<'a> {
259276
getter: self.getter.clone(),
260277
setter: self.setter.clone(),
261278
deleter: None,
279+
doc: None,
262280
};
263281

264282
PyObject::new(payload, self.ctx.property_type(), None)

0 commit comments

Comments
 (0)