Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 15 additions & 20 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ pip-install-dependency-groups dev
pip install -ve.
```

Or if you use uv:

```bash
uv sync
```

<details><summary>Optional: External Jupyter kernel (click to expand)</summary>

You can set up a kernel for external Jupyter then deactivate your environment:
Expand All @@ -87,16 +93,11 @@ a rebuild.
CMake is common for C++ development, and ties nicely to many C++ tools, like
IDEs. If you want to use it for building, you can. Make a build directory and
run CMake. If you have a specific Python you want to use, add
`-DPYTHON_EXECUTABLE=$(which python)` or similar to the CMake line. If you need
`-DPython_EXECUTABLE=$(which python)` or similar to the CMake line. If you need
help installing the latest CMake version, [visit this
page](https://cliutils.gitlab.io/modern-cmake/chapters/intro/installing.html);
one option is to use pip to install CMake.

> Note: Since setuptools uses a subdirectory called `build`, it is _slightly_
> better to avoid making your CMake directory `build` as well. Also, you will
> often have multiple CMake directories (`build-release`, `build-debug`, etc.),
> so avoiding the descriptive name `build` is not a bad idea.

You have three options for running code in python:

1. Run from the build directory (only works with some commands, like `python -m
Expand All @@ -105,25 +106,20 @@ pytest`, and not others, like `pytest`
3. Set `CMAKE_INSTALL_PREFIX` to your site-packages and install (recommended
for virtual environments).

Here is the recommendation for a CMake install:
Here is the recommendation for a CMake install, using uv:

```bash
python3 -m venv env_cmake
source ./env_cmake/bin/activate
pip install dependency-groups
pip-install-dependency-groups dev
cmake -S . -B build-debug \
-GNinja \
-DCMAKE_INSTALL_PREFIX=$(python -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False))")
cmake --build build-debug -j4
cmake --install build-debug # Option 3 only
uv venv
uv pip install --group dev
cmake --workflow default

# Option 3 only:
cmake --install --preset default --prefix $(python -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(plat_specific=False,standard_lib=False))")
```

Note that option 3 will require reinstalling if the python files change, while
options 1-2 will not if you have a recent version of CMake (symlinks are made).

This could be simplified if pybind11 supported the new CMake FindPython tools.

## Testing

Run the unit tests (requires pytest and NumPy).
Expand All @@ -132,8 +128,7 @@ Run the unit tests (requires pytest and NumPy).
python3 -m pytest
```

For CMake, you can also use the `test` target from anywhere, or use `python3 -m
pytest` or `ctest` from the build directory.
For CMake, you can use `ctest --preset default` (the workflow above will run the tests).

The build requires `setuptools_scm`. The tests require `numpy`, `pytest`, and
`pytest-benchmark`. `pytest-sugar` adds some nice formatting.
Expand Down
16 changes: 8 additions & 8 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ jobs:
cmake:
name: CMake 🐍 ${{ matrix.python-version }}
runs-on: ubuntu-latest
env:
PIP_ONLY_BINARY: numpy
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.13", "pypy3.10"]
include:
- python-version: "3.9"
cmake-extras: "-DCMAKE_CXX_STANDARD=17"
- python-version: "3.11"
- python-version: "3.13"
- python-version: "3.13t"
- python-version: "pypy3.10"

steps:
- uses: actions/checkout@v4
Expand All @@ -87,17 +87,17 @@ jobs:
create-symlink: true

- name: Install python tools
run: uv pip install --system --python=python --group dev pytest-github-actions-annotate-failures
run: |
uv pip install --system --python=python --group dev --only-binary numpy pytest-github-actions-annotate-failures

- name: Configure
run: cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Debug -DBOOST_HISTOGRAM_ERRORS=ON ${{ matrix.cmake-extras }}
run: cmake --preset default -DCMAKE_BUILD_TYPE=Debug ${{ matrix.cmake-extras }}

- name: Build
run: cmake --build build -j 4
run: cmake --build --preset default -j 4

- name: Test
working-directory: ./build
run: python -m pytest -ra
run: ctest --preset default -j 4

build_wheels:
name: ${{ matrix.only }}
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
"RelWithDebInfo")
endif()

# If no Python venv set, and .venv exists, use it.
if(NOT DEFINED ENV{VIRTUALENV}
AND NOT DEFINED Python_ROOT_DIR
AND NOT DEFINED Python_EXECUTABLE
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
set(Python_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
endif()

# Adding pybind11 and setting up Python
# Will display pybind11 version
set(PYBIND11_FINDPYTHON TRUE)
Expand Down
42 changes: 42 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"version": 6,
"configurePresets": [
{
"name": "default",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/default",
"warnings": { "dev": true },
"cacheVariables": {
"BOOST_HISTOGRAM_ERRORS": "ON"
}
}
],
"buildPresets": [
{
"name": "default",
"verbose": true,
"configurePreset": "default"
}
],
"testPresets": [
{
"name": "default",
"displayName": "Default Test",
"configurePreset": "default",
"output": {
"outputOnFailure": true
}
}
],
"workflowPresets": [
{
"name": "default",
"displayName": "Default workflow",
"steps": [
{ "type": "configure", "name": "default" },
{ "type": "build", "name": "default" },
{ "type": "test", "name": "default" }
]
}
]
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ dev = [
{ include-group = "test" },
"ipykernel",
"nbconvert",
"numpy",
"setuptools_scm",
"typer",
"uhi",
Expand Down Expand Up @@ -93,6 +92,7 @@ test = [
"pytest-benchmark",
"pytest>=6.0",
"pytest-xdist",
"numpy",
]


Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ foreach(TEST_FILE IN LISTS BOOST_HIST_PY_TESTS)
NAME ${TEST_NAME}
COMMAND ${Python_EXECUTABLE} -m pytest "${TEST_FILE}" --rootdir=.
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}")
set_tests_properties(${TEST_NAME} PROPERTIES SKIP_RETURN_CODE 5)
endforeach()
Loading