CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-setuptools-rust

Setuptools Rust extension plugin

Pending
Overview
Eval results
Files

extension-building.mddocs/

Extension Building

Configuration and building of Rust extensions as Python modules or standalone binaries. setuptools-rust provides comprehensive support for different binding types, cross-compilation, build customization, and integration with the Python packaging ecosystem.

Capabilities

Extension Configuration

Define Rust extensions that will be built as Python modules, with full control over build options, features, and binding types.

class RustExtension:
    def __init__(
        self,
        target: Union[str, Dict[str, str]],
        path: str = "Cargo.toml",
        args: Optional[Sequence[str]] = (),
        cargo_manifest_args: Optional[Sequence[str]] = (),
        features: Optional[Sequence[str]] = (),
        rustc_flags: Optional[Sequence[str]] = (),
        rust_version: Optional[str] = None,
        quiet: bool = False,
        debug: Optional[bool] = None,
        binding: Binding = Binding.PyO3,
        strip: Strip = Strip.No,
        script: bool = False,
        native: bool = False,
        optional: bool = False,
        py_limited_api: Literal["auto", True, False] = "auto",
        env: Optional[Dict[str, str]] = None,
    ):
        """
        Configure a Rust extension for building as a Python module.

        Parameters:
        - target: Extension target name or dict mapping target to module name
        - path: Path to Cargo.toml file (default: "Cargo.toml")
        - args: Additional arguments passed to cargo build
        - cargo_manifest_args: Arguments passed to cargo for manifest operations
        - features: List of Cargo features to enable
        - rustc_flags: Additional flags passed to rustc
        - rust_version: Minimum required Rust version
        - quiet: Suppress cargo output during build
        - debug: Enable debug build (None uses setuptools debug setting)
        - binding: Binding type (PyO3, RustCPython, NoBinding, Exec)
        - strip: Symbol stripping mode (No, Debug, All)
        - script: Install as console script
        - native: Use native target (no cross-compilation)
        - optional: Mark extension as optional (build failures won't stop installation)
        - py_limited_api: Python limited API compatibility
        - env: Environment variables for the build process
        """

    def get_lib_name(self, *, quiet: bool) -> str:
        """
        Parse Cargo.toml to get the shared library name.

        Parameters:
        - quiet: Suppress output during parsing

        Returns:
        str: The shared library name from Cargo.toml
        """

    def get_rust_version(self) -> Optional[SimpleSpec]:
        """
        Get parsed Rust version requirement.

        Returns:
        Optional[SimpleSpec]: Parsed version requirement or None
        """

    def get_cargo_profile(self) -> Optional[str]:
        """
        Extract cargo profile from build arguments.

        Returns:
        Optional[str]: Cargo profile name or None
        """

    def entry_points(self) -> List[str]:
        """
        Generate console script entry points for the extension.

        Returns:
        List[str]: List of entry point specifications
        """

    def install_script(self, module_name: str, exe_path: str) -> None:
        """
        Install console script for the extension.

        Parameters:
        - module_name: Name of the Python module
        - exe_path: Path to the executable
        """

    def metadata(self, *, quiet: bool) -> CargoMetadata:
        """
        Get cargo metadata for the extension (cached).

        Parameters:
        - quiet: Suppress cargo output

        Returns:
        CargoMetadata: Cargo metadata dictionary
        """

Binary Configuration

Define Rust binaries that will be built as standalone executables, inheriting most functionality from RustExtension but with binary-specific behavior.

class RustBin(RustExtension):
    def __init__(
        self,
        target: Union[str, Dict[str, str]],
        path: str = "Cargo.toml",
        args: Optional[Sequence[str]] = (),
        cargo_manifest_args: Optional[Sequence[str]] = (),
        features: Optional[Sequence[str]] = (),
        rust_version: Optional[str] = None,
        quiet: bool = False,
        debug: Optional[bool] = None,
        strip: Strip = Strip.No,
        optional: bool = False,
        env: Optional[dict[str, str]] = None,
    ):
        """
        Configure a Rust binary for building as a standalone executable.

        Parameters: Same as RustExtension except:
        - No binding parameter (always uses Exec binding)
        - No script, native, or py_limited_api parameters
        """

    def entry_points(self) -> List[str]:
        """
        Generate entry points for binary (returns empty list).

        Returns:
        List[str]: Empty list (binaries don't create console scripts)
        """

Binding Types

Enumeration of supported Rust-Python binding types, determining how the Rust code interfaces with Python.

class Binding(IntEnum):
    PyO3 = auto()        # Extension built using PyO3 bindings
    RustCPython = auto() # Extension built using rust-cpython bindings  
    NoBinding = auto()   # Bring your own bindings
    Exec = auto()        # Build executable instead of extension

    def __repr__(self) -> str:
        """String representation of the binding type."""

Symbol Stripping

Control symbol stripping in built extensions for size optimization and debugging.

class Strip(IntEnum):
    No = auto()    # Do not strip symbols
    Debug = auto() # Strip debug symbols only
    All = auto()   # Strip all symbols

    def __repr__(self) -> str:
        """String representation of the stripping mode."""

Usage Examples

Basic PyO3 Extension

from setuptools import setup
from setuptools_rust import RustExtension, Binding

setup(
    name="my-pyo3-extension",
    rust_extensions=[
        RustExtension(
            "my_package.rust_module",
            path="rust/Cargo.toml",
            binding=Binding.PyO3,
            features=["python-extension"],
        )
    ],
    zip_safe=False,
)

Cross-compilation Setup

RustExtension(
    "my_package.cross_compiled",
    path="Cargo.toml", 
    args=["--target", "x86_64-pc-windows-gnu"],
    env={"CARGO_BUILD_TARGET": "x86_64-pc-windows-gnu"},
)

Debug Build with Custom Features

RustExtension(
    "my_package.debug_module",
    path="Cargo.toml",
    debug=True,
    features=["debugging", "profiling"],
    rustc_flags=["-C", "debuginfo=2"],
)

Optional Extension

RustExtension(
    "my_package.optional_rust",
    path="optional/Cargo.toml",
    optional=True,  # Build failure won't stop installation
    quiet=True,     # Suppress cargo output
)

Standalone Binary

from setuptools import setup
from setuptools_rust import RustBin, Strip

setup(
    name="my-rust-tools",
    rust_extensions=[
        RustBin(
            "my-cli-tool",
            path="cli/Cargo.toml",
            strip=Strip.All,  # Strip all symbols for smaller binary
        )
    ],
)

Type Definitions

from typing import Union, Dict, List, Optional, Sequence, Literal, Any, NewType
from enum import IntEnum, auto

CargoMetadata = NewType("CargoMetadata", Dict[str, Any])

class SimpleSpec:
    """Parsed Rust version requirement specification."""

class _BuiltModule:
    """Internal type representing a built module."""

Install with Tessl CLI

npx tessl i tessl/pypi-setuptools-rust

docs

commands.md

configuration.md

extension-building.md

index.md

tile.json