mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
Remove PropertyBuilder and add new_getset
This commit is contained in:
@@ -692,7 +692,8 @@ pub fn impl_pystruct_sequence(attr: AttributeArgs, item: Item) -> Result<TokenSt
|
||||
let property = quote! {
|
||||
class.set_str_attr(
|
||||
#field_name_str,
|
||||
ctx.new_property(
|
||||
ctx.new_readonly_getset(
|
||||
#field_name_str,
|
||||
|zelf: &::rustpython_vm::obj::objtuple::PyTuple,
|
||||
_vm: &::rustpython_vm::VirtualMachine| {
|
||||
zelf.fast_getitem(#idx)
|
||||
|
||||
@@ -644,20 +644,16 @@ pub fn init(ctx: &PyContext) {
|
||||
PyBaseException::extend_class(ctx, &excs.base_exception_type);
|
||||
|
||||
extend_class!(ctx, &excs.syntax_error, {
|
||||
"msg" => ctx.new_property(make_arg_getter(0)),
|
||||
"filename" => ctx.new_property(make_arg_getter(1)),
|
||||
"lineno" => ctx.new_property(make_arg_getter(2)),
|
||||
"offset" => ctx.new_property(make_arg_getter(3)),
|
||||
"text" => ctx.new_property(make_arg_getter(4)),
|
||||
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.import_error, {
|
||||
"__init__" => ctx.new_method(import_error_init),
|
||||
"msg" => ctx.new_property(make_arg_getter(0)),
|
||||
"msg" => ctx.new_readonly_getset("msg", make_arg_getter(0)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.stop_iteration, {
|
||||
"value" => ctx.new_property(make_arg_getter(0)),
|
||||
"value" => ctx.new_readonly_getset("value", make_arg_getter(0)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.key_error, {
|
||||
@@ -665,27 +661,27 @@ pub fn init(ctx: &PyContext) {
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_decode_error, {
|
||||
"encoding" => ctx.new_property(make_arg_getter(0)),
|
||||
"object" => ctx.new_property(make_arg_getter(1)),
|
||||
"start" => ctx.new_property(make_arg_getter(2)),
|
||||
"end" => ctx.new_property(make_arg_getter(3)),
|
||||
"reason" => ctx.new_property(make_arg_getter(4)),
|
||||
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_encode_error, {
|
||||
"encoding" => ctx.new_property(make_arg_getter(0)),
|
||||
"object" => ctx.new_property(make_arg_getter(1)),
|
||||
"start" => ctx.new_property(make_arg_getter(2)),
|
||||
"end" => ctx.new_property(make_arg_getter(3)),
|
||||
"reason" => ctx.new_property(make_arg_getter(4)),
|
||||
"encoding" => ctx.new_readonly_getset("encoding", make_arg_getter(0)),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(1)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(2)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(3)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(4)),
|
||||
});
|
||||
|
||||
extend_class!(ctx, &excs.unicode_translate_error, {
|
||||
"encoding" => ctx.new_property(none_getter),
|
||||
"object" => ctx.new_property(make_arg_getter(0)),
|
||||
"start" => ctx.new_property(make_arg_getter(1)),
|
||||
"end" => ctx.new_property(make_arg_getter(2)),
|
||||
"reason" => ctx.new_property(make_arg_getter(3)),
|
||||
"encoding" => ctx.new_readonly_getset("encoding", none_getter),
|
||||
"object" => ctx.new_readonly_getset("object", make_arg_getter(0)),
|
||||
"start" => ctx.new_readonly_getset("start", make_arg_getter(1)),
|
||||
"end" => ctx.new_readonly_getset("end", make_arg_getter(2)),
|
||||
"reason" => ctx.new_readonly_getset("reason", make_arg_getter(3)),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -92,17 +92,17 @@ impl PyCodeRef {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
extend_class!(context, &context.types.code_type, {
|
||||
pub fn init(ctx: &PyContext) {
|
||||
extend_class!(ctx, &ctx.types.code_type, {
|
||||
(slot new) => PyCodeRef::new,
|
||||
"__repr__" => context.new_method(PyCodeRef::repr),
|
||||
"__repr__" => ctx.new_method(PyCodeRef::repr),
|
||||
|
||||
"co_argcount" => context.new_property(PyCodeRef::co_argcount),
|
||||
"co_consts" => context.new_property(PyCodeRef::co_consts),
|
||||
"co_filename" => context.new_property(PyCodeRef::co_filename),
|
||||
"co_firstlineno" => context.new_property(PyCodeRef::co_firstlineno),
|
||||
"co_kwonlyargcount" => context.new_property(PyCodeRef::co_kwonlyargcount),
|
||||
"co_name" => context.new_property(PyCodeRef::co_name),
|
||||
"co_flags" => context.new_property(PyCodeRef::co_flags),
|
||||
"co_argcount" => ctx.new_readonly_getset("co_argcount", PyCodeRef::co_argcount),
|
||||
"co_consts" => ctx.new_readonly_getset("co_consts", PyCodeRef::co_consts),
|
||||
"co_filename" => ctx.new_readonly_getset("co_filename", PyCodeRef::co_filename),
|
||||
"co_firstlineno" => ctx.new_readonly_getset("co_firstlineno", PyCodeRef::co_firstlineno),
|
||||
"co_kwonlyargcount" => ctx.new_readonly_getset("co_kwonlyargcount", PyCodeRef::co_kwonlyargcount),
|
||||
"co_name" => ctx.new_readonly_getset("co_name", PyCodeRef::co_name),
|
||||
"co_flags" => ctx.new_readonly_getset("co_flags", PyCodeRef::co_flags),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,52 +4,13 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use super::objtype::PyClassRef;
|
||||
use crate::function::{IntoPyNativeFunc, OptionalArg};
|
||||
use crate::function::OptionalArg;
|
||||
use crate::pyobject::{
|
||||
IdProtocol, PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue,
|
||||
TypeProtocol,
|
||||
IdProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
};
|
||||
use crate::slots::SlotDescriptor;
|
||||
use crate::vm::VirtualMachine;
|
||||
|
||||
// Read-only property, doesn't have __set__ or __delete__
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyReadOnlyProperty {
|
||||
getter: PyObjectRef,
|
||||
}
|
||||
|
||||
impl PyValue for PyReadOnlyProperty {
|
||||
fn class(vm: &VirtualMachine) -> PyClassRef {
|
||||
vm.ctx.readonly_property_type()
|
||||
}
|
||||
}
|
||||
|
||||
pub type PyReadOnlyPropertyRef = PyRef<PyReadOnlyProperty>;
|
||||
|
||||
impl SlotDescriptor for PyReadOnlyProperty {
|
||||
fn descr_get(
|
||||
vm: &VirtualMachine,
|
||||
zelf: PyObjectRef,
|
||||
obj: Option<PyObjectRef>,
|
||||
cls: OptionalArg<PyObjectRef>,
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
if vm.is_none(&obj) {
|
||||
if Self::_cls_is(&cls, &vm.ctx.types.type_type) {
|
||||
vm.invoke(&zelf.getter, cls.unwrap())
|
||||
} else {
|
||||
Ok(zelf.into_object())
|
||||
}
|
||||
} else {
|
||||
vm.invoke(&zelf.getter, obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(with(SlotDescriptor))]
|
||||
impl PyReadOnlyProperty {}
|
||||
|
||||
/// Property attribute.
|
||||
///
|
||||
/// fget
|
||||
@@ -255,81 +216,12 @@ fn py_none_to_option(vm: &VirtualMachine, value: &PyObjectRef) -> Option<PyObjec
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PropertyBuilder<'a> {
|
||||
ctx: &'a PyContext,
|
||||
getter: Option<PyObjectRef>,
|
||||
setter: Option<PyObjectRef>,
|
||||
}
|
||||
|
||||
impl<'a> PropertyBuilder<'a> {
|
||||
pub fn new(ctx: &'a PyContext) -> Self {
|
||||
Self {
|
||||
ctx,
|
||||
getter: None,
|
||||
setter: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_getter<I, R, VM, F: IntoPyNativeFunc<I, R, VM>>(self, func: F) -> Self {
|
||||
let func = self.ctx.new_method(func);
|
||||
Self {
|
||||
ctx: self.ctx,
|
||||
getter: Some(func),
|
||||
setter: self.setter,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_setter<
|
||||
I,
|
||||
V,
|
||||
VM,
|
||||
F: IntoPyNativeFunc<(I, V), impl super::objgetset::IntoPyNoResult, VM>,
|
||||
>(
|
||||
self,
|
||||
func: F,
|
||||
) -> Self {
|
||||
let func = self.ctx.new_method(func);
|
||||
Self {
|
||||
ctx: self.ctx,
|
||||
getter: self.getter,
|
||||
setter: Some(func),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create(self) -> PyObjectRef {
|
||||
if self.setter.is_some() {
|
||||
let payload = PyProperty {
|
||||
getter: self.getter.clone(),
|
||||
setter: self.setter.clone(),
|
||||
deleter: None,
|
||||
doc: RefCell::new(None),
|
||||
};
|
||||
|
||||
PyObject::new(payload, self.ctx.property_type(), None)
|
||||
} else {
|
||||
let payload = PyReadOnlyProperty {
|
||||
getter: self.getter.expect(
|
||||
"One of add_getter/add_setter must be called when constructing a property",
|
||||
),
|
||||
};
|
||||
|
||||
PyObject::new(payload, self.ctx.readonly_property_type(), None)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(context: &PyContext) {
|
||||
PyReadOnlyProperty::extend_class(context, &context.types.readonly_property_type);
|
||||
|
||||
pub(crate) fn init(context: &PyContext) {
|
||||
PyProperty::extend_class(context, &context.types.property_type);
|
||||
|
||||
// This is a bit unfortunate, but this instance attribute overlaps with the
|
||||
// class __doc__ string..
|
||||
extend_class!(context, &context.types.property_type, {
|
||||
"__doc__" =>
|
||||
PropertyBuilder::new(context)
|
||||
.add_getter(PyProperty::doc_getter)
|
||||
.add_setter(PyProperty::doc_setter)
|
||||
.create(),
|
||||
"__doc__" => context.new_getset("__doc__", PyProperty::doc_getter, PyProperty::doc_setter),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ use std::fmt;
|
||||
use super::objdict::PyDictRef;
|
||||
use super::objlist::PyList;
|
||||
use super::objmappingproxy::PyMappingProxy;
|
||||
use super::objproperty::PropertyBuilder;
|
||||
use super::objstr::PyStringRef;
|
||||
use super::objtuple::PyTuple;
|
||||
use super::objweakref::PyWeak;
|
||||
@@ -80,16 +79,13 @@ impl PyClassRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn _mro(self, _vm: &VirtualMachine) -> PyTuple {
|
||||
#[pyproperty(name = "__mro__")]
|
||||
fn get_mro(self, _vm: &VirtualMachine) -> PyTuple {
|
||||
let elements: Vec<PyObjectRef> =
|
||||
_mro(&self).iter().map(|x| x.as_object().clone()).collect();
|
||||
PyTuple::from(elements)
|
||||
}
|
||||
|
||||
fn _set_mro(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
Err(vm.new_attribute_error("read-only attribute".to_owned()))
|
||||
}
|
||||
|
||||
#[pyproperty(magic)]
|
||||
fn bases(self, vm: &VirtualMachine) -> PyObjectRef {
|
||||
vm.ctx
|
||||
@@ -338,6 +334,18 @@ impl PyClassRef {
|
||||
}
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
#[pyproperty(magic)]
|
||||
fn dict(self) -> PyMappingProxy {
|
||||
PyMappingProxy::new(self)
|
||||
}
|
||||
|
||||
#[pyproperty(magic, setter)]
|
||||
fn set_dict(self, _value: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
|
||||
Err(vm.new_not_implemented_error(
|
||||
"Setting __dict__ attribute on a type isn't yet implemented".to_owned(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -346,18 +354,6 @@ impl PyClassRef {
|
||||
|
||||
pub(crate) fn init(ctx: &PyContext) {
|
||||
PyClassRef::extend_class(ctx, &ctx.types.type_type);
|
||||
extend_class!(&ctx, &ctx.types.type_type, {
|
||||
"__dict__" =>
|
||||
PropertyBuilder::new(ctx)
|
||||
.add_getter(type_dict)
|
||||
.add_setter(type_dict_setter)
|
||||
.create(),
|
||||
"__mro__" =>
|
||||
PropertyBuilder::new(ctx)
|
||||
.add_getter(PyClassRef::_mro)
|
||||
.add_setter(PyClassRef::_set_mro)
|
||||
.create(),
|
||||
});
|
||||
}
|
||||
|
||||
fn _mro(cls: &PyClassRef) -> Vec<PyClassRef> {
|
||||
@@ -409,20 +405,6 @@ pub fn type_new(
|
||||
new(vm, args.insert(cls.into_object()))
|
||||
}
|
||||
|
||||
fn type_dict(class: PyClassRef, _vm: &VirtualMachine) -> PyMappingProxy {
|
||||
PyMappingProxy::new(class)
|
||||
}
|
||||
|
||||
fn type_dict_setter(
|
||||
_instance: PyClassRef,
|
||||
_value: PyObjectRef,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
Err(vm.new_not_implemented_error(
|
||||
"Setting __dict__ attribute on a type isn't yet implemented".to_owned(),
|
||||
))
|
||||
}
|
||||
|
||||
impl PyClassRef {
|
||||
/// This is the internal get_attr implementation for fast lookup on a class.
|
||||
pub fn get_attr(&self, attr_name: &str) -> Option<PyObjectRef> {
|
||||
|
||||
@@ -25,13 +25,13 @@ use crate::obj::objcomplex::PyComplex;
|
||||
use crate::obj::objdict::{PyDict, PyDictRef};
|
||||
use crate::obj::objfloat::PyFloat;
|
||||
use crate::obj::objfunction::{PyBoundMethod, PyFunction};
|
||||
use crate::obj::objgetset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet};
|
||||
use crate::obj::objint::{PyInt, PyIntRef};
|
||||
use crate::obj::objiter;
|
||||
use crate::obj::objlist::PyList;
|
||||
use crate::obj::objnamespace::PyNamespace;
|
||||
use crate::obj::objnone::{PyNone, PyNoneRef};
|
||||
use crate::obj::objobject;
|
||||
use crate::obj::objproperty::PropertyBuilder;
|
||||
use crate::obj::objset::PySet;
|
||||
use crate::obj::objstr;
|
||||
use crate::obj::objtuple::{PyTuple, PyTupleRef};
|
||||
@@ -503,11 +503,23 @@ impl PyContext {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_property<F, I, V, VM>(&self, f: F) -> PyObjectRef
|
||||
pub fn new_readonly_getset<F, T>(&self, name: impl Into<String>, f: F) -> PyObjectRef
|
||||
where
|
||||
F: IntoPyNativeFunc<I, V, VM>,
|
||||
F: IntoPyGetterFunc<T>,
|
||||
{
|
||||
PropertyBuilder::new(self).add_getter(f).create()
|
||||
PyObject::new(PyGetSet::with_get(name.into(), f), self.getset_type(), None)
|
||||
}
|
||||
|
||||
pub fn new_getset<G, S, T, U>(&self, name: impl Into<String>, g: G, s: S) -> PyObjectRef
|
||||
where
|
||||
G: IntoPyGetterFunc<T>,
|
||||
S: IntoPySetterFunc<U>,
|
||||
{
|
||||
PyObject::new(
|
||||
PyGetSet::with_get_set(name.into(), g, s),
|
||||
self.getset_type(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_code_object(&self, code: bytecode::CodeObject) -> PyCodeRef {
|
||||
|
||||
@@ -564,7 +564,7 @@ mod fileio {
|
||||
vm.set_attr(&file_io, "name", name)?;
|
||||
vm.set_attr(&file_io, "__fileno", vm.new_int(file_no))?;
|
||||
vm.set_attr(&file_io, "closefd", vm.new_bool(false))?;
|
||||
vm.set_attr(&file_io, "closed", vm.new_bool(false))?;
|
||||
vm.set_attr(&file_io, "__closed", vm.new_bool(false))?;
|
||||
Ok(vm.get_none())
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ mod fileio {
|
||||
winapi::um::handleapi::CloseHandle(raw_handle as _);
|
||||
}
|
||||
vm.set_attr(&instance, "closefd", vm.new_bool(true))?;
|
||||
vm.set_attr(&instance, "closed", vm.new_bool(true))?;
|
||||
vm.set_attr(&instance, "__closed", vm.new_bool(true))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -676,7 +676,7 @@ mod fileio {
|
||||
libc::close(raw_fd as _);
|
||||
}
|
||||
vm.set_attr(&instance, "closefd", vm.new_bool(true))?;
|
||||
vm.set_attr(&instance, "closed", vm.new_bool(true))?;
|
||||
vm.set_attr(&instance, "__closed", vm.new_bool(true))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -952,7 +952,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"readable" => ctx.new_method(io_base_readable),
|
||||
"writable" => ctx.new_method(io_base_writable),
|
||||
"flush" => ctx.new_method(io_base_flush),
|
||||
"closed" => ctx.new_property(io_base_closed),
|
||||
"closed" => ctx.new_readonly_getset("closed", io_base_closed),
|
||||
"__closed" => ctx.new_bool(false),
|
||||
"close" => ctx.new_method(io_base_close),
|
||||
"readline" => ctx.new_method(io_base_readline),
|
||||
@@ -1017,7 +1017,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"tell" => ctx.new_method(PyStringIORef::tell),
|
||||
"readline" => ctx.new_method(PyStringIORef::readline),
|
||||
"truncate" => ctx.new_method(PyStringIORef::truncate),
|
||||
"closed" => ctx.new_property(PyStringIORef::closed),
|
||||
"closed" => ctx.new_readonly_getset("closed", PyStringIORef::closed),
|
||||
"close" => ctx.new_method(PyStringIORef::close),
|
||||
});
|
||||
|
||||
@@ -1033,7 +1033,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
"tell" => ctx.new_method(PyBytesIORef::tell),
|
||||
"readline" => ctx.new_method(PyBytesIORef::readline),
|
||||
"truncate" => ctx.new_method(PyBytesIORef::truncate),
|
||||
"closed" => ctx.new_property(PyBytesIORef::closed),
|
||||
"closed" => ctx.new_readonly_getset("closed", PyBytesIORef::closed),
|
||||
"close" => ctx.new_method(PyBytesIORef::close),
|
||||
});
|
||||
|
||||
|
||||
@@ -1235,8 +1235,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
ScandirIterator::extend_class(ctx, &scandir_iter);
|
||||
|
||||
let dir_entry = py_class!(ctx, "DirEntry", ctx.object(), {
|
||||
"name" => ctx.new_property(DirEntryRef::name),
|
||||
"path" => ctx.new_property(DirEntryRef::path),
|
||||
"name" => ctx.new_readonly_getset("name", DirEntryRef::name),
|
||||
"path" => ctx.new_readonly_getset("path", DirEntryRef::path),
|
||||
"is_dir" => ctx.new_method(DirEntryRef::is_dir),
|
||||
"is_file" => ctx.new_method(DirEntryRef::is_file),
|
||||
"is_symlink" => ctx.new_method(DirEntryRef::is_symlink),
|
||||
|
||||
@@ -68,13 +68,13 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let ctx = &vm.ctx;
|
||||
|
||||
let passwd_type = py_class!(ctx, "struct_passwd", ctx.object(), {
|
||||
"pw_name" => ctx.new_property(PasswdRef::pw_name),
|
||||
"pw_passwd" => ctx.new_property(PasswdRef::pw_passwd),
|
||||
"pw_uid" => ctx.new_property(PasswdRef::pw_uid),
|
||||
"pw_gid" => ctx.new_property(PasswdRef::pw_gid),
|
||||
"pw_gecos" => ctx.new_property(PasswdRef::pw_gecos),
|
||||
"pw_dir" => ctx.new_property(PasswdRef::pw_dir),
|
||||
"pw_shell" => ctx.new_property(PasswdRef::pw_shell),
|
||||
"pw_name" => ctx.new_readonly_getset("pw_name", PasswdRef::pw_name),
|
||||
"pw_passwd" => ctx.new_readonly_getset("pw_passwd", PasswdRef::pw_passwd),
|
||||
"pw_uid" => ctx.new_readonly_getset("pw_uid", PasswdRef::pw_uid),
|
||||
"pw_gid" => ctx.new_readonly_getset("pw_gid", PasswdRef::pw_gid),
|
||||
"pw_gecos" => ctx.new_readonly_getset("pw_gecos", PasswdRef::pw_gecos),
|
||||
"pw_dir" => ctx.new_readonly_getset("pw_dir", PasswdRef::pw_dir),
|
||||
"pw_shell" => ctx.new_readonly_getset("pw_shell", PasswdRef::pw_shell),
|
||||
});
|
||||
|
||||
py_module!(vm, "pwd", {
|
||||
|
||||
@@ -253,18 +253,18 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
|
||||
let popen = py_class!(ctx, "Popen", ctx.object(), {
|
||||
(slot new) => PopenRef::new,
|
||||
"poll" => ctx.new_method(PopenRef::poll),
|
||||
"returncode" => ctx.new_property(PopenRef::return_code),
|
||||
"returncode" => ctx.new_readonly_getset("returncode", PopenRef::return_code),
|
||||
"wait" => ctx.new_method(PopenRef::wait),
|
||||
"stdin" => ctx.new_property(PopenRef::stdin),
|
||||
"stdout" => ctx.new_property(PopenRef::stdout),
|
||||
"stderr" => ctx.new_property(PopenRef::stderr),
|
||||
"stdin" => ctx.new_readonly_getset("stdin", PopenRef::stdin),
|
||||
"stdout" => ctx.new_readonly_getset("stdout", PopenRef::stdout),
|
||||
"stderr" => ctx.new_readonly_getset("stderr", PopenRef::stderr),
|
||||
"terminate" => ctx.new_method(PopenRef::terminate),
|
||||
"kill" => ctx.new_method(PopenRef::kill),
|
||||
"communicate" => ctx.new_method(PopenRef::communicate),
|
||||
"pid" => ctx.new_property(PopenRef::pid),
|
||||
"pid" => ctx.new_readonly_getset("pid", PopenRef::pid),
|
||||
"__enter__" => ctx.new_method(PopenRef::enter),
|
||||
"__exit__" => ctx.new_method(PopenRef::exit),
|
||||
"args" => ctx.new_property(PopenRef::args),
|
||||
"args" => ctx.new_readonly_getset("args", PopenRef::args),
|
||||
});
|
||||
|
||||
py_module!(vm, "_subprocess", {
|
||||
|
||||
Reference in New Issue
Block a user