PyModuleDef and #[pymodule(with(...))]

This commit is contained in:
Jeong YunWon
2023-04-20 21:44:50 +09:00
parent cbcdcf4ad5
commit 317f432a20
16 changed files with 323 additions and 122 deletions

View File

@@ -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(())

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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;

View File

@@ -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(())
}
}

View File

@@ -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, {

View File

@@ -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]

View File

@@ -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))

View File

@@ -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},

View File

@@ -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);

View File

@@ -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},

View File

@@ -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,

View File

@@ -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

View File

@@ -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 {}

View File

@@ -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
}

View File

@@ -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