Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
54156f6
export c api
bschoenmaeckers Apr 4, 2026
2250a1c
type mapping v1
bschoenmaeckers Apr 5, 2026
bc96211
Type mapping v2
bschoenmaeckers Apr 5, 2026
46307f6
Implement type flags
bschoenmaeckers Apr 5, 2026
b08d41a
Implement `PyUnicode_FromStringAndSize`
bschoenmaeckers Apr 5, 2026
34c13f4
Do not use `C-unwind`
bschoenmaeckers Apr 5, 2026
24b2c63
implement `PyLong_AsLong`
bschoenmaeckers Apr 5, 2026
384b378
Add `with_vm` helper
bschoenmaeckers Apr 5, 2026
f49e859
Move `PyThreadState` to `pystate.rs`
bschoenmaeckers Apr 5, 2026
e18eef7
Basic multi-threading support
bschoenmaeckers Apr 5, 2026
565bf5e
Cleanup
bschoenmaeckers Apr 5, 2026
85b2928
Attach thread in `Py_InitializeEx`
bschoenmaeckers Apr 5, 2026
c603d37
Map RustPython type flags to CPython type flags
bschoenmaeckers Apr 7, 2026
cee9403
Use `*const Py<PyType>` instead of `*mut PyTypeObject`
bschoenmaeckers Apr 7, 2026
0a50fcc
Implement `PyUnicode_AsUTF8AndSize`
bschoenmaeckers Apr 7, 2026
f588979
Implement `PyType_GetName`
bschoenmaeckers Apr 7, 2026
edaca0c
Implement alternative `PyLong` constructors
bschoenmaeckers Apr 7, 2026
e4c8bd7
Move `init_static_type_pointers` to `pylifecycle.rs`
bschoenmaeckers Apr 7, 2026
26c2777
Add support for `None`, `True`, `False`, `Ellipsis` & `NotImplemented`
bschoenmaeckers Apr 7, 2026
09466e2
Add support for PyBytes
bschoenmaeckers Apr 8, 2026
94cc39b
Add basic exception support
bschoenmaeckers Apr 8, 2026
2ef64d2
Add import support
bschoenmaeckers Apr 8, 2026
55b1e14
Add basic call support
bschoenmaeckers Apr 8, 2026
2a7a82e
Use pyo3 as test harness
bschoenmaeckers Apr 8, 2026
96e16b1
Fix pyo3 by correctly setting `PYO3_CONFIG_FILE`
bschoenmaeckers Apr 9, 2026
e351fb2
Fix python bool creation test
bschoenmaeckers Apr 9, 2026
2fece20
Implement `PyUnicode_EqualToUTF8AndSize`
bschoenmaeckers Apr 9, 2026
e56029d
Add `PyExc_SystemError`
bschoenmaeckers Apr 9, 2026
9702a47
Compile to dynamic lib
bschoenmaeckers Apr 9, 2026
738d4d4
Add test for static type pointers
bschoenmaeckers Apr 9, 2026
8ad7e0c
Streamline returning PyResult
bschoenmaeckers Apr 9, 2026
32faf14
Fix some clippy warning
bschoenmaeckers Apr 9, 2026
a34ced9
Use bounded channel for vm request response
bschoenmaeckers Apr 9, 2026
5a8c57b
Test creating a new (heap) exception type
bschoenmaeckers Apr 9, 2026
3dda576
Don't check for NULL in `Py_DecRef`/`Py_IncRef`
bschoenmaeckers Apr 9, 2026
a1b3af6
Add basic `PyDict` support
bschoenmaeckers Apr 9, 2026
3c7ef8f
Implement minimal tuple functions
bschoenmaeckers Apr 9, 2026
5625ba3
Implement `PyObject_Repr` & `PyObject_Str`
bschoenmaeckers Apr 9, 2026
ea45d78
Implement `PyObject_GetAttr`
bschoenmaeckers Apr 9, 2026
fcbc6b9
Implement `PyUnicode_InternInPlace`
bschoenmaeckers Apr 9, 2026
ff9d385
Add support for running python source code
bschoenmaeckers Apr 10, 2026
7b36240
Make all modules private
bschoenmaeckers Apr 10, 2026
8805658
Merge remote-tracking branch 'origin/main' into c-api
bschoenmaeckers Apr 10, 2026
c4b8ea3
Implement `PyErr_SetString`
bschoenmaeckers Apr 10, 2026
dc56590
Add basic support for `PyList`
bschoenmaeckers Apr 10, 2026
47ed41d
Support `PyLong_AsLong` for non `PyInt` types
bschoenmaeckers Apr 10, 2026
375a170
Add support for `PyComplex`
bschoenmaeckers Apr 10, 2026
fe8107a
Implement c_variadic `PyObject_CallMethodObjArgs`
bschoenmaeckers Apr 10, 2026
2f6fc50
Implement `PyCapsule`
bschoenmaeckers Apr 11, 2026
52442ae
Allow creating empty tuples
bschoenmaeckers Apr 11, 2026
537fc69
Implement `PyCMethod_New`
bschoenmaeckers Apr 11, 2026
62485f6
Add `PyMethodPointer` union
bschoenmaeckers Apr 11, 2026
61de6bf
Also support `NoArgs` CFunction's
bschoenmaeckers Apr 11, 2026
248ea52
Fix error return of `PyCFunction`
bschoenmaeckers Apr 11, 2026
ad0d1af
Add `PyDict` iter support
bschoenmaeckers Apr 11, 2026
d81ad21
Add more `Exception` type statics
bschoenmaeckers Apr 11, 2026
6cd7fc9
Add support for `set`, `get`, & `del` on any object
bschoenmaeckers Apr 13, 2026
d228a78
Merge remote-tracking branch 'origin/main' into c-api
bschoenmaeckers Apr 13, 2026
ae3f3db
Refactor `FfiResult`
bschoenmaeckers Apr 13, 2026
4d23f7c
Fix unset exception types
bschoenmaeckers Apr 13, 2026
56f3823
Add `PyBaseObject_Type` static
bschoenmaeckers Apr 13, 2026
4f6798a
Add `PyObject_SetAttr`
bschoenmaeckers Apr 13, 2026
685c4b7
Add `PyObject_GenericGetDict` & `PyObject_GenericSetDict`
bschoenmaeckers Apr 13, 2026
ac50f2b
Fix some clippy warning
bschoenmaeckers Apr 13, 2026
16e1193
Merge branch 'main' into c-api
bschoenmaeckers Apr 14, 2026
9e931f7
Add `PyObject_SetAttrString`
bschoenmaeckers Apr 14, 2026
384e15e
Add `PyObject_GC_UnTrack`
bschoenmaeckers Apr 14, 2026
09aab0a
Implement `Py_IS_TYPE`
bschoenmaeckers Apr 15, 2026
7ee1e27
Add all exception statics
bschoenmaeckers Apr 16, 2026
661e7bd
Implement `PyObject_Vectorcall`
bschoenmaeckers Apr 16, 2026
65c80c8
Add `PyObject_GetAttrString`
bschoenmaeckers Apr 16, 2026
d2c2c63
Use custom RustPython build of `PyO3`
bschoenmaeckers Apr 17, 2026
b4bc0d8
Add basic support for new classes
bschoenmaeckers Apr 17, 2026
2dc9a82
Add support for class attributes
bschoenmaeckers Apr 17, 2026
3fad7e4
Add basic support for PyO3 class methods
bschoenmaeckers Apr 20, 2026
a07b7c6
Merge remote-tracking branch 'origin/main' into c-api
bschoenmaeckers Apr 20, 2026
842f54d
Add `PyTuple_FromArray` & `PyTuple_Pack`
bschoenmaeckers Apr 20, 2026
2e03e5d
Add `PyFloat` support
bschoenmaeckers Apr 20, 2026
535861b
Add `Py_NewRef`
bschoenmaeckers Apr 20, 2026
1ff142b
Add `PyLong_AsUnsignedLongLong`
bschoenmaeckers Apr 20, 2026
f2e824a
Add `PyNumber_Index`
bschoenmaeckers Apr 20, 2026
59a5fa6
Fix float test
bschoenmaeckers Apr 20, 2026
b8a3646
Implement `PyTraceBack_Print`
bschoenmaeckers Apr 22, 2026
8d7b7d7
Implement `PyUnicode_AsEncodedString`
bschoenmaeckers Apr 22, 2026
708c657
Merge remote-tracking branch 'origin/main' into c-api
bschoenmaeckers Apr 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move init_static_type_pointers to pylifecycle.rs
  • Loading branch information
