Partial support for __init_subclass__ dunder method.

This doesn't support passing kwargs to __init_subclass__.
This commit is contained in:
Bolun Thompson committed 2020-07-20 12:47:03 -07:00
1 parent 0c11b8bf67
commit 05bd893e3d
2 files changed
+27 -1

No files matched your search

+5
View File
@@ -138,6 +138,11 @@ impl PyBaseObject {
Ok(vm.ctx.not_implemented())
}
#[pyclassmethod(magic)]
fn init_subclass(_cls: PyClassRef, vm: &VirtualMachine) -> PyResult {
Ok(vm.ctx.none())
}
#[pymethod(magic)]
pub fn dir(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<PyList> {
let attributes: PyAttributes = obj.class().get_attributes();
+22 -1
View File
@@ -2,6 +2,7 @@ use parking_lot::RwLock;
use std::collections::{HashMap, HashSet};
use std::fmt;
use super::objclassmethod::PyClassMethod;
use super::objdict::PyDictRef;
use super::objlist::PyList;
use super::objmappingproxy::PyMappingProxy;
@@ -14,7 +15,7 @@ use crate::pyobject::{
IdProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable, PyLease, PyObject, PyObjectRef,
PyRef, PyResult, PyValue, TypeProtocol,
};
use crate::slots::{PyClassSlots, PyTpFlags};
use crate::slots::{PyClassSlots, PyTpFlags, SlotDescriptor};
use crate::vm::VirtualMachine;
use itertools::Itertools;
use std::ops::Deref;
@@ -301,6 +302,12 @@ impl PyClassRef {
}
}
if let Some(f) = attributes.get_mut("__init_subclass__") {
if f.class().is(&vm.ctx.function_type()) {
*f = PyClassMethod::new(f.clone()).into_ref(vm).into_object();
}
}
let typ = new(metatype, name.as_str(), base.clone(), bases, attributes)
.map_err(|e| vm.new_type_error(e))?;
@@ -327,6 +334,20 @@ impl PyClassRef {
}
}
if let Some(initter) = typ.get_super_attr("__init_subclass__") {
let initter = PyClassMethod::descr_get(
vm,
initter,
None,
OptionalArg::Present(typ.clone().into_object()),
)?;
let init_args = PyFuncArgs {
args: Vec::new(),
kwargs: args.kwargs,
};
vm.invoke(&initter, init_args)?;
};
Ok(typ.into_object())
}