From 0f22b25be8fa15489c95e0e7a175a280f2c992c4 Mon Sep 17 00:00:00 2001 From: "Keller Fabian Rudolf (CC-AD/EYC3)" Date: Tue, 3 May 2022 12:57:24 +0200 Subject: [PATCH 1/3] make pybind11 test fixture fully self-contained --- misc/test-stubgenc.sh | 12 +- test-data/pybind11_mypy_demo/LICENSE | 36 +++++ test-data/pybind11_mypy_demo/pyproject.toml | 8 ++ test-data/pybind11_mypy_demo/setup.py | 42 ++++++ test-data/pybind11_mypy_demo/src/main.cpp | 132 ++++++++++++++++++ .../stubgen/pybind11_mypy_demo/__init__.pyi | 0 .../stubgen/pybind11_mypy_demo/basics.pyi | 0 7 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 test-data/pybind11_mypy_demo/LICENSE create mode 100644 test-data/pybind11_mypy_demo/pyproject.toml create mode 100644 test-data/pybind11_mypy_demo/setup.py create mode 100644 test-data/pybind11_mypy_demo/src/main.cpp rename test-data/{ => pybind11_mypy_demo}/stubgen/pybind11_mypy_demo/__init__.pyi (100%) rename test-data/{ => pybind11_mypy_demo}/stubgen/pybind11_mypy_demo/basics.pyi (100%) diff --git a/misc/test-stubgenc.sh b/misc/test-stubgenc.sh index 175c912e6712..acc4c99e6cb2 100755 --- a/misc/test-stubgenc.sh +++ b/misc/test-stubgenc.sh @@ -1,14 +1,16 @@ #!/bin/bash -# This script is expected to be run from root of the mypy repo + +cd "$(dirname $0)/.." # Install dependencies, demo project and mypy python -m pip install -r test-requirements.txt -python -m pip install pybind11-mypy-demo==0.0.1 +python -m pip install test-data/pybind11_mypy_demo python -m pip install . # Remove expected stubs and generate new inplace -rm -rf test-data/stubgen/pybind11_mypy_demo -stubgen -p pybind11_mypy_demo -o test-data/stubgen/ +STUBGEN_OUTPUT_FOLDER=test-data/pybind11_mypy_demo/stubgen +rm -rf $STUBGEN_OUTPUT_FOLDER/* +stubgen -p pybind11_mypy_demo -o $STUBGEN_OUTPUT_FOLDER # Compare generated stubs to expected ones -git diff --exit-code test-data/stubgen/pybind11_mypy_demo +git diff --exit-code $STUBGEN_OUTPUT_FOLDER diff --git a/test-data/pybind11_mypy_demo/LICENSE b/test-data/pybind11_mypy_demo/LICENSE new file mode 100644 index 000000000000..e4d84cb6c5da --- /dev/null +++ b/test-data/pybind11_mypy_demo/LICENSE @@ -0,0 +1,36 @@ +Copyright (c) 2016 The Pybind Development Team, All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +You are under no obligation whatsoever to provide any bug fixes, patches, or +upgrades to the features, functionality or performance of the source code +("Enhancements") to anyone; however, if you choose to make your Enhancements +available either publicly, or directly to the author of this software, without +imposing a separate written license agreement for such Enhancements, then you +hereby grant the following license: a non-exclusive, royalty-free perpetual +license to install, use, modify, prepare derivative works, incorporate into +other computer software, distribute, and sublicense such enhancements or +derivative works thereof, in binary and source code form. \ No newline at end of file diff --git a/test-data/pybind11_mypy_demo/pyproject.toml b/test-data/pybind11_mypy_demo/pyproject.toml new file mode 100644 index 000000000000..fe3d51d70add --- /dev/null +++ b/test-data/pybind11_mypy_demo/pyproject.toml @@ -0,0 +1,8 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel", + "pybind11>=2.6.0", +] + +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/test-data/pybind11_mypy_demo/setup.py b/test-data/pybind11_mypy_demo/setup.py new file mode 100644 index 000000000000..6d7180d59404 --- /dev/null +++ b/test-data/pybind11_mypy_demo/setup.py @@ -0,0 +1,42 @@ +import sys + +from pybind11 import get_cmake_dir +# Available at setup time due to pyproject.toml +from pybind11.setup_helpers import Pybind11Extension, build_ext +from setuptools import setup + +__version__ = "0.0.1" + +# The main interface is through Pybind11Extension. +# * You can add cxx_std=11/14/17, and then build_ext can be removed. +# * You can set include_pybind11=false to add the include directory yourself, +# say from a submodule. +# +# Note: +# Sort input source files if you glob sources to ensure bit-for-bit +# reproducible builds (https://github.com/pybind/python_example/pull/53) + +ext_modules = [ + Pybind11Extension( + "pybind11_mypy_demo", + ["src/main.cpp"], + # Example: passing in the version to the compiled code + define_macros=[('VERSION_INFO', __version__)], + ), +] + +setup( + name="pybind11-mypy-demo", + version=__version__, + author="Sergei Izmailov", + author_email="sergei.a.izmailov@gmail.com", # Subject to change + url="https://github.com/sizmailov/pybind11-mypy-demo", # Subject to change + description="A demo project using pybind11 to test mypy stubgen", + long_description="", + ext_modules=ext_modules, + extras_require={"test": "pytest"}, + # Currently, build_ext only provides an optional "highest supported C++ + # level" feature, but in the future it may provide more features. + cmdclass={"build_ext": build_ext}, + zip_safe=False, +) diff --git a/test-data/pybind11_mypy_demo/src/main.cpp b/test-data/pybind11_mypy_demo/src/main.cpp new file mode 100644 index 000000000000..7d1e36fd1ec9 --- /dev/null +++ b/test-data/pybind11_mypy_demo/src/main.cpp @@ -0,0 +1,132 @@ +#include +#include + +namespace py = pybind11; + +namespace basics { + +int answer() { + return 42; +} + +int sum(int a, int b) { + return a + b; +} + +double midpoint(double left, double right){ + return left + (right - left)/2; +} + +double weighted_midpoint(double left, double right, double alpha=0.5) { + return left + (right - left) * alpha; +} + +struct Point { + + enum class LengthUnit { + mm=0, + pixel, + inch + }; + + enum class AngleUnit { + radian=0, + degree + }; + + Point() : Point(0, 0) {} + Point(double x, double y) : x(x), y(y) {} + + static const Point origin; + static const Point x_axis; + static const Point y_axis; + + static LengthUnit length_unit; + static AngleUnit angle_unit; + + double length() const { + return std::sqrt(x * x + y * y); + } + + double distance_to(double other_x, double other_y) const { + double dx = x - other_x; + double dy = y - other_y; + return std::sqrt(dx*dx + dy*dy); + } + + double distance_to(const Point& other) const { + return distance_to(other.x, other.y); + } + + double x, y; +}; + +const Point Point::origin = Point(0, 0); +const Point Point::x_axis = Point(1, 0); +const Point Point::y_axis = Point(0, 1); + +Point::LengthUnit Point::length_unit = Point::LengthUnit::mm; +Point::AngleUnit Point::angle_unit = Point::AngleUnit::radian; + +} + +void bind_basics(py::module& basics) { + + using namespace basics; + + // Functions + basics.def("answer", &answer); + basics.def("sum", &sum); + basics.def("midpoint", &midpoint, py::arg("left"), py::arg("right")); + basics.def("weighted_midpoint", weighted_midpoint, py::arg("left"), py::arg("right"), py::arg("alpha")=0.5); + + + // Classes + py::class_ pyPoint(basics, "Point"); + py::enum_ pyLengthUnit(pyPoint, "LengthUnit"); + py::enum_ pyAngleUnit(pyPoint, "AngleUnit"); + + pyPoint + .def(py::init<>()) + .def(py::init(), py::arg("x"), py::arg("y")) + .def("distance_to", py::overload_cast(&Point::distance_to, py::const_), py::arg("x"), py::arg("y")) + .def("distance_to", py::overload_cast(&Point::distance_to, py::const_), py::arg("other")) + .def_readwrite("x", &Point::x) + .def_property("y", + [](Point& self){ return self.y; }, + [](Point& self, double value){ self.y = value; } + ) + .def_property_readonly("length", &Point::length) + .def_property_readonly_static("x_axis", [](py::object cls){return Point::x_axis;}) + .def_property_readonly_static("y_axis", [](py::object cls){return Point::y_axis;}) + .def_readwrite_static("length_unit", &Point::length_unit) + .def_property_static("angle_unit", + [](py::object& /*cls*/){ return Point::angle_unit; }, + [](py::object& /*cls*/, Point::AngleUnit value){ Point::angle_unit = value; } + ) + ; + + pyPoint.attr("origin") = Point::origin; + + pyLengthUnit + .value("mm", Point::LengthUnit::mm) + .value("pixel", Point::LengthUnit::pixel) + .value("inch", Point::LengthUnit::inch) + ; + + pyAngleUnit + .value("radian", Point::AngleUnit::radian) + .value("degree", Point::AngleUnit::degree) + ; + + // Module-level attributes + basics.attr("PI") = std::acos(-1); + basics.attr("__version__") = "0.0.1"; +} + +PYBIND11_MODULE(pybind11_mypy_demo, m) { + + auto basics = m.def_submodule("basics"); + bind_basics(basics); + +} \ No newline at end of file diff --git a/test-data/stubgen/pybind11_mypy_demo/__init__.pyi b/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/__init__.pyi similarity index 100% rename from test-data/stubgen/pybind11_mypy_demo/__init__.pyi rename to test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/__init__.pyi diff --git a/test-data/stubgen/pybind11_mypy_demo/basics.pyi b/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi similarity index 100% rename from test-data/stubgen/pybind11_mypy_demo/basics.pyi rename to test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi From e681915a327b5e4ad1b8f3de18dc8a9361d3a7cd Mon Sep 17 00:00:00 2001 From: "Keller Fabian Rudolf (CC-AD/EYC3)" Date: Tue, 3 May 2022 18:40:07 +0200 Subject: [PATCH 2/3] update reference stubgen output --- misc/test-stubgenc.sh | 4 +++- test-data/pybind11_mypy_demo/pyproject.toml | 4 +++- .../pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/misc/test-stubgenc.sh b/misc/test-stubgenc.sh index acc4c99e6cb2..bb27c2bdd574 100755 --- a/misc/test-stubgenc.sh +++ b/misc/test-stubgenc.sh @@ -1,10 +1,12 @@ #!/bin/bash +set -e + cd "$(dirname $0)/.." # Install dependencies, demo project and mypy python -m pip install -r test-requirements.txt -python -m pip install test-data/pybind11_mypy_demo +python -m pip install ./test-data/pybind11_mypy_demo python -m pip install . # Remove expected stubs and generate new inplace diff --git a/test-data/pybind11_mypy_demo/pyproject.toml b/test-data/pybind11_mypy_demo/pyproject.toml index fe3d51d70add..b089071fad3f 100644 --- a/test-data/pybind11_mypy_demo/pyproject.toml +++ b/test-data/pybind11_mypy_demo/pyproject.toml @@ -2,7 +2,9 @@ requires = [ "setuptools>=42", "wheel", - "pybind11>=2.6.0", + # Officially supported pybind11 version. This is pinned to guarantee 100% reproducible CI. + # As a results, needs to be updated deliberately at will. + "pybind11==2.9.2", ] build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi b/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi index 99093fd6087a..226080ac9d57 100644 --- a/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi +++ b/test-data/pybind11_mypy_demo/stubgen/pybind11_mypy_demo/basics.pyi @@ -18,6 +18,8 @@ class Point: def __setstate__(self, state: int) -> None: ... @property def name(self) -> str: ... + @property + def value(self) -> int: ... class LengthUnit: __entries: ClassVar[dict] = ... @@ -34,6 +36,8 @@ class Point: def __setstate__(self, state: int) -> None: ... @property def name(self) -> str: ... + @property + def value(self) -> int: ... angle_unit: ClassVar[Point.AngleUnit] = ... length_unit: ClassVar[Point.LengthUnit] = ... x_axis: ClassVar[Point] = ... # read-only From 5012113f6eae1eef379c5ff71a1bfb55117e8114 Mon Sep 17 00:00:00 2001 From: "Keller Fabian Rudolf (CC-AD/EYC3)" Date: Wed, 11 May 2022 08:50:10 +0200 Subject: [PATCH 3/3] minimize pybind11_mypy_demo to bare minimum --- misc/test-stubgenc.sh | 3 +- test-data/pybind11_mypy_demo/LICENSE | 36 ------------- test-data/pybind11_mypy_demo/pyproject.toml | 2 +- test-data/pybind11_mypy_demo/setup.py | 34 ++---------- test-data/pybind11_mypy_demo/src/main.cpp | 58 +++++++++++++++++---- 5 files changed, 56 insertions(+), 77 deletions(-) delete mode 100644 test-data/pybind11_mypy_demo/LICENSE diff --git a/misc/test-stubgenc.sh b/misc/test-stubgenc.sh index bb27c2bdd574..7da135f0bf16 100755 --- a/misc/test-stubgenc.sh +++ b/misc/test-stubgenc.sh @@ -1,6 +1,7 @@ #!/bin/bash set -e +set -x cd "$(dirname $0)/.." @@ -10,7 +11,7 @@ python -m pip install ./test-data/pybind11_mypy_demo python -m pip install . # Remove expected stubs and generate new inplace -STUBGEN_OUTPUT_FOLDER=test-data/pybind11_mypy_demo/stubgen +STUBGEN_OUTPUT_FOLDER=./test-data/pybind11_mypy_demo/stubgen rm -rf $STUBGEN_OUTPUT_FOLDER/* stubgen -p pybind11_mypy_demo -o $STUBGEN_OUTPUT_FOLDER diff --git a/test-data/pybind11_mypy_demo/LICENSE b/test-data/pybind11_mypy_demo/LICENSE deleted file mode 100644 index e4d84cb6c5da..000000000000 --- a/test-data/pybind11_mypy_demo/LICENSE +++ /dev/null @@ -1,36 +0,0 @@ -Copyright (c) 2016 The Pybind Development Team, All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -You are under no obligation whatsoever to provide any bug fixes, patches, or -upgrades to the features, functionality or performance of the source code -("Enhancements") to anyone; however, if you choose to make your Enhancements -available either publicly, or directly to the author of this software, without -imposing a separate written license agreement for such Enhancements, then you -hereby grant the following license: a non-exclusive, royalty-free perpetual -license to install, use, modify, prepare derivative works, incorporate into -other computer software, distribute, and sublicense such enhancements or -derivative works thereof, in binary and source code form. \ No newline at end of file diff --git a/test-data/pybind11_mypy_demo/pyproject.toml b/test-data/pybind11_mypy_demo/pyproject.toml index b089071fad3f..878abe731b1b 100644 --- a/test-data/pybind11_mypy_demo/pyproject.toml +++ b/test-data/pybind11_mypy_demo/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "setuptools>=42", "wheel", # Officially supported pybind11 version. This is pinned to guarantee 100% reproducible CI. - # As a results, needs to be updated deliberately at will. + # As a result, the version needs to be bumped manually at will. "pybind11==2.9.2", ] diff --git a/test-data/pybind11_mypy_demo/setup.py b/test-data/pybind11_mypy_demo/setup.py index 6d7180d59404..0da1cfbcef19 100644 --- a/test-data/pybind11_mypy_demo/setup.py +++ b/test-data/pybind11_mypy_demo/setup.py @@ -1,42 +1,18 @@ -import sys - -from pybind11 import get_cmake_dir -# Available at setup time due to pyproject.toml -from pybind11.setup_helpers import Pybind11Extension, build_ext +# pybind11 is available at setup time due to pyproject.toml +from pybind11.setup_helpers import Pybind11Extension from setuptools import setup -__version__ = "0.0.1" - -# The main interface is through Pybind11Extension. -# * You can add cxx_std=11/14/17, and then build_ext can be removed. -# * You can set include_pybind11=false to add the include directory yourself, -# say from a submodule. -# -# Note: -# Sort input source files if you glob sources to ensure bit-for-bit -# reproducible builds (https://github.com/pybind/python_example/pull/53) - +# Documentation: https://pybind11.readthedocs.io/en/stable/compiling.html ext_modules = [ Pybind11Extension( "pybind11_mypy_demo", ["src/main.cpp"], - # Example: passing in the version to the compiled code - define_macros=[('VERSION_INFO', __version__)], + cxx_std=17, ), ] setup( name="pybind11-mypy-demo", - version=__version__, - author="Sergei Izmailov", - author_email="sergei.a.izmailov@gmail.com", # Subject to change - url="https://github.com/sizmailov/pybind11-mypy-demo", # Subject to change - description="A demo project using pybind11 to test mypy stubgen", - long_description="", + version="0.0.1", ext_modules=ext_modules, - extras_require={"test": "pytest"}, - # Currently, build_ext only provides an optional "highest supported C++ - # level" feature, but in the future it may provide more features. - cmdclass={"build_ext": build_ext}, - zip_safe=False, ) diff --git a/test-data/pybind11_mypy_demo/src/main.cpp b/test-data/pybind11_mypy_demo/src/main.cpp index 7d1e36fd1ec9..5cedef391b2d 100644 --- a/test-data/pybind11_mypy_demo/src/main.cpp +++ b/test-data/pybind11_mypy_demo/src/main.cpp @@ -1,3 +1,47 @@ +/** + * This file contains the pybind11 reference implementation for the stugen tests, + * and was originally inspired by: + * + * https://github.com/sizmailov/pybind11-mypy-demo + * + * Copyright (c) 2016 The Pybind Development Team, All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You are under no obligation whatsoever to provide any bug fixes, patches, or + * upgrades to the features, functionality or performance of the source code + * ("Enhancements") to anyone; however, if you choose to make your Enhancements + * available either publicly, or directly to the author of this software, without + * imposing a separate written license agreement for such Enhancements, then you + * hereby grant the following license: a non-exclusive, royalty-free perpetual + * license to install, use, modify, prepare derivative works, incorporate into + * other computer software, distribute, and sublicense such enhancements or + * derivative works thereof, in binary and source code form. + */ + #include #include @@ -68,7 +112,7 @@ const Point Point::y_axis = Point(0, 1); Point::LengthUnit Point::length_unit = Point::LengthUnit::mm; Point::AngleUnit Point::angle_unit = Point::AngleUnit::radian; -} +} // namespace: basics void bind_basics(py::module& basics) { @@ -80,7 +124,6 @@ void bind_basics(py::module& basics) { basics.def("midpoint", &midpoint, py::arg("left"), py::arg("right")); basics.def("weighted_midpoint", weighted_midpoint, py::arg("left"), py::arg("right"), py::arg("alpha")=0.5); - // Classes py::class_ pyPoint(basics, "Point"); py::enum_ pyLengthUnit(pyPoint, "LengthUnit"); @@ -103,21 +146,18 @@ void bind_basics(py::module& basics) { .def_property_static("angle_unit", [](py::object& /*cls*/){ return Point::angle_unit; }, [](py::object& /*cls*/, Point::AngleUnit value){ Point::angle_unit = value; } - ) - ; + ); pyPoint.attr("origin") = Point::origin; pyLengthUnit .value("mm", Point::LengthUnit::mm) .value("pixel", Point::LengthUnit::pixel) - .value("inch", Point::LengthUnit::inch) - ; + .value("inch", Point::LengthUnit::inch); pyAngleUnit .value("radian", Point::AngleUnit::radian) - .value("degree", Point::AngleUnit::degree) - ; + .value("degree", Point::AngleUnit::degree); // Module-level attributes basics.attr("PI") = std::acos(-1); @@ -125,8 +165,6 @@ void bind_basics(py::module& basics) { } PYBIND11_MODULE(pybind11_mypy_demo, m) { - auto basics = m.def_submodule("basics"); bind_basics(basics); - } \ No newline at end of file