This document describes the modern Python packaging setup for ReplicantDriveSim, following PEP 517/518/621/660 standards.
- Overview
- Quick Start
- Package Configuration
- Installation Methods
- Build System
- Development Workflow
- Conda Environment
- Makefile Targets
- PyPI Publishing
- Migration Notes
ReplicantDriveSim now uses modern Python packaging standards:
- PEP 517: Build system specification
- PEP 518: Declaring build dependencies
- PEP 621: Project metadata in
pyproject.toml - PEP 660: Editable installs for development
✅ Single source of truth: All configuration in pyproject.toml
✅ No redundancy: environment.yml references pyproject.toml for Python dependencies
✅ Deprecated files: Removed setup.cfg, minimized setup.py
✅ Build automation: Comprehensive Makefile for common tasks
✅ PyPI ready: Production-grade packaging for distribution
# Install in editable mode (development)
make install
# Install with all dependencies
make install-all
# Build native library and Unity app
make build-all
# Run tests
make test
# Get help
make help# Editable install (development)
pip install -e .
# Production install
pip install .
# With optional dependencies
pip install -e .[dev] # Development tools
pip install -e .[docs] # Documentation tools
pip install -e .[mlflow] # MLflow tracking
pip install -e .[all] # Everything# Create environment (includes package installation)
conda env create -f environment.yml
# Activate environment
conda activate drive
# Update environment
make conda-updateAll package configuration is centralized in pyproject.toml:
[build-system]
requires = ["setuptools>=75.1.0", "wheel", "pybind11>=2.12.0"]
build-backend = "setuptools.build_meta"
[project]
name = "replicantdrivesim"
version = "0.6.6"
description = "A Unity-based traffic simulation environment..."
readme = "README.md"
requires-python = ">=3.10.1,<=3.10.12"
license = {text = "MIT"}
[project.dependencies]
# Core runtime dependencies
[project.optional-dependencies]
dev = [...] # Development tools (pytest, black, mypy, etc.)
docs = [...] # Documentation tools (sphinx, etc.)
mlflow = [...] # MLflow experiment tracking
all = ["replicantdrivesim[dev,docs,mlflow]"]
[project.scripts]
replicantdrivesim = "replicantdrivesim.cli:main"
[tool.setuptools.package-data]
replicantdrivesim = [
"*.so", "*.dll", "*.dylib",
"configs/*.yaml",
"Builds/**/*",
]- mlagents 1.1.0: Unity ML-Agents Python SDK
- gymnasium 0.26.3: RL environment API
- ray[rllib] 2.31.0: Distributed RL framework
- numpy 1.23.5: Numerical computing
- torch: Deep learning framework
- pybind11: C++/Python bindings
Python 3.10.1 - 3.10.12 (strict requirement for ML-Agents compatibility)
Recommended for active development:
# Minimal install
make install
# or
pip install -e .
# With development tools
make install-dev
# or
pip install -e .[dev]Benefits:
- Changes to Python code immediately reflected
- No need to reinstall after editing
- Supports debugging with breakpoints
For deployment or end-users:
make install-prod
# or
pip install .Benefits:
- Faster imports (no symlinks)
- Isolated from source changes
- Suitable for containers/deployments
# Build distributions
make dist
# Install from wheel
pip install dist/replicantdrivesim-0.6.6-py3-none-any.whlThe project includes a C++ native library for high-performance vehicle dynamics simulation.
Build manually:
./build_native_library.shBuild with Make:
make build-nativeBuild artifacts:
Assets/Plugins/TrafficSimulation/build/- CMake build directory*.so(Linux),*.dylib(macOS),*.dll(Windows) - Compiled libraries
Clean and rebuild:
make rebuild-nativeUnity standalone builds for the simulation environment.
Build manually:
./build_unity_app.shBuild with Make:
make build-unityBuild artifacts:
Builds/StandaloneOSX/- macOS buildBuilds/StandaloneLinux64/- Linux buildBuilds/StandaloneWindows64/- Windows build
Clean and rebuild:
make rebuild-unity# Build both native library and Unity app
make build-all
# Clean everything and rebuild
make rebuild-all# Clone repository
git clone https://github.com/chrisjcc/ReplicantDriveSim.git
cd ReplicantDriveSim
# Create conda environment
conda env create -f environment.yml
conda activate drive
# Or use make
make conda-env
conda activate drive
# Build native library
make build-native
# Build Unity application (optional)
make build-unity# Activate environment
conda activate drive
# Make code changes...
# Run tests
make test
# Format code
make format
# Run linting
make lint
# Type checking
make type-check
# Run all checks
make check# Format and check code
make format
make check
# Run full test suite with coverage
make test-cov
# Ensure builds work
make build-allThe environment.yml file follows a "single source of truth" approach:
- Conda dependencies: System libraries, Python interpreter, build tools
- Pip dependencies: Reference to
pyproject.toml(avoids duplication)
name: drive
channels:
- conda-forge
- defaults
dependencies:
# System libraries (conda-only)
- python=3.10.12
- cmake>=3.29.0
- ...
# Python packages from pyproject.toml
- pip:
- -e .[all] # Install from pyproject.toml✅ No duplication: Python dependencies declared once in pyproject.toml
✅ Consistency: Conda and pip users get same versions
✅ Maintainability: Update dependencies in one place
✅ Flexibility: Can install with/without conda
# Create environment
make conda-env
# or
conda env create -f environment.yml
# Update environment after changing pyproject.toml
make conda-update
# or
conda env update -f environment.yml --prune
# Remove environment
conda env remove -n drive| Target | Description |
|---|---|
make install |
Install in editable mode (development) |
make install-prod |
Production install (non-editable) |
make install-dev |
Install with dev dependencies |
make install-all |
Install with all optional dependencies |
make uninstall |
Uninstall package |
| Target | Description |
|---|---|
make build-native |
Build C++ native library |
make build-unity |
Build Unity application |
make build-all |
Build both native library and Unity app |
make rebuild-native |
Clean and rebuild native library |
make rebuild-unity |
Clean and rebuild Unity app |
make rebuild-all |
Clean and rebuild everything |
| Target | Description |
|---|---|
make test |
Run pytest test suite |
make test-cov |
Run tests with coverage report |
make test-verbose |
Run tests in verbose mode |
| Target | Description |
|---|---|
make lint |
Run flake8 linting |
make format |
Format code with black and isort |
make format-check |
Check formatting without changes |
make type-check |
Run mypy type checking |
make check |
Run all quality checks |
| Target | Description |
|---|---|
make docs |
Build Sphinx documentation |
make docs-serve |
Build and serve docs at localhost:8000 |
| Target | Description |
|---|---|
make clean |
Remove Python build artifacts |
make clean-native |
Remove native library artifacts |
make clean-unity |
Remove Unity build artifacts |
make clean-test |
Remove test/coverage artifacts |
make clean-docs |
Remove documentation artifacts |
make clean-all |
Remove all build artifacts |
| Target | Description |
|---|---|
make dev-setup |
Complete development environment setup |
make conda-env |
Create conda environment |
make conda-update |
Update conda environment |
| Target | Description |
|---|---|
make ci-test |
Run tests in CI mode (XML coverage) |
make ci-build |
CI build target (everything) |
| Target | Description |
|---|---|
make dist |
Build source and wheel distributions |
make upload-test |
Upload to TestPyPI |
make upload |
Upload to PyPI |
| Target | Description |
|---|---|
make show-deps |
Show installed dependencies |
make show-version |
Show package version |
make show-info |
Show package information |
# Install build and upload tools
pip install build twine# Build source distribution and wheel
make dist
# Check distributions
ls -lh dist/
# replicantdrivesim-0.6.6.tar.gz
# replicantdrivesim-0.6.6-py3-none-any.whl# Upload to TestPyPI
make upload-test
# Test installation from TestPyPI
pip install --index-url https://test.pypi.org/simple/ replicantdrivesim# Upload to PyPI (production)
make upload
# Install from PyPI
pip install replicantdrivesimUpdate version in pyproject.toml:
[project]
version = "0.6.7" # Increment versionThen rebuild and publish:
make clean-all
make dist
make uploadpyproject.toml: Complete PEP 621 compliant configuration (199 lines)Makefile: Comprehensive build automation (200+ lines)PACKAGING.md: This documentation file
environment.yml: Now referencespyproject.tomlfor Python deps (47 lines, down from 116)setup.py: Minimized to stub with documentation (23 lines, down from 7 functional)
setup.cfg: Deprecated per PEP 621 (all config moved topyproject.toml)
✅ pip install: Still works exactly as before ✅ pip install -e .: Editable installs unchanged ✅ python setup.py: Still functional (legacy support) ✅ Existing code: No changes to package imports or usage
Before:
pip install -e .After (same command works, but now preferred):
make installBefore:
./build_native_library.sh
./build_unity_app.shAfter (same scripts work, but now wrapped):
make build-allBefore:
- pip install -e .[dev]
- pytestAfter (equivalent):
- make install-dev
- make ci-testError:
ERROR: Package 'replicantdrivesim' requires a different Python: 3.11.x not in '<=3.10.12,>=3.10.1'
Solution: Use Python 3.10.1-3.10.12 (required for ML-Agents):
conda env create -f environment.yml # Installs Python 3.10.12
conda activate driveError:
ModuleNotFoundError: No module named 'pybind11'
Solution: Install build dependencies:
pip install -r requirements-build.txt
# or
make install-devError:
CMake Error: Could not find CMAKE_ROOT
Solution: Install CMake:
conda install cmake
# or
brew install cmake # macOS
sudo apt install cmake # UbuntuError:
Unity not found in PATH
Solution: Ensure Unity 6 (6000.0.30f1) is installed and in PATH:
export PATH="/Applications/Unity/Hub/Editor/6000.0.30f1/Unity.app/Contents/MacOS:$PATH"✅ DO: Declare dependencies in pyproject.toml
✅ DO: Use version constraints for stability (mlagents==1.1.0)
✅ DO: Pin exact versions for reproducibility
❌ DON'T: Duplicate dependencies in multiple files
❌ DON'T: Use requirements.txt for package dependencies
✅ DO: Use editable installs (make install)
✅ DO: Run tests before committing (make test)
✅ DO: Format code automatically (make format)
✅ DO: Use Makefile for common tasks
❌ DON'T: Edit installed package files
❌ DON'T: Skip linting/type checking
✅ DO: Use Makefile targets for builds
✅ DO: Clean before rebuilding (make rebuild-all)
✅ DO: Verify builds in CI/CD
❌ DON'T: Commit build artifacts to git
❌ DON'T: Manually run build scripts in production
- Official Docs: https://readthedocs.org/projects/replicantdrivesim
- GitHub: https://github.com/chrisjcc/ReplicantDriveSim
- Issues: https://github.com/chrisjcc/ReplicantDriveSim/issues
- PEP 517: Build System
- PEP 518: Build Dependencies
- PEP 621: Project Metadata
- PEP 660: Editable Installs
Document Version: 1.0 Date: 2026-01-01 Author: Claude (AI Assistant) Reviewed By: Pending