GeezerVison is showing github.com — Merge pull request #6740 from youknowone/multi-phase-module-init · RustPython/RustPython@47df6dd
File treeExpand file treeCollapse file tree Open diff view settings example_projects/frozen_stdlib/src
Some content is hiddenLarge Commits have some content hidden by default. Use the searchbox below for content that may be hidden. Dismiss bannerExpand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: Lib/test/test_pickle.py -46Lines changed: 0 additions & 46 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -136,46 +136,6 @@ def test_c_methods(self): # TODO(RUSTPYTHON): Remove this test when it passes | 136 | 136 | def test_buffers_error(self): # TODO(RUSTPYTHON): Remove this test when it passes | 137 | 137 | return super().test_buffers_error() | 138 | 138 |
| 139 | | - # TODO: RUSTPYTHON | 140 | | - @unittest.expectedFailure | 141 | | - def test_builtin_functions(self): # TODO(RUSTPYTHON): Remove this test when it passes | 142 | | - return super().test_builtin_functions() | 143 | | - | 144 | | - # TODO: RUSTPYTHON | 145 | | - @unittest.expectedFailure | 146 | | - def test_bytearray_memoization(self): # TODO(RUSTPYTHON): Remove this test when it passes | 147 | | - return super().test_bytearray_memoization() | 148 | | - | 149 | | - # TODO: RUSTPYTHON | 150 | | - @unittest.expectedFailure | 151 | | - def test_bytes_memoization(self): # TODO(RUSTPYTHON): Remove this test when it passes | 152 | | - return super().test_bytes_memoization() | 153 | | - | 154 | | - # TODO: RUSTPYTHON | 155 | | - @unittest.expectedFailure | 156 | | - def test_in_band_buffers(self): # TODO(RUSTPYTHON): Remove this test when it passes | 157 | | - return super().test_in_band_buffers() | 158 | | - | 159 | | - # TODO: RUSTPYTHON | 160 | | - @unittest.expectedFailure | 161 | | - def test_oob_buffers(self): # TODO(RUSTPYTHON): Remove this test when it passes | 162 | | - return super().test_oob_buffers() | 163 | | - | 164 | | - # TODO: RUSTPYTHON | 165 | | - @unittest.expectedFailure | 166 | | - def test_oob_buffers_writable_to_readonly(self): # TODO(RUSTPYTHON): Remove this test when it passes | 167 | | - return super().test_oob_buffers_writable_to_readonly() | 168 | | - | 169 | | - # TODO: RUSTPYTHON | 170 | | - @unittest.expectedFailure | 171 | | - def test_buffers_error(self): # TODO(RUSTPYTHON): Remove this test when it passes | 172 | | - return super().test_buffers_error() | 173 | | - | 174 | | - # TODO: RUSTPYTHON | 175 | | - @unittest.expectedFailure | 176 | | - def test_builtin_functions(self): # TODO(RUSTPYTHON): Remove this test when it passes | 177 | | - return super().test_builtin_functions() | 178 | | - | 179 | 139 | # TODO: RUSTPYTHON | 180 | 140 | @unittest.expectedFailure | 181 | 141 | def test_bytearray_memoization(self): # TODO(RUSTPYTHON): Remove this test when it passes | @@ -201,7 +161,6 @@ def test_oob_buffers(self): # TODO(RUSTPYTHON): Remove this test when it passes | 201 | 161 | def test_oob_buffers_writable_to_readonly(self): # TODO(RUSTPYTHON): Remove this test when it passes | 202 | 162 | return super().test_oob_buffers_writable_to_readonly() | 203 | 163 |
| 204 | | - | 205 | 164 | class InMemoryPickleTests(AbstractPickleTests, AbstractUnpickleTests, | 206 | 165 | BigmemPickleTests, unittest.TestCase): | 207 | 166 |
| @@ -250,11 +209,6 @@ def test_oob_buffers_writable_to_readonly(self): # TODO(RUSTPYTHON): Remove this | 250 | 209 | def test_buffers_error(self): # TODO(RUSTPYTHON): Remove this test when it passes | 251 | 210 | return super().test_buffers_error() | 252 | 211 |
| 253 | | - # TODO: RUSTPYTHON | 254 | | - @unittest.expectedFailure | 255 | | - def test_builtin_functions(self): # TODO(RUSTPYTHON): Remove this test when it passes | 256 | | - return super().test_builtin_functions() | 257 | | - | 258 | 212 | # TODO: RUSTPYTHON | 259 | 213 | @unittest.expectedFailure | 260 | 214 | def test_bytearray_memoization(self): # TODO(RUSTPYTHON): Remove this test when it passes | |
Collapse file Copy file name to clipboardExpand all lines: Lib/test/test_pickletools.py -5Lines changed: 0 additions & 5 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -67,11 +67,6 @@ def test_optimize_binput_and_memoize(self): | 67 | 67 | def test_buffers_error(self): # TODO(RUSTPYTHON): Remove this test when it passes | 68 | 68 | return super().test_buffers_error() | 69 | 69 |
| 70 | | - # TODO: RUSTPYTHON | 71 | | - @unittest.expectedFailure | 72 | | - def test_builtin_functions(self): # TODO(RUSTPYTHON): Remove this test when it passes | 73 | | - return super().test_builtin_functions() | 74 | | - | 75 | 70 | # TODO: RUSTPYTHON | 76 | 71 | @unittest.expectedFailure | 77 | 72 | def test_bytearray_memoization(self): # TODO(RUSTPYTHON): Remove this test when it passes | |
Collapse file Copy file name to clipboardExpand all lines: benches/execution.rs +3-4Lines changed: 3 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -24,10 +24,9 @@ fn bench_rustpython_code(b: &mut Bencher, name: &str, source: &str) { | 24 | 24 | settings.path_list.push("Lib/".to_string()); | 25 | 25 | settings.write_bytecode = false; | 26 | 26 | 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| { | 31 | 30 | // Note: bench_cpython is both compiling and executing the code. | 32 | 31 | // As such we compile the code in the benchmark loop as well. | 33 | 32 | b.iter(|| { | |
Collapse file Copy file name to clipboardExpand all lines: benches/microbenchmarks.rs +4-6Lines changed: 4 additions & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -113,12 +113,10 @@ fn bench_rustpython_code(group: &mut BenchmarkGroup<WallTime>, bench: &MicroBenc | 113 | 113 | settings.write_bytecode = false; | 114 | 114 | settings.user_site_directory = false; | 115 | 115 |
| 116 | | - Interpreter::with_init(settings, |vm| { | 117 | | - for (name, init) in rustpython_stdlib::get_module_inits() { | 118 | | - vm.add_native_module(name, init); | 119 | | - } | 120 | | - }) | 121 | | - .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| { | 122 | 120 | let setup_code = vm | 123 | 121 | .compile(&bench.setup, Mode::Exec, bench.name.to_owned()) | 124 | 122 | .expect("Error compiling setup code"); | |
Collapse file Copy file name to clipboardExpand all lines: crates/common/src/crt_fd.rs +3-1Lines changed: 3 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -5,8 +5,10 @@ use alloc::fmt; | 5 | 5 | use core::cmp; | 6 | 6 | use std::{ffi, io}; | 7 | 7 |
| | 8 | +#[cfg(unix)] | | 9 | +use std::os::fd::AsFd; | 8 | 10 | #[cfg(not(windows))] | 9 | | -use std::os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; | | 11 | +use std::os::fd::{AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; | 10 | 12 | #[cfg(windows)] | 11 | 13 | use std::os::windows::io::BorrowedHandle; | 12 | 14 |
| |
Collapse file Copy file name to clipboardExpand all lines: crates/derive-impl/src/pymodule.rs +13-20Lines changed: 13 additions & 20 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -58,7 +58,7 @@ struct ModuleContext { | 58 | 58 | name: String, | 59 | 59 | function_items: FunctionNursery, | 60 | 60 | attribute_items: ItemNursery, | 61 | | - has_extend_module: bool, // TODO: check if `fn extend_module` exists | | 61 | + has_module_exec: bool, | 62 | 62 | errors: Vec<syn::Error>, | 63 | 63 | } | 64 | 64 |
| @@ -82,6 +82,12 @@ pub fn impl_pymodule(attr: PunctuatedNestedMeta, module_item: Item) -> Result<To | 82 | 82 |
| 83 | 83 | // collect to context | 84 | 84 | for item in items.iter_mut() { | | 85 | + // Check if module_exec function is already defined | | 86 | + if let Item::Fn(func) = item | | 87 | + && func.sig.ident == "module_exec" | | 88 | + { | | 89 | + context.has_module_exec = true; | | 90 | + } | 85 | 91 | if matches!(item, Item::Impl(_) | Item::Trait(_)) { | 86 | 92 | // #[pyclass] implementations | 87 | 93 | continue; | @@ -123,7 +129,7 @@ pub fn impl_pymodule(attr: PunctuatedNestedMeta, module_item: Item) -> Result<To | 123 | 129 | pub(crate) const DOC: Option<&'static str> = #doc; | 124 | 130 | }, | 125 | 131 | parse_quote! { | 126 | | - pub(crate) fn __module_def( | | 132 | + pub(crate) fn module_def( | 127 | 133 | ctx: &::rustpython_vm::Context, | 128 | 134 | ) -> &'static ::rustpython_vm::builtins::PyModuleDef { | 129 | 135 | DEF.get_or_init(|| { | @@ -133,29 +139,17 @@ pub fn impl_pymodule(attr: PunctuatedNestedMeta, module_item: Item) -> Result<To | 133 | 139 | methods: METHOD_DEFS, | 134 | 140 | slots: Default::default(), | 135 | 141 | }; | 136 | | - def.slots.exec = Some(extend_module); | | 142 | + def.slots.exec = Some(module_exec); | 137 | 143 | def | 138 | 144 | }) | 139 | 145 | } | 140 | 146 | }, | 141 | | - parse_quote! { | 142 | | - #[allow(dead_code)] | 143 | | - pub(crate) fn make_module( | 144 | | - vm: &::rustpython_vm::VirtualMachine | 145 | | - ) -> ::rustpython_vm::PyRef<::rustpython_vm::builtins::PyModule> { | 146 | | - use ::rustpython_vm::PyPayload; | 147 | | - let module = ::rustpython_vm::builtins::PyModule::from_def(__module_def(&vm.ctx)).into_ref(&vm.ctx); | 148 | | - __init_dict(vm, &module); | 149 | | - extend_module(vm, &module).unwrap(); | 150 | | - module | 151 | | - } | 152 | | - }, | 153 | 147 | ]); | 154 | 148 | } | 155 | | - if !is_submodule && !context.has_extend_module { | | 149 | + if !is_submodule && !context.has_module_exec { | 156 | 150 | items.push(parse_quote! { | 157 | | - pub(crate) fn extend_module(vm: &::rustpython_vm::VirtualMachine, module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>) -> ::rustpython_vm::PyResult<()> { | 158 | | - __extend_module(vm, module); | | 151 | + pub(crate) fn module_exec(vm: &::rustpython_vm::VirtualMachine, module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>) -> ::rustpython_vm::PyResult<()> { | | 152 | + __module_exec(vm, module); | 159 | 153 | Ok(()) | 160 | 154 | } | 161 | 155 | }); | @@ -192,11 +186,10 @@ pub fn impl_pymodule(attr: PunctuatedNestedMeta, module_item: Item) -> Result<To | 192 | 186 | } | 193 | 187 | }, | 194 | 188 | parse_quote! { | 195 | | - pub(crate) fn __extend_module( | | 189 | + pub(crate) fn __module_exec( | 196 | 190 | vm: &::rustpython_vm::VirtualMachine, | 197 | 191 | module: &::rustpython_vm::Py<::rustpython_vm::builtins::PyModule>, | 198 | 192 | ) { | 199 | | - module.__init_methods(vm).unwrap(); | 200 | 193 | __init_attributes(vm, module); | 201 | 194 | } | 202 | 195 | }, | |
Collapse file Copy file name to clipboardExpand all lines: crates/derive/src/lib.rs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -143,8 +143,8 @@ pub fn pyexception(attr: TokenStream, item: TokenStream) -> TokenStream { | 143 | 143 | } | 144 | 144 |
| 145 | 145 | /// This attribute must be applied to an inline module. | 146 | | -/// It defines a Python module in the form a `make_module` function in the module; | 147 | | -/// this has to be used in a `get_module_inits` to properly register the module. | | 146 | +/// It defines a Python module in the form of a `module_def` function in the module; | | 147 | +/// this has to be used in a `add_native_module` to properly register the module. | 148 | 148 | /// Additionally, this macro defines 'MODULE_NAME' and 'DOC' in the module. | 149 | 149 | /// # Arguments | 150 | 150 | /// - `name`: the name of the python module, | |
Collapse file Copy file name to clipboardExpand all lines: crates/stdlib/src/_opcode.rs +2-2Lines changed: 2 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | | -pub(crate) use opcode::make_module; | | 1 | +pub(crate) use _opcode::module_def; | 2 | 2 |
| 3 | 3 | #[pymodule] | 4 | | -mod opcode { | | 4 | +mod _opcode { | 5 | 5 | use crate::vm::{ | 6 | 6 | AsObject, PyObjectRef, PyResult, VirtualMachine, | 7 | 7 | builtins::{PyInt, PyIntRef}, | |
Collapse file Copy file name to clipboardExpand all lines: crates/stdlib/src/_sqlite3.rs +13-21Lines changed: 13 additions & 21 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 8 | 8 | // spell-checker:ignore cantlock commithook foreignkey notnull primarykey gettemppath autoindex convpath | 9 | 9 | // spell-checker:ignore dbmoved vnode nbytes | 10 | 10 |
| 11 | | -use rustpython_vm::{AsObject, PyRef, VirtualMachine, builtins::PyModule}; | 12 | | - | 13 | | -// pub(crate) use _sqlite::make_module; | 14 | | -pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> { | 15 | | - // TODO: sqlite version check | 16 | | - let module = _sqlite::make_module(vm); | 17 | | - _sqlite::setup_module(module.as_object(), vm); | 18 | | - module | 19 | | -} | | 11 | +pub(crate) use _sqlite3::module_def; | 20 | 12 |
| 21 | 13 | #[pymodule] | 22 | | -mod _sqlite { | | 14 | +mod _sqlite3 { | 23 | 15 | use libsqlite3_sys::{ | 24 | 16 | SQLITE_BLOB, SQLITE_DETERMINISTIC, SQLITE_FLOAT, SQLITE_INTEGER, SQLITE_NULL, | 25 | 17 | SQLITE_OPEN_CREATE, SQLITE_OPEN_READWRITE, SQLITE_OPEN_URI, SQLITE_TEXT, SQLITE_TRACE_STMT, | @@ -58,8 +50,8 @@ mod _sqlite { | 58 | 50 | TryFromBorrowedObject, VirtualMachine, atomic_func, | 59 | 51 | builtins::{ | 60 | 52 | PyBaseException, PyBaseExceptionRef, PyByteArray, PyBytes, PyDict, PyDictRef, PyFloat, | 61 | | - PyInt, PyIntRef, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, PyTypeRef, | 62 | | - PyUtf8Str, PyUtf8StrRef, | | 53 | + PyInt, PyIntRef, PyModule, PySlice, PyStr, PyStrRef, PyTuple, PyTupleRef, PyType, | | 54 | + PyTypeRef, PyUtf8Str, PyUtf8StrRef, | 63 | 55 | }, | 64 | 56 | convert::IntoObject, | 65 | 57 | function::{ | @@ -852,26 +844,26 @@ mod _sqlite { | 852 | 844 | .expect("enable traceback not initialize") | 853 | 845 | } | 854 | 846 |
| 855 | | - pub(super) fn setup_module(module: &PyObject, vm: &VirtualMachine) { | | 847 | + pub(crate) fn module_exec(vm: &VirtualMachine, module: &Py<PyModule>) -> PyResult<()> { | | 848 | + __module_exec(vm, module); | | 849 | + | 856 | 850 | for (name, code) in ERROR_CODES { | 857 | 851 | let name = vm.ctx.intern_str(*name); | 858 | 852 | let code = vm.new_pyobj(*code); | 859 | | - module.set_attr(name, code, vm).unwrap(); | | 853 | + module.set_attr(name, code, vm)?; | 860 | 854 | } | 861 | 855 |
| 862 | | - setup_module_exceptions(module, vm); | | 856 | + setup_module_exceptions(module.as_object(), vm); | 863 | 857 |
| 864 | 858 | let _ = CONVERTERS.set(vm.ctx.new_dict()); | 865 | 859 | let _ = ADAPTERS.set(vm.ctx.new_dict()); | 866 | 860 | let _ = USER_FUNCTION_EXCEPTION.set(PyAtomicRef::from(None)); | 867 | 861 | let _ = ENABLE_TRACEBACK.set(Radium::new(false)); | 868 | 862 |
| 869 | | - module | 870 | | - .set_attr("converters", converters().to_owned(), vm) | 871 | | - .unwrap(); | 872 | | - module | 873 | | - .set_attr("adapters", adapters().to_owned(), vm) | 874 | | - .unwrap(); | | 863 | + module.set_attr("converters", converters().to_owned(), vm)?; | | 864 | + module.set_attr("adapters", adapters().to_owned(), vm)?; | | 865 | + | | 866 | + Ok(()) | 875 | 867 | } | 876 | 868 |
| 877 | 869 | #[pyattr] | |
Collapse file Copy file name to clipboardExpand all lines: crates/stdlib/src/array.rs +22-28Lines changed: 22 additions & 28 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | // spell-checker:ignore typecode tofile tolist fromfile | 2 | 2 |
| 3 | | -use rustpython_vm::{PyRef, VirtualMachine, builtins::PyModule}; | 4 | | - | 5 | | -pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> { | 6 | | - let module = array::make_module(vm); | 7 | | - | 8 | | - let array = module | 9 | | - .get_attr("array", vm) | 10 | | - .expect("Expect array has array type."); | 11 | | - | 12 | | - let collections_abc = vm | 13 | | - .import("collections.abc", 0) | 14 | | - .expect("Expect collections exist."); | 15 | | - let abc = collections_abc | 16 | | - .get_attr("abc", vm) | 17 | | - .expect("Expect collections has abc submodule."); | 18 | | - let mutable_sequence = abc | 19 | | - .get_attr("MutableSequence", vm) | 20 | | - .expect("Expect collections.abc has MutableSequence type."); | 21 | | - | 22 | | - let register = &mutable_sequence | 23 | | - .get_attr("register", vm) | 24 | | - .expect("Expect collections.abc.MutableSequence has register method."); | 25 | | - register | 26 | | - .call((array,), vm) | 27 | | - .expect("Expect collections.abc.MutableSequence.register(array.array) not fail."); | 28 | | - | 29 | | - module | 30 | | -} | | 3 | +pub(crate) use array::module_def; | 31 | 4 |
| 32 | 5 | #[pymodule(name = "array")] | 33 | 6 | mod array { | @@ -1658,4 +1631,25 @@ mod array { | 1658 | 1631 | }; | 1659 | 1632 | PyArray::from(array).into_ref_with_type(vm, cls) | 1660 | 1633 | } | | 1634 | + | | 1635 | + // Register array.array as collections.abc.MutableSequence | | 1636 | + pub(crate) fn module_exec( | | 1637 | + vm: &VirtualMachine, | | 1638 | + module: &Py<crate::vm::builtins::PyModule>, | | 1639 | + ) -> PyResult<()> { | | 1640 | + __module_exec(vm, module); | | 1641 | + | | 1642 | + let array_type = module | | 1643 | + .get_attr("array", vm) | | 1644 | + .expect("array module has array type"); | | 1645 | + | | 1646 | + // vm.import returns the top-level module, so we need to get abc submodule | | 1647 | + let collections_abc = vm.import("collections.abc", 0)?; | | 1648 | + let abc = collections_abc.get_attr("abc", vm)?; | | 1649 | + let mutable_sequence = abc.get_attr("MutableSequence", vm)?; | | 1650 | + let register = mutable_sequence.get_attr("register", vm)?; | | 1651 | + register.call((array_type,), vm)?; | | 1652 | + | | 1653 | + Ok(()) | | 1654 | + } | 1661 | 1655 | } |
|