Repository navigation
Add basic capi error support #7787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
2562f9d
40d97ea
6b79cb5
71438c6
d708bfe
bbf3656
bccd38e
9e20cf7
268856b
8432c17
130321e
30ac061
4e4f7df
22985ca
b2c2f69
d18d259
4e7bcbf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -157,6 +157,7 @@ pybuilddir | |
| pycore | ||
| pyinner | ||
| pydecimal | ||
| pyerrors | ||
| Pyfunc | ||
| pylifecycle | ||
| pymain | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -112,10 +112,15 @@ jobs: | |
| uses: ./.github/actions/install-macos-deps | ||
|
|
||
| - name: run rust tests | ||
| run: cargo test --workspace ${{ env.WORKSPACE_EXCLUDES }} --features threading ${{ env.CARGO_ARGS }} | ||
| run: cargo test --workspace --exclude rustpython-capi ${{ env.WORKSPACE_EXCLUDES }} --features threading ${{ env.CARGO_ARGS }} | ||
| env: | ||
| INSTA_WORKSPACE_ROOT: ${{ github.workspace }} | ||
|
|
||
| - name: run c-api tests | ||
| working-directory: crates/capi | ||
| run: cargo test | ||
| if: runner.os != 'Windows' # Requires pyo3 0.29+ on Windows | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. anything wrong about this? we can pick proper pyo3 version for windows
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It used to work because we were accidentally linking with the system python. This is now solved. But to make the linker happy we need PyO3/pyo3#5866, this will land in PyO3 0.29 which is unreleased as the time of writing. Furthermore the windows linker expect all symbols to be defined we can only enable this at a later stage when we have defined all ABI3 symbols, see https://github.com/RustPython/RustPython/actions/runs/25607984643/job/75173077533 |
||
|
|
||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| - run: cargo doc --locked | ||
| if: runner.os == 'Linux' | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,33 @@ | ||
| #![allow(clippy::missing_safety_doc)] | ||
|
|
||
| use crate::pyerrors::init_exception_statics; | ||
| use crate::pylifecycle::MAIN_INTERP; | ||
| use rustpython_vm::Interpreter; | ||
| pub use rustpython_vm::PyObject; | ||
| use rustpython_vm::{Context, Interpreter}; | ||
| use std::sync::MutexGuard; | ||
|
|
||
| extern crate alloc; | ||
|
|
||
| pub mod object; | ||
| pub mod pyerrors; | ||
| pub mod pylifecycle; | ||
| pub mod pystate; | ||
| pub mod refcount; | ||
| mod util; | ||
|
|
||
| /// Get main interpreter of this process. Will be None if it has not been initialized yet. | ||
| pub fn get_main_interpreter() -> MutexGuard<'static, Option<Interpreter>> { | ||
| MAIN_INTERP | ||
| .lock() | ||
| .expect("Failed to lock interpreter mutex") | ||
| } | ||
|
|
||
| /// Set the main interpreter of this process. This method will panic when there is already an | ||
| /// interpreter set. | ||
| pub fn set_main_interpreter(interpreter: Interpreter) { | ||
|
bschoenmaeckers marked this conversation as resolved.
Outdated
|
||
| let mut interp = get_main_interpreter(); | ||
| assert!(interp.is_none(), "Main interpreter is already set"); | ||
| // Safety: Interpreter was not initialized before, so we can safely assume the statics are not used | ||
| unsafe { init_exception_statics(&Context::genesis().exceptions) }; | ||
| *interp = Some(interpreter); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| use crate::PyObject; | ||
| use crate::pystate::with_vm; | ||
| use core::ffi::{c_int, c_uint, c_ulong}; | ||
| use rustpython_vm::builtins::PyType; | ||
| use rustpython_vm::{AsObject, Context, Py}; | ||
|
|
||
| const PY_TPFLAGS_LONG_SUBCLASS: u64 = 1 << 24; | ||
| const PY_TPFLAGS_LIST_SUBCLASS: u64 = 1 << 25; | ||
| const PY_TPFLAGS_TUPLE_SUBCLASS: u64 = 1 << 26; | ||
| const PY_TPFLAGS_BYTES_SUBCLASS: u64 = 1 << 27; | ||
| const PY_TPFLAGS_UNICODE_SUBCLASS: u64 = 1 << 28; | ||
| const PY_TPFLAGS_DICT_SUBCLASS: u64 = 1 << 29; | ||
| const PY_TPFLAGS_BASE_EXC_SUBCLASS: u64 = 1 << 30; | ||
| const PY_TPFLAGS_TYPE_SUBCLASS: u64 = 1 << 31; | ||
|
|
||
| pub type PyTypeObject = Py<PyType>; | ||
|
|
||
| #[unsafe(no_mangle)] | ||
| pub unsafe extern "C" fn Py_TYPE(op: *mut PyObject) -> *const PyTypeObject { | ||
| unsafe { (*op).class() } | ||
| } | ||
|
|
||
| #[unsafe(no_mangle)] | ||
| pub unsafe extern "C" fn Py_IS_TYPE(op: *mut PyObject, ty: *mut PyTypeObject) -> c_int { | ||
| with_vm(|_vm| { | ||
| let obj = unsafe { &*op }; | ||
| let ty = unsafe { &*ty }; | ||
| obj.class().is(ty) | ||
| }) | ||
| } | ||
|
|
||
| #[unsafe(no_mangle)] | ||
| pub unsafe extern "C" fn PyType_GetFlags(ptr: *const PyTypeObject) -> c_ulong { | ||
| let ctx = Context::genesis(); | ||
| let zoo = &ctx.types; | ||
| let exp_zoo = &ctx.exceptions; | ||
|
|
||
| let ty = unsafe { &*ptr }; | ||
| let mut flags = ty.slots.flags.bits(); | ||
|
|
||
| if ty.is_subtype(zoo.int_type) { | ||
| flags |= PY_TPFLAGS_LONG_SUBCLASS; | ||
| } | ||
| if ty.is_subtype(zoo.list_type) { | ||
| flags |= PY_TPFLAGS_LIST_SUBCLASS | ||
| } | ||
| if ty.is_subtype(zoo.tuple_type) { | ||
| flags |= PY_TPFLAGS_TUPLE_SUBCLASS; | ||
| } | ||
| if ty.is_subtype(zoo.bytes_type) { | ||
| flags |= PY_TPFLAGS_BYTES_SUBCLASS; | ||
| } | ||
| if ty.is_subtype(zoo.str_type) { | ||
| flags |= PY_TPFLAGS_UNICODE_SUBCLASS; | ||
| } | ||
| if ty.is_subtype(zoo.dict_type) { | ||
| flags |= PY_TPFLAGS_DICT_SUBCLASS; | ||
| } | ||
| if ty.is_subtype(exp_zoo.base_exception_type) { | ||
| flags |= PY_TPFLAGS_BASE_EXC_SUBCLASS; | ||
| } | ||
| if ty.is_subtype(zoo.type_type) { | ||
| flags |= PY_TPFLAGS_TYPE_SUBCLASS; | ||
| } | ||
|
|
||
| flags as c_ulong | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn Py_GetConstantBorrowed(constant_id: c_uint) -> *mut PyObject { | ||
| with_vm(|vm| { | ||
| let ctx = &vm.ctx; | ||
| let constant = match constant_id { | ||
| 0 => ctx.none.as_object(), | ||
| 1 => ctx.false_value.as_object(), | ||
| 2 => ctx.true_value.as_object(), | ||
| 3 => ctx.ellipsis.as_object(), | ||
| 4 => ctx.not_implemented.as_object(), | ||
| _ => { | ||
| return Err( | ||
| vm.new_system_error("Invalid constant ID passed to Py_GetConstantBorrowed") | ||
| ); | ||
| } | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| .as_raw(); | ||
| Ok(constant) | ||
| }) | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.