Skip to content

Commit

Permalink
Merge pull request #82 from PyO3/python-313t
Browse files Browse the repository at this point in the history
Generate import libraries for free-threaded Python 3.13+ builds
  • Loading branch information
ravenexp authored Nov 30, 2024
2 parents ca5ab09 + c3a6098 commit d13167d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 7 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/dll.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
name: Collect pythonXY.dll
runs-on: windows-latest
steps:
- uses: actions/setup-python@v5
- uses: Quansight-Labs/setup-python@v5
with:
python-version: |
pypy3.8
Expand All @@ -20,12 +20,13 @@ jobs:
3.11
3.12
3.13
3.13t
allow-prereleases: true
- name: Copy pythonXY.dll
shell: bash
run: |
set -e
for VER in 3.7 3.8 3.9 3.10 3.11 3.12 3.13; do
for VER in 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.13t; do
VER_NUM=$(echo $VER | sed 's/\.//')
PREFIX=$(py -$VER -c "import sys; print(sys.base_prefix, end='')")
cp "$PREFIX/python$VER_NUM.dll" .
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ Generating version-specific `python3y.dll` import libraries
-----------------------------------------------------------

As an advanced feature, `python3-dll-a` can generate Python version
specific import libraries such as `python39.lib`.
specific import libraries such as `python39.lib` or `python313t.lib`.

See the `ImportLibraryGenerator` builder API description for details.

Maintenance
-----------

This crate embeds Module-Defitions based on the `stable_abi.toml` file from CPython.
This crate embeds Module-Definitions based on the `stable_abi.toml` file from CPython.

The upstream version of this file is located in the [CPython project][cpython]
repository under the path `Misc/stable_abi.toml`.
Expand Down
57 changes: 54 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
//! -----------------------------------------------------------
//!
//! As an advanced feature, `python3-dll-a` can generate Python version
//! specific import libraries such as `python39.lib`.
//! specific import libraries such as `python39.lib` or `python313t.lib`.
//!
//! See the [`ImportLibraryGenerator`] builder API description for details.
Expand Down Expand Up @@ -137,6 +137,9 @@ pub enum PythonImplementation {
/// Generates `python3.dll` or `pythonXY.dll` import library directly from the
/// embedded Python ABI definitions data for the specified compile target.
///
/// ABI-tagged versioned Python DLLs such as `python313t.dll` are also supported
/// via an optional ABI flags string parameter.
///
/// Example usage
/// -------------
///
Expand Down Expand Up @@ -164,6 +167,13 @@ pub enum PythonImplementation {
/// .version(Some((3, 8)))
/// .generate(Path::new("target/python3-lib"))
/// .unwrap();
///
/// // Generate `python313t.lib` in "target/python3-lib"
/// ImportLibraryGenerator::new("x86_64", "msvc")
/// .version(Some((3, 13)))
/// .abiflags(Some("t"))
/// .generate(Path::new("target/python3-lib"))
/// .unwrap();
/// ```
#[derive(Debug, Clone)]
pub struct ImportLibraryGenerator {
Expand All @@ -175,6 +185,11 @@ pub struct ImportLibraryGenerator {
version: Option<(u8, u8)>,
/// Python interpreter implementation
implementation: PythonImplementation,
/// Optional Python ABI flags
///
/// For example, `"t"` stands for the free-threaded CPython v3.13 build
/// aka CPython `3.13t`.
abiflags: Option<String>,
}

impl ImportLibraryGenerator {
Expand All @@ -186,11 +201,12 @@ impl ImportLibraryGenerator {
/// The compile target environment ABI name (as in `CARGO_CFG_TARGET_ENV`)
/// is passed in `env`.
pub fn new(arch: &str, env: &str) -> Self {
Self {
ImportLibraryGenerator {
arch: arch.to_string(),
env: env.to_string(),
version: None,
implementation: PythonImplementation::CPython,
abiflags: None,
}
}

Expand All @@ -202,6 +218,19 @@ impl ImportLibraryGenerator {
self
}

/// Sets the ABI flags for the `pythonXY<abi>.dll` import library.
///
/// For example, `"t"` stands for the free-threaded CPython v3.13 build
/// aka CPython `3.13t`.
/// In this case, `python313t.dll` import library will be generated.
///
/// The untagged versioned `pythonXY.dll` import library
/// is generated by default.
pub fn abiflags(&mut self, flags: Option<&str>) -> &mut Self {
self.abiflags = flags.map(ToOwned::to_owned);
self
}

/// Sets Python interpreter implementation
pub fn implementation(&mut self, implementation: PythonImplementation) -> &mut Self {
self.implementation = implementation;
Expand Down Expand Up @@ -256,7 +285,11 @@ impl ImportLibraryGenerator {
Some((3, 10)) => ("python310.def", include_str!("python310.def")),
Some((3, 11)) => ("python311.def", include_str!("python311.def")),
Some((3, 12)) => ("python312.def", include_str!("python312.def")),
Some((3, 13)) => ("python313.def", include_str!("python313.def")),
Some((3, 13)) => match self.abiflags.as_deref() {
Some("t") => ("python313t.def", include_str!("python313t.def")),
None => ("python313.def", include_str!("python313.def")),
_ => return Err(Error::new(ErrorKind::Other, "Unsupported Python ABI flags")),
},
_ => return Err(Error::new(ErrorKind::Other, "Unsupported Python version")),
},
PythonImplementation::PyPy => match self.version {
Expand Down Expand Up @@ -532,6 +565,15 @@ mod tests {
.unwrap();
}

// Free-threaded CPython v3.13+
for minor in 13..=13 {
ImportLibraryGenerator::new("x86_64", "gnu")
.version(Some((3, minor)))
.abiflags(Some("t"))
.generate(&dir)
.unwrap();
}

// PyPy
for minor in 7..=10 {
ImportLibraryGenerator::new("x86_64", "gnu")
Expand Down Expand Up @@ -571,6 +613,15 @@ mod tests {
.unwrap();
}

// Free-threaded CPython v3.13+
for minor in 13..=13 {
ImportLibraryGenerator::new("x86_64", "msvc")
.version(Some((3, minor)))
.abiflags(Some("t"))
.generate(&dir)
.unwrap();
}

// PyPy
for minor in 7..=10 {
ImportLibraryGenerator::new("x86_64", "msvc")
Expand Down

0 comments on commit d13167d

Please sign in to comment.