diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1dac31f..2e06d31 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,7 @@ name: Test +# note: when updating the matrix, make sure the `workflow_dispatch` and `generate-matrix` entries match + on: workflow_dispatch: inputs: @@ -15,13 +17,12 @@ on: python_version: type: choice description: Python version to test with - default: '3.12' + default: '3.13' options: - 'all' - '3.9' - - '3.10' - - '3.11' - - '3.12' + - '3.13t' + - '3.13' - 'pypy3.9' - 'pypy3.10' test_specification: @@ -57,9 +58,8 @@ jobs: - windows-latest PYTHON_VERSION: | - '3.9' - - '3.10' - - '3.11' - - '3.12' + - '3.13t' + - '3.13' - 'pypy3.9' - 'pypy3.10' steps: diff --git a/Contributing.md b/Contributing.md index 8ae74f5..4a77fad 100644 --- a/Contributing.md +++ b/Contributing.md @@ -50,5 +50,5 @@ a PR, but generally stick to conforming to the suggested linter rules. 2. Update `Changelog.md` to reflect the new changes. 3. Check out the commit you want to make a release from. 4. Run `git tag ` e.g. `git tag v0.1.0`. -5. Run `git push origin ` e.g. `git tag v0.1.0`. +5. Run `git push origin ` e.g. `git push origin v0.1.0`. - This will trigger the 'release' github action which will upload to PyPi. diff --git a/tests/test_import_hook/common.py b/tests/test_import_hook/common.py index fda11b3..375bfff 100644 --- a/tests/test_import_hook/common.py +++ b/tests/test_import_hook/common.py @@ -8,6 +8,7 @@ import shutil import subprocess import sys +import sysconfig import tempfile import time from collections.abc import Iterator @@ -22,7 +23,10 @@ # the CI does not have enough space to keep the outputs. # When running locally you may set this to False for debugging -CLEAR_WORKSPACE = False +CLEAR_WORKSPACE = True + +# https://docs.python.org/3/howto/free-threading-python.html#identifying-free-threaded-python +IS_FREE_THREADED = sysconfig.get_config_var("Py_GIL_DISABLED") MATURIN_DIR = (script_dir / "../maturin").resolve() TEST_CRATES_DIR = MATURIN_DIR / "test-crates" @@ -33,6 +37,13 @@ "pyo3-bin", # not imported as a python module (subprocess only) "workspace-inverted-order", # this directory is not a maturin package, only the subdirectory } +# these test-crates do not work with free-threaded python +# (to verify: run `maturin develop` to install them into an appropriate virtualenv and try to run the +# corresponding `check_installed.py` script) +if IS_FREE_THREADED: + IGNORED_TEST_CRATES |= { + "pyo3-ffi-pure", + } IMPORT_HOOK_HEADER = """ diff --git a/tests/test_import_hook/file_importer_helpers/my_script_1.rs b/tests/test_import_hook/file_importer_helpers/my_script_1.rs index c426d7c..2b36198 100644 --- a/tests/test_import_hook/file_importer_helpers/my_script_1.rs +++ b/tests/test_import_hook/file_importer_helpers/my_script_1.rs @@ -3,7 +3,7 @@ use pyo3::prelude::*; #[pyfunction] fn get_num() -> usize { 10 } -#[pymodule] +#[pymodule(gil_used = false)] fn my_script(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(get_num, m)?)?; Ok(()) diff --git a/tests/test_import_hook/file_importer_helpers/my_script_2.rs b/tests/test_import_hook/file_importer_helpers/my_script_2.rs index f87e88d..8436598 100644 --- a/tests/test_import_hook/file_importer_helpers/my_script_2.rs +++ b/tests/test_import_hook/file_importer_helpers/my_script_2.rs @@ -6,7 +6,7 @@ fn get_num() -> usize { 20 } #[pyfunction] fn get_other_num() -> usize { 100 } -#[pymodule] +#[pymodule(gil_used = false)] fn my_script(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(get_num, m)?)?; m.add_function(wrap_pyfunction!(get_other_num, m)?)?; diff --git a/tests/test_import_hook/file_importer_helpers/my_script_3.rs b/tests/test_import_hook/file_importer_helpers/my_script_3.rs index b58dd62..3b94b05 100644 --- a/tests/test_import_hook/file_importer_helpers/my_script_3.rs +++ b/tests/test_import_hook/file_importer_helpers/my_script_3.rs @@ -9,7 +9,7 @@ fn get_num() -> usize { } } -#[pymodule] +#[pymodule(gil_used = false)] fn my_script(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(get_num, m)?)?; Ok(()) diff --git a/tests/test_import_hook/file_importer_helpers/reload_template.rs b/tests/test_import_hook/file_importer_helpers/reload_template.rs index 35a7fad..fea9997 100644 --- a/tests/test_import_hook/file_importer_helpers/reload_template.rs +++ b/tests/test_import_hook/file_importer_helpers/reload_template.rs @@ -95,7 +95,7 @@ fn register_child_module(py: Python<'_>, parent_module: &Bound<'_, PyModule>) -> Ok(()) } -#[pymodule] +#[pymodule(gil_used = false)] fn my_module(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(get_num, m)?)?; m.add_function(wrap_pyfunction!(get_global_num, m)?)?; diff --git a/tests/test_import_hook/project_importer_helpers/blank-project/src/lib.rs b/tests/test_import_hook/project_importer_helpers/blank-project/src/lib.rs index 1cee12c..3cd2f81 100644 --- a/tests/test_import_hook/project_importer_helpers/blank-project/src/lib.rs +++ b/tests/test_import_hook/project_importer_helpers/blank-project/src/lib.rs @@ -1,6 +1,6 @@ use pyo3::prelude::*; -#[pymodule] +#[pymodule(gil_used = false)] fn blank_project(_m: &Bound<'_, PyModule>) -> PyResult<()> { Ok(()) } diff --git a/tests/test_import_hook/project_importer_helpers/my_project.rs b/tests/test_import_hook/project_importer_helpers/my_project.rs index 18e82e8..dda92e3 100644 --- a/tests/test_import_hook/project_importer_helpers/my_project.rs +++ b/tests/test_import_hook/project_importer_helpers/my_project.rs @@ -10,7 +10,7 @@ fn get_num() -> usize { } } -#[pymodule] +#[pymodule(gil_used = false)] fn my_project(m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(get_num))?; Ok(()) diff --git a/tests/test_import_hook/project_importer_helpers/reload_template.rs b/tests/test_import_hook/project_importer_helpers/reload_template.rs index 03cb9af..46cd3ff 100644 --- a/tests/test_import_hook/project_importer_helpers/reload_template.rs +++ b/tests/test_import_hook/project_importer_helpers/reload_template.rs @@ -95,7 +95,7 @@ fn register_child_module(py: Python<'_>, parent_module: &Bound<'_, PyModule>) -> Ok(()) } -#[pymodule] +#[pymodule(gil_used = false)] fn my_project(py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_wrapped(wrap_pyfunction!(get_num))?; m.add_wrapped(wrap_pyfunction!(get_global_num))?;