mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
clean up functions and methods
This commit is contained in:
1 parent
589d2b0e1b
commit
5cd375aaa9
14 files changed
+115
-104
No files matched your search
@@ -290,7 +290,7 @@ impl ModuleItem for FunctionItem {
|
||||
#doc
|
||||
.into_function()
|
||||
.with_module(vm.ctx.new_utf8_str(#module.to_owned()))
|
||||
.build(&vm.ctx)
|
||||
.into_ref(&vm.ctx)
|
||||
);
|
||||
quote! {
|
||||
vm.__module_set_attr(&module, #py_name, #new_func).unwrap();
|
||||
|
||||
@@ -43,7 +43,7 @@ fn run(vm: &vm::VirtualMachine) -> vm::PyResult<()> {
|
||||
// typing `quit()` is too long, let's make `on(False)` work instead.
|
||||
scope
|
||||
.globals
|
||||
.set_item("on", vm.ctx.new_function("on", on), vm)?;
|
||||
.set_item("on", vm.ctx.new_function("on", on).into(), vm)?;
|
||||
|
||||
// let's include a fibonacci function, but let's be lazy and write it in Python
|
||||
add_python_function!(
|
||||
|
||||
@@ -25,7 +25,7 @@ macro_rules! create_property {
|
||||
move |this: &PyExpatLikeXmlParser, func: PyObjectRef| *this.$element.write() = func,
|
||||
);
|
||||
|
||||
$attributes.insert($name.to_owned(), attr);
|
||||
$attributes.insert($name.to_owned(), attr.into());
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use super::{pytype, PyClassMethod, PyStrRef, PyTypeRef};
|
||||
use super::{pytype, PyClassMethod, PyStr, PyStrRef, PyTypeRef};
|
||||
use crate::{
|
||||
function::{FuncArgs, PyNativeFunc},
|
||||
builtins::PyBoundMethod,
|
||||
function::{FuncArgs, IntoPyNativeFunc, PyNativeFunc},
|
||||
slots::{Callable, SlotDescriptor},
|
||||
PyClassImpl, PyContext, PyObject, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
|
||||
VirtualMachine,
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
@@ -21,34 +21,29 @@ impl PyNativeFuncDef {
|
||||
doc: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PyNativeFuncDef {
|
||||
pub fn with_doc(mut self, doc: String, ctx: &PyContext) -> Self {
|
||||
self.doc = Some(ctx.new_stringref(doc));
|
||||
self.doc = Some(PyStr::new_ref(doc, ctx));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn into_function(self) -> PyBuiltinFunction {
|
||||
self.into()
|
||||
}
|
||||
pub fn build_function(self, ctx: &PyContext) -> PyObjectRef {
|
||||
self.into_function().build(ctx)
|
||||
pub fn build_function(self, ctx: &PyContext) -> PyRef<PyBuiltinFunction> {
|
||||
self.into_function().into_ref(ctx)
|
||||
}
|
||||
pub fn build_method(self, ctx: &PyContext, class: PyTypeRef) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
pub fn build_method(self, ctx: &PyContext, class: PyTypeRef) -> PyRef<PyBuiltinMethod> {
|
||||
PyRef::new_ref(
|
||||
PyBuiltinMethod { value: self, class },
|
||||
ctx.types.method_descriptor_type.clone(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
pub fn build_classmethod(self, ctx: &PyContext, class: PyTypeRef) -> PyObjectRef {
|
||||
pub fn build_classmethod(self, ctx: &PyContext, class: PyTypeRef) -> PyRef<PyClassMethod> {
|
||||
// TODO: classmethod_descriptor
|
||||
PyObject::new(
|
||||
PyClassMethod::from(self.build_method(ctx, class)),
|
||||
ctx.types.classmethod_type.clone(),
|
||||
None,
|
||||
)
|
||||
let callable = self.build_method(ctx, class).into();
|
||||
PyClassMethod::new_ref(callable, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,8 +80,8 @@ impl PyBuiltinFunction {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self, ctx: &PyContext) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
pub fn into_ref(self, ctx: &PyContext) -> PyRef<Self> {
|
||||
PyRef::new_ref(
|
||||
self,
|
||||
ctx.types.builtin_function_or_method_type.clone(),
|
||||
None,
|
||||
@@ -183,11 +178,12 @@ impl SlotDescriptor for PyBuiltinMethod {
|
||||
Ok(obj) => obj,
|
||||
Err(result) => return result,
|
||||
};
|
||||
if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
Ok(zelf.into())
|
||||
let r = if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
zelf.into()
|
||||
} else {
|
||||
Ok(vm.ctx.new_bound_method(zelf.into(), obj))
|
||||
}
|
||||
PyBoundMethod::new_ref(obj, zelf.into(), &vm.ctx).into()
|
||||
};
|
||||
Ok(r)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,6 +193,20 @@ impl Callable for PyBuiltinMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl PyBuiltinMethod {
|
||||
pub fn new_ref<F, FKind>(
|
||||
name: impl Into<PyStr>,
|
||||
class: PyTypeRef,
|
||||
f: F,
|
||||
ctx: &PyContext,
|
||||
) -> PyRef<Self>
|
||||
where
|
||||
F: IntoPyNativeFunc<FKind>,
|
||||
{
|
||||
ctx.make_funcdef(name, f).build_method(ctx, class)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(with(SlotDescriptor, Callable), flags(METHOD_DESCR))]
|
||||
impl PyBuiltinMethod {
|
||||
#[pyproperty(magic)]
|
||||
|
||||
@@ -92,11 +92,6 @@ impl PyValue for PyByteArray {
|
||||
/// Fill bytearray class methods dictionary.
|
||||
pub(crate) fn init(context: &PyContext) {
|
||||
PyByteArray::extend_class(context, &context.types.bytearray_type);
|
||||
let bytearray_type = &context.types.bytearray_type;
|
||||
extend_class!(context, bytearray_type, {
|
||||
"maketrans" => context.new_method("maketrans", bytearray_type.clone(), PyBytesInner::maketrans),
|
||||
});
|
||||
|
||||
PyByteArrayIterator::extend_class(context, &context.types.bytearray_iterator_type);
|
||||
}
|
||||
|
||||
@@ -227,6 +222,11 @@ impl PyByteArray {
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult {
|
||||
PyBytesInner::maketrans(from, to, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn pop(zelf: PyRef<Self>, index: OptionalArg<isize>, vm: &VirtualMachine) -> PyResult<u8> {
|
||||
let elements = &mut zelf.try_resizable(vm)?.elements;
|
||||
|
||||
@@ -90,10 +90,6 @@ impl PyValue for PyBytes {
|
||||
|
||||
pub(crate) fn init(context: &PyContext) {
|
||||
PyBytes::extend_class(context, &context.types.bytes_type);
|
||||
let bytes_type = &context.types.bytes_type;
|
||||
extend_class!(context, bytes_type, {
|
||||
"maketrans" => context.new_method("maketrans", bytes_type.clone(), PyBytesInner::maketrans),
|
||||
});
|
||||
PyBytesIterator::extend_class(context, &context.types.bytes_iterator_type);
|
||||
}
|
||||
|
||||
@@ -159,6 +155,11 @@ impl PyBytes {
|
||||
self.inner.contains(needle, vm)
|
||||
}
|
||||
|
||||
#[pymethod]
|
||||
fn maketrans(from: PyBytesInner, to: PyBytesInner, vm: &VirtualMachine) -> PyResult {
|
||||
PyBytesInner::maketrans(from, to, vm)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn getitem(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
self.inner.getitem("byte", needle, vm) // byte != Self::NAME
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use super::PyTypeRef;
|
||||
use crate::{
|
||||
builtins::PyBoundMethod,
|
||||
slots::{SlotConstructor, SlotDescriptor},
|
||||
PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine,
|
||||
};
|
||||
|
||||
/// classmethod(function) -> method
|
||||
@@ -51,7 +52,7 @@ impl SlotDescriptor for PyClassMethod {
|
||||
) -> PyResult {
|
||||
let (zelf, obj) = Self::_unwrap(zelf, obj, vm)?;
|
||||
let cls = cls.unwrap_or_else(|| obj.clone_class().into());
|
||||
Ok(vm.ctx.new_bound_method(zelf.callable.clone(), cls))
|
||||
Ok(PyBoundMethod::new_ref(cls, zelf.callable.clone(), &vm.ctx).into())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +64,12 @@ impl SlotConstructor for PyClassMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl PyClassMethod {
|
||||
pub fn new_ref(callable: PyObjectRef, ctx: &PyContext) -> PyRef<Self> {
|
||||
PyRef::new_ref(Self { callable }, ctx.types.classmethod_type.clone(), None)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(with(SlotDescriptor, SlotConstructor), flags(BASETYPE, HAS_DICT))]
|
||||
impl PyClassMethod {
|
||||
#[pyproperty(magic)]
|
||||
|
||||
@@ -408,7 +408,7 @@ impl SlotDescriptor for PyFunction {
|
||||
let obj = if vm.is_none(&obj) && !Self::_cls_is(&cls, &obj.class()) {
|
||||
zelf.into()
|
||||
} else {
|
||||
vm.ctx.new_bound_method(zelf.into(), obj)
|
||||
PyBoundMethod::new_ref(obj, zelf.into(), &vm.ctx).into()
|
||||
};
|
||||
Ok(obj)
|
||||
}
|
||||
@@ -423,9 +423,8 @@ impl Callable for PyFunction {
|
||||
#[pyclass(module = false, name = "method")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyBoundMethod {
|
||||
// TODO: these shouldn't be public
|
||||
object: PyObjectRef,
|
||||
pub function: PyObjectRef,
|
||||
function: PyObjectRef,
|
||||
}
|
||||
|
||||
impl Callable for PyBoundMethod {
|
||||
@@ -480,15 +479,25 @@ impl SlotConstructor for PyBoundMethod {
|
||||
}
|
||||
}
|
||||
|
||||
impl PyBoundMethod {
|
||||
fn new(object: PyObjectRef, function: PyObjectRef) -> Self {
|
||||
PyBoundMethod { object, function }
|
||||
}
|
||||
|
||||
pub fn new_ref(object: PyObjectRef, function: PyObjectRef, ctx: &PyContext) -> PyRef<Self> {
|
||||
PyRef::new_ref(
|
||||
Self::new(object, function),
|
||||
ctx.types.bound_method_type.clone(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(
|
||||
with(Callable, Comparable, SlotGetattro, SlotConstructor),
|
||||
flags(HAS_DICT)
|
||||
)]
|
||||
impl PyBoundMethod {
|
||||
pub fn new(object: PyObjectRef, function: PyObjectRef) -> Self {
|
||||
PyBoundMethod { object, function }
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
fn repr(&self, vm: &VirtualMachine) -> PyResult<String> {
|
||||
let funcname =
|
||||
|
||||
@@ -595,12 +595,14 @@ impl PyType {
|
||||
if !attributes.contains_key("__dict__") {
|
||||
attributes.insert(
|
||||
"__dict__".to_owned(),
|
||||
vm.ctx.new_getset(
|
||||
"__dict__",
|
||||
vm.ctx.types.object_type.clone(),
|
||||
subtype_get_dict,
|
||||
subtype_set_dict,
|
||||
),
|
||||
vm.ctx
|
||||
.new_getset(
|
||||
"__dict__",
|
||||
vm.ctx.types.object_type.clone(),
|
||||
subtype_get_dict,
|
||||
subtype_set_dict,
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use super::{PyStr, PyTypeRef};
|
||||
use crate::{
|
||||
builtins::builtinfunc::PyBuiltinMethod,
|
||||
function::IntoPyNativeFunc,
|
||||
slots::{SlotConstructor, SlotDescriptor},
|
||||
PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, VirtualMachine,
|
||||
@@ -53,7 +54,7 @@ impl PyStaticMethod {
|
||||
where
|
||||
F: IntoPyNativeFunc<FKind>,
|
||||
{
|
||||
let callable = ctx.new_method(name, class, f);
|
||||
let callable = PyBuiltinMethod::new_ref(name, class, f, ctx).into();
|
||||
PyRef::new_ref(Self { callable }, ctx.types.staticmethod_type.clone(), None)
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -173,7 +173,7 @@ impl CodecsRegistry {
|
||||
),
|
||||
];
|
||||
let errors = std::array::IntoIter::new(errors)
|
||||
.map(|(name, f)| (name.to_owned(), f))
|
||||
.map(|(name, f)| (name.to_owned(), f.into()))
|
||||
.collect();
|
||||
let inner = RegistryInner {
|
||||
search_path: Vec::new(),
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ macro_rules! named_function {
|
||||
)
|
||||
.into_function()
|
||||
.with_module(ctx.new_utf8_str(stringify!($module).to_owned()))
|
||||
.build(ctx)
|
||||
.into_ref(ctx)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
+12
-33
@@ -6,7 +6,7 @@ use crate::common::{
|
||||
pub use crate::pyobjectrc::{PyObject, PyObjectRef, PyObjectWeak, PyObjectWrap, PyRef, PyWeakRef};
|
||||
use crate::{
|
||||
builtins::{
|
||||
builtinfunc::PyNativeFuncDef,
|
||||
builtinfunc::{PyBuiltinFunction, PyBuiltinMethod, PyNativeFuncDef},
|
||||
bytearray, bytes,
|
||||
code::{self, PyCode},
|
||||
getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet},
|
||||
@@ -249,10 +249,6 @@ impl PyContext {
|
||||
create_type_with_slots(name, &self.types.type_type, base, slots)
|
||||
}
|
||||
|
||||
pub(crate) fn new_stringref(&self, s: String) -> pystr::PyStrRef {
|
||||
PyRef::new_ref(pystr::PyStr::from(s), self.types.str_type.clone(), None)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn make_funcdef<F, FKind>(&self, name: impl Into<PyStr>, f: F) -> PyNativeFuncDef
|
||||
where
|
||||
@@ -261,7 +257,8 @@ impl PyContext {
|
||||
PyNativeFuncDef::new(f.into_func(), PyStr::new_ref(name, self))
|
||||
}
|
||||
|
||||
pub fn new_function<F, FKind>(&self, name: impl Into<PyStr>, f: F) -> PyObjectRef
|
||||
// #[deprecated]
|
||||
pub fn new_function<F, FKind>(&self, name: impl Into<PyStr>, f: F) -> PyRef<PyBuiltinFunction>
|
||||
where
|
||||
F: IntoPyNativeFunc<FKind>,
|
||||
{
|
||||
@@ -273,23 +270,11 @@ impl PyContext {
|
||||
name: impl Into<PyStr>,
|
||||
class: PyTypeRef,
|
||||
f: F,
|
||||
) -> PyObjectRef
|
||||
) -> PyRef<PyBuiltinMethod>
|
||||
where
|
||||
F: IntoPyNativeFunc<FKind>,
|
||||
{
|
||||
self.make_funcdef(name, f).build_method(self, class)
|
||||
}
|
||||
|
||||
pub fn new_classmethod<F, FKind>(
|
||||
&self,
|
||||
name: impl Into<PyStr>,
|
||||
class: PyTypeRef,
|
||||
f: F,
|
||||
) -> PyObjectRef
|
||||
where
|
||||
F: IntoPyNativeFunc<FKind>,
|
||||
{
|
||||
self.make_funcdef(name, f).build_classmethod(self, class)
|
||||
PyBuiltinMethod::new_ref(name, class, f, self)
|
||||
}
|
||||
|
||||
pub fn new_readonly_getset<F, T>(
|
||||
@@ -297,11 +282,11 @@ impl PyContext {
|
||||
name: impl Into<String>,
|
||||
class: PyTypeRef,
|
||||
f: F,
|
||||
) -> PyObjectRef
|
||||
) -> PyRef<PyGetSet>
|
||||
where
|
||||
F: IntoPyGetterFunc<T>,
|
||||
{
|
||||
PyObject::new(
|
||||
PyRef::new_ref(
|
||||
PyGetSet::new(name.into(), class).with_get(f),
|
||||
self.types.getset_type.clone(),
|
||||
None,
|
||||
@@ -314,12 +299,12 @@ impl PyContext {
|
||||
class: PyTypeRef,
|
||||
g: G,
|
||||
s: S,
|
||||
) -> PyObjectRef
|
||||
) -> PyRef<PyGetSet>
|
||||
where
|
||||
G: IntoPyGetterFunc<T>,
|
||||
S: IntoPySetterFunc<U>,
|
||||
{
|
||||
PyObject::new(
|
||||
PyRef::new_ref(
|
||||
PyGetSet::new(name.into(), class).with_get(g).with_set(s),
|
||||
self.types.getset_type.clone(),
|
||||
None,
|
||||
@@ -333,14 +318,6 @@ impl PyContext {
|
||||
PyRef::new_ref(PyCode::new(code), self.types.code_type.clone(), None)
|
||||
}
|
||||
|
||||
pub fn new_bound_method(&self, function: PyObjectRef, object: PyObjectRef) -> PyObjectRef {
|
||||
PyObject::new(
|
||||
PyBoundMethod::new(object, function),
|
||||
self.types.bound_method_type.clone(),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_base_object(&self, class: PyTypeRef, dict: Option<PyDictRef>) -> PyObjectRef {
|
||||
PyObject::new(object::PyBaseObject, class, dict)
|
||||
}
|
||||
@@ -960,7 +937,9 @@ pub trait PyClassImpl: PyClassDef {
|
||||
class.set_str_attr("__module__", ctx.new_utf8_str(module_name));
|
||||
}
|
||||
if class.slots.new.load().is_some() {
|
||||
let bound = ctx.new_bound_method(ctx.slot_new_wrapper.clone(), class.clone().into());
|
||||
let bound: PyObjectRef =
|
||||
PyBoundMethod::new_ref(class.clone().into(), ctx.slot_new_wrapper.clone(), ctx)
|
||||
.into();
|
||||
class.set_str_attr("__new__", bound);
|
||||
}
|
||||
}
|
||||
|
||||
+20
-18
@@ -215,24 +215,26 @@ pub fn js_to_py(vm: &VirtualMachine, js_val: JsValue) -> PyObjectRef {
|
||||
}
|
||||
} else if js_val.is_function() {
|
||||
let func = js_sys::Function::from(js_val);
|
||||
vm.ctx.new_function(
|
||||
func.name(),
|
||||
move |args: FuncArgs, vm: &VirtualMachine| -> PyResult {
|
||||
let this = Object::new();
|
||||
for (k, v) in args.kwargs {
|
||||
Reflect::set(&this, &k.into(), &py_to_js(vm, v))
|
||||
.expect("property to be settable");
|
||||
}
|
||||
let js_args = args
|
||||
.args
|
||||
.into_iter()
|
||||
.map(|v| py_to_js(vm, v))
|
||||
.collect::<Array>();
|
||||
func.apply(&this, &js_args)
|
||||
.map(|val| js_to_py(vm, val))
|
||||
.map_err(|err| js_err_to_py_err(vm, &err))
|
||||
},
|
||||
)
|
||||
vm.ctx
|
||||
.new_function(
|
||||
String::from(func.name()),
|
||||
move |args: FuncArgs, vm: &VirtualMachine| -> PyResult {
|
||||
let this = Object::new();
|
||||
for (k, v) in args.kwargs {
|
||||
Reflect::set(&this, &k.into(), &py_to_js(vm, v))
|
||||
.expect("property to be settable");
|
||||
}
|
||||
let js_args = args
|
||||
.args
|
||||
.into_iter()
|
||||
.map(|v| py_to_js(vm, v))
|
||||
.collect::<Array>();
|
||||
func.apply(&this, &js_args)
|
||||
.map(|val| js_to_py(vm, val))
|
||||
.map_err(|err| js_err_to_py_err(vm, &err))
|
||||
},
|
||||
)
|
||||
.into()
|
||||
} else if let Some(err) = js_val.dyn_ref::<js_sys::Error>() {
|
||||
js_err_to_py_err(vm, err).into()
|
||||
} else if js_val.is_undefined() {
|
||||
|
||||
Reference in new issue
Block a user