Skip to content

A template repository demonstrating how to build a C++ powered Python package, using nix and uv.

Notifications You must be signed in to change notification settings

0nyr/python_cpp_uv_nix_template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python C++ Extension with NixOS, uv, and pybind11

This project demonstrates how to create a Python package with C++ extensions using:

  • NixOS for reproducible development environment
  • uv for Python package management
  • pybind11 for Python-C++ bindings
  • CMake for building C++ extensions
  • Python 3.13 as the target Python version

Project Structure

├── src/
│   ├── cpp/
│   │   ├── main.h          # C++ header with template functions
│   │   ├── main.cpp        # C++ implementation
│   │   └── bindings.cpp    # pybind11 bindings
│   └── python/
│       └── example_package/
│           ├── __init__.py     # Python package init (imports C++ functions)
│           ├── main.py         # Demo script
│           ├── nyr_cpp.pyi     # Type stubs for C++ functions
│           └── nyr_cpp.so      # Compiled C++ extension (generated)
├── build/                  # CMake build directory (generated)
├── CMakeLists.txt         # CMake configuration
├── build.sh               # Build script
├── pyproject.toml         # Python package configuration
├── flake.nix              # Nix development environment
└── README.md              # This file

Features

The C++ module nyr provides:

  • hello_world(message: str) - Prints a hello message
  • fast_pow(base: float, exp: int) - Fast exponentiation (double precision)
  • fast_pow_float(base: float, exp: int) - Fast exponentiation (single precision)
  • fast_pow_long(base: float, exp: int) - Fast exponentiation with long exponent

All functions use optimized algorithms and are accessible from Python with full type hints.

Building and Running

1. Enter the Development Environment

nix develop

This will:

  • Install all required dependencies (Python 3.13, CMake, pybind11, gcc)
  • Set up the Python virtual environment with uv
  • Configure CMake paths

Note that uv automatically install the current project package in "editable" mode. Changes to the source code are immediately reflected without reinstalling.

2. Build the C++ Extension

bash build.sh

This will:

  • Create a build/ directory
  • Configure the project with CMake
  • Compile the C++ extension
  • Copy the resulting .so file to the Python package

3. Test the Package

python -m example_package.main

Expected output:

Hello-World from example-package!

--- Testing C++ functions from Python ---
Hello, World: from Python calling C++!
fast_pow(2.0, 10) = 1024.0
fast_pow_float(3.0, 5) = 243.0
fast_pow_long(1.5, 20) = 3325.256730079651
fast_pow(5.0, 0) = 1.0
fast_pow(2.0, -3) = 0.125
--- C++ functions tested successfully! ---

Development Workflow

  1. Modify C++ code: Edit files in src/cpp/
  2. Rebuild: Run ./build.sh
  3. Test: Run python -m example_package.main

The build script automatically copies the compiled extension to the Python package directory.

Key Configuration Files

  • flake.nix: Defines the Nix development environment with all dependencies
  • CMakeLists.txt: CMake configuration for building the pybind11 module
  • pyproject.toml: Python package metadata and dependencies
  • src/cpp/bindings.cpp: pybind11 module definition
  • src/python/example_package/nyr_cpp.pyi: Type stubs for IDE support

Benefits of this Setup

  • Reproducible: Nix ensures consistent environment across machines
  • Fast: uv provides fast Python package management
  • Type-safe: Full type hints for C++ functions in Python
  • Modern: Uses latest Python 3.13 and C++20 standards
  • Efficient: Optimized C++ algorithms with Python convenience

Extending the Project

To add new C++ functions:

  1. Add declarations to src/cpp/main.h
  2. Implement in src/cpp/main.cpp
  3. Bind in src/cpp/bindings.cpp using pybind11
  4. Add type stubs to src/python/example_package/nyr_cpp.pyi
  5. Import in src/python/example_package/__init__.py
  6. Rebuild with ./build.sh

About

A template repository demonstrating how to build a C++ powered Python package, using nix and uv.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published