bschoenmaeckers committed Apr 7, 2026
commit e4c8bd74f2fbdc19e32c0061cfe219a4056b2c87
1 change: 0 additions & 1 deletion crates/capi/src/longobject.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use core::ffi::{c_long, c_longlong, c_ulong, c_ulonglong};
use core::ptr;

use crate::PyObject;
use crate::pyerrors::{PyErr_SetString, PyExc_OverflowError};
Expand Down
21 changes: 0 additions & 21 deletions crates/capi/src/object.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::PyObject;
use crate::pylifecycle::INITIALIZED;
use crate::pystate::with_vm;
use core::ffi::c_ulong;
use rustpython_vm::builtins::PyType;
Expand Down Expand Up @@ -28,26 +27,6 @@ pub static mut PyTuple_Type: MaybeUninit<&'static Py<PyType>> = MaybeUninit::uni
#[unsafe(no_mangle)]
pub static mut PyUnicode_Type: MaybeUninit<&'static Py<PyType>> = MaybeUninit::uninit();

/// Initialize the static type pointers. This should be called once during interpreter initialization,
/// and before any of the static type pointers are used.
///
/// Panics:
/// Panics when the interpreter is already initialized.
#[allow(static_mut_refs)]
pub(crate) fn init_static_type_pointers() {
assert!(
!INITIALIZED.is_completed(),
"Python already initialized, we should not touch the static type pointers"
);
let zoo = &Context::genesis().types;
unsafe {
PyType_Type.write(zoo.type_type);
PyLong_Type.write(zoo.int_type);
PyTuple_Type.write(zoo.tuple_type);
PyUnicode_Type.write(zoo.str_type);
};
}

