[v2] py: Fix include order
diff mbox series

Message ID 20260220144008.211492-1-barnabas.pocze@ideasonboard.com
State New
Headers show
Series
  • [v2] py: Fix include order
Related show

Commit Message

Barnabás Pőcze Feb. 20, 2026, 2:40 p.m. UTC
Python.h hence the pybind header must be included first since pyconfig.h
unconditionally overrides certain feature test macros[0]. This was mostly
hidden by the fact that macro redefinitions with the same value do not
trigger compiler warnings. However, glibc 43 has changed certain defaults[1],
causing mismatches, leading to compiler warnings.

So change the include order so that `<pybind11/...>` headers are included
first and then the local `"py_..."` headers, and then everything else.

Adjust `.clang-format` and the documentation as well.

[0]: https://docs.python.org/3/c-api/intro.html#include-files
[1]: https://sourceware.org/git/?p=glibc.git;a=commit;h=a5cc3018f31a125f019685b239c6e5a0bf1a272b

Link: https://github.com/python/cpython/issues/61322
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
---
changes in v2:
  * edit documentation

v1: https://patchwork.libcamera.org/patch/26184/
---
 .clang-format                                 |  6 ++++++
 Documentation/coding-style.rst                |  6 ++++++
 src/py/libcamera/py_camera_manager.h          |  4 ++--
 src/py/libcamera/py_color_space.cpp           |  6 +++---
 src/py/libcamera/py_controls_generated.cpp.in |  4 ++--
 src/py/libcamera/py_enums.cpp                 |  4 ++--
 src/py/libcamera/py_formats_generated.cpp.in  |  4 ++--
 src/py/libcamera/py_geometry.cpp              | 10 +++++-----
 src/py/libcamera/py_helpers.cpp               |  8 ++++----
 src/py/libcamera/py_helpers.h                 |  4 ++--
 src/py/libcamera/py_main.cpp                  | 15 +++++++--------
 src/py/libcamera/py_main.h                    |  4 ++--
 src/py/libcamera/py_transform.cpp             |  6 +++---
 13 files changed, 46 insertions(+), 35 deletions(-)

--
2.53.0

Comments

