Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8b7c26a

Browse files
committed
Implement Py_mod_create slot support in multi-phase init
1 parent bc02b23 commit 8b7c26a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+788
-739
lines changed

benches/execution.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,9 @@ fn bench_rustpython_code(b: &mut Bencher, name: &str, source: &str) {
2424
settings.path_list.push("Lib/".to_string());
2525
settings.write_bytecode = false;
2626
settings.user_site_directory = false;
27-
Interpreter::with_init(settings, |vm| {
28-
vm.add_native_modules(rustpython_stdlib::get_module_inits());
29-
})
30-
.enter(|vm| {
27+
let builder = Interpreter::builder(settings);
28+
let defs = rustpython_stdlib::stdlib_module_defs(&builder.ctx);
29+
builder.add_native_modules(&defs).build().enter(|vm| {
3130
// Note: bench_cpython is both compiling and executing the code.
3231
// As such we compile the code in the benchmark loop as well.
3332
b.iter(|| {

benches/microbenchmarks.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ fn bench_rustpython_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenc
113113
settings.write_bytecode = false;
114114
settings.user_site_directory = false;
115115

116-
Interpreter::with_init(settings, |vm| {
117-
vm.add_native_module_defs(rustpython_stdlib::get_module_defs());
118-
})
119-
.enter(|vm| {
116+
let builder = Interpreter::builder(settings);
117+
let defs = rustpython_stdlib::stdlib_module_defs(&builder.ctx);
118+
let interp = builder.add_native_modules(&defs).build();
119+
interp.enter(|vm| {
120120
let setup_code = vm
121121
.compile(&bench.setup, Mode::Exec, bench.name.to_owned())
122122
.expect("Error compiling setup code");

crates/derive-impl/src/pymodule.rs

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,18 +144,6 @@ pub fn impl_pymodule(attr: PunctuatedNestedMeta, module_item: Item) -> Result<To
144144
})
145145
}
146146
},
147-
parse_quote! {
148-
#[allow(dead_code)]
149-
pub(crate) fn make_module(
150-
vm: &::rustpython_vm::VirtualMachine
151-
) -> ::rustpython_vm::PyRef<::rustpython_vm::builtins::PyModule> {
152-
use ::rustpython_vm::PyPayload;
153-
let module = ::rustpython_vm::builtins::PyModule::from_def(module_def(&vm.ctx)).into_ref(&vm.ctx);
154-
__init_dict(vm, &module);
155-
module_exec(vm, &module).unwrap();
156-
module
157-
}
158-
},
159147
]);
160148
}
161149
if !is_submodule && !context.has_module_exec {
@@ -202,7 +190,6 @@ pub fn impl_pymodule(attr: PunctuatedNestedMeta, module_item: Item) -> Result<To
202190
vm: &::rustpython_vm::VirtualMachine,
203191
module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>,
204192
) {
205-
module.__init_methods(vm).unwrap();
206193
__init_attributes(vm, module);
207194
}
208195
},

crates/derive/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub fn pyexception(attr: TokenStream, item: TokenStream) -> TokenStream {
144144

145145
/// This attribute must be applied to an inline module.
146146
/// It defines a Python module in the form of a `module_def` function in the module;
147-
/// this has to be used in a `get_module_defs` to properly register the module.
147+
/// this has to be used in a `add_native_module` to properly register the module.
148148
/// Additionally, this macro defines 'MODULE_NAME' and 'DOC' in the module.
149149
/// # Arguments
150150
/// - `name`: the name of the python module,
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
pub(crate) use opcode::module_def;
1+
pub(crate) use _opcode::module_def;
22

33
#[pymodule]
4-
mod opcode {
4+
mod _opcode {
55
use crate::vm::{
66
AsObject, PyObjectRef, PyResult, VirtualMachine,
77
builtins::{PyInt, PyIntRef},
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
// spell-checker:ignore cantlock commithook foreignkey notnull primarykey gettemppath autoindex convpath
99
// spell-checker:ignore dbmoved vnode nbytes
1010

11-
pub(crate) use _sqlite::module_def;
11+
pub(crate) use _sqlite3::module_def;
1212

1313
#[pymodule]
14-
mod _sqlite {
14+
mod _sqlite3 {
1515
use libsqlite3_sys::{
1616
SQLITE_BLOB, SQLITE_DETERMINISTIC, SQLITE_FLOAT, SQLITE_INTEGER, SQLITE_NULL,
1717
SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE, SQLITE_OPEN_URI, SQLITE_TEXT, SQLITE_TRACE_STMT,

crates/stdlib/src/lib.rs

Lines changed: 76 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ mod json;
3838
#[cfg(not(any(target_os = "ios", target_arch = "wasm32")))]
3939
mod locale;
4040

41+
mod _opcode;
4142
mod math;
4243
#[cfg(any(unix, windows))]
4344
mod mmap;
44-
mod opcode;
4545
mod pyexpat;
4646
mod pystruct;
4747
mod random;
@@ -65,6 +65,11 @@ mod posixshmem;
6565
#[cfg(unix)]
6666
mod posixsubprocess;
6767
// libc is missing constants on redox
68+
#[cfg(all(
69+
feature = "sqlite",
70+
not(any(target_os = "android", target_arch = "wasm32"))
71+
))]
72+
mod _sqlite3;
6873
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
6974
mod grp;
7075
#[cfg(windows)]
@@ -75,11 +80,6 @@ mod resource;
7580
mod scproxy;
7681
#[cfg(any(unix, windows, target_os = "wasi"))]
7782
mod select;
78-
#[cfg(all(
79-
feature = "sqlite",
80-
not(any(target_os = "android", target_arch = "wasm32"))
81-
))]
82-
mod sqlite;
8383

8484
#[cfg(all(not(target_arch = "wasm32"), feature = "ssl-openssl"))]
8585
mod openssl;
@@ -105,131 +105,87 @@ mod tkinter;
105105
use rustpython_common as common;
106106
use rustpython_vm as vm;
107107

108-
use crate::vm::{builtins, stdlib::StdlibDefFunc};
109-
use alloc::borrow::Cow;
108+
use crate::vm::{Context, builtins};
110109

111110
/// Returns module definitions for multi-phase init modules.
112111
/// These modules are added to sys.modules BEFORE their exec function runs,
113112
/// allowing safe circular imports.
114-
pub fn get_module_defs() -> impl Iterator<Item = (Cow<'static, str>, StdlibDefFunc)> {
115-
macro_rules! modules {
116-
{
117-
$(
118-
#[cfg($cfg:meta)]
119-
{ $( $key:expr => $val:expr),* $(,)? }
120-
)*
121-
} => {{
122-
[
123-
$(
124-
$(#[cfg($cfg)] (Cow::<'static, str>::from($key), $val as StdlibDefFunc),)*
125-
)*
126-
]
127-
.into_iter()
128-
}};
129-
}
130-
modules! {
131-
#[cfg(all())]
132-
{
133-
"array" => array::module_def,
134-
"binascii" => binascii::module_def,
135-
"_bisect" => bisect::module_def,
136-
"_blake2" => blake2::module_def,
137-
"_bz2" => bz2::module_def,
138-
"cmath" => cmath::module_def,
139-
"_contextvars" => contextvars::module_def,
140-
"_csv" => csv::module_def,
141-
"faulthandler" => faulthandler::module_def,
142-
"gc" => gc::module_def,
143-
"_hashlib" => hashlib::module_def,
144-
"_json" => json::module_def,
145-
"math" => math::module_def,
146-
"_md5" => md5::module_def,
147-
"_opcode" => opcode::module_def,
148-
"_random" => random::module_def,
149-
"_sha1" => sha1::module_def,
150-
"_sha256" => sha256::module_def,
151-
"_sha3" => sha3::module_def,
152-
"_sha512" => sha512::module_def,
153-
"_statistics" => statistics::module_def,
154-
"_struct" => pystruct::module_def,
155-
"_suggestions" => suggestions::module_def,
156-
"zlib" => zlib::module_def,
157-
"pyexpat" => pyexpat::module_def,
158-
"unicodedata" => unicodedata::module_def,
159-
}
113+
pub fn stdlib_module_defs(ctx: &Context) -> Vec<&'static builtins::PyModuleDef> {
114+
vec![
115+
_opcode::module_def(ctx),
116+
array::module_def(ctx),
117+
binascii::module_def(ctx),
118+
bisect::module_def(ctx),
119+
blake2::module_def(ctx),
120+
bz2::module_def(ctx),
121+
cmath::module_def(ctx),
122+
contextvars::module_def(ctx),
123+
csv::module_def(ctx),
124+
faulthandler::module_def(ctx),
160125
#[cfg(any(unix, target_os = "wasi"))]
161-
{
162-
"fcntl" => fcntl::module_def,
163-
}
164-
#[cfg(any(unix, windows, target_os = "wasi"))]
165-
{
166-
"select" => select::module_def,
167-
}
168-
#[cfg(not(target_arch = "wasm32"))]
169-
{
170-
"_multiprocessing" => multiprocessing::module_def,
171-
"_socket" => socket::module_def,
172-
}
126+
fcntl::module_def(ctx),
127+
gc::module_def(ctx),
128+
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
129+
grp::module_def(ctx),
130+
hashlib::module_def(ctx),
131+
json::module_def(ctx),
132+
#[cfg(not(any(target_os = "ios", target_arch = "wasm32")))]
133+
locale::module_def(ctx),
173134
#[cfg(not(any(target_os = "android", target_arch = "wasm32")))]
174-
{
175-
"_lzma" => lzma::module_def,
176-
}
177-
#[cfg(all(feature = "sqlite", not(any(target_os = "android", target_arch = "wasm32"))))]
178-
{
179-
"_sqlite3" => sqlite::module_def,
180-
}
181-
#[cfg(all(not(target_arch = "wasm32"), feature = "ssl-rustls"))]
182-
{
183-
"_ssl" => ssl::module_def,
184-
}
135+
lzma::module_def(ctx),
136+
math::module_def(ctx),
137+
md5::module_def(ctx),
138+
#[cfg(any(unix, windows))]
139+
mmap::module_def(ctx),
140+
#[cfg(not(target_arch = "wasm32"))]
141+
multiprocessing::module_def(ctx),
185142
#[cfg(all(not(target_arch = "wasm32"), feature = "ssl-openssl"))]
186-
{
187-
"_ssl" => openssl::module_def,
188-
}
143+
openssl::module_def(ctx),
189144
#[cfg(windows)]
190-
{
191-
"_overlapped" => overlapped::module_def,
192-
}
145+
overlapped::module_def(ctx),
193146
#[cfg(unix)]
194-
{
195-
"_posixsubprocess" => posixsubprocess::module_def,
196-
}
147+
posixsubprocess::module_def(ctx),
197148
#[cfg(all(unix, not(target_os = "redox"), not(target_os = "android")))]
198-
{
199-
"_posixshmem" => posixshmem::module_def,
200-
}
201-
#[cfg(any(unix, windows))]
202-
{
203-
"mmap" => mmap::module_def,
204-
}
149+
posixshmem::module_def(ctx),
150+
pyexpat::module_def(ctx),
151+
pystruct::module_def(ctx),
152+
random::module_def(ctx),
205153
#[cfg(all(unix, not(target_os = "redox")))]
206-
{
207-
"syslog" => syslog::module_def,
208-
"resource" => resource::module_def,
209-
}
210-
#[cfg(all(unix, not(any(target_os = "ios", target_os = "redox"))))]
211-
{
212-
"termios" => termios::module_def,
213-
}
214-
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
215-
{
216-
"grp" => grp::module_def,
217-
}
154+
resource::module_def(ctx),
218155
#[cfg(target_os = "macos")]
219-
{
220-
"_scproxy" => scproxy::module_def,
221-
}
222-
#[cfg(not(any(target_os = "android", target_os = "ios", target_os = "windows", target_arch = "wasm32", target_os = "redox")))]
223-
{
224-
"_uuid" => uuid::module_def,
225-
}
226-
#[cfg(not(any(target_os = "ios", target_arch = "wasm32")))]
227-
{
228-
"_locale" => locale::module_def,
229-
}
156+
scproxy::module_def(ctx),
157+
#[cfg(any(unix, windows, target_os = "wasi"))]
158+
select::module_def(ctx),
159+
sha1::module_def(ctx),
160+
sha256::module_def(ctx),
161+
sha3::module_def(ctx),
162+
sha512::module_def(ctx),
163+
#[cfg(not(target_arch = "wasm32"))]
164+
socket::module_def(ctx),
165+
#[cfg(all(
166+
feature = "sqlite",
167+
not(any(target_os = "android", target_arch = "wasm32"))
168+
))]
169+
_sqlite3::module_def(ctx),
170+
#[cfg(all(not(target_arch = "wasm32"), feature = "ssl-rustls"))]
171+
ssl::module_def(ctx),
172+
statistics::module_def(ctx),
173+
suggestions::module_def(ctx),
174+
#[cfg(all(unix, not(target_os = "redox")))]
175+
syslog::module_def(ctx),
176+
#[cfg(all(unix, not(any(target_os = "ios", target_os = "redox"))))]
177+
termios::module_def(ctx),
230178
#[cfg(feature = "tkinter")]
231-
{
232-
"_tkinter" => tkinter::module_def,
233-
}
234-
}
179+
tkinter::module_def(ctx),
180+
unicodedata::module_def(ctx),
181+
#[cfg(not(any(
182+
target_os = "android",
183+
target_os = "ios",
184+
target_os = "windows",
185+
target_arch = "wasm32",
186+
target_os = "redox"
187+
)))]
188+
uuid::module_def(ctx),
189+
zlib::module_def(ctx),
190+
]
235191
}