#[unsafe(no_mangle)]
pub extern "C" fn Py_TYPE(op: *mut PyObject) -> *const Py<PyType> {
// SAFETY: The caller must guarantee that `op` is a valid pointer to a `PyObject`.
Expand Down
26 changes: 24 additions & 2 deletions crates/capi/src/pylifecycle.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::log_stub;
use crate::object::init_static_type_pointers;
use crate::object::{PyLong_Type, PyTuple_Type, PyType_Type, PyUnicode_Type};
use crate::pystate::attach_vm_to_thread;
use core::ffi::c_int;
use rustpython_vm::Interpreter;
use rustpython_vm::vm::thread::ThreadedVirtualMachine;
use rustpython_vm::{Context, Interpreter};
use std::sync::{Once, OnceLock, mpsc};

static VM_REQUEST_TX: OnceLock<mpsc::Sender<mpsc::Sender<ThreadedVirtualMachine>>> =
Expand All @@ -20,6 +20,28 @@ pub(crate) fn request_vm_from_interpreter() -> ThreadedVirtualMachine {
response_rx.recv().expect("Failed to receive VM response")
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also somewhat cursed. I want to be able to create ThreadedVirtualMachine scoped to the thread where PyGILState_Ensure is called. This may be from a different thread than where the main interpreter is running. So I need a way to share the Interpreter between different threads.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to understand why rustpython_vm::vm::thread::with_vm is not enough but this is required

Copy link
Copy Markdown
Contributor Author

@bschoenmaeckers bschoenmaeckers Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to understand why rustpython_vm::vm::thread::with_vm is not enough but this is required

This is so I can call PyGILState_Ensure from any thread, without holding a reference to a Interpreter. This may happen when creating a new thread using std::thread::spawn, and trying to run python code in there. See my test_new_thread testcase.

#[test]
fn test_new_thread() {
Python::attach(|py| {
let number = PyInt::new(py, 123).unbind();
std::thread::spawn(move || {
Python::attach(|py| {
let number = number.bind(py);
assert!(number.is_instance_of::<PyInt>());
});
})
.join()
.unwrap();
})
}


/// Initialize the static type pointers. This should be called once during interpreter initialization,
/// and before any of the static type pointers are used.
///
/// Panics:
/// Panics when the interpreter is already initialized.
#[allow(static_mut_refs)]
pub(crate) fn init_static_type_pointers() {
assert!(
!INITIALIZED.is_completed(),
"Python already initialized, we should not touch the static type pointers"
);
let context = Context::genesis();
let types = &context.types;

unsafe {
PyType_Type.write(types.type_type);
PyLong_Type.write(types.int_type);
PyTuple_Type.write(types.tuple_type);
PyUnicode_Type.write(types.str_type);
};
}

#[unsafe(no_mangle)]
pub extern "C" fn Py_IsInitialized() -> c_int {
INITIALIZED.is_completed() as _
Expand Down
2 changes: 1 addition & 1 deletion crates/capi/src/unicodeobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub extern "C" fn PyUnicode_FromStringAndSize(s: *const c_char, len: isize) -> *

#[unsafe(no_mangle)]
pub extern "C" fn PyUnicode_AsUTF8AndSize(obj: *mut PyObject, size: *mut isize) -> *const c_char {
with_vm(|vm| {
with_vm(|_vm| {
let obj = unsafe {
obj.as_ref()
.expect("PyUnicode_AsUTF8AndSize called with null pointer")
Expand Down