mirror of
https://github.com/RustPython/RustPython.git
synced 2026-06-02 19:39:49 +09:00
PyModuleDef and #[pymodule(with(...))]
This commit is contained in:
@@ -2,7 +2,7 @@ use crate::error::Diagnostic;
|
||||
use crate::util::{
|
||||
format_doc, iter_use_idents, pyclass_ident_and_attrs, text_signature, AttrItemMeta,
|
||||
AttributeExt, ClassItemMeta, ContentItem, ContentItemInner, ErrorVec, ItemMeta, ItemNursery,
|
||||
SimpleItemMeta, ALL_ALLOWED_NAMES,
|
||||
ModuleItemMeta, SimpleItemMeta, ALL_ALLOWED_NAMES,
|
||||
};
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
@@ -45,7 +45,9 @@ impl FromStr for AttrName {
|
||||
#[derive(Default)]
|
||||
struct ModuleContext {
|
||||
name: String,
|
||||
module_extend_items: ItemNursery,
|
||||
function_items: FunctionNursery,
|
||||
attribute_items: ItemNursery,
|
||||
has_extend_module: bool, // TODO: check if `fn extend_module` exists
|
||||
errors: Vec<syn::Error>,
|
||||
}
|
||||
|
||||
@@ -56,7 +58,7 @@ pub fn impl_pymodule(attr: AttributeArgs, module_item: Item) -> Result<TokenStre
|
||||
};
|
||||
let fake_ident = Ident::new("pymodule", module_item.span());
|
||||
let module_meta =
|
||||
SimpleItemMeta::from_nested(module_item.ident.clone(), fake_ident, attr.into_iter())?;
|
||||
ModuleItemMeta::from_nested(module_item.ident.clone(), fake_ident, attr.into_iter())?;
|
||||
|
||||
// generation resources
|
||||
let mut context = ModuleContext {
|
||||
@@ -91,7 +93,8 @@ pub fn impl_pymodule(attr: AttributeArgs, module_item: Item) -> Result<TokenStre
|
||||
|
||||
// append additional items
|
||||
let module_name = context.name.as_str();
|
||||
let module_extend_items = context.module_extend_items.validate()?;
|
||||
let function_items = context.function_items.validate()?;
|
||||
let attribute_items = context.attribute_items.validate()?;
|
||||
let doc = doc.or_else(|| {
|
||||
crate::doc::Database::shared()
|
||||
.try_path(module_name)
|
||||
@@ -104,29 +107,99 @@ pub fn impl_pymodule(attr: AttributeArgs, module_item: Item) -> Result<TokenStre
|
||||
} else {
|
||||
quote!(None)
|
||||
};
|
||||
let is_submodule = module_meta.sub()?;
|
||||
let withs = module_meta.with()?;
|
||||
if !is_submodule {
|
||||
items.extend(iter_chain![
|
||||
parse_quote! {
|
||||
pub(crate) const MODULE_NAME: &'static str = #module_name;
|
||||
},
|
||||
parse_quote! {
|
||||
pub(crate) const DOC: Option<&'static str> = #doc;
|
||||
},
|
||||
parse_quote! {
|
||||
pub(crate) fn __module_def(
|
||||
ctx: &::rustpython_vm::Context,
|
||||
) -> &'static ::rustpython_vm::builtins::PyModuleDef {
|
||||
DEF.get_or_init(|| {
|
||||
let mut def = ::rustpython_vm::builtins::PyModuleDef {
|
||||
name: ctx.intern_str(MODULE_NAME),
|
||||
doc: DOC.map(|doc| ctx.intern_str(doc)),
|
||||
slots: Default::default(),
|
||||
};
|
||||
def.slots.exec = Some(extend_module);
|
||||
def
|
||||
})
|
||||
}
|
||||
},
|
||||
parse_quote! {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn make_module(
|
||||
vm: &::rustpython_vm::VirtualMachine
|
||||
) -> ::rustpython_vm::PyRef<::rustpython_vm::builtins::PyModule> {
|
||||
use ::rustpython_vm::PyPayload;
|
||||
let module = ::rustpython_vm::builtins::PyModule::from_def(__module_def(&vm.ctx)).into_ref(&vm.ctx);
|
||||
__init_dict(vm, &module);
|
||||
extend_module(vm, &module).unwrap();
|
||||
module
|
||||
}
|
||||
},
|
||||
]);
|
||||
}
|
||||
if !is_submodule && !context.has_extend_module {
|
||||
items.push(parse_quote! {
|
||||
pub(crate) fn extend_module(vm: &::rustpython_vm::VirtualMachine, module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>) -> ::rustpython_vm::PyResult<()> {
|
||||
__extend_module(vm, module);
|
||||
Ok(())
|
||||
}
|
||||
});
|
||||
}
|
||||
items.extend(iter_chain![
|
||||
parse_quote! {
|
||||
pub(crate) const MODULE_NAME: &'static str = #module_name;
|
||||
},
|
||||
parse_quote! {
|
||||
pub(crate) const DOC: Option<&'static str> = #doc;
|
||||
},
|
||||
parse_quote! {
|
||||
pub(crate) fn extend_module(
|
||||
vm: &::rustpython_vm::VirtualMachine,
|
||||
module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>,
|
||||
) {
|
||||
#module_extend_items
|
||||
::rustpython_vm::common::static_cell! {
|
||||
pub(crate) static DEF: ::rustpython_vm::builtins::PyModuleDef;
|
||||
}
|
||||
},
|
||||
parse_quote! {
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn make_module(
|
||||
vm: &::rustpython_vm::VirtualMachine
|
||||
) -> ::rustpython_vm::PyRef<::rustpython_vm::builtins::PyModule> {
|
||||
let module = vm.new_module(MODULE_NAME, vm.ctx.new_dict(), DOC);
|
||||
extend_module(vm, &module);
|
||||
module
|
||||
pub(crate) fn __init_attributes(
|
||||
vm: &::rustpython_vm::VirtualMachine,
|
||||
module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>,
|
||||
) {
|
||||
#(
|
||||
super::#withs::__init_attributes(vm, module);
|
||||
)*
|
||||
let ctx = &vm.ctx;
|
||||
#attribute_items
|
||||
}
|
||||
},
|
||||
parse_quote! {
|
||||
pub(crate) fn __extend_module(
|
||||
vm: &::rustpython_vm::VirtualMachine,
|
||||
module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>,
|
||||
) {
|
||||
__init_methods(vm, module);
|
||||
__init_attributes(vm, module);
|
||||
}
|
||||
},
|
||||
parse_quote! {
|
||||
// TODO: remove once PyMethodDef done
|
||||
pub(crate) fn __init_methods(
|
||||
vm: &::rustpython_vm::VirtualMachine,
|
||||
module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>,
|
||||
) {
|
||||
#(
|
||||
super::#withs::__init_methods(vm, module);
|
||||
)*
|
||||
let ctx = &vm.ctx;
|
||||
#function_items
|
||||
}
|
||||
},
|
||||
parse_quote! {
|
||||
pub(crate) fn __init_dict(
|
||||
vm: &::rustpython_vm::VirtualMachine,
|
||||
module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>,
|
||||
) {
|
||||
::rustpython_vm::builtins::PyModule::__init_dict_from_def(vm, module);
|
||||
}
|
||||
},
|
||||
]);
|
||||
@@ -248,6 +321,53 @@ where
|
||||
Ok((result, cfgs))
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct FunctionNursery {
|
||||
items: Vec<FunctionNurseryItem>,
|
||||
}
|
||||
|
||||
struct FunctionNurseryItem {
|
||||
py_names: Vec<String>,
|
||||
cfgs: Vec<Attribute>,
|
||||
ident: Ident,
|
||||
#[allow(dead_code)]
|
||||
doc: String,
|
||||
tokens: TokenStream,
|
||||
}
|
||||
|
||||
impl FunctionNursery {
|
||||
fn add_item(&mut self, item: FunctionNurseryItem) {
|
||||
self.items.push(item);
|
||||
}
|
||||
|
||||
fn validate(self) -> Result<ValidatedFunctionNursery> {
|
||||
let mut name_set = HashSet::new();
|
||||
for item in &self.items {
|
||||
for py_name in &item.py_names {
|
||||
if !name_set.insert((py_name.to_owned(), &item.cfgs)) {
|
||||
bail_span!(item.ident, "duplicate method name `{}`", py_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(ValidatedFunctionNursery(self))
|
||||
}
|
||||
}
|
||||
|
||||
struct ValidatedFunctionNursery(FunctionNursery);
|
||||
|
||||
impl ToTokens for ValidatedFunctionNursery {
|
||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||
for item in &self.0.items {
|
||||
let cfgs = &item.cfgs;
|
||||
let item_tokens = &item.tokens;
|
||||
tokens.extend(quote! {
|
||||
#(#cfgs)*
|
||||
#item_tokens
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// #[pyfunction]
|
||||
struct FunctionItem {
|
||||
inner: ContentItemInner<AttrName>,
|
||||
@@ -318,7 +438,7 @@ impl ModuleItem for FunctionItem {
|
||||
let py_name = item_meta.simple_name()?;
|
||||
let sig_doc = text_signature(func.sig(), &py_name);
|
||||
|
||||
let (tokens, py_names) = {
|
||||
let (tokens, py_names, doc) = {
|
||||
let module = args.module_name();
|
||||
let doc = args.attrs.doc().or_else(|| {
|
||||
crate::doc::Database::shared()
|
||||
@@ -332,10 +452,10 @@ impl ModuleItem for FunctionItem {
|
||||
} else {
|
||||
sig_doc
|
||||
};
|
||||
let doc = quote!(.with_doc(#doc.to_owned(), &vm.ctx));
|
||||
let with_doc = quote!(.with_doc(#doc.to_owned(), &vm.ctx));
|
||||
let new_func = quote_spanned!(ident.span()=>
|
||||
vm.ctx.make_func_def(vm.ctx.intern_str(#py_name), #ident)
|
||||
#doc
|
||||
#with_doc
|
||||
.into_function()
|
||||
.with_module(vm.new_pyobj(#module.to_owned()))
|
||||
.into_ref(&vm.ctx)
|
||||
@@ -348,6 +468,7 @@ impl ModuleItem for FunctionItem {
|
||||
vm.__module_set_attr(module, #py_name, func).unwrap();
|
||||
}},
|
||||
vec![py_name],
|
||||
doc,
|
||||
)
|
||||
} else {
|
||||
let mut py_names = HashSet::new();
|
||||
@@ -381,17 +502,18 @@ impl ModuleItem for FunctionItem {
|
||||
}
|
||||
}},
|
||||
py_names,
|
||||
doc,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
args.context.module_extend_items.add_item(
|
||||
ident.clone(),
|
||||
args.context.function_items.add_item(FunctionNurseryItem {
|
||||
ident: ident.to_owned(),
|
||||
py_names,
|
||||
args.cfgs.to_vec(),
|
||||
cfgs: args.cfgs.to_vec(),
|
||||
doc,
|
||||
tokens,
|
||||
10,
|
||||
)?;
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -432,8 +554,8 @@ impl ModuleItem for ClassItem {
|
||||
class_meta.class_name()?
|
||||
};
|
||||
let class_new = quote_spanned!(ident.span() =>
|
||||
let new_class = <#ident as ::rustpython_vm::class::PyClassImpl>::make_class(&vm.ctx);
|
||||
new_class.set_attr(rustpython_vm::identifier!(vm, __module__), vm.new_pyobj(#module_name));
|
||||
let new_class = <#ident as ::rustpython_vm::class::PyClassImpl>::make_class(ctx);
|
||||
new_class.set_attr(rustpython_vm::identifier!(ctx, __module__), vm.new_pyobj(#module_name));
|
||||
);
|
||||
(class_name, class_new)
|
||||
};
|
||||
@@ -473,7 +595,7 @@ impl ModuleItem for ClassItem {
|
||||
},
|
||||
};
|
||||
|
||||
args.context.module_extend_items.add_item(
|
||||
args.context.attribute_items.add_item(
|
||||
ident.clone(),
|
||||
py_names,
|
||||
args.cfgs.to_vec(),
|
||||
@@ -561,7 +683,7 @@ impl ModuleItem for AttributeItem {
|
||||
let tokens = quote_spanned! { ident.span() =>
|
||||
vm.__module_set_attr(module, #py_name, vm.new_pyobj(#ident)).unwrap();
|
||||
};
|
||||
args.context.module_extend_items.add_item(
|
||||
args.context.attribute_items.add_item(
|
||||
ident.clone(),
|
||||
vec![py_name],
|
||||
cfgs.clone(),
|
||||
@@ -624,7 +746,7 @@ impl ModuleItem for AttributeItem {
|
||||
};
|
||||
|
||||
args.context
|
||||
.module_extend_items
|
||||
.attribute_items
|
||||
.add_item(ident, py_names, cfgs, tokens, 1)?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -197,6 +197,21 @@ impl ItemMetaInner {
|
||||
};
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn _optional_list(
|
||||
&self,
|
||||
key: &str,
|
||||
) -> Result<Option<impl std::iter::Iterator<Item = &'_ NestedMeta>>> {
|
||||
let value = if let Some((_, meta)) = self.meta_map.get(key) {
|
||||
let Meta::List(syn::MetaList { path: _, nested, .. }) = meta else {
|
||||
bail_span!(meta, "#[{}({}(...))] must be a list", self.meta_name(), key)
|
||||
};
|
||||
Some(nested.into_iter())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait ItemMeta: Sized {
|
||||
@@ -251,6 +266,38 @@ impl ItemMeta for SimpleItemMeta {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ModuleItemMeta(pub ItemMetaInner);
|
||||
|
||||
impl ItemMeta for ModuleItemMeta {
|
||||
const ALLOWED_NAMES: &'static [&'static str] = &["name", "with", "sub"];
|
||||
|
||||
fn from_inner(inner: ItemMetaInner) -> Self {
|
||||
Self(inner)
|
||||
}
|
||||
fn inner(&self) -> &ItemMetaInner {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ModuleItemMeta {
|
||||
pub fn sub(&self) -> Result<bool> {
|
||||
self.inner()._bool("sub")
|
||||
}
|
||||
pub fn with(&self) -> Result<Vec<&syn::Path>> {
|
||||
let mut withs = Vec::new();
|
||||
let Some(nested) = self.inner()._optional_list("with")? else {
|
||||
return Ok(withs);
|
||||
};
|
||||
for meta in nested {
|
||||
let NestedMeta::Meta(Meta::Path(path)) = meta else {
|
||||
bail_span!(meta, "#[pymodule(with(...))] arguments should be paths")
|
||||
};
|
||||
withs.push(path);
|
||||
}
|
||||
Ok(withs)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct AttrItemMeta(pub ItemMetaInner);
|
||||
|
||||
impl ItemMeta for AttrItemMeta {
|
||||
|
||||
@@ -7,20 +7,11 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
openssl_probe::init_ssl_cert_env_vars();
|
||||
}
|
||||
openssl::init();
|
||||
|
||||
let module = _ssl::make_module(vm);
|
||||
#[cfg(ossl101)]
|
||||
ossl101::extend_module(vm, &module);
|
||||
#[cfg(ossl111)]
|
||||
ossl101::extend_module(vm, &module);
|
||||
#[cfg(windows)]
|
||||
windows::extend_module(vm, &module);
|
||||
|
||||
module
|
||||
_ssl::make_module(vm)
|
||||
}
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[pymodule]
|
||||
#[pymodule(with(ossl101, windows))]
|
||||
mod _ssl {
|
||||
use super::bio;
|
||||
use crate::{
|
||||
@@ -1405,9 +1396,21 @@ mod _ssl {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(ossl101))]
|
||||
#[pymodule(sub)]
|
||||
mod ossl101 {}
|
||||
|
||||
#[cfg(not(ossl111))]
|
||||
#[pymodule(sub)]
|
||||
mod ossl111 {}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[pymodule(sub)]
|
||||
mod windows {}
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[cfg(ossl101)]
|
||||
#[pymodule]
|
||||
#[pymodule(sub)]
|
||||
mod ossl101 {
|
||||
#[pyattr]
|
||||
use openssl_sys::{
|
||||
@@ -1418,14 +1421,14 @@ mod ossl101 {
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[cfg(ossl111)]
|
||||
#[pymodule]
|
||||
#[pymodule(sub)]
|
||||
mod ossl111 {
|
||||
#[pyattr]
|
||||
use openssl_sys::SSL_OP_NO_TLSv1_3 as OP_NO_TLSv1_3;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[pymodule]
|
||||
#[pymodule(sub)]
|
||||
mod windows {
|
||||
use crate::{
|
||||
common::ascii,
|
||||
|
||||
@@ -47,7 +47,7 @@ pub use mappingproxy::PyMappingProxy;
|
||||
pub(crate) mod memory;
|
||||
pub use memory::PyMemoryView;
|
||||
pub(crate) mod module;
|
||||
pub use module::PyModule;
|
||||
pub use module::{PyModule, PyModuleDef};
|
||||
pub(crate) mod namespace;
|
||||
pub use namespace::PyNamespace;
|
||||
pub(crate) mod object;
|
||||
|
||||
@@ -5,12 +5,53 @@ use crate::{
|
||||
convert::ToPyObject,
|
||||
function::FuncArgs,
|
||||
types::{GetAttr, Initializer, Representable},
|
||||
AsObject, Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
#[pyclass(module = false, name = "module")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyModule {}
|
||||
pub struct PyModuleDef {
|
||||
// pub index: usize,
|
||||
pub name: &'static PyStrInterned,
|
||||
pub doc: Option<&'static PyStrInterned>,
|
||||
// pub size: isize,
|
||||
// pub methods: &'static [PyMethodDef],
|
||||
pub slots: PyModuleSlots,
|
||||
// traverse: traverseproc
|
||||
// clear: inquiry
|
||||
// free: freefunc
|
||||
}
|
||||
|
||||
pub type ModuleCreate =
|
||||
fn(&VirtualMachine, &PyObject, &'static PyModuleDef) -> PyResult<PyRef<PyModule>>;
|
||||
pub type ModuleExec = fn(&VirtualMachine, &Py<PyModule>) -> PyResult<()>;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PyModuleSlots {
|
||||
pub create: Option<ModuleCreate>,
|
||||
pub exec: Option<ModuleExec>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for PyModuleSlots {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("PyModuleSlots")
|
||||
.field("create", &self.create.is_some())
|
||||
.field("exec", &self.exec.is_some())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::new_without_default)] // avoid Default implementation
|
||||
#[pyclass(module = false, name = "module")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyModule {
|
||||
// PyObject *md_dict;
|
||||
pub def: Option<&'static PyModuleDef>,
|
||||
// state: Any
|
||||
// weaklist
|
||||
// for logging purposes after md_dict is cleared
|
||||
pub name: Option<&'static PyStrInterned>,
|
||||
}
|
||||
|
||||
impl PyPayload for PyModule {
|
||||
fn class(ctx: &Context) -> &'static Py<PyType> {
|
||||
@@ -26,9 +67,23 @@ pub struct ModuleInitArgs {
|
||||
}
|
||||
|
||||
impl PyModule {
|
||||
// pub(crate) fn new(d: PyDictRef) -> Self {
|
||||
// PyModule { dict: d.into() }
|
||||
// }
|
||||
#[allow(clippy::new_without_default)]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
def: None,
|
||||
name: None,
|
||||
}
|
||||
}
|
||||
pub fn from_def(def: &'static PyModuleDef) -> Self {
|
||||
Self {
|
||||
def: Some(def),
|
||||
name: Some(def.name),
|
||||
}
|
||||
}
|
||||
pub fn __init_dict_from_def(vm: &VirtualMachine, module: &Py<PyModule>) {
|
||||
let doc = module.def.unwrap().doc.map(|doc| doc.to_owned());
|
||||
module.init_module_dict(module.name.unwrap(), doc, vm);
|
||||
}
|
||||
}
|
||||
|
||||
impl Py<PyModule> {
|
||||
@@ -63,13 +118,13 @@ impl Py<PyModule> {
|
||||
pub(crate) fn init_module_dict(
|
||||
&self,
|
||||
name: &'static PyStrInterned,
|
||||
doc: PyObjectRef,
|
||||
doc: Option<PyStrRef>,
|
||||
vm: &VirtualMachine,
|
||||
) {
|
||||
let dict = self.dict();
|
||||
dict.set_item(identifier!(vm, __name__), name.to_object(), vm)
|
||||
.expect("Failed to set __name__ on module");
|
||||
dict.set_item(identifier!(vm, __doc__), doc, vm)
|
||||
dict.set_item(identifier!(vm, __doc__), doc.to_pyobject(vm), vm)
|
||||
.expect("Failed to set __doc__ on module");
|
||||
dict.set_item("__package__", vm.ctx.none(), vm)
|
||||
.expect("Failed to set __package__ on module");
|
||||
@@ -98,7 +153,7 @@ impl Py<PyModule> {
|
||||
impl PyModule {
|
||||
#[pyslot]
|
||||
fn slot_new(cls: PyTypeRef, _args: FuncArgs, vm: &VirtualMachine) -> PyResult {
|
||||
PyModule {}.into_ref_with_type(vm, cls).map(Into::into)
|
||||
PyModule::new().into_ref_with_type(vm, cls).map(Into::into)
|
||||
}
|
||||
|
||||
#[pymethod(magic)]
|
||||
@@ -121,11 +176,7 @@ impl Initializer for PyModule {
|
||||
.slots
|
||||
.flags
|
||||
.has_feature(crate::types::PyTypeFlags::HAS_DICT));
|
||||
zelf.init_module_dict(
|
||||
vm.ctx.intern_str(args.name.as_str()),
|
||||
args.doc.to_pyobject(vm),
|
||||
vm,
|
||||
);
|
||||
zelf.init_module_dict(vm.ctx.intern_str(args.name.as_str()), args.doc, vm);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -939,7 +939,7 @@ pub fn init_module(vm: &VirtualMachine, module: &Py<PyModule>) {
|
||||
|
||||
crate::protocol::VecBuffer::make_class(&vm.ctx);
|
||||
|
||||
builtins::extend_module(vm, module);
|
||||
builtins::extend_module(vm, module).unwrap();
|
||||
|
||||
let debug_mode: bool = vm.state.settings.optimize == 0;
|
||||
extend_module!(vm, module, {
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
use crate::bytecode::frozen_lib::FrozenModule;
|
||||
use crate::{
|
||||
builtins::{PyBaseExceptionRef, PyModule},
|
||||
PyRef, VirtualMachine,
|
||||
};
|
||||
|
||||
pub fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
let module = _imp::make_module(vm);
|
||||
lock::extend_module(vm, &module);
|
||||
module
|
||||
}
|
||||
use crate::{builtins::PyBaseExceptionRef, VirtualMachine};
|
||||
pub(crate) use _imp::make_module;
|
||||
|
||||
#[cfg(feature = "threading")]
|
||||
#[pymodule]
|
||||
#[pymodule(sub)]
|
||||
mod lock {
|
||||
use crate::{stdlib::thread::RawRMutex, PyResult, VirtualMachine};
|
||||
|
||||
@@ -39,7 +31,7 @@ mod lock {
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "threading"))]
|
||||
#[pymodule]
|
||||
#[pymodule(sub)]
|
||||
mod lock {
|
||||
use crate::vm::VirtualMachine;
|
||||
#[pyfunction]
|
||||
@@ -85,12 +77,12 @@ fn find_frozen(name: &str, vm: &VirtualMachine) -> Result<FrozenModule, FrozenEr
|
||||
.ok_or(FrozenError::NotFound)
|
||||
}
|
||||
|
||||
#[pymodule]
|
||||
#[pymodule(with(lock))]
|
||||
mod _imp {
|
||||
use crate::{
|
||||
builtins::{PyBytesRef, PyCode, PyMemoryView, PyModule, PyStrRef},
|
||||
function::OptionalArg,
|
||||
import, PyObjectRef, PyRef, PyResult, TryFromObject, VirtualMachine,
|
||||
import, PyObjectRef, PyRef, PyResult, VirtualMachine,
|
||||
};
|
||||
|
||||
#[pyattr]
|
||||
@@ -117,16 +109,16 @@ mod _imp {
|
||||
#[pyfunction]
|
||||
fn create_builtin(spec: PyObjectRef, vm: &VirtualMachine) -> PyResult {
|
||||
let sys_modules = vm.sys_module.get_attr("modules", vm).unwrap();
|
||||
let name = spec.get_attr("name", vm)?;
|
||||
let name = PyStrRef::try_from_object(vm, name)?;
|
||||
let name: PyStrRef = spec.get_attr("name", vm)?.try_into_value(vm)?;
|
||||
|
||||
if let Ok(module) = sys_modules.get_item(&*name, vm) {
|
||||
Ok(module)
|
||||
let module = if let Ok(module) = sys_modules.get_item(&*name, vm) {
|
||||
module
|
||||
} else if let Some(make_module_func) = vm.state.module_inits.get(name.as_str()) {
|
||||
Ok(make_module_func(vm).into())
|
||||
make_module_func(vm).into()
|
||||
} else {
|
||||
Ok(vm.ctx.none())
|
||||
}
|
||||
vm.ctx.none()
|
||||
};
|
||||
Ok(module)
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
|
||||
@@ -51,7 +51,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
let module = _io::make_module(vm);
|
||||
|
||||
#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))]
|
||||
fileio::extend_module(vm, &module);
|
||||
fileio::extend_module(vm, &module).unwrap();
|
||||
|
||||
let unsupported_operation = _io::UNSUPPORTED_OPERATION
|
||||
.get_or_init(|| _io::make_unsupportedop(ctx))
|
||||
|
||||
@@ -8,7 +8,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
module
|
||||
}
|
||||
|
||||
#[pymodule(name = "nt")]
|
||||
#[pymodule(name = "nt", with(super::os::_os))]
|
||||
pub(crate) mod module {
|
||||
use crate::{
|
||||
builtins::{PyStrRef, PyTupleRef},
|
||||
|
||||
@@ -299,7 +299,7 @@ fn bytes_as_osstr<'a>(b: &'a [u8], vm: &VirtualMachine) -> PyResult<&'a ffi::OsS
|
||||
.map_err(|_| vm.new_unicode_decode_error("can't decode path for utf-8".to_owned()))
|
||||
}
|
||||
|
||||
#[pymodule(name = "_os")]
|
||||
#[pymodule(sub)]
|
||||
pub(super) mod _os {
|
||||
use super::{
|
||||
errno_err, DirFd, FollowSymlinks, IOErrorBuilder, OsPath, OsPathOrFd, OutputMode,
|
||||
@@ -1710,8 +1710,6 @@ impl SupportFunc {
|
||||
}
|
||||
|
||||
pub fn extend_module(vm: &VirtualMachine, module: &Py<PyModule>) {
|
||||
_os::extend_module(vm, module);
|
||||
|
||||
let support_funcs = _os::support_funcs();
|
||||
let supports_fd = PySet::default().into_ref(&vm.ctx);
|
||||
let supports_dir_fd = PySet::default().into_ref(&vm.ctx);
|
||||
|
||||
@@ -18,7 +18,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
module
|
||||
}
|
||||
|
||||
#[pymodule(name = "posix")]
|
||||
#[pymodule(name = "posix", with(super::os::_os))]
|
||||
pub mod module {
|
||||
use crate::{
|
||||
builtins::{PyDictRef, PyInt, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
//! `posix` compatible module for `not(any(unix, windows))`
|
||||
|
||||
use crate::{builtins::PyModule, PyObjectRef, PyRef, VirtualMachine};
|
||||
use crate::{builtins::PyModule, PyRef, VirtualMachine};
|
||||
|
||||
pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
let module = module::make_module(vm);
|
||||
@@ -8,7 +7,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
module
|
||||
}
|
||||
|
||||
#[pymodule(name = "posix")]
|
||||
#[pymodule(name = "posix", with(super::os::_os))]
|
||||
pub(crate) mod module {
|
||||
use crate::{
|
||||
builtins::PyStrRef,
|
||||
|
||||
@@ -917,7 +917,7 @@ mod sys {
|
||||
}
|
||||
|
||||
pub(crate) fn init_module(vm: &VirtualMachine, module: &Py<PyModule>, builtins: &Py<PyModule>) {
|
||||
sys::extend_module(vm, module);
|
||||
sys::extend_module(vm, module).unwrap();
|
||||
|
||||
let modules = vm.ctx.new_dict();
|
||||
modules
|
||||
|
||||
@@ -2,21 +2,9 @@
|
||||
|
||||
// See also:
|
||||
// https://docs.python.org/3/library/time.html
|
||||
use crate::{builtins::PyModule, PyRef, VirtualMachine};
|
||||
|
||||
pub use time::*;
|
||||
|
||||
pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
|
||||
let module = time::make_module(vm);
|
||||
#[cfg(unix)]
|
||||
unix::extend_module(vm, &module);
|
||||
#[cfg(windows)]
|
||||
windows::extend_module(vm, &module);
|
||||
|
||||
module
|
||||
}
|
||||
|
||||
#[pymodule(name = "time")]
|
||||
#[pymodule(name = "time", with(platform))]
|
||||
mod time {
|
||||
use crate::{
|
||||
builtins::{PyStrRef, PyTypeRef},
|
||||
@@ -386,15 +374,12 @@ mod time {
|
||||
}
|
||||
|
||||
#[allow(unused_imports)]
|
||||
#[cfg(unix)]
|
||||
use super::unix::*;
|
||||
#[cfg(windows)]
|
||||
use super::windows::*;
|
||||
use super::platform::*;
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[pymodule(name = "time")]
|
||||
mod unix {
|
||||
#[pymodule(sub)]
|
||||
mod platform {
|
||||
#[allow(unused_imports)]
|
||||
use super::{SEC_TO_NS, US_TO_NS};
|
||||
#[cfg_attr(target_os = "macos", allow(unused_imports))]
|
||||
@@ -631,8 +616,8 @@ mod unix {
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[pymodule(name = "time")]
|
||||
mod windows {
|
||||
#[pymodule]
|
||||
mod platform {
|
||||
use super::{time_muldiv, MS_TO_NS, SEC_TO_NS};
|
||||
use crate::{
|
||||
builtins::{PyNamespace, PyStrRef},
|
||||
@@ -815,3 +800,8 @@ mod windows {
|
||||
Ok(Duration::from_nanos((k_time + u_time) * 100))
|
||||
}
|
||||
}
|
||||
|
||||
// mostly for wasm32
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
#[pymodule(sub)]
|
||||
mod platform {}
|
||||
|
||||
@@ -118,7 +118,7 @@ impl VirtualMachine {
|
||||
// set __spec__, __loader__, etc. attributes
|
||||
let new_module = || {
|
||||
PyRef::new_ref(
|
||||
PyModule {},
|
||||
PyModule::new(),
|
||||
ctx.types.module_type.to_owned(),
|
||||
Some(ctx.new_dict()),
|
||||
)
|
||||
@@ -200,9 +200,9 @@ impl VirtualMachine {
|
||||
PyRc::get_mut(&mut vm.state).unwrap().frozen = frozen;
|
||||
|
||||
vm.builtins
|
||||
.init_module_dict(vm.ctx.intern_str("builtins"), vm.ctx.none(), &vm);
|
||||
.init_module_dict(vm.ctx.intern_str("builtins"), None, &vm);
|
||||
vm.sys_module
|
||||
.init_module_dict(vm.ctx.intern_str("sys"), vm.ctx.none(), &vm);
|
||||
.init_module_dict(vm.ctx.intern_str("sys"), None, &vm);
|
||||
|
||||
vm
|
||||
}
|
||||
|
||||
@@ -22,14 +22,13 @@ impl VirtualMachine {
|
||||
|
||||
pub fn new_module(&self, name: &str, dict: PyDictRef, doc: Option<&str>) -> PyRef<PyModule> {
|
||||
let module = PyRef::new_ref(
|
||||
PyModule {},
|
||||
PyModule::new(),
|
||||
self.ctx.types.module_type.to_owned(),
|
||||
Some(dict),
|
||||
);
|
||||
module.init_module_dict(
|
||||
self.ctx.intern_str(name),
|
||||
doc.map(|doc| self.new_pyobj(doc.to_owned()))
|
||||
.unwrap_or_else(|| self.ctx.none()),
|
||||
doc.map(|doc| self.ctx.new_str(doc)),
|
||||
self,
|
||||
);
|
||||
module
|
||||
|
||||
Reference in New Issue
Block a user