forked from Rust-related/RustPython
Add PyTypSlot::init
This commit is contained in:
committed by
Jeong Yunwon
parent
a19efa21ce
commit
88080505e4
@@ -381,9 +381,10 @@ pub(crate) fn impl_define_exception(exc_def: PyExceptionDef) -> Result<TokenStre
|
||||
#slot_new_impl
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
pub(crate) fn init(
|
||||
zelf: ::rustpython_vm::PyRef<::rustpython_vm::builtins::PyBaseException>,
|
||||
zelf: PyObjectRef,
|
||||
args: ::rustpython_vm::function::FuncArgs,
|
||||
vm: &::rustpython_vm::VirtualMachine,
|
||||
) -> ::rustpython_vm::PyResult<()> {
|
||||
|
||||
@@ -15,8 +15,10 @@ mod _contextvars {
|
||||
|
||||
#[pyimpl]
|
||||
impl PyContext {
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, _vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn init(zelf: PyObjectRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let _zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
unimplemented!("Context.__init__ is currently under construction")
|
||||
}
|
||||
|
||||
@@ -97,8 +99,10 @@ mod _contextvars {
|
||||
|
||||
#[pyimpl]
|
||||
impl ContextVar {
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, _args: ContextVarOptions, _vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn init(_zelf: PyObjectRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let _: ContextVarOptions = _args.bind(vm)?;
|
||||
unimplemented!("ContextVar.__init__() is currently under construction")
|
||||
}
|
||||
|
||||
@@ -167,8 +171,10 @@ mod _contextvars {
|
||||
|
||||
#[pyimpl]
|
||||
impl ContextToken {
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, _args: ContextTokenOptions, _vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn init(_zelf: PyObjectRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let _: ContextTokenOptions = _args.bind(vm)?;
|
||||
unimplemented!("Token.__init__() is currently under construction")
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ mod _socket {
|
||||
convert::{ToPyException, ToPyObject, TryFromBorrowedObject, TryFromObject},
|
||||
function::{ArgBytesLike, ArgMemoryBuffer, Either, FuncArgs, OptionalArg, OptionalOption},
|
||||
utils::ToCString,
|
||||
AsObject, PyObjectRef, PyPayload, PyResult, VirtualMachine,
|
||||
AsObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
use crossbeam_utils::atomic::AtomicCell;
|
||||
use num_traits::ToPrimitive;
|
||||
@@ -548,15 +548,16 @@ mod _socket {
|
||||
Self::default().into_ref_with_type(vm, cls).map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(
|
||||
&self,
|
||||
family: OptionalArg<i32>,
|
||||
socket_kind: OptionalArg<i32>,
|
||||
proto: OptionalArg<i32>,
|
||||
fileno: OptionalOption<PyObjectRef>,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let (family, socket_kind, proto, fileno): (
|
||||
OptionalArg<i32>,
|
||||
OptionalArg<i32>,
|
||||
OptionalArg<i32>,
|
||||
OptionalOption<PyObjectRef>,
|
||||
) = args.bind(vm)?;
|
||||
let mut family = family.unwrap_or(-1);
|
||||
let mut socket_kind = socket_kind.unwrap_or(-1);
|
||||
let mut proto = proto.unwrap_or(-1);
|
||||
@@ -628,7 +629,7 @@ mod _socket {
|
||||
)
|
||||
.map_err(|err| err.to_pyexception(vm))?;
|
||||
};
|
||||
self.init_inner(family, socket_kind, proto, sock, vm)
|
||||
zelf.init_inner(family, socket_kind, proto, sock, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
|
||||
@@ -105,11 +105,14 @@ impl PyByteArray {
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, options: ByteInnerNewOptions, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let options: ByteInnerNewOptions = args.bind(vm)?;
|
||||
// First unpack bytearray and *then* get a lock to set it.
|
||||
let mut inner = options.get_bytearray_inner(vm)?;
|
||||
std::mem::swap(&mut *self.inner_mut(), &mut inner);
|
||||
std::mem::swap(&mut *zelf.inner_mut(), &mut inner);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -88,14 +88,12 @@ impl PyDict {
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(
|
||||
&self,
|
||||
dict_obj: OptionalArg<PyObjectRef>,
|
||||
kwargs: KwArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
self.update(dict_obj, kwargs, vm)
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let (dict_obj, kwargs): (OptionalArg<PyObjectRef>, KwArgs) = args.bind(vm)?;
|
||||
zelf.update(dict_obj, kwargs, vm)
|
||||
}
|
||||
|
||||
// Used in update and ior.
|
||||
|
||||
@@ -345,14 +345,17 @@ impl PyList {
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, iterable: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let iterable: OptionalArg<PyObjectRef> = args.bind(vm)?;
|
||||
let mut elements = if let OptionalArg::Present(iterable) = iterable {
|
||||
iterable.try_to_value(vm)?
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
std::mem::swap(self.borrow_vec_mut().deref_mut(), &mut elements);
|
||||
std::mem::swap(zelf.borrow_vec_mut().deref_mut(), &mut elements);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -38,14 +38,18 @@ impl PyModule {
|
||||
PyModule {}.into_ref_with_type(vm, cls).map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(zelf: PyRef<Self>, args: ModuleInitArgs, vm: &VirtualMachine) {
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let args: ModuleInitArgs = args.bind(vm)?;
|
||||
debug_assert!(zelf
|
||||
.class()
|
||||
.slots
|
||||
.flags
|
||||
.has_feature(crate::types::PyTypeFlags::HAS_DICT));
|
||||
zelf.init_module_dict(args.name.into(), args.doc.to_pyobject(vm), vm);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn getattr_inner(zelf: &Py<Self>, name: PyStrRef, vm: &VirtualMachine) -> PyResult {
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
function::{FuncArgs, PyComparisonValue},
|
||||
recursion::ReprGuard,
|
||||
types::{Comparable, Constructor, PyComparisonOp},
|
||||
AsObject, Context, PyObject, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
AsObject, Context, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
/// A simple attribute-based namespace.
|
||||
@@ -41,8 +41,10 @@ impl PyNamespace {
|
||||
|
||||
#[pyimpl(flags(BASETYPE, HAS_DICT), with(Constructor, Comparable))]
|
||||
impl PyNamespace {
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(zelf: PyRef<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
if !args.args.is_empty() {
|
||||
return Err(vm.new_type_error("no positional arguments expected".to_owned()));
|
||||
}
|
||||
|
||||
@@ -250,8 +250,11 @@ impl PyBaseObject {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(_args: FuncArgs) {}
|
||||
fn init(_zelf: PyObjectRef, _args: FuncArgs, _vm: &VirtualMachine) -> PyResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[pyproperty(name = "__class__")]
|
||||
fn get_class(obj: PyObjectRef) -> PyTypeRef {
|
||||
|
||||
@@ -99,12 +99,18 @@ impl PyProperty {
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, args: PropertyArgs) {
|
||||
*self.getter.write() = args.fget;
|
||||
*self.setter.write() = args.fset;
|
||||
*self.deleter.write() = args.fdel;
|
||||
*self.doc.write() = args.doc;
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let args: PropertyArgs = args.bind(vm)?;
|
||||
|
||||
*zelf.getter.write() = args.fget;
|
||||
*zelf.setter.write() = args.fset;
|
||||
*zelf.deleter.write() = args.fdel;
|
||||
*zelf.doc.write() = args.doc;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Descriptor methods
|
||||
|
||||
@@ -401,13 +401,16 @@ impl PySet {
|
||||
PySet::default().into_ref_with_type(vm, cls).map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, iterable: OptionalArg<ArgIterable>, vm: &VirtualMachine) -> PyResult<()> {
|
||||
if self.len() > 0 {
|
||||
self.clear();
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let iterable: OptionalArg<ArgIterable> = args.bind(vm)?;
|
||||
if zelf.len() > 0 {
|
||||
zelf.clear();
|
||||
}
|
||||
if let OptionalArg::Present(it) = iterable {
|
||||
self.update(PosArgs::new(vec![it]), vm)?;
|
||||
zelf.update(PosArgs::new(vec![it]), vm)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -719,12 +719,8 @@ impl Callable for PyType {
|
||||
return Ok(obj);
|
||||
}
|
||||
|
||||
if let Some(init_method_or_err) = vm.get_method(obj.clone(), "__init__") {
|
||||
let init_method = init_method_or_err?;
|
||||
let res = vm.invoke(&init_method, args)?;
|
||||
if !vm.is_none(&res) {
|
||||
return Err(vm.new_type_error("__init__ must return None".to_owned()));
|
||||
}
|
||||
if let Some(init_method) = obj.class().mro_find_map(|cls| cls.slots.init.load()) {
|
||||
init_method(obj.clone(), args, vm)?;
|
||||
}
|
||||
Ok(obj)
|
||||
}
|
||||
|
||||
@@ -431,8 +431,10 @@ impl PyBaseException {
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
pub(crate) fn init(zelf: PyRef<Self>, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
pub(crate) fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
*zelf.args.write() = PyTuple::new_ref(args.args, &vm.ctx);
|
||||
Ok(())
|
||||
}
|
||||
@@ -1160,12 +1162,7 @@ pub(super) mod types {
|
||||
PyBaseException::slot_new(cls, args, vm)
|
||||
}
|
||||
|
||||
fn import_error_init(
|
||||
zelf: PyRef<PyBaseException>,
|
||||
args: FuncArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
let zelf: PyObjectRef = zelf.into();
|
||||
fn import_error_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
zelf.set_attr(
|
||||
"name",
|
||||
vm.unwrap_or_none(args.kwargs.get("name").cloned()),
|
||||
@@ -1270,11 +1267,7 @@ pub(super) mod types {
|
||||
PyBaseException::slot_new(cls, args, vm)
|
||||
}
|
||||
|
||||
fn base_exception_init(
|
||||
zelf: PyRef<PyBaseException>,
|
||||
args: FuncArgs,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
fn base_exception_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
PyBaseException::init(zelf, args, vm)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ mod _ast {
|
||||
|
||||
#[pyimpl(flags(BASETYPE, HAS_DICT))]
|
||||
impl AstNode {
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let obj: PyObjectRef = zelf.class().clone().into();
|
||||
let fields = obj.get_attr("_fields", vm)?;
|
||||
let fields = zelf.clone().get_attr("_fields", vm)?;
|
||||
let fields: Vec<PyStrRef> = fields.try_to_value(vm)?;
|
||||
let numargs = args.args.len();
|
||||
if numargs > fields.len() {
|
||||
|
||||
@@ -63,12 +63,12 @@ mod _collections {
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(
|
||||
zelf: PyRef<Self>,
|
||||
PyDequeOptions { iterable, maxlen }: PyDequeOptions,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let PyDequeOptions { iterable, maxlen } = args.bind(vm)?;
|
||||
|
||||
// TODO: This is _basically_ pyobject_to_opt_usize in itertools.rs
|
||||
// need to move that function elsewhere and refactor usages.
|
||||
let maxlen = if let Some(obj) = maxlen.into_option() {
|
||||
|
||||
@@ -1371,6 +1371,13 @@ mod _io {
|
||||
.ok_or_else(|| vm.new_runtime_error("reentrant call inside buffered io".to_owned()))
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
fn slot_init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let (raw, BufferSize { buffer_size }): (PyObjectRef, _) = args.bind(vm)?;
|
||||
zelf.init(raw, BufferSize { buffer_size }, vm)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn init(
|
||||
&self,
|
||||
@@ -1783,16 +1790,14 @@ mod _io {
|
||||
fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
Self::default().into_ref_with_type(vm, cls).map(Into::into)
|
||||
}
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(
|
||||
&self,
|
||||
reader: PyObjectRef,
|
||||
writer: PyObjectRef,
|
||||
buffer_size: BufferSize,
|
||||
vm: &VirtualMachine,
|
||||
) -> PyResult<()> {
|
||||
self.read.init(reader, buffer_size.clone(), vm)?;
|
||||
self.write.init(writer, buffer_size, vm)?;
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let (reader, writer, buffer_size): (PyObjectRef, PyObjectRef, BufferSize) =
|
||||
args.bind(vm)?;
|
||||
zelf.read.init(reader, buffer_size.clone(), vm)?;
|
||||
zelf.write.init(writer, buffer_size, vm)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -2193,9 +2198,12 @@ mod _io {
|
||||
.map_err(|_| vm.new_value_error("I/O operation on uninitialized object".to_owned()))
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(&self, args: TextIOWrapperArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let mut data = self.lock_opt(vm)?;
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let args: TextIOWrapperArgs = args.bind(vm)?;
|
||||
let mut data = zelf.lock_opt(vm)?;
|
||||
*data = None;
|
||||
|
||||
let encoding = match args.encoding {
|
||||
@@ -3829,8 +3837,11 @@ mod fileio {
|
||||
.map(Into::into)
|
||||
}
|
||||
|
||||
#[pyslot]
|
||||
#[pymethod(magic)]
|
||||
fn init(zelf: PyRef<Self>, args: FileIOArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
fn init(zelf: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let zelf: PyRef<Self> = zelf.try_into_value(vm)?;
|
||||
let args: FileIOArgs = args.bind(vm)?;
|
||||
let mode_obj = args.mode.unwrap_or_else(|| PyStr::from("rb").into_ref(vm));
|
||||
let mode_str = mode_obj.as_str();
|
||||
let name = args.name;
|
||||
|
||||
@@ -61,7 +61,7 @@ pub struct PyTypeSlots {
|
||||
pub descr_get: AtomicCell<Option<DescrGetFunc>>,
|
||||
pub descr_set: AtomicCell<Option<DescrSetFunc>>,
|
||||
// tp_dictoffset
|
||||
// tp_init
|
||||
pub init: AtomicCell<Option<InitFunc>>,
|
||||
// tp_alloc
|
||||
pub new: AtomicCell<Option<NewFunc>>,
|
||||
// tp_free
|
||||
@@ -155,6 +155,7 @@ pub(crate) type DescrGetFunc =
|
||||
pub(crate) type DescrSetFunc =
|
||||
fn(PyObjectRef, PyObjectRef, Option<PyObjectRef>, &VirtualMachine) -> PyResult<()>;
|
||||
pub(crate) type NewFunc = fn(PyTypeRef, FuncArgs, &VirtualMachine) -> PyResult;
|
||||
pub(crate) type InitFunc = fn(PyObjectRef, FuncArgs, &VirtualMachine) -> PyResult<()>;
|
||||
pub(crate) type DelFunc = fn(&PyObject, &VirtualMachine) -> PyResult<()>;
|
||||
pub(crate) type AsSequenceFunc = fn(&PyObject, &VirtualMachine) -> Cow<'static, PySequenceMethods>;
|
||||
|
||||
@@ -324,6 +325,14 @@ fn descr_set_wrapper(
|
||||
.map(drop)
|
||||
}
|
||||
|
||||
fn init_wrapper(obj: PyObjectRef, args: FuncArgs, vm: &VirtualMachine) -> PyResult<()> {
|
||||
let res = vm.call_special_method(obj, "__init__", args)?;
|
||||
if !vm.is_none(&res) {
|
||||
return Err(vm.new_type_error("__init__ must return None".to_owned()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn new_wrapper(cls: PyTypeRef, mut args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
let new = vm
|
||||
.get_attribute_opt(cls.as_object().to_owned(), "__new__")?
|
||||
@@ -379,6 +388,9 @@ impl PyType {
|
||||
"__set__" | "__delete__" => {
|
||||
update_slot!(descr_set, descr_set_wrapper);
|
||||
}
|
||||
"__init__" => {
|
||||
update_slot!(init, init_wrapper);
|
||||
}
|
||||
"__new__" => {
|
||||
update_slot!(new, new_wrapper);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user