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
1 change: 1 addition & 0 deletions pybind11/.clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ Checks: |
-bugprone-reserved-identifier,
-bugprone-unused-raii,
-performance-enum-size,
-performance-inefficient-string-concatenation,

CheckOptions:
- key: modernize-use-equals-default.IgnoreMacros
Expand Down
11 changes: 11 additions & 0 deletions pybind11/.codespell-ignore-lines
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ template <op_id id, op_type ot, typename L, typename R>
template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra>
class_ &def(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {
class_ &def_cast(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {
int valu;
explicit movable_int(int v) : valu{v} {}
movable_int(movable_int &&other) noexcept : valu(other.valu) { other.valu = 91; }
explicit indestructible_int(int v) : valu{v} {}
REQUIRE(hld.as_raw_ptr_unowned<zombie>()->valu == 19);
REQUIRE(othr.valu == 19);
REQUIRE(orig.valu == 91);
(m.pass_valu, "Valu", "pass_valu:Valu(_MvCtor)*_CpCtor"),
atyp_valu rtrn_valu() { atyp_valu obj{"Valu"}; return obj; }
assert m.atyp_valu().get_mtxt() == "Valu"
// valu(e), ref(erence), ptr or p (pointer), r = rvalue, m = mutable, c = const,
@pytest.mark.parametrize("access", ["ro", "rw", "static_ro", "static_rw"])
struct IntStruct {
explicit IntStruct(int v) : value(v){};
Expand Down
149 changes: 55 additions & 94 deletions pybind11/.github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ the following rules to make the process as smooth as possible:
* Make a new branch for every feature you're working on.
* Make small and clean pull requests that are easy to review but make sure they
do add value by themselves.
* Add tests for any new functionality and run the test suite (`cmake --build
build --target pytest`) to ensure that no existing features break.
* Add tests for any new functionality and run the test suite (`cmake --workflow
venv`) to ensure that no existing features break.
* Please run [`pre-commit`][pre-commit] to check your code matches the
project style. (Note that `gawk` is required.) Use `pre-commit run
--all-files` before committing (or use installed-mode, check pre-commit docs)
Expand Down Expand Up @@ -81,11 +81,11 @@ nox -s build
### Full setup

To setup an ideal development environment, run the following commands on a
system with CMake 3.14+:
system with CMake 3.15+:

```bash
python3 -m venv venv
source venv/bin/activate
python3 -m venv .venv
source .venv/bin/activate
pip install -r tests/requirements.txt
cmake -S . -B build -DDOWNLOAD_CATCH=ON -DDOWNLOAD_EIGEN=ON
cmake --build build -j4
Expand All @@ -96,13 +96,44 @@ Tips:
* You can use `virtualenv` (faster, from PyPI) instead of `venv`.
* You can select any name for your environment folder; if it contains "env" it
will be ignored by git.
* If you don't have CMake 3.14+, just add "cmake" to the pip install command.
* You can use `-DPYBIND11_FINDPYTHON=ON` to use FindPython on CMake 3.12+
* In classic mode, you may need to set `-DPYTHON_EXECUTABLE=/path/to/python`.
FindPython uses `-DPython_ROOT_DIR=/path/to` or
* If you don't have CMake 3.15+, just add "cmake" to the pip install command.
* You can use `-DPYBIND11_FINDPYTHON=ON` to use FindPython.
* For a specific Python, you can use `-DPython_ROOT_DIR=/path/to` or
`-DPython_EXECUTABLE=/path/to/python`.

### Configuration options
## CMake presets

We also support CMake presets. If you have [uv](https://docs.astral.sh/uv/),
you can use:

```bash
cmake --workflow venv
```

to setup a venv and run all tests. You can break this up into components
if you want to use a specific version of Python (or any other config option) or
build only one of the valid targets (listed below).

```bash
cmake --preset venv -DPYBIND11_CREATE_WITH_UV=3.13t
cmake --build --preset venv
cmake --build --preset venv -t cpptest
```

The `default` preset will use an existing venv or Python install. If you'd like
to run pytest yourself, say to easily control the options:

```bash
cd build
source .venv/bin/activate
cd tests
python -m pytest
```

The `.so` file is not installed into the venv, so you need to run from this
directory, the local directory is included with `python -m`.

## Configuration options

In CMake, configuration options are given with "-D". Options are stored in the
build directory, in the `CMakeCache.txt` file, so they are remembered for each
Expand Down Expand Up @@ -149,8 +180,8 @@ To run the tests, you can "build" the check target:
cmake --build build --target check
```

`--target` can be spelled `-t` in CMake 3.15+. You can also run individual
tests with these targets:
`--target` can be spelled `-t`. You can also run individual tests with these
targets:

* `pytest`: Python tests only, using the
[pytest](https://docs.pytest.org/en/stable/) framework
Expand Down Expand Up @@ -231,17 +262,17 @@ of the pybind11 repo.
more complex to run, compared to `clang-format`, but support for `clang-tidy`
is built into the pybind11 CMake configuration. To run `clang-tidy`, the
following recipe should work. Run the `docker` command from the top-level
directory inside your pybind11 git clone. Files will be modified in place,
so you can use git to monitor the changes.
directory inside your pybind11 git clone.

```bash
docker run --rm -v $PWD:/mounted_pybind11 -it silkeh/clang:15-bullseye
apt-get update && apt-get install -y git python3-dev python3-pytest
cmake -S /mounted_pybind11/ -B build -DCMAKE_CXX_CLANG_TIDY="$(which clang-tidy);--use-color" -DDOWNLOAD_EIGEN=ON -DDOWNLOAD_CATCH=ON -DCMAKE_CXX_STANDARD=17
cmake --build build -j 2
docker run --rm -v $PWD:/pybind11 -w /pybind11 -it silkeh/clang:20
apt-get update && apt-get install -y git python3-dev python3-pytest ninja-build
cmake --preset tidy
cmake --build --preset tidy
```

You can add `--fix` to the options list if you want.
You can add `--fix` to the options list in the preset if you want to apply fixes
(remember `-j1` to run only one thread).

### Include what you use

Expand All @@ -250,7 +281,7 @@ macOS), then run:

```bash
cmake -S . -B build-iwyu -DCMAKE_CXX_INCLUDE_WHAT_YOU_USE=$(which include-what-you-use)
cmake --build build
cmake --build build-iwyu
```

The report is sent to stderr; you can pipe it into a file if you wish.
Expand Down Expand Up @@ -299,85 +330,15 @@ files inside the package, that you get access to via functions in the package,
and a `pybind11-global` package that can be included via `pybind11[global]` if
you want the more invasive but discoverable file locations.

If you want to install or package the GitHub source, it is best to have Pip 10
or newer on Windows, macOS, or Linux (manylinux1 compatible, includes most
distributions). You can then build the SDists, or run any procedure that makes
SDists internally, like making wheels or installing.


```bash
# Editable development install example
python3 -m pip install -e .
```

Since Pip itself does not have an `sdist` command (it does have `wheel` and
`install`), you may want to use the upcoming `build` package:

```bash
python3 -m pip install build

# Normal package
python3 -m build -s .

# Global extra
PYBIND11_GLOBAL_SDIST=1 python3 -m build -s .
```
If you want to package the GitHub source for the "global" package, you need
to use nox. Normal packaging will only make the normal package.

If you want to use the classic "direct" usage of `python setup.py`, you will
need CMake 3.15+ and either `make` or `ninja` preinstalled (possibly via `pip
install cmake ninja`), since directly running Python on `setup.py` cannot pick
up and install `pyproject.toml` requirements. As long as you have those two
things, though, everything works the way you would expect:

```bash
# Normal package
python3 setup.py sdist

# Global extra
PYBIND11_GLOBAL_SDIST=1 python3 setup.py sdist
nox -s build
nox -s build_global
```

A detailed explanation of the build procedure design for developers wanting to
work on or maintain the packaging system is as follows:

#### 1. Building from the source directory

When you invoke any `setup.py` command from the source directory, including
`pip wheel .` and `pip install .`, you will activate a full source build. This
is made of the following steps:

1. If the tool is PEP 518 compliant, like Pip 10+, it will create a temporary
virtual environment and install the build requirements (mostly CMake) into
it. (if you are not on Windows, macOS, or a manylinux compliant system, you
can disable this with `--no-build-isolation` as long as you have CMake 3.15+
installed)
2. The environment variable `PYBIND11_GLOBAL_SDIST` is checked - if it is set
and truthy, this will be make the accessory `pybind11-global` package,
instead of the normal `pybind11` package. This package is used for
installing the files directly to your environment root directory, using
`pybind11[global]`.
2. `setup.py` reads the version from `pybind11/_version.py` and verifies it
matches `includes/pybind11/detail/common.h`.
3. CMake is run with `-DCMAKE_INSTALL_PREIFX=pybind11`. Since the CMake install
procedure uses only relative paths and is identical on all platforms, these
files are valid as long as they stay in the correct relative position to the
includes. `pybind11/share/cmake/pybind11` has the CMake files, and
`pybind11/include` has the includes. The build directory is discarded.
4. Simpler files are placed in the SDist: `tools/setup_*.py.in`,
`tools/pyproject.toml` (`main` or `global`)
5. The package is created by running the setup function in the
`tools/setup_*.py`. `setup_main.py` fills in Python packages, and
`setup_global.py` fills in only the data/header slots.
6. A context manager cleans up the temporary CMake install directory (even if
an error is thrown).

### 2. Building from SDist

Since the SDist has the rendered template files in `tools` along with the
includes and CMake files in the correct locations, the builds are completely
trivial and simple. No extra requirements are required. You can even use Pip 9
if you really want to.


[pre-commit]: https://pre-commit.com
[clang-format]: https://clang.llvm.org/docs/ClangFormat.html
Expand Down
2 changes: 1 addition & 1 deletion pybind11/.github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ docs:
all:
- changed-files:
- all-globs-to-all-files:
- '!docs/changelog.rst'
- '!docs/changelog.md'
- '!docs/upgrade.rst'
- base-branch: "^(?!dependabot).*"
- base-branch: "^(?!pre-commit-ci).*"
Expand Down
2 changes: 1 addition & 1 deletion pybind11/.github/labeler_merged.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
needs changelog:
- all:
- changed-files:
- all-globs-to-all-files: "!docs/changelog.rst"
- all-globs-to-all-files: "!docs/changelog.md"
- base-branch: "^(?!dependabot).*"
- base-branch: "^(?!pre-commit-ci).*"
10 changes: 3 additions & 7 deletions pybind11/.github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ It is recommended to use conventional commit format, see conventionalcommits.org

## Suggested changelog entry:

<!-- Fill in the below block with the expected RestructuredText entry. Delete if no entry needed;
but do not delete header or rst block if an entry is needed! Will be collected via a script. -->
<!-- Fill in the block below with the expected entry. Delete if no entry needed;
but do not delete the header if an entry is needed! Will be collected via a script. -->

```rst
```

<!-- If the upgrade guide needs updating, note that here too -->
* Placeholder.
Loading
Loading