Skip to content

Commit e790f34

Browse files
committed
Add ABI facade support for pristine PyO3 packages
1 parent 2dc9a82 commit e790f34

42 files changed

Lines changed: 2707 additions & 361 deletions

Some content is hidden

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

Cargo.lock

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ tkinter = ["rustpython-stdlib/tkinter"]
3131
winresource = "0.1"
3232

3333
[dependencies]
34+
rustpython-capi = { path = "crates/capi" }
3435
rustpython-compiler = { workspace = true }
3536
rustpython-pylib = { workspace = true, optional = true }
3637
rustpython-stdlib = { workspace = true, optional = true, features = ["compiler"] }
@@ -53,7 +54,7 @@ rustyline = { workspace = true }
5354

5455
[dev-dependencies]
5556
criterion = { workspace = true }
56-
pyo3 = { git = "https://github.com/bschoenmaeckers/pyo3", branch = "RustPython", features = ["auto-initialize"] }
57+
pyo3 = { path = "/tmp/pyo3-abi-facade", features = ["auto-initialize"] }
5758
rustpython-stdlib = { workspace = true }
5859
ruff_python_parser = { workspace = true }
5960

@@ -102,7 +103,7 @@ lto = "thin"
102103

103104
[patch.crates-io]
104105
parking_lot_core = { git = "https://github.com/youknowone/parking_lot", branch = "rustpython" }
105-
pyo3-ffi = { git = "https://github.com/bschoenmaeckers/pyo3", branch = "RustPython" }
106+
pyo3-ffi = { path = "/tmp/pyo3-abi-facade/pyo3-ffi" }
106107
# REDOX START, Uncomment when you want to compile/check with redoxer
107108
# REDOX END
108109

Lib/collections/__init__.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,24 @@
1616

1717
__all__ = [
1818
'ChainMap',
19+
'Collection',
20+
'Container',
1921
'Counter',
22+
'Callable',
23+
'Iterable',
24+
'Iterator',
25+
'ItemsView',
26+
'KeysView',
2027
'OrderedDict',
28+
'Mapping',
29+
'MappingView',
30+
'MutableMapping',
31+
'MutableSet',
32+
'Reversible',
33+
'Sequence',
34+
'Set',
35+
'Sized',
36+
'ValuesView',
2137
'UserDict',
2238
'UserList',
2339
'UserString',
@@ -32,6 +48,25 @@
3248
_sys.modules['collections.abc'] = _collections_abc
3349
abc = _collections_abc
3450

51+
# Compatibility aliases for packages which still import ABCs from
52+
# `collections` instead of `collections.abc`.
53+
Collection = _collections_abc.Collection
54+
Container = _collections_abc.Container
55+
Callable = _collections_abc.Callable
56+
Iterable = _collections_abc.Iterable
57+
Iterator = _collections_abc.Iterator
58+
ItemsView = _collections_abc.ItemsView
59+
KeysView = _collections_abc.KeysView
60+
Mapping = _collections_abc.Mapping
61+
MappingView = _collections_abc.MappingView
62+
MutableMapping = _collections_abc.MutableMapping
63+
MutableSet = _collections_abc.MutableSet
64+
Reversible = _collections_abc.Reversible
65+
Sequence = _collections_abc.Sequence
66+
Set = _collections_abc.Set
67+
Sized = _collections_abc.Sized
68+
ValuesView = _collections_abc.ValuesView
69+
3570
from itertools import chain as _chain
3671
from itertools import repeat as _repeat
3772
from itertools import starmap as _starmap

build.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
fn main() {
2-
if std::env::var("CARGO_CFG_TARGET_OS").unwrap() == "windows" {
2+
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
3+
4+
if target_os != "windows" {
5+
println!("cargo:rustc-link-arg-bin=rustpython=-Wl,-export_dynamic");
6+
}
7+
8+
if target_os == "windows" {
39
println!("cargo:rerun-if-changed=logo.ico");
410
let mut res = winresource::WindowsResource::new();
511
if std::path::Path::new("logo.ico").exists() {

crates/capi/Cargo.toml

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,18 @@ rust-version.workspace = true
88
repository.workspace = true
99
license.workspace = true
1010

11-
[lib]
12-
crate-type = ["cdylib"]
13-
1411
[dependencies]
1512
bitflags.workspace = true
13+
libc.workspace = true
14+
libloading = "0.9"
1615
num-complex.workspace = true
1716
rustpython-vm = { workspace = true, features = ["threading", "compiler"]}
1817

19-
[features]
20-
# Enable PyObject_CallMethodObjArgs variadic function, which is only available on nightly Rust.
21-
nightly = []
18+
[build-dependencies]
19+
cc = "1"
2220

2321
[dev-dependencies]
24-
pyo3 = { git = "https://github.com/bschoenmaeckers/pyo3", branch = "RustPython", features = ["auto-initialize", "abi3"] }
22+
pyo3 = { path = "/tmp/pyo3-abi-facade", features = ["auto-initialize", "abi3"] }
2523

2624
[lints]
2725
workspace = true

crates/capi/build.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn main() {
2+
println!("cargo:rerun-if-changed=csrc/pyobject_callmethodobjargs.c");
3+
cc::Build::new()
4+
.file("csrc/pyobject_callmethodobjargs.c")
5+
.compile("rustpython_capi_shims");
6+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <stdarg.h>
2+
#include <stddef.h>
3+
#include <stdlib.h>
4+
5+
typedef struct _object PyObject;
6+
7+
extern PyObject *RustPython_PyObject_CallMethodObjArgsArray(
8+
PyObject *receiver,
9+
PyObject *name,
10+
PyObject *const *args,
11+
size_t nargs
12+
);
13+
14+
PyObject *PyObject_CallMethodObjArgs(PyObject *receiver, PyObject *name, ...) {
15+
va_list ap;
16+
size_t nargs = 0;
17+
18+
va_start(ap, name);
19+
while (va_arg(ap, PyObject *) != NULL) {
20+
nargs++;
21+
}
22+
va_end(ap);
23+
24+
PyObject **args = NULL;
25+
if (nargs > 0) {
26+
args = (PyObject **)malloc(sizeof(PyObject *) * nargs);
27+
if (args == NULL) {
28+
return NULL;
29+
}
30+
va_start(ap, name);
31+
for (size_t i = 0; i < nargs; i++) {
32+
args[i] = va_arg(ap, PyObject *);
33+
}
34+
(void)va_arg(ap, PyObject *);
35+
va_end(ap);
36+
}
37+
38+
PyObject *result = RustPython_PyObject_CallMethodObjArgsArray(receiver, name, args, nargs);
39+
free(args);
40+
return result;
41+
}
42+
43+
void *RustPython_Keep_PyObject_CallMethodObjArgs(void) {
44+
return (void *)&PyObject_CallMethodObjArgs;
45+
}

0 commit comments

Comments
 (0)