Laurent Pinchart Feb. 20, 2026, 3:33 p.m. UTC | #1
On Fri, Feb 20, 2026 at 03:40:08PM +0100, Barnabás Pőcze wrote:
> Python.h hence the pybind header must be included first since pyconfig.h
> unconditionally overrides certain feature test macros[0]. This was mostly
> hidden by the fact that macro redefinitions with the same value do not
> trigger compiler warnings. However, glibc 43 has changed certain defaults[1],
> causing mismatches, leading to compiler warnings.
> 
> So change the include order so that `<pybind11/...>` headers are included
> first and then the local `"py_..."` headers, and then everything else.
> 
> Adjust `.clang-format` and the documentation as well.
> 
> [0]: https://docs.python.org/3/c-api/intro.html#include-files
> [1]: https://sourceware.org/git/?p=glibc.git;a=commit;h=a5cc3018f31a125f019685b239c6e5a0bf1a272b
> 
> Link: https://github.com/python/cpython/issues/61322
> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
> ---
> changes in v2:
>   * edit documentation
> 
> v1: https://patchwork.libcamera.org/patch/26184/
> ---
>  .clang-format                                 |  6 ++++++
>  Documentation/coding-style.rst                |  6 ++++++
>  src/py/libcamera/py_camera_manager.h          |  4 ++--
>  src/py/libcamera/py_color_space.cpp           |  6 +++---
>  src/py/libcamera/py_controls_generated.cpp.in |  4 ++--
>  src/py/libcamera/py_enums.cpp                 |  4 ++--
>  src/py/libcamera/py_formats_generated.cpp.in  |  4 ++--
>  src/py/libcamera/py_geometry.cpp              | 10 +++++-----
>  src/py/libcamera/py_helpers.cpp               |  8 ++++----
>  src/py/libcamera/py_helpers.h                 |  4 ++--
>  src/py/libcamera/py_main.cpp                  | 15 +++++++--------
>  src/py/libcamera/py_main.h                    |  4 ++--
>  src/py/libcamera/py_transform.cpp             |  6 +++---
>  13 files changed, 46 insertions(+), 35 deletions(-)
> 
> diff --git a/.clang-format b/.clang-format
> index 7fc30f614..7dbeea784 100644
> --- a/.clang-format
> +++ b/.clang-format
> @@ -77,6 +77,12 @@ IncludeCategories:
>    - Regex:           '<Q([A-Za-z0-9\-_])+>'
>      CaseSensitive:   true
>      Priority:        9
> +  # Python.h hence pybind11 headers must be included first
> +  # https://docs.python.org/3/c-api/intro.html#include-files
> +  - Regex:           '<pybind11/.*>'
> +    Priority:        -9
> +  - Regex:           '"py_.*"'
> +    Priority:        -8
>    # Headers in <> with an extension. (+system libraries)
>    - Regex:           '<([A-Za-z0-9\-_])+\.h>'
>      Priority:        2
> diff --git a/Documentation/coding-style.rst b/Documentation/coding-style.rst
> index 3352b75c7..e0864b78d 100644
> --- a/Documentation/coding-style.rst
> +++ b/Documentation/coding-style.rst
> @@ -95,6 +95,12 @@ System and library headers shall be included with angle brackets. Project
>  headers shall be included with angle brackets for the libcamera public API
>  headers, and with double quotes for internal libcamera headers.
> 
> +.. note::
> +   As an exception pybind11 headers and local ``py_*`` headers must be included first
> +   in the Python bindings due to the requirements outlined in the `Python documentation`_.
> +
> +.. _Python documentation: https://docs.python.org/3/c-api/intro.html#include-files
> +
> 
>  C++ Specific Rules
>  ------------------
> diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h
> index af69b915e..7da65172e 100644
> --- a/src/py/libcamera/py_camera_manager.h
> +++ b/src/py/libcamera/py_camera_manager.h
> @@ -5,12 +5,12 @@
> 
>  #pragma once
> 
> +#include <pybind11/pybind11.h>
> +
>  #include <libcamera/base/mutex.h>
> 
>  #include <libcamera/libcamera.h>
> 
> -#include <pybind11/pybind11.h>
> -
>  using namespace libcamera;
> 
>  class PyCameraManager
> diff --git a/src/py/libcamera/py_color_space.cpp b/src/py/libcamera/py_color_space.cpp
> index fd5a5dabe..2f4d2d891 100644
> --- a/src/py/libcamera/py_color_space.cpp
> +++ b/src/py/libcamera/py_color_space.cpp
> @@ -5,15 +5,15 @@
>   * Python bindings - Color Space classes
>   */
> 
> -#include <libcamera/color_space.h>
> -#include <libcamera/libcamera.h>
> -
>  #include <pybind11/operators.h>
>  #include <pybind11/pybind11.h>
>  #include <pybind11/stl.h>
> 
>  #include "py_main.h"
> 
> +#include <libcamera/color_space.h>
> +#include <libcamera/libcamera.h>

While at it you can drop color_space.h as it's included in libcamera.h.

> +
>  namespace py = pybind11;
> 
>  using namespace libcamera;
> diff --git a/src/py/libcamera/py_controls_generated.cpp.in b/src/py/libcamera/py_controls_generated.cpp.in
> index 22a132d19..c42a477bb 100644
> --- a/src/py/libcamera/py_controls_generated.cpp.in
> +++ b/src/py/libcamera/py_controls_generated.cpp.in
> @@ -7,12 +7,12 @@
>   * This file is auto-generated. Do not edit.
>   */
> 
> -#include <libcamera/{{header}}>
> -
>  #include <pybind11/pybind11.h>
> 
>  #include "py_main.h"
> 
> +#include <libcamera/{{header}}>
> +
>  namespace py = pybind11;
> 
>  class Py{{mode|capitalize}}
> diff --git a/src/py/libcamera/py_enums.cpp b/src/py/libcamera/py_enums.cpp
> index 9e75ec1a9..715b63880 100644
> --- a/src/py/libcamera/py_enums.cpp
> +++ b/src/py/libcamera/py_enums.cpp
> @@ -5,12 +5,12 @@
>   * Python bindings - Enumerations
>   */
> 
> -#include <libcamera/libcamera.h>
> -
>  #include <pybind11/pybind11.h>
> 
>  #include "py_main.h"
> 
> +#include <libcamera/libcamera.h>
> +
>  namespace py = pybind11;
> 
>  using namespace libcamera;
> diff --git a/src/py/libcamera/py_formats_generated.cpp.in b/src/py/libcamera/py_formats_generated.cpp.in
> index c5fb90639..bd0ccdc3e 100644
> --- a/src/py/libcamera/py_formats_generated.cpp.in
> +++ b/src/py/libcamera/py_formats_generated.cpp.in
> @@ -7,10 +7,10 @@
>   * This file is auto-generated. Do not edit.
>   */
> 
> -#include <libcamera/formats.h>
> -
>  #include <pybind11/pybind11.h>
> 
> +#include <libcamera/formats.h>
> +
>  #include "py_main.h"
> 
>  namespace py = pybind11;
> diff --git a/src/py/libcamera/py_geometry.cpp b/src/py/libcamera/py_geometry.cpp
> index c7e303609..d96015f03 100644
> --- a/src/py/libcamera/py_geometry.cpp
> +++ b/src/py/libcamera/py_geometry.cpp
> @@ -5,17 +5,17 @@
>   * Python bindings - Geometry classes
>   */
> 
> -#include <array>
> -
> -#include <libcamera/geometry.h>
> -#include <libcamera/libcamera.h>
> -
>  #include <pybind11/operators.h>
>  #include <pybind11/pybind11.h>
>  #include <pybind11/stl.h>
> 
>  #include "py_main.h"
> 
> +#include <array>
> +
> +#include <libcamera/geometry.h>
> +#include <libcamera/libcamera.h>

