Skip to content

Commit 2ea9ec4

Browse files
committed
feat(native): Initial support for Python 3.13
1 parent 3368ba4 commit 2ea9ec4

File tree

8 files changed

+55
-39
lines changed

8 files changed

+55
-39
lines changed

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
strategy:
7575
matrix:
7676
node-version: [22]
77-
python-version: ["3.9", "3.10", "3.11", "3.12", "fallback"]
77+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "fallback"]
7878
target: ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu"]
7979
include:
8080
- target: x86_64-unknown-linux-gnu
@@ -155,7 +155,7 @@ jobs:
155155
node-version: [22.x]
156156
os-version: ["macos-13"]
157157
target: ["x86_64-apple-darwin", "aarch64-apple-darwin"]
158-
python-version: ["3.9", "3.10", "3.11", "3.12", "fallback"]
158+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "fallback"]
159159
include:
160160
- target: x86_64-apple-darwin
161161
package_target_arch: x64

.github/workflows/rust-cubesql.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ jobs:
128128
# Current used version + 1 LTS
129129
# TODO: Add 24 after it's been released (don't forget to uncomment excludes below!)
130130
node-version: [22]
131-
python-version: ["3.9", "3.10", "3.11", "3.12", "fallback"]
131+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "fallback"]
132132
target: ["x86_64-unknown-linux-gnu", "aarch64-unknown-linux-gnu"]
133133
# minimize number of jobs
134134
exclude:
@@ -243,6 +243,8 @@ jobs:
243243
python-version: "3.11"
244244
- target: x86_64-apple-darwin
245245
python-version: "3.12"
246+
- target: x86_64-apple-darwin
247+
python-version: "3.13"
246248
- target: x86_64-apple-darwin
247249
python-version: "fallback"
248250
- target: aarch64-apple-darwin

packages/cubejs-backend-native/Cargo.lock

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

packages/cubejs-backend-native/Cargo.toml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,8 @@ log-reroute = "0.1"
3434
minijinja = { version = "1", features = ["json", "loader"] }
3535
once_cell = "1.10"
3636
# python
37-
pyo3 = { version = "0.20.0", features = [], optional = true }
38-
pyo3-asyncio = { version = "0.20.0", features = [
39-
"tokio-runtime",
40-
"attributes",
41-
], optional = true }
37+
pyo3 = { version = "0.22.6", features = ["gil-refs", "py-clone"], optional = true }
38+
pyo3-async-runtimes = { version = "0.22.0", features = ["tokio-runtime", "attributes"], optional = true }
4239
serde = { version = "1.0.217", features = ["derive"] }
4340
serde_json = "1.0.127"
4441
simple_logger = "1.7.0"
@@ -54,4 +51,4 @@ features = ["napi-1", "napi-4", "napi-6", "futures"]
5451
default = ["neon-entrypoint"]
5552
neon-debug = []
5653
neon-entrypoint = []
57-
python = ["pyo3", "pyo3-asyncio"]
54+
python = ["pyo3", "pyo3-async-runtimes"]

packages/cubejs-backend-native/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"value": [
5656
"libpython",
5757
[
58+
"3.13",
5859
"3.12",
5960
"3.11",
6061
"3.10",

packages/cubejs-backend-native/src/cross/clrepr.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use crate::cross::py_in_js::{
66
};
77
#[cfg(feature = "python")]
88
use crate::utils::bind_method;
9+
#[cfg(feature = "python")]
10+
use pyo3::Python;
911
use neon::prelude::*;
1012
use neon::result::Throw;
1113
use neon::types::JsDate;
@@ -240,7 +242,7 @@ impl CLRepr {
240242
#[cfg(feature = "python")]
241243
if from.is_a::<BoxedJsPyFunctionWrapper, _>(cx) {
242244
let ref_wrap = from.downcast_or_throw::<BoxedJsPyFunctionWrapper, _>(cx)?;
243-
let fun = ref_wrap.borrow().get_fun().clone();
245+
let fun = Python::with_gil(|py| ref_wrap.borrow().get_fun().clone_ref(py));
244246

245247
return Ok(CLRepr::PythonRef(PythonRef::PyFunction(fun)));
246248
}

packages/cubejs-backend-native/src/python/runtime.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ impl PyRuntime {
111111

112112
let is_coroutine = unsafe { pyo3::ffi::PyCoro_CheckExact(call_res.as_ptr()) == 1 };
113113
if is_coroutine {
114-
let fut = pyo3_asyncio::tokio::into_future(call_res.as_ref(py))?;
114+
let fut = pyo3_async_runtimes::tokio::into_future(call_res.bind(py).clone())?;
115115
Ok(PyScheduledFunResult::Poll(Box::pin(fut)))
116116
} else {
117117
Ok(PyScheduledFunResult::Ready(CLRepr::from_python_ref(
@@ -206,12 +206,12 @@ impl PyRuntime {
206206
trace!("Initializing executor in a separate thread");
207207

208208
std::thread::spawn(|| {
209-
pyo3_asyncio::tokio::get_runtime()
210-
.block_on(pyo3_asyncio::tokio::re_exports::pending::<()>())
209+
pyo3_async_runtimes::tokio::get_runtime()
210+
.block_on(pyo3_async_runtimes::tokio::re_exports::pending::<()>())
211211
});
212212

213213
let res = Python::with_gil(|py| -> Result<(), PyErr> {
214-
pyo3_asyncio::tokio::run(py, async move {
214+
pyo3_async_runtimes::tokio::run(py, async move {
215215
loop {
216216
if let Some(task) = receiver.recv().await {
217217
trace!("New task");
@@ -247,7 +247,7 @@ pub fn py_runtime_init<'a, C: Context<'a>>(
247247

248248
pyo3::prepare_freethreaded_python();
249249
// it's safe to unwrap
250-
pyo3_asyncio::tokio::init_with_runtime(runtime).unwrap();
250+
pyo3_async_runtimes::tokio::init_with_runtime(runtime).unwrap();
251251

252252
if PY_RUNTIME.set(PyRuntime::new(channel)).is_err() {
253253
cx.throw_error("Error on setting PyRuntime")

packages/cubejs-backend-native/src/template/mj_value/python.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ impl Object for JinjaPythonFunction {
254254
)
255255
})?;
256256

257-
let call_future = py_runtime.call_async(self.inner.clone(), arguments);
257+
let call_future = Python::with_gil(|py| py_runtime.call_async(self.inner.clone_ref(py), arguments));
258258

259259
let tokio = tokio_runtime().map_err(|err| {
260260
mj::Error::new(

0 commit comments

Comments
 (0)