Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 13f0940

Browse files
committed
refactor getter/setter/deleter
1 parent fbc87f4 commit 13f0940

File tree

1 file changed

+25
-62
lines changed

1 file changed

+25
-62
lines changed

vm/src/builtins/property.rs

Lines changed: 25 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -166,29 +166,33 @@ impl PyProperty {
166166

167167
// Python builder functions
168168

169-
#[pymethod]
170-
fn getter(
169+
// Helper method to create a new property with updated attributes
170+
fn clone_property_with(
171171
zelf: PyRef<Self>,
172-
getter: Option<PyObjectRef>,
172+
new_getter: Option<PyObjectRef>,
173+
new_setter: Option<PyObjectRef>,
174+
new_deleter: Option<PyObjectRef>,
173175
vm: &VirtualMachine,
174176
) -> PyResult<PyRef<Self>> {
175-
let new_getter = getter.or_else(|| zelf.fget());
176-
177-
// Determine doc based on getter_doc flag
177+
// Determine doc based on getter_doc flag and whether we're updating the getter
178178
let doc = if zelf.getter_doc.load(Ordering::Relaxed) && new_getter.is_some() {
179179
// If the original property uses getter doc and we have a new getter,
180180
// pass Py_None to let __init__ get the doc from the new getter
181181
Some(vm.ctx.none())
182+
} else if zelf.getter_doc.load(Ordering::Relaxed) {
183+
// If original used getter_doc but we're not changing the getter,
184+
// pass None to let init get doc from existing getter
185+
Some(vm.ctx.none())
182186
} else {
183187
// Otherwise use the existing doc
184188
zelf.doc_getter()
185189
};
186190

187-
// Create property args
191+
// Create property args with updated values
188192
let args = PropertyArgs {
189-
fget: new_getter,
190-
fset: zelf.fset(),
191-
fdel: zelf.fdel(),
193+
fget: new_getter.or_else(|| zelf.fget()),
194+
fset: new_setter.or_else(|| zelf.fset()),
195+
fdel: new_deleter.or_else(|| zelf.fdel()),
192196
doc,
193197
name: None,
194198
};
@@ -206,38 +210,22 @@ impl PyProperty {
206210
Ok(new_prop_ref)
207211
}
208212

213+
#[pymethod]
214+
fn getter(
215+
zelf: PyRef<Self>,
216+
getter: Option<PyObjectRef>,
217+
vm: &VirtualMachine,
218+
) -> PyResult<PyRef<Self>> {
219+
Self::clone_property_with(zelf, getter, None, None, vm)
220+
}
221+
209222
#[pymethod]
210223
fn setter(
211224
zelf: PyRef<Self>,
212225
setter: Option<PyObjectRef>,
213226
vm: &VirtualMachine,
214227
) -> PyResult<PyRef<Self>> {
215-
// For setter, we need to preserve doc handling from the original property
216-
let doc = if zelf.getter_doc.load(Ordering::Relaxed) {
217-
// If original used getter_doc, pass None to let init get doc from getter
218-
Some(vm.ctx.none())
219-
} else {
220-
zelf.doc_getter()
221-
};
222-
223-
let args = PropertyArgs {
224-
fget: zelf.fget(),
225-
fset: setter.or_else(|| zelf.fset()),
226-
fdel: zelf.fdel(),
227-
doc,
228-
name: None,
229-
};
230-
231-
let new_prop = PyProperty::py_new(zelf.class().to_owned(), FuncArgs::default(), vm)?;
232-
let new_prop_ref = new_prop.downcast::<PyProperty>().unwrap();
233-
PyProperty::init(new_prop_ref.clone(), args, vm)?;
234-
235-
// Copy the name if it exists
236-
if let Some(name) = zelf.name.read().clone() {
237-
*new_prop_ref.name.write() = Some(name);
238-
}
239-
240-
Ok(new_prop_ref)
228+
Self::clone_property_with(zelf, None, setter, None, vm)
241229
}
242230

243231
#[pymethod]
@@ -246,32 +234,7 @@ impl PyProperty {
246234
deleter: Option<PyObjectRef>,
247235
vm: &VirtualMachine,
248236
) -> PyResult<PyRef<Self>> {
249-
// For deleter, we need to preserve doc handling from the original property
250-
let doc = if zelf.getter_doc.load(Ordering::Relaxed) {
251-
// If original used getter_doc, pass None to let init get doc from getter
252-
Some(vm.ctx.none())
253-
} else {
254-
zelf.doc_getter()
255-
};
256-
257-
let args = PropertyArgs {
258-
fget: zelf.fget(),
259-
fset: zelf.fset(),
260-
fdel: deleter.or_else(|| zelf.fdel()),
261-
doc,
262-
name: None,
263-
};
264-
265-
let new_prop = PyProperty::py_new(zelf.class().to_owned(), FuncArgs::default(), vm)?;
266-
let new_prop_ref = new_prop.downcast::<PyProperty>().unwrap();
267-
PyProperty::init(new_prop_ref.clone(), args, vm)?;
268-
269-
// Copy the name if it exists
270-
if let Some(name) = zelf.name.read().clone() {
271-
*new_prop_ref.name.write() = Some(name);
272-
}
273-
274-
Ok(new_prop_ref)
237+
Self::clone_property_with(zelf, None, None, deleter, vm)
275238
}
276239

277240
#[pygetset(magic)]

0 commit comments

Comments
 (0)