Same here for geometry.h.

> +
>  namespace py = pybind11;
> 
>  using namespace libcamera;
> diff --git a/src/py/libcamera/py_helpers.cpp b/src/py/libcamera/py_helpers.cpp
> index 8c55ef845..b9142225c 100644
> --- a/src/py/libcamera/py_helpers.cpp
> +++ b/src/py/libcamera/py_helpers.cpp
> @@ -3,14 +3,14 @@
>   * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
>   */
> 
> -#include "py_helpers.h"
> -
> -#include <libcamera/libcamera.h>
> -
>  #include <pybind11/functional.h>
>  #include <pybind11/stl.h>
>  #include <pybind11/stl_bind.h>
> 
> +#include "py_helpers.h"
> +
> +#include <libcamera/libcamera.h>
> +
>  namespace py = pybind11;
> 
>  using namespace libcamera;
> diff --git a/src/py/libcamera/py_helpers.h b/src/py/libcamera/py_helpers.h
> index 983969dff..989fae77b 100644
> --- a/src/py/libcamera/py_helpers.h
> +++ b/src/py/libcamera/py_helpers.h
> @@ -5,9 +5,9 @@
> 
>  #pragma once
> 
> -#include <libcamera/libcamera.h>
> -
>  #include <pybind11/pybind11.h>
> 
> +#include <libcamera/libcamera.h>
> +
>  pybind11::object controlValueToPy(const libcamera::ControlValue &cv);
>  libcamera::ControlValue pyToControlValue(const pybind11::object &ob, libcamera::ControlType type);
> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
> index a983ea75c..d0ef6915b 100644
> --- a/src/py/libcamera/py_main.cpp
> +++ b/src/py/libcamera/py_main.cpp
> @@ -5,6 +5,13 @@
>   * Python bindings
>   */
> 
> +#include <pybind11/functional.h>
> +#include <pybind11/pybind11.h>
> +#include <pybind11/stl.h>
> +#include <pybind11/stl_bind.h>
> +
> +#include "py_camera_manager.h"
> +#include "py_helpers.h"
>  #include "py_main.h"
> 
>  #include <limits>
> @@ -17,14 +24,6 @@
> 
>  #include <libcamera/libcamera.h>
> 
> -#include <pybind11/functional.h>
> -#include <pybind11/pybind11.h>
> -#include <pybind11/stl.h>
> -#include <pybind11/stl_bind.h>
> -
> -#include "py_camera_manager.h"
> -#include "py_helpers.h"
> -
>  namespace py = pybind11;
> 
>  using namespace libcamera;
> diff --git a/src/py/libcamera/py_main.h b/src/py/libcamera/py_main.h
> index 4d594326e..dd31c6d9a 100644
> --- a/src/py/libcamera/py_main.h
> +++ b/src/py/libcamera/py_main.h
> @@ -5,10 +5,10 @@
> 
>  #pragma once
> 
> -#include <libcamera/base/log.h>
> -
>  #include <pybind11/pybind11.h>
> 
> +#include <libcamera/base/log.h>
> +
>  namespace libcamera {
> 
>  LOG_DECLARE_CATEGORY(Python)
> diff --git a/src/py/libcamera/py_transform.cpp b/src/py/libcamera/py_transform.cpp
> index 768260ffc..8719b5ff5 100644
> --- a/src/py/libcamera/py_transform.cpp
> +++ b/src/py/libcamera/py_transform.cpp
> @@ -5,15 +5,15 @@
>   * Python bindings - Transform class
>   */
> 
> -#include <libcamera/transform.h>
> -#include <libcamera/libcamera.h>
> -
>  #include <pybind11/operators.h>
>  #include <pybind11/pybind11.h>
>  #include <pybind11/stl.h>
> 
>  #include "py_main.h"
> 
> +#include <libcamera/transform.h>
> +#include <libcamera/libcamera.h>

Same here, drop transform.h.

No need to resubmit just for this.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +
>  namespace py = pybind11;
> 
>  using namespace libcamera;

Patch
diff mbox series

diff --git a/.clang-format b/.clang-format
index 7fc30f614..7dbeea784 100644
--- a/.clang-format
+++ b/.clang-format
@@ -77,6 +77,12 @@  IncludeCategories:
   - Regex:           '<Q([A-Za-z0-9\-_])+>'
     CaseSensitive:   true
     Priority:        9
+  # Python.h hence pybind11 headers must be included first
+  # https://docs.python.org/3/c-api/intro.html#include-files
+  - Regex:           '<pybind11/.*>'
+    Priority:        -9
+  - Regex:           '"py_.*"'
+    Priority:        -8
   # Headers in <> with an extension. (+system libraries)
   - Regex:           '<([A-Za-z0-9\-_])+\.h>'
     Priority:        2
diff --git a/Documentation/coding-style.rst b/Documentation/coding-style.rst
index 3352b75c7..e0864b78d 100644
--- a/Documentation/coding-style.rst
+++ b/Documentation/coding-style.rst
@@ -95,6 +95,12 @@  System and library headers shall be included with angle brackets. Project
 headers shall be included with angle brackets for the libcamera public API
 headers, and with double quotes for internal libcamera headers.

+.. note::
+   As an exception pybind11 headers and local ``py_*`` headers must be included first
+   in the Python bindings due to the requirements outlined in the `Python documentation`_.
+
+.. _Python documentation: https://docs.python.org/3/c-api/intro.html#include-files
+

 C++ Specific Rules
 ------------------
diff --git a/src/py/libcamera/py_camera_manager.h b/src/py/libcamera/py_camera_manager.h
index af69b915e..7da65172e 100644
--- a/src/py/libcamera/py_camera_manager.h
+++ b/src/py/libcamera/py_camera_manager.h
@@ -5,12 +5,12 @@ 

 #pragma once

+#include <pybind11/pybind11.h>
+
 #include <libcamera/base/mutex.h>

 #include <libcamera/libcamera.h>

-#include <pybind11/pybind11.h>
-
 using namespace libcamera;

 class PyCameraManager
diff --git a/src/py/libcamera/py_color_space.cpp b/src/py/libcamera/py_color_space.cpp
index fd5a5dabe..2f4d2d891 100644
--- a/src/py/libcamera/py_color_space.cpp
+++ b/src/py/libcamera/py_color_space.cpp
@@ -5,15 +5,15 @@ 
  * Python bindings - Color Space classes
  */

-#include <libcamera/color_space.h>
-#include <libcamera/libcamera.h>
-
 #include <pybind11/operators.h>
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>

 #include "py_main.h"

+#include <libcamera/color_space.h>
+#include <libcamera/libcamera.h>
+
 namespace py = pybind11;

 using namespace libcamera;
diff --git a/src/py/libcamera/py_controls_generated.cpp.in b/src/py/libcamera/py_controls_generated.cpp.in
index 22a132d19..c42a477bb 100644
--- a/src/py/libcamera/py_controls_generated.cpp.in
+++ b/src/py/libcamera/py_controls_generated.cpp.in
@@ -7,12 +7,12 @@ 
  * This file is auto-generated. Do not edit.
  */

-#include <libcamera/{{header}}>
-
 #include <pybind11/pybind11.h>

 #include "py_main.h"

+#include <libcamera/{{header}}>
+
 namespace py = pybind11;

 class Py{{mode|capitalize}}
diff --git a/src/py/libcamera/py_enums.cpp b/src/py/libcamera/py_enums.cpp
index 9e75ec1a9..715b63880 100644
--- a/src/py/libcamera/py_enums.cpp
+++ b/src/py/libcamera/py_enums.cpp
@@ -5,12 +5,12 @@ 
  * Python bindings - Enumerations
  */

-#include <libcamera/libcamera.h>
-
 #include <pybind11/pybind11.h>

 #include "py_main.h"

+#include <libcamera/libcamera.h>
+
 namespace py = pybind11;

 using namespace libcamera;
diff --git a/src/py/libcamera/py_formats_generated.cpp.in b/src/py/libcamera/py_formats_generated.cpp.in
index c5fb90639..bd0ccdc3e 100644
--- a/src/py/libcamera/py_formats_generated.cpp.in
+++ b/src/py/libcamera/py_formats_generated.cpp.in
@@ -7,10 +7,10 @@ 
  * This file is auto-generated. Do not edit.
  */

-#include <libcamera/formats.h>
-
 #include <pybind11/pybind11.h>

+#include <libcamera/formats.h>
+
 #include "py_main.h"

 namespace py = pybind11;
diff --git a/src/py/libcamera/py_geometry.cpp b/src/py/libcamera/py_geometry.cpp
index c7e303609..d96015f03 100644
--- a/src/py/libcamera/py_geometry.cpp
+++ b/src/py/libcamera/py_geometry.cpp
@@ -5,17 +5,17 @@ 
  * Python bindings - Geometry classes
  */

-#include <array>
-
-#include <libcamera/geometry.h>
-#include <libcamera/libcamera.h>
-
 #include <pybind11/operators.h>
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>

 #include "py_main.h"

+#include <array>
+
+#include <libcamera/geometry.h>
+#include <libcamera/libcamera.h>
+
 namespace py = pybind11;

 using namespace libcamera;
diff --git a/src/py/libcamera/py_helpers.cpp b/src/py/libcamera/py_helpers.cpp
index 8c55ef845..b9142225c 100644
--- a/src/py/libcamera/py_helpers.cpp
+++ b/src/py/libcamera/py_helpers.cpp
@@ -3,14 +3,14 @@ 
  * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
  */

-#include "py_helpers.h"
-
-#include <libcamera/libcamera.h>
-
 #include <pybind11/functional.h>
 #include <pybind11/stl.h>
 #include <pybind11/stl_bind.h>

+#include "py_helpers.h"
+
+#include <libcamera/libcamera.h>
+
 namespace py = pybind11;

 using namespace libcamera;
diff --git a/src/py/libcamera/py_helpers.h b/src/py/libcamera/py_helpers.h
index 983969dff..989fae77b 100644
--- a/src/py/libcamera/py_helpers.h
+++ b/src/py/libcamera/py_helpers.h
@@ -5,9 +5,9 @@ 

 #pragma once

-#include <libcamera/libcamera.h>
-
 #include <pybind11/pybind11.h>

+#include <libcamera/libcamera.h>
+
 pybind11::object controlValueToPy(const libcamera::ControlValue &cv);
 libcamera::ControlValue pyToControlValue(const pybind11::object &ob, libcamera::ControlType type);
diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
index a983ea75c..d0ef6915b 100644
--- a/src/py/libcamera/py_main.cpp
+++ b/src/py/libcamera/py_main.cpp
@@ -5,6 +5,13 @@ 
  * Python bindings
  */

+#include <pybind11/functional.h>
+#include <pybind11/pybind11.h>
+#include <pybind11/stl.h>
+#include <pybind11/stl_bind.h>
+
+#include "py_camera_manager.h"
+#include "py_helpers.h"
 #include "py_main.h"

 #include <limits>
@@ -17,14 +24,6 @@ 

 #include <libcamera/libcamera.h>

-#include <pybind11/functional.h>
-#include <pybind11/pybind11.h>
-#include <pybind11/stl.h>
-#include <pybind11/stl_bind.h>
-
-#include "py_camera_manager.h"
-#include "py_helpers.h"
-
 namespace py = pybind11;

 using namespace libcamera;
diff --git a/src/py/libcamera/py_main.h b/src/py/libcamera/py_main.h
index 4d594326e..dd31c6d9a 100644
--- a/src/py/libcamera/py_main.h
+++ b/src/py/libcamera/py_main.h
@@ -5,10 +5,10 @@ 

 #pragma once

-#include <libcamera/base/log.h>
-
 #include <pybind11/pybind11.h>

+#include <libcamera/base/log.h>
+
 namespace libcamera {

 LOG_DECLARE_CATEGORY(Python)
diff --git a/src/py/libcamera/py_transform.cpp b/src/py/libcamera/py_transform.cpp
index 768260ffc..8719b5ff5 100644
--- a/src/py/libcamera/py_transform.cpp
+++ b/src/py/libcamera/py_transform.cpp
@@ -5,15 +5,15 @@ 
  * Python bindings - Transform class
  */

-#include <libcamera/transform.h>
-#include <libcamera/libcamera.h>
-
 #include <pybind11/operators.h>
 #include <pybind11/pybind11.h>
 #include <pybind11/stl.h>

 #include "py_main.h"

+#include <libcamera/transform.h>
+#include <libcamera/libcamera.h>
+
 namespace py = pybind11;

 using namespace libcamera;