Build Python wheels on CI with minimal configuration.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Cibuildwheel provides advanced environment variable parsing with bash syntax support and context-aware evaluation for comprehensive build customization.
Parse environment variable specifications from configuration strings.
def parse_environment(env_string: str) -> ParsedEnvironment:
"""
Parse environment variable specification string.
Args:
env_string: Environment specification (e.g., "VAR1=value1 VAR2=value2")
Returns:
ParsedEnvironment object containing parsed assignments
Raises:
EnvironmentParseError: If parsing fails due to syntax errors
"""Container for environment variable assignments with evaluation capabilities.
@dataclasses.dataclass(kw_only=True)
class ParsedEnvironment:
assignments: list[EnvironmentAssignment]
def as_dictionary(
self,
prev_environment: Mapping[str, str],
executor: bashlex_eval.EnvironmentExecutor | None = None
) -> dict[str, str]:
"""
Convert parsed environment to a dictionary with evaluated values.
Args:
prev_environment: Existing environment variables for context
executor: Optional bash expression executor
Returns:
Dictionary of environment variable names to evaluated values
"""
def add(self, name: str, value: str, prepend: bool = False) -> None:
"""
Add a new environment variable assignment.
Args:
name: Variable name
value: Variable value (can contain expressions)
prepend: If True, add to beginning of assignments list
"""Protocol defining how environment assignments are evaluated.
class EnvironmentAssignment(Protocol):
name: str
def evaluated_value(
self,
*,
environment: Mapping[str, str],
executor: bashlex_eval.EnvironmentExecutor | None = None
) -> str:
"""
Evaluate the assignment value in the given environment context.
Args:
environment: Current environment variables
executor: Optional bash expression executor
Returns:
Evaluated string value
"""Different types of environment variable assignments.
class EnvironmentAssignmentRaw:
"""Simple string assignment without expression evaluation."""
name: str
value: str
class EnvironmentAssignmentBash:
"""Assignment with bash expression evaluation support."""
name: str
value: strException raised when environment parsing fails.
class EnvironmentParseError(Exception):
"""Raised when environment variable parsing fails."""# Basic key=value pairs
env_string = "CFLAGS=-O2 LDFLAGS=-s DEBUG=1"
# With quotes for values containing spaces
env_string = 'CFLAGS="-O2 -g" DESCRIPTION="My Package"'# Variable expansion
env_string = "PATH=$PATH:/usr/local/bin HOME_BIN=$HOME/bin"
# Command substitution
env_string = "VERSION=$(python setup.py --version) BUILD_DATE=$(date)"
# Conditional expressions
env_string = "CFLAGS=${CFLAGS:--O2} DEBUG=${DEBUG:-0}"# Line continuation
env_string = """
CFLAGS=-O2 \\
LDFLAGS=-s \\
DEBUG=1
"""
# Multiple assignments
env_string = """
CC=gcc
CXX=g++
CFLAGS=-O2 -g
LDFLAGS=-s
"""[tool.cibuildwheel]
# Simple environment variables
environment = {CFLAGS = "-O2", LDFLAGS = "-s", DEBUG = "1"}
# With bash expressions
environment = {
PATH = "$PATH:/usr/local/bin",
VERSION = "$(python setup.py --version)",
BUILD_TYPE = "${BUILD_TYPE:-release}"
}
# Platform-specific environments
[tool.cibuildwheel.linux]
environment = {
CC = "gcc",
CXX = "g++",
CFLAGS = "-O2 -fPIC"
}
[tool.cibuildwheel.windows]
environment = {
CC = "cl.exe",
CXX = "cl.exe",
CFLAGS = "/O2"
}# Single assignment
export CIBW_ENVIRONMENT="CFLAGS=-O2"
# Multiple assignments
export CIBW_ENVIRONMENT="CFLAGS=-O2 LDFLAGS=-s DEBUG=1"
# With bash expressions
export CIBW_ENVIRONMENT="PATH=\$PATH:/usr/local/bin VERSION=\$(python setup.py --version)"
# Platform-specific
export CIBW_ENVIRONMENT_LINUX="CC=gcc CXX=g++"
export CIBW_ENVIRONMENT_WINDOWS="CC=cl.exe CXX=cl.exe"# Space-separated key=value pairs
"CFLAGS=-O2 LDFLAGS=-s DEBUG=1"
# Quoted values for spaces
'CFLAGS="-O2 -g" DESCRIPTION="My Package"'
# Bash expressions
"PATH=$PATH:/usr/local/bin VERSION=$(python setup.py --version)"Pass specific environment variables from the host to the build environment:
[tool.cibuildwheel]
# Pass through authentication tokens
environment-pass = ["API_TOKEN", "SECRET_KEY", "GITHUB_TOKEN"]
# Platform-specific pass-through
[tool.cibuildwheel.linux]
environment-pass = ["DOCKER_HOST", "DOCKER_CERT_PATH"]# Via environment variable
export CIBW_ENVIRONMENT_PASS="API_TOKEN SECRET_KEY GITHUB_TOKEN"
export CIBW_ENVIRONMENT_PASS_LINUX="DOCKER_HOST DOCKER_CERT_PATH"Automatically pass common CI environment variables:
# Common CI variables that are often needed:
CI_VARS = [
"CI", "GITHUB_ACTIONS", "GITHUB_TOKEN", "GITHUB_REF",
"TRAVIS", "TRAVIS_TAG", "TRAVIS_BRANCH",
"APPVEYOR", "APPVEYOR_REPO_TAG_NAME",
"AZURE_PIPELINES", "BUILD_SOURCEBRANCH"
]import os
from cibuildwheel.environment import parse_environment
# Generate environment based on conditions
if os.environ.get("DEBUG"):
env_string = "CFLAGS=-g -O0 DEBUG=1"
else:
env_string = "CFLAGS=-O2 -DNDEBUG DEBUG=0"
parsed_env = parse_environment(env_string)# Base environment
base_env = parse_environment("CC=gcc CFLAGS=-O2")
# Add platform-specific variables
if platform == "linux":
base_env.add("LDFLAGS", "-s")
elif platform == "windows":
base_env.add("CC", "cl.exe")Cibuildwheel provides special variables during builds:
{project}: Path to the project being built{package}: Path to the package directory{wheel}: Path to the built wheel (in repair commands){dest_dir}: Destination directory for repaired wheels[tool.cibuildwheel]
# Use in test commands
test-command = "cd {project} && python -m pytest tests/"
# Use in repair commands
repair-wheel-command = "auditwheel repair -w {dest_dir} {wheel}"from cibuildwheel.environment import parse_environment
# Parse simple environment
env = parse_environment("CFLAGS=-O2 LDFLAGS=-s")
env_dict = env.as_dictionary({})
# Result: {"CFLAGS": "-O2", "LDFLAGS": "-s"}import os
from cibuildwheel.environment import parse_environment
# Environment with expressions
env_string = "PATH=$PATH:/usr/local/bin HOME_BIN=$HOME/bin"
env = parse_environment(env_string)
# Evaluate with current environment
current_env = dict(os.environ)
evaluated = env.as_dictionary(current_env)
# Result: {"PATH": "/usr/bin:/usr/local/bin", "HOME_BIN": "/home/user/bin"}[tool.cibuildwheel]
# Base environment for all platforms
environment = {DEBUG = "0", OPTIMIZE = "1"}
[tool.cibuildwheel.linux]
# Linux-specific compiler settings
environment = {
CC = "gcc",
CXX = "g++",
CFLAGS = "-O2 -fPIC",
LDFLAGS = "-s"
}
[tool.cibuildwheel.windows]
# Windows-specific compiler settings
environment = {
CC = "cl.exe",
CXX = "cl.exe",
CFLAGS = "/O2 /MD",
LDFLAGS = "/LTCG"
}
[tool.cibuildwheel.macos]
# macOS-specific settings
environment = {
CC = "clang",
CXX = "clang++",
CFLAGS = "-O2 -arch x86_64 -arch arm64",
MACOSX_DEPLOYMENT_TARGET = "10.14"
}[tool.cibuildwheel]
environment = {
# Build configuration
BUILD_TYPE = "${BUILD_TYPE:-Release}",
CMAKE_BUILD_PARALLEL_LEVEL = "${CMAKE_BUILD_PARALLEL_LEVEL:-4}",
# Compiler flags
CFLAGS = "${CFLAGS:--O2} -DVERSION=$(python setup.py --version)",
CXXFLAGS = "${CXXFLAGS:--O2} -std=c++17",
# Paths
PKG_CONFIG_PATH = "/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH",
LD_LIBRARY_PATH = "/usr/local/lib:$LD_LIBRARY_PATH"
}
# Pass through CI variables
environment-pass = [
"GITHUB_TOKEN", "CI", "GITHUB_ACTIONS",
"TRAVIS", "APPVEYOR", "AZURE_PIPELINES"
]from cibuildwheel.environment import parse_environment, EnvironmentParseError
try:
# This might fail due to syntax errors
env = parse_environment("INVALID SYNTAX")
except EnvironmentParseError as e:
print(f"Environment parsing failed: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-cibuildwheel