crates/stdlib/src/openssl.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,18 @@ use std::sync::LazyLock;
3333
cfg_if::cfg_if! {
3434
if #[cfg(openssl_vendored)] {
3535
static PROBE: LazyLock<ProbeResult> = LazyLock::new(openssl_probe::probe);
36-
fn probe() -> &'static ProbeResult { &PROBE }
3736
} else {
38-
static EMPTY_PROBE: LazyLock<ProbeResult> = LazyLock::new(|| ProbeResult { cert_file: None, cert_dir: vec![] });
39-
fn probe() -> &'static ProbeResult {
40-
&EMPTY_PROBE
41-
}
37+
static PROBE: LazyLock<ProbeResult> = LazyLock::new(|| ProbeResult { cert_file: None, cert_dir: vec![] });
4238
}
4339
}
4440

41+
fn probe() -> &'static ProbeResult {
42+
&PROBE
43+
}
44+
4545
#[allow(non_upper_case_globals)]
4646
#[pymodule(with(cert::ssl_cert, ssl_error::ssl_error, ossl101, ossl111, windows))]
4747
mod _ssl {
48-
#[cfg(openssl_vendored)]
49-
use super::PROBE;
5048
use super::{bio, probe};
5149

5250
// Import error types and helpers used in this module (others are exposed via pymodule(with(...)))
@@ -103,7 +101,7 @@ mod _ssl {
103101
// if openssl is vendored, it doesn't know the locations
104102
// of system certificates - cache the probe result now.
105103
#[cfg(openssl_vendored)]
106-
std::sync::LazyLock::force(&PROBE);
104+
std::sync::LazyLock::force(&super::PROBE);
107105

108106
__module_exec(vm, module);
109107
Ok(())

crates/stdlib/src/pyexpat.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ mod _pyexpat {
4242
use crate::vm::{
4343
Context, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine,
4444
builtins::{PyBytesRef, PyModule, PyStr, PyStrRef, PyType},
45+
extend_module,
4546
function::ArgBytesLike,
4647
function::{Either, IntoFuncArgs, OptionalArg},
4748
};
@@ -53,10 +54,13 @@ mod _pyexpat {
5354
__module_exec(vm, module);
5455

5556
// Add submodules
56-
let model = PyModule::from_def(super::_model::module_def(&vm.ctx)).into_ref(&vm.ctx);
57-
let errors = PyModule::from_def(super::_errors::module_def(&vm.ctx)).into_ref(&vm.ctx);
58-
module.set_attr("model", model, vm)?;
59-
module.set_attr("errors", errors, vm)?;
57+
let model = super::_model::module_def(&vm.ctx).create_module(vm)?;
58+
let errors = super::_errors::module_def(&vm.ctx).create_module(vm)?;
59+
60+
extend_module!(vm, module, {
61+
"model" => model,
62+
"errors" => errors,
63+
});
6064

6165
Ok(())
6266
}

0 commit comments

Comments
 (0)