Skip to content
Open
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
25 changes: 22 additions & 3 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,11 +280,30 @@ To run include what you use, install (`brew install include-what-you-use` on
macOS), then run:

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

The report is sent to stderr; you can pipe it into a file if you wish.
The build always succeeds and IWYU writes its advice to stderr; pipe the build
output into a file if you wish. Nothing enforces the result, so read the
report and apply what is correct, with these cautions:

- The same header is reported once per translation unit that includes it, so
deduplicate before acting.
- Only act on a removal that both standard libraries (macOS and Linux) agree
on; take an addition from either.
- `<Python.h>` must stay the first include (via `detail/common.h`); do not let
a reorder suggestion move it.
- Ignore "should add" lines for `<math>` and other headers that are not real
public headers; a mapping for `<math>` makes IWYU abort.

Two support files drive the analysis. `tools/iwyu.sh` wraps
`include-what-you-use` and asks it to also check every pybind11 header, except
`pybind11.h` and `cast.h`, which crash IWYU 0.26. `tools/iwyu.imp` maps the
headers a suggestion must not name to the one pybind11 should use: CPython
internals to `<Python.h>`, libc++ detail headers and the C headers of
libstdc++ to the standard C++ header. Read the comment at its top before you
add an entry.

### Build recipes

Expand Down
17 changes: 17 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@
"CMAKE_CXX_CLANG_TIDY": "clang-tidy;--use-color;--warnings-as-errors=*",
"CMAKE_CXX_STANDARD": "17"
}
},
{
"name": "iwyu",
"displayName": "Include-what-you-use",
"inherits": "venv",
"binaryDir": "build-iwyu",
"cacheVariables": {
"CMAKE_CXX_INCLUDE_WHAT_YOU_USE": "${sourceDir}/tools/iwyu.sh",
"CMAKE_CXX_STANDARD": "17",
"CMAKE_OSX_SYSROOT": "macosx",
"PYBIND11_WERROR": false
}
}
],
"buildPresets": [
Expand All @@ -57,6 +69,11 @@
"configurePreset": "tidy",
"nativeToolOptions": ["-k0"]
},
{
"name": "iwyu",
"displayName": "Include-what-you-use Build",
"configurePreset": "iwyu"
},
{
"name": "tests",
"displayName": "Tests (for workflow)",
Expand Down
11 changes: 11 additions & 0 deletions include/pybind11/attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,21 @@
#pragma once

#include "detail/common.h"
#include "detail/internals.h"
#include "detail/type_caster_base.h"
#include "detail/typeid.h"
#include "detail/value_and_holder.h"
#include "cast.h"
#include "pytypes.h"
#include "trampoline_self_life_support.h"

#include <cstdint>
#include <functional>
#include <string>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <vector>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

Expand Down
5 changes: 5 additions & 0 deletions include/pybind11/buffer_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

#include "detail/common.h"

#include <string>
#include <type_traits>
#include <utility>
#include <vector>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

PYBIND11_NAMESPACE_BEGIN(detail)
Expand Down
7 changes: 6 additions & 1 deletion include/pybind11/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@
#pragma once

#include "pybind11.h"
#include "detail/common.h"
#include "detail/descr.h"
#include "cast.h"
#include "pytypes.h"

#include <chrono>
#include <cmath>
#include <cstdint>
#include <ctime>
#include <datetime.h>
#include <mutex>
#include <ratio>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)
Expand Down
6 changes: 6 additions & 0 deletions include/pybind11/complex.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@
#pragma once

#include "pybind11.h"
#include "detail/common.h"
#include "detail/descr.h"
#include "cast.h"
#include "pytypes.h"

#include <complex>
#include <string>
#include <type_traits>

/// glibc defines I as a macro which breaks things, e.g., boost template names
#ifdef I
Expand Down
6 changes: 3 additions & 3 deletions include/pybind11/conduit/wrap_include_python_h.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed
#endif

#include <Python.h>
#include <frameobject.h>
#include <pythread.h>
#include <Python.h> // IWYU pragma: export

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we check applying this on some of our test files? I think without more experts IWYU will include a lot of detail headers where we only want the core headers like pybind11 included by convention in downstream cpp files.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing this reminded me, back at Google I spent a significant amount of time battling with things like that:

https://github.com/google/pybind11clif/pull/30152/changes

IIUC that was for a different IWYU implementation, i.e. my old changes are probably not directly relevant, but indirectly related to @Skylion007's point, I had to add a bunch of these:

// IWYU pragma: private, include "third_party/pybind11/include/pybind11/pybind11.h"

I figure any IWYU will have to "know" this somehow, and for the case of <Python.h>, that information would ideally live in cpython.

That said, there is a different problem here: IWYU is removing <frameobject.h> and <pythread.h>, I believe incorrectly, at least for some older versions of cpython. I don't remember why exactly they are or were needed, but I can imagine that removing them here could break upstream use cases.

#include <frameobject.h> // IWYU pragma: export
#include <pythread.h> // IWYU pragma: export

#if defined(_MSC_VER)
# pragma warning(pop)
Expand Down
1 change: 1 addition & 0 deletions include/pybind11/critical_section.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#pragma once

#include "detail/pybind11_namespace_macros.h"
#include "pytypes.h"

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
Expand Down
2 changes: 2 additions & 0 deletions include/pybind11/detail/argument_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@

#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <iterator>
#include <new>
#include <type_traits>
#include <utility>
#include <vector>
Expand Down
22 changes: 22 additions & 0 deletions include/pybind11/detail/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,29 @@
#include <pybind11/attr.h>
#include <pybind11/options.h>

#include "../buffer_info.h"
#include "../cast.h"
#include "../pytypes.h"
#include "../trampoline_self_life_support.h"
#include "common.h"
#include "cpp_conduit.h"
#include "exception_translation.h"
#include "internals.h"
#include "type_caster_base.h"
#include "value_and_holder.h"

#include <cassert>
#include <cstddef>
#include <cstring>
#include <forward_list>
#include <memory>
#include <string>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)
Expand Down
14 changes: 8 additions & 6 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

#pragma once

#include <pybind11/conduit/wrap_include_python_h.h>
#include <pybind11/conduit/wrap_include_python_h.h> // IWYU pragma: export

#include <cassert>
#include <cstdint>
#include <initializer_list>
#include <new>
#include <utility>
#if PY_VERSION_HEX < 0x03090000
# error "PYTHON < 3.9 IS UNSUPPORTED. pybind11 v3.0 was the last to support Python 3.8."
#endif
Expand Down Expand Up @@ -44,7 +50,7 @@
PYBIND11_VERSION_RELEASE_LEVEL, \
PYBIND11_VERSION_RELEASE_SERIAL)

#include "pybind11_namespace_macros.h"
#include "pybind11_namespace_macros.h" // IWYU pragma: export

#if !(defined(_MSC_VER) && __cplusplus == 199711L)
# if __cplusplus >= 201402L
Expand Down Expand Up @@ -229,14 +235,10 @@
#include <cstddef>
#include <cstring>
#include <exception>
#include <forward_list>
#include <memory>
#include <stdexcept>
#include <string>
#include <type_traits>
#include <typeindex>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#if defined(__has_include)
# if __has_include(<version>)
Expand Down
1 change: 1 addition & 0 deletions include/pybind11/detail/cpp_conduit.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include <pybind11/pytypes.h>

#include "../conduit/pybind11_platform_abi_id.h"
#include "common.h"
#include "internals.h"

Expand Down
5 changes: 5 additions & 0 deletions include/pybind11/detail/descr.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@

#include "common.h"

#include <array>
#include <type_traits>
#include <typeinfo>
#include <utility>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

Expand Down
4 changes: 4 additions & 0 deletions include/pybind11/detail/exception_translation.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@

#pragma once

#include "../pytypes.h"
#include "common.h"
#include "internals.h"

#include <exception>
#include <forward_list>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

Expand Down
2 changes: 2 additions & 0 deletions include/pybind11/detail/function_record_pyobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
#include <pybind11/conduit/pybind11_platform_abi_id.h>
#include <pybind11/pytypes.h>

#include "../cast.h"
#include "common.h"
#include "internals.h"

#include <cstring>
#include <utility>
Expand Down
1 change: 1 addition & 0 deletions include/pybind11/detail/function_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

#include <pybind11/detail/common.h>

#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <utility>
Expand Down
4 changes: 4 additions & 0 deletions include/pybind11/detail/holder_caster_foreign_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@

#include <pybind11/gil.h>

#include "../pytypes.h"
#include "common.h"

#include <memory>
#include <utility>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)

Expand Down
14 changes: 13 additions & 1 deletion include/pybind11/detail/init.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,20 @@

#pragma once

#include "class.h"
#include "../attr.h"
#include "../cast.h"
#include "../pytypes.h"
#include "common.h"
#include "descr.h"
#include "internals.h"
#include "struct_smart_holder.h"
#include "type_caster_base.h"
#include "using_smart_holder.h"
#include "value_and_holder.h"

#include <memory>
#include <type_traits>
#include <utility>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

Expand Down
16 changes: 16 additions & 0 deletions include/pybind11/detail/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,31 @@
#include <pybind11/pytypes.h>
#include <pybind11/trampoline_self_life_support.h>

#include "../buffer_info.h"
#include "common.h"
#include "struct_smart_holder.h"
#include "value_and_holder.h"

#include <atomic>
#include <cstdint>
#include <cstring>
#include <exception>
#include <forward_list>
#include <functional>
#include <limits>
#include <memory>
#include <mutex>
#include <new>
#include <stdexcept>
#include <string>
#include <thread>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

/// Tracks the `internals` and `type_info` ABI version independent of the main library version.
///
Expand Down
1 change: 1 addition & 0 deletions include/pybind11/detail/native_enum_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sstream>
#include <string>
#include <typeindex>
#include <unordered_map>

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
PYBIND11_NAMESPACE_BEGIN(detail)
Expand Down
9 changes: 7 additions & 2 deletions include/pybind11/detail/type_caster_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,32 @@

#include <pybind11/gil.h>
#include <pybind11/pytypes.h>
#include <pybind11/trampoline_self_life_support.h>

#include "../conduit/pybind11_platform_abi_id.h"
#include "common.h"
#include "cpp_conduit.h"
#include "descr.h"
#include "dynamic_raw_ptr_cast_if_possible.h"
#include "internals.h"
#include "struct_smart_holder.h"
#include "typeid.h"
#include "using_smart_holder.h"
#include "value_and_holder.h"

#include <cassert>
#include <cstdint>
#include <cstring>
#include <forward_list>
#include <iterator>
#include <memory>
#include <new>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

Expand Down
Loading
Loading