From dbb006ee6114ea083335584aff8d062aeed16814 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sun, 9 Aug 2026 16:07:10 -0400 Subject: [PATCH 1/2] style: add pre-commit configuration Model the configuration on pybind11's, without the hooks that have no targets here (clang-format, shellcheck, pylint, rst checks). Exclude tests/*_docs/ fixtures, which are compared byte-for-byte against generated output. Apply the resulting fixes, including some real spelling corrections, and replace the hatch-fmt CI job with a prek lint job. Assisted-by: ClaudeCode:claude-fable-5 --- .github/workflows/ci.yml | 10 +- .gitignore | 1 - .pre-commit-config.yaml | 117 ++++++++++++++++++ README.md | 14 +-- cmake/CMakeLists.txt | 40 +++--- cmake/pybind11_mkdoc_functions.cmake | 110 ++++++++-------- pybind11_mkdoc/__init__.py | 6 +- pybind11_mkdoc/mkdoc_lib.py | 44 +++++-- .../pybind11_mkdoc/pybind11_mkdocConfig.cmake | 17 +-- .../pybind11_mkdocConfigVersion.cmake | 42 ++++--- .../pybind11_mkdoc_functions.cmake | 110 ++++++++-------- tests/cli_test.py | 13 +- tests/cmake_test.py | 19 ++- tests/doxygen_parsing_test.py | 5 +- tests/duplicate_name_test.py | 4 +- tests/long_parameter_test.py | 4 +- tests/read_args_test.py | 24 +++- tests/sample_header_test.py | 13 +- 18 files changed, 391 insertions(+), 202 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 658de93..24746ee 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,19 +3,19 @@ name: CI on: pull_request: push: - branches: + branches: - master tags: - 'v*' jobs: - format: + lint: runs-on: ubuntu-latest - name: Format + name: Lint steps: - uses: actions/checkout@v7 - uses: astral-sh/setup-uv@v9.0.0 - - run: uvx hatch fmt + - run: uvx prek run -a --show-diff-on-failure checks: strategy: @@ -41,7 +41,7 @@ jobs: - name: Test package run: uv run --with "clang<19" --group test pytest - + checks_windows: strategy: fail-fast: false diff --git a/.gitignore b/.gitignore index 623b582..d0e41ea 100644 --- a/.gitignore +++ b/.gitignore @@ -139,4 +139,3 @@ dmypy.json # Cython debug symbols cython_debug/ - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f9b0667 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,117 @@ +# To use locally: +# +# prek -a +# +# Or: +# +# prek install # (runs every time you commit in git) +# +# To update this file: +# +# prek autoupdate +# +# See https://github.com/pre-commit/pre-commit + +ci: + autoupdate_commit_msg: "chore(deps): update pre-commit hooks" + autofix_commit_msg: "style: pre-commit fixes" + autoupdate_schedule: monthly + +# Test fixtures are compared byte-for-byte against generated output +exclude: ^tests/.*_docs/ + +repos: + +# Ruff, the Python auto-correcting linter/formatter written in Rust +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.16.1 + hooks: + - id: ruff-check + args: ["--fix", "--show-fixes"] + - id: ruff-format + +# Check static types with mypy +- repo: https://github.com/pre-commit/mirrors-mypy + rev: "v2.3.0" + hooks: + - id: mypy + exclude: ^tests/ + additional_dependencies: + - pytest + +# CMake formatting +- repo: https://github.com/cheshirekow/cmake-format-precommit + rev: "v0.6.13" + hooks: + - id: cmake-format + additional_dependencies: [pyyaml] + types: [file] + files: (\.cmake|CMakeLists.txt)(.in)?$ + +# Standard hooks +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v6.0.0" + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: check-docstring-first + - id: check-merge-conflict + - id: check-symlinks + - id: check-toml + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + - id: trailing-whitespace + +# Also code format the docs +- repo: https://github.com/adamchainz/blacken-docs + rev: "1.20.0" + hooks: + - id: blacken-docs + additional_dependencies: + - black==23.* + +# Changes tabs to spaces +- repo: https://github.com/Lucas-C/pre-commit-hooks + rev: "v1.5.6" + hooks: + - id: remove-tabs + +# Avoid directional quotes +- repo: https://github.com/sirosen/texthooks + rev: "0.7.1" + hooks: + - id: fix-ligatures + - id: fix-smartquotes + +# Check for spelling +- repo: https://github.com/codespell-project/codespell + rev: "v2.4.3" + hooks: + - id: codespell + +# Also check spelling +# Use mirror because pre-commit autoupdate confuses tags in the upstream repo. +# See https://github.com/crate-ci/typos/issues/390 +- repo: https://github.com/adhtruong/mirrors-typos + rev: "v1.48.0" + hooks: + - id: typos + args: [] + +# Disallow some common capitalization mistakes +- repo: local + hooks: + - id: disallow-caps + name: Disallow improper capitalization + language: pygrep + entry: PyBind|\bNumpy\b|Cmake|CCache|PyTest + exclude: ^\.pre-commit-config.yaml$ + +# Check schemas on some of our YAML files +- repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.37.4 + hooks: + - id: check-github-workflows + - id: check-dependabot diff --git a/README.md b/README.md index e18d794..7eb2c01 100644 --- a/README.md +++ b/README.md @@ -76,21 +76,21 @@ py::class_(m, "MyClass", DOC(MyClass)) ### CMake The `pybind11_mkdoc` CMake function is included to easily generate header for a pybind11 module when -compiling said module in CMake. The function generates the headers based on the arguments provided. -In addition, it add target dependencies so the pybind11-mkdoc header file is generated before -the pybind11 module. Also, it will automatically add the current binary directory to the pybind11 +compiling said module in CMake. The function generates the headers based on the arguments provided. +In addition, it add target dependencies so the pybind11-mkdoc header file is generated before +the pybind11 module. Also, it will automatically add the current binary directory to the pybind11 module's includes, so it can easily be included when compiling the module. The required parameters are: * OUTPUT - The name of the output file. * PYBIND11_MODULE - The pybind11 module target that these docs will be used for. -* HEADERS - The header files to create docs for. These can be absoulte paths or relative to the +* HEADERS - The header files to create docs for. These can be absolute paths or relative to the current source directory. The optional parameters are: * EXTRA_ARGS - This string argument will be added verbatim to the pybind11-mkdoc command. -Below is an exmaple of how it is used: +Below is an example of how it is used: ```cmake # Find pybind11-mkdoc # This assumes you have already run a find_package for Python. @@ -104,9 +104,9 @@ find_package(pybind11_mkdoc REQUIRED CONFIG) # Add the pybind11 module pybind11_add_module(my_pybind11_module my_src_files.cc) pybind11_mkdoc( - OUTPUT my_pybind11_module_docs.h + OUTPUT my_pybind11_module_docs.h PYBIND11_MODULE my_pybind11_module - HEADERS + HEADERS header_1.h /absolute/path/to/header_2.h ) diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 5407ce3..a76863a 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,12 +1,12 @@ cmake_minimum_required(VERSION 3.25...4.3) -# Read the version from the Python package; project() accepts numeric components only, -# so any dev/pre-release suffix is dropped. -file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/../pybind11_mkdoc/__init__.py" version_line - REGEX "^__version__ *= *[\"']" -) +# Read the version from the Python package; project() accepts numeric components +# only, so any dev/pre-release suffix is dropped. +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/../pybind11_mkdoc/__init__.py" + version_line REGEX "^__version__ *= *[\"']") if(NOT version_line MATCHES "([0-9]+(\\.[0-9]+)*)") - message(FATAL_ERROR "Could not read __version__ from pybind11_mkdoc/__init__.py") + message( + FATAL_ERROR "Could not read __version__ from pybind11_mkdoc/__init__.py") endif() project(pybind11_mkdoc VERSION "${CMAKE_MATCH_1}") @@ -15,27 +15,21 @@ include(CMakePackageConfigHelpers) # Generate version file write_basic_package_version_file( - "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfigVersion.cmake" - VERSION ${PROJECT_VERSION} - COMPATIBILITY SameMajorVersion -) + "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion) # Create config file configure_package_config_file( - "${CMAKE_CURRENT_SOURCE_DIR}/pybind11_mkdocConfig.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfig.cmake" - INSTALL_DESTINATION pybind11_mkdoc -) + "${CMAKE_CURRENT_SOURCE_DIR}/pybind11_mkdocConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfig.cmake" + INSTALL_DESTINATION pybind11_mkdoc) # Install config + version -install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfig.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfigVersion.cmake" - DESTINATION pybind11_mkdoc -) +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfigVersion.cmake" + DESTINATION pybind11_mkdoc) # Install functions -install(FILES - "${CMAKE_CURRENT_SOURCE_DIR}/pybind11_mkdoc_functions.cmake" - DESTINATION pybind11_mkdoc -) +install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/pybind11_mkdoc_functions.cmake" + DESTINATION pybind11_mkdoc) diff --git a/cmake/pybind11_mkdoc_functions.cmake b/cmake/pybind11_mkdoc_functions.cmake index 7a5c00f..198a25f 100644 --- a/cmake/pybind11_mkdoc_functions.cmake +++ b/cmake/pybind11_mkdoc_functions.cmake @@ -1,68 +1,62 @@ -# This function is used to run pybind11-mkdoc for the headers of a pybind11 module. -# In addition, this will also add target dependencies so the pybind11-mkdoc header -# file is generated before the pybind11 module. Also, this will automatically add -# the current binary directory to the pybind11 module's includes, so it can -# easily be included when compiling the module. +# This function is used to run pybind11-mkdoc for the headers of a pybind11 +# module. In addition, this will also add target dependencies so the +# pybind11-mkdoc header file is generated before the pybind11 module. Also, this +# will automatically add the current binary directory to the pybind11 module's +# includes, so it can easily be included when compiling the module. # -# The required parameters are: -# * OUTPUT - The name of the output file. -# * PYBIND11_MODULE - The pybind11 module target that these docs will be used for. -# * HEADERS - The header files to create docs for. These can be absoulte paths or relative to the -# current source directory. +# The required parameters are: * OUTPUT - The name of the output file. * +# PYBIND11_MODULE - The pybind11 module target that these docs will be used for. +# * HEADERS - The header files to create docs for. These can be absolute paths +# or relative to the current source directory. # -# The optional parameters are: -# * EXTRA_ARGS - A list of arguments that will be added verbatim to the pybind11-mkdoc command. +# The optional parameters are: * EXTRA_ARGS - A list of arguments that will be +# added verbatim to the pybind11-mkdoc command. # -# Example usage: -# pybind11_add_module(my_pybind11_module src/my_pybind11_module.cc) -# pybind11_mkdoc( -# OUTPUT my_pybind11_module_doc.h -# PYBIND11_MODULE my_pybind11_module -# HEADERS -# include/my_header_1.h -# /absolute/path/to/header.h -# ) -function (pybind11_mkdoc) - set(options) - set(oneValueArgs OUTPUT PYBIND11_MODULE) - set(multiValueArgs HEADERS EXTRA_ARGS) - cmake_parse_arguments(PARSE_ARGV 0 arg - "${options}" "${oneValueArgs}" "${multiValueArgs}" - ) +# Example usage: pybind11_add_module(my_pybind11_module +# src/my_pybind11_module.cc) pybind11_mkdoc( OUTPUT my_pybind11_module_doc.h +# PYBIND11_MODULE my_pybind11_module HEADERS include/my_header_1.h +# /absolute/path/to/header.h ) +function(pybind11_mkdoc) + set(options) + set(oneValueArgs OUTPUT PYBIND11_MODULE) + set(multiValueArgs HEADERS EXTRA_ARGS) + cmake_parse_arguments(PARSE_ARGV 0 arg "${options}" "${oneValueArgs}" + "${multiValueArgs}") - # Include directories for the pybind11 module - set(prop "$") + # Include directories for the pybind11 module + set(prop "$") - # Remove the header file from the list - set(HEADERS "") - # Run through all the other arguments. - foreach(header ${arg_HEADERS}) - if(IS_ABSOLUTE ${header}) - # If it is an absolute path, then add it as is. - list(APPEND HEADERS ${header}) - else() - # Otherwise, assume it is relative to the current source directory. - list(APPEND HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${header}") - endif() - endforeach() + # Remove the header file from the list + set(HEADERS "") + # Run through all the other arguments. + foreach(header ${arg_HEADERS}) + if(IS_ABSOLUTE ${header}) + # If it is an absolute path, then add it as is. + list(APPEND HEADERS ${header}) + else() + # Otherwise, assume it is relative to the current source directory. + list(APPEND HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${header}") + endif() + endforeach() - # Add a custom target and command for the full header file location that runs pybind11-mkdoc - # We automatically include the source directory and build/include - add_custom_target( - pybind11_mkdoc_${arg_OUTPUT} - DEPENDS ${arg_OUTPUT} - ) + # Add a custom target and command for the full header file location that runs + # pybind11-mkdoc We automatically include the source directory and + # build/include + add_custom_target(pybind11_mkdoc_${arg_OUTPUT} DEPENDS ${arg_OUTPUT}) - add_custom_command( - OUTPUT ${arg_OUTPUT} - COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o ${arg_OUTPUT} "$<$:-I$>" ${HEADERS} - DEPENDS ${HEADERS} - COMMAND_EXPAND_LISTS - ) + add_custom_command( + OUTPUT ${arg_OUTPUT} + COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o + ${arg_OUTPUT} "$<$:-I$>" ${HEADERS} + DEPENDS ${HEADERS} + COMMAND_EXPAND_LISTS) - # Add a dependency so that the pybind11-mkdoc command runs before we try to compile the pybind11 module - add_dependencies(${arg_PYBIND11_MODULE} pybind11_mkdoc_${arg_OUTPUT}) + # Add a dependency so that the pybind11-mkdoc command runs before we try to + # compile the pybind11 module + add_dependencies(${arg_PYBIND11_MODULE} pybind11_mkdoc_${arg_OUTPUT}) - # Add the current binary directory to the pybind11 module so it can be included easily - target_include_directories(${arg_PYBIND11_MODULE} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + # Add the current binary directory to the pybind11 module so it can be + # included easily + target_include_directories(${arg_PYBIND11_MODULE} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) endfunction() diff --git a/pybind11_mkdoc/__init__.py b/pybind11_mkdoc/__init__.py index 21ad05d..1cfb59d 100644 --- a/pybind11_mkdoc/__init__.py +++ b/pybind11_mkdoc/__init__.py @@ -34,7 +34,7 @@ def _append_include_dir(args: list, include_dir: str, *, verbose: bool = True): if os.path.isdir(include_dir): args.append(f"-I{include_dir}") elif verbose: - print(f"Include directory '{include_dir}' does not exist!", file=sys.stderr) # noqa: T201 + print(f"Include directory '{include_dir}' does not exist!", file=sys.stderr) def _append_definition(args: list, definition: str): @@ -87,7 +87,9 @@ def main(): allow_abbrev=False, ) - parser.add_argument("-v", "--version", action="version", version=f"%(prog)s {__version__}") + parser.add_argument( + "-v", "--version", action="version", version=f"%(prog)s {__version__}" + ) parser.add_argument( "-o", diff --git a/pybind11_mkdoc/mkdoc_lib.py b/pybind11_mkdoc/mkdoc_lib.py index 90bd583..d90a911 100755 --- a/pybind11_mkdoc/mkdoc_lib.py +++ b/pybind11_mkdoc/mkdoc_lib.py @@ -114,7 +114,9 @@ def sanitize_name(name): section_command_re = re.compile(r"\s*[\\@](\w+)(?:\[([^\]]+)\])?(?:\s+(.*))?$") code_segment_re = re.compile(r"(```)") -prefix_re = re.compile(r"(\s*)((?:[*\-•]\s)|(?:\(?\d+[\.)]\s)|(?:[\w:]+(?:\s+\[[^\]]+\])?:(?:\s+|$)))") +prefix_re = re.compile( + r"(\s*)((?:[*\-•]\s)|(?:\(?\d+[\.)]\s)|(?:[\w:]+(?:\s+\[[^\]]+\])?:(?:\s+|$)))" +) named_arg_re = re.compile(r"([\w:]+)\s*(.*)") IGNORED_DOXYGEN_COMMANDS = { @@ -182,8 +184,14 @@ def sanitize_name(name): # Applied before the Doxygen sections are consumed. BLOCK_DOXYGEN_REPLACEMENTS = [ - (re.compile(r"[\\@]code\s?(.*?)\s?[\\@]endcode", flags=re.DOTALL), "```\n\\1\n```\n"), - (re.compile(r"[\\@]verbatim\s?(.*?)\s?[\\@]endverbatim", flags=re.DOTALL), "```\n\\1\n```\n"), + ( + re.compile(r"[\\@]code\s?(.*?)\s?[\\@]endcode", flags=re.DOTALL), + "```\n\\1\n```\n", + ), + ( + re.compile(r"[\\@]verbatim\s?(.*?)\s?[\\@]endverbatim", flags=re.DOTALL), + "```\n\\1\n```\n", + ), ] MARKUP_REPLACEMENTS = [ @@ -381,7 +389,9 @@ def _consume_doxygen_sections(s): result += _format_named_entries("Template Args", t_params) result += _format_list_entries("Returns", returns) result += _format_named_entries("Raises", raises) - result += _format_section_entries((heading, " ".join(text).strip()) for heading, text in sections) + result += _format_section_entries( + (heading, " ".join(text).strip()) for heading, text in sections + ) return "\n".join(result) @@ -500,7 +510,9 @@ def flush_paragraph(paragraph=paragraph, wrapped=wrapped): continue prefix, indent = get_prefix_and_indent(line) - if paragraph and ((indent != current_indent) or (prefix and prefix != current_prefix)): + if paragraph and ( + (indent != current_indent) or (prefix and prefix != current_prefix) + ): # Prefix/indent changed → start new paragraph flush_paragraph() @@ -693,10 +705,16 @@ def read_args(args): cpp_dirs = [] if "-stdlib=libc++" not in args: - cpp_dirs.append(max(glob("/usr/include/c++/*"), default=None, key=_folder_version)) + cpp_dirs.append( + max(glob("/usr/include/c++/*"), default=None, key=_folder_version) + ) cpp_dirs.append( - max(glob(f"/usr/include/{platform.machine()}-linux-gnu/c++/*"), default=None, key=_folder_version) + max( + glob(f"/usr/include/{platform.machine()}-linux-gnu/c++/*"), + default=None, + key=_folder_version, + ) ) elif llvm_dir is not None: cpp_dirs.append(str(PurePosixPath(llvm_dir) / "include" / "c++" / "v1")) @@ -706,7 +724,9 @@ def read_args(args): elif llvm_dir is not None: cpp_dirs.append( max( - glob(str(PurePosixPath(llvm_dir) / "lib" / "clang" / "*" / "include")), + glob( + str(PurePosixPath(llvm_dir) / "lib" / "clang" / "*" / "include") + ), default=None, key=_folder_version, ) @@ -717,7 +737,13 @@ def read_args(args): # Capability to specify additional include directories manually if "CPP_INCLUDE_DIRS" in os.environ: - cpp_dirs.extend([cpp_dir for cpp_dir in os.environ["CPP_INCLUDE_DIRS"].split() if os.path.exists(cpp_dir)]) + cpp_dirs.extend( + [ + cpp_dir + for cpp_dir in os.environ["CPP_INCLUDE_DIRS"].split() + if os.path.exists(cpp_dir) + ] + ) for cpp_dir in cpp_dirs: if cpp_dir is None: diff --git a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake index c72741b..d3a91c8 100644 --- a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake +++ b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake @@ -1,14 +1,17 @@ +# Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### Any +# changes to this file will be overwritten by the next CMake run #### The input +# file was pybind11_mkdocConfig.cmake.in ######## -####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### -####### Any changes to this file will be overwritten by the next CMake run #### -####### The input file was pybind11_mkdocConfig.cmake.in ######## - -get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../" ABSOLUTE) +get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../" + ABSOLUTE) macro(set_and_check _var _file) set(${_var} "${_file}") if(NOT EXISTS "${_file}") - message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") + message( + FATAL_ERROR + "File or directory ${_file} referenced by variable ${_var} does not exist !" + ) endif() endmacro() @@ -22,7 +25,7 @@ macro(check_required_components _NAME) endforeach() endmacro() -#################################################################################### +# ############################################################################## include("${CMAKE_CURRENT_LIST_DIR}/pybind11_mkdoc_functions.cmake") diff --git a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake index df97cb6..a68d214 100644 --- a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake +++ b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake @@ -1,13 +1,12 @@ -# This is a basic version file for the Config-mode of find_package(). -# It is used by write_basic_package_version_file() as input file for configure_file() -# to create a version-file which can be installed along a config.cmake file. +# This is a basic version file for the Config-mode of find_package(). It is used +# by write_basic_package_version_file() as input file for configure_file() to +# create a version-file which can be installed along a config.cmake file. # # The created file sets PACKAGE_VERSION_EXACT if the current version string and # the requested version string are exactly the same and it sets -# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, -# but only if the requested major version is the same as the current one. -# The variable CVF_VERSION must be set before calling configure_file(). - +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, but +# only if the requested major version is the same as the current one. The +# variable CVF_VERSION must be set before calling configure_file(). set(PACKAGE_VERSION "2.6.2") @@ -26,14 +25,22 @@ else() if(PACKAGE_FIND_VERSION_RANGE) # both endpoints of the range must have the expected major version - math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") - if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR - OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) - OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT))) + math(EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") + if(NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" + AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" + AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL + CVF_VERSION_MAJOR_NEXT) + )) set(PACKAGE_VERSION_COMPATIBLE FALSE) - elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR - AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) - OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) + elseif( + PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" + AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" + AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX) + )) set(PACKAGE_VERSION_COMPATIBLE TRUE) else() set(PACKAGE_VERSION_COMPATIBLE FALSE) @@ -51,13 +58,14 @@ else() endif() endif() - -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, +# ignore it: if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") return() endif() -# check that the installed version has the same 32/64bit-ness as the one which is currently searching: +# check that the installed version has the same 32/64bit-ness as the one which +# is currently searching: if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") math(EXPR installedBits "8 * 8") set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") diff --git a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake index 7a5c00f..198a25f 100644 --- a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake +++ b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake @@ -1,68 +1,62 @@ -# This function is used to run pybind11-mkdoc for the headers of a pybind11 module. -# In addition, this will also add target dependencies so the pybind11-mkdoc header -# file is generated before the pybind11 module. Also, this will automatically add -# the current binary directory to the pybind11 module's includes, so it can -# easily be included when compiling the module. +# This function is used to run pybind11-mkdoc for the headers of a pybind11 +# module. In addition, this will also add target dependencies so the +# pybind11-mkdoc header file is generated before the pybind11 module. Also, this +# will automatically add the current binary directory to the pybind11 module's +# includes, so it can easily be included when compiling the module. # -# The required parameters are: -# * OUTPUT - The name of the output file. -# * PYBIND11_MODULE - The pybind11 module target that these docs will be used for. -# * HEADERS - The header files to create docs for. These can be absoulte paths or relative to the -# current source directory. +# The required parameters are: * OUTPUT - The name of the output file. * +# PYBIND11_MODULE - The pybind11 module target that these docs will be used for. +# * HEADERS - The header files to create docs for. These can be absolute paths +# or relative to the current source directory. # -# The optional parameters are: -# * EXTRA_ARGS - A list of arguments that will be added verbatim to the pybind11-mkdoc command. +# The optional parameters are: * EXTRA_ARGS - A list of arguments that will be +# added verbatim to the pybind11-mkdoc command. # -# Example usage: -# pybind11_add_module(my_pybind11_module src/my_pybind11_module.cc) -# pybind11_mkdoc( -# OUTPUT my_pybind11_module_doc.h -# PYBIND11_MODULE my_pybind11_module -# HEADERS -# include/my_header_1.h -# /absolute/path/to/header.h -# ) -function (pybind11_mkdoc) - set(options) - set(oneValueArgs OUTPUT PYBIND11_MODULE) - set(multiValueArgs HEADERS EXTRA_ARGS) - cmake_parse_arguments(PARSE_ARGV 0 arg - "${options}" "${oneValueArgs}" "${multiValueArgs}" - ) +# Example usage: pybind11_add_module(my_pybind11_module +# src/my_pybind11_module.cc) pybind11_mkdoc( OUTPUT my_pybind11_module_doc.h +# PYBIND11_MODULE my_pybind11_module HEADERS include/my_header_1.h +# /absolute/path/to/header.h ) +function(pybind11_mkdoc) + set(options) + set(oneValueArgs OUTPUT PYBIND11_MODULE) + set(multiValueArgs HEADERS EXTRA_ARGS) + cmake_parse_arguments(PARSE_ARGV 0 arg "${options}" "${oneValueArgs}" + "${multiValueArgs}") - # Include directories for the pybind11 module - set(prop "$") + # Include directories for the pybind11 module + set(prop "$") - # Remove the header file from the list - set(HEADERS "") - # Run through all the other arguments. - foreach(header ${arg_HEADERS}) - if(IS_ABSOLUTE ${header}) - # If it is an absolute path, then add it as is. - list(APPEND HEADERS ${header}) - else() - # Otherwise, assume it is relative to the current source directory. - list(APPEND HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${header}") - endif() - endforeach() + # Remove the header file from the list + set(HEADERS "") + # Run through all the other arguments. + foreach(header ${arg_HEADERS}) + if(IS_ABSOLUTE ${header}) + # If it is an absolute path, then add it as is. + list(APPEND HEADERS ${header}) + else() + # Otherwise, assume it is relative to the current source directory. + list(APPEND HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${header}") + endif() + endforeach() - # Add a custom target and command for the full header file location that runs pybind11-mkdoc - # We automatically include the source directory and build/include - add_custom_target( - pybind11_mkdoc_${arg_OUTPUT} - DEPENDS ${arg_OUTPUT} - ) + # Add a custom target and command for the full header file location that runs + # pybind11-mkdoc We automatically include the source directory and + # build/include + add_custom_target(pybind11_mkdoc_${arg_OUTPUT} DEPENDS ${arg_OUTPUT}) - add_custom_command( - OUTPUT ${arg_OUTPUT} - COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o ${arg_OUTPUT} "$<$:-I$>" ${HEADERS} - DEPENDS ${HEADERS} - COMMAND_EXPAND_LISTS - ) + add_custom_command( + OUTPUT ${arg_OUTPUT} + COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o + ${arg_OUTPUT} "$<$:-I$>" ${HEADERS} + DEPENDS ${HEADERS} + COMMAND_EXPAND_LISTS) - # Add a dependency so that the pybind11-mkdoc command runs before we try to compile the pybind11 module - add_dependencies(${arg_PYBIND11_MODULE} pybind11_mkdoc_${arg_OUTPUT}) + # Add a dependency so that the pybind11-mkdoc command runs before we try to + # compile the pybind11 module + add_dependencies(${arg_PYBIND11_MODULE} pybind11_mkdoc_${arg_OUTPUT}) - # Add the current binary directory to the pybind11 module so it can be included easily - target_include_directories(${arg_PYBIND11_MODULE} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + # Add the current binary directory to the pybind11 module so it can be + # included easily + target_include_directories(${arg_PYBIND11_MODULE} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) endfunction() diff --git a/tests/cli_test.py b/tests/cli_test.py index c9e7dcc..6fc46ee 100644 --- a/tests/cli_test.py +++ b/tests/cli_test.py @@ -21,7 +21,9 @@ def test_simple_header_cli(tmp_path: Path, name: str) -> None: # Run pybind11-mkdoc and put the output in a temp file tf = tmp_path / "tmp.h" header = DIR / "sample_header_docs" / name - subprocess.run([sys.executable, "-m", "pybind11_mkdoc", "-o", tf, header], check=True) + subprocess.run( + [sys.executable, "-m", "pybind11_mkdoc", "-o", tf, header], check=True + ) # Ensure the header file matches res = tf.read_text(encoding="utf-8") @@ -48,7 +50,14 @@ def test_append_definition(definition: str, expected_arg: str) -> None: def test_parse_failure_sets_exit_code(tmp_path: Path) -> None: tf = tmp_path / "tmp.h" result = subprocess.run( - [sys.executable, "-m", "pybind11_mkdoc", "-o", tf, tmp_path / "does_not_exist.h"], + [ + sys.executable, + "-m", + "pybind11_mkdoc", + "-o", + tf, + tmp_path / "does_not_exist.h", + ], check=False, capture_output=True, ) diff --git a/tests/cmake_test.py b/tests/cmake_test.py index c84c2c0..27b4d7f 100644 --- a/tests/cmake_test.py +++ b/tests/cmake_test.py @@ -10,7 +10,15 @@ def test_pybind11_mkdoc_cmake(tmp_path: Path) -> None: # Run pybind11-mkdoc and put the output in a temp file build_dir = tmp_path / "build" subprocess.run( - ["cmake", "-B", build_dir, "-S", DIR / "cmake_docs", f"-DPython_EXECUTABLE={sys.executable}"], check=True + [ + "cmake", + "-B", + build_dir, + "-S", + DIR / "cmake_docs", + f"-DPython_EXECUTABLE={sys.executable}", + ], + check=True, ) subprocess.run(["cmake", "--build", build_dir], check=True) @@ -31,7 +39,14 @@ def test_pybind11_mkdoc_cmake_extra_args(tmp_path: Path) -> None: env["PYBIND11_TEST_EXTRA_ARGS"] = "-DMY_EXTRA_DEFINE=1;-DMY_OTHER_DEFINE=1" subprocess.run( - ["cmake", "-B", build_dir, "-S", DIR / "cmake_docs", f"-DPython_EXECUTABLE={sys.executable}"], + [ + "cmake", + "-B", + build_dir, + "-S", + DIR / "cmake_docs", + f"-DPython_EXECUTABLE={sys.executable}", + ], check=True, env=env, ) diff --git a/tests/doxygen_parsing_test.py b/tests/doxygen_parsing_test.py index 986d579..4e92cb7 100644 --- a/tests/doxygen_parsing_test.py +++ b/tests/doxygen_parsing_test.py @@ -98,7 +98,10 @@ def test_function_docstrings_end_with_blank_line_before_closing_quotes(): * Details begin after the summary. */""") - assert format_function_docstring(comment) == "Summary line.\n\nDetails begin after the summary.\n\n" + assert ( + format_function_docstring(comment) + == "Summary line.\n\nDetails begin after the summary.\n\n" + ) def test_single_line_function_docstrings_do_not_get_extra_blank_lines(): diff --git a/tests/duplicate_name_test.py b/tests/duplicate_name_test.py index a42969e..754e619 100644 --- a/tests/duplicate_name_test.py +++ b/tests/duplicate_name_test.py @@ -9,7 +9,9 @@ def test_suffixed_names_do_not_collide(tmp_path): - comments = pybind11_mkdoc.mkdoc_lib.extract_all([str(DIR / "duplicate_name_docs" / "duplicate_name.h")]) + comments = pybind11_mkdoc.mkdoc_lib.extract_all( + [str(DIR / "duplicate_name_docs" / "duplicate_name.h")] + ) output = tmp_path / "docs.h" with output.open("w") as fd: diff --git a/tests/long_parameter_test.py b/tests/long_parameter_test.py index 76c5430..a815be8 100644 --- a/tests/long_parameter_test.py +++ b/tests/long_parameter_test.py @@ -7,7 +7,9 @@ def test_long_parameter(capsys): - comments = pybind11_mkdoc.mkdoc_lib.extract_all([os.path.join(DIR, "long_parameter_docs", "long_parameter.h")]) + comments = pybind11_mkdoc.mkdoc_lib.extract_all( + [os.path.join(DIR, "long_parameter_docs", "long_parameter.h")] + ) pybind11_mkdoc.mkdoc_lib.write_header(comments, sys.stdout) res = capsys.readouterr() diff --git a/tests/read_args_test.py b/tests/read_args_test.py index b536ad0..2b55f8f 100644 --- a/tests/read_args_test.py +++ b/tests/read_args_test.py @@ -14,14 +14,23 @@ def config_calls(monkeypatch): """Record cindex.Config.set_library_* calls instead of configuring libclang.""" calls = {} monkeypatch.setattr(cindex.Config, "loaded", False) - monkeypatch.setattr(cindex.Config, "set_library_file", lambda p: calls.__setitem__("file", p)) - monkeypatch.setattr(cindex.Config, "set_library_path", lambda p: calls.__setitem__("path", p)) + monkeypatch.setattr( + cindex.Config, "set_library_file", lambda p: calls.__setitem__("file", p) + ) + monkeypatch.setattr( + cindex.Config, "set_library_path", lambda p: calls.__setitem__("path", p) + ) return calls @pytest.fixture def clean_env(monkeypatch): - for var in ["LIBCLANG_PATH", "LLVM_DIR_PATH", "CLANG_INCLUDE_DIR", "CPP_INCLUDE_DIRS"]: + for var in [ + "LIBCLANG_PATH", + "LLVM_DIR_PATH", + "CLANG_INCLUDE_DIR", + "CPP_INCLUDE_DIRS", + ]: monkeypatch.delenv(var, raising=False) @@ -58,7 +67,9 @@ def test_linux_libclang_path_without_llvm_dir(monkeypatch, config_calls, tmp_pat @pytest.mark.usefixtures("linux", "clean_env") -def test_linux_libclang_path_without_llvm_dir_libcpp(monkeypatch, config_calls, tmp_path): +def test_linux_libclang_path_without_llvm_dir_libcpp( + monkeypatch, config_calls, tmp_path +): lib = tmp_path / "libclang.so.1" lib.touch() monkeypatch.setattr(mkdoc_lib, "glob", lambda _pattern: []) @@ -102,7 +113,10 @@ def test_macos_xcode_preferred(monkeypatch, config_calls): assert config_calls["path"] == XCODE + "Toolchains/XcodeDefault.xctoolchain/usr/lib" idx = parameters.index("-isysroot") - assert parameters[idx + 1] == XCODE + "Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" + assert ( + parameters[idx + 1] + == XCODE + "Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk" + ) @pytest.mark.usefixtures("darwin", "clean_env") diff --git a/tests/sample_header_test.py b/tests/sample_header_test.py index b4aad48..4a22299 100644 --- a/tests/sample_header_test.py +++ b/tests/sample_header_test.py @@ -9,8 +9,13 @@ def test_generate_headers(capsys, tmp_path): with open(DIR / "sample_header_docs" / "sample_header_truth.h") as f: expected = f.read() - comments = pybind11_mkdoc.mkdoc_lib.extract_all([str(DIR / "sample_header_docs" / "sample_header.h")]) - assert [c[0] for c in comments] == ["mkd_doc_RootLevelSymbol", "mkd_doc_drake_MidLevelSymbol"] + comments = pybind11_mkdoc.mkdoc_lib.extract_all( + [str(DIR / "sample_header_docs" / "sample_header.h")] + ) + assert [c[0] for c in comments] == [ + "mkd_doc_RootLevelSymbol", + "mkd_doc_drake_MidLevelSymbol", + ] output = tmp_path / "docs.h" with output.open("w") as fd: @@ -34,7 +39,9 @@ def test_generate_headers_2(capsys, tmp_path): with open(DIR / "sample_header_docs" / "sample_header_2_truth.h") as f: expected = f.read() - comments = pybind11_mkdoc.mkdoc_lib.extract_all([str(DIR / "sample_header_docs" / "sample_header_2.h")]) + comments = pybind11_mkdoc.mkdoc_lib.extract_all( + [str(DIR / "sample_header_docs" / "sample_header_2.h")] + ) output = tmp_path / "docs.h" with output.open("w") as fd: From f7f85bf9797e627f66d680b38c042fd3112045dd Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Fri, 14 Aug 2026 11:46:39 -0400 Subject: [PATCH 2/2] style: add cmake-format config to preserve comments Take the cmake-format settings from pybind11, most importantly markup.enable_markup: false, which stops the formatter from reflowing hand-written comment lists and examples. Also skip the two CMake-written package config files. Assisted-by: ClaudeCode:claude-opus-5 --- .cmake-format.yaml | 71 +++++++++++++++++++ .pre-commit-config.yaml | 2 + cmake/CMakeLists.txt | 14 ++-- cmake/pybind11_mkdoc_functions.cmake | 57 +++++++-------- .../pybind11_mkdoc/pybind11_mkdocConfig.cmake | 17 ++--- .../pybind11_mkdocConfigVersion.cmake | 42 +++++------ .../pybind11_mkdoc_functions.cmake | 57 +++++++-------- 7 files changed, 161 insertions(+), 99 deletions(-) create mode 100644 .cmake-format.yaml diff --git a/.cmake-format.yaml b/.cmake-format.yaml new file mode 100644 index 0000000..3321fbe --- /dev/null +++ b/.cmake-format.yaml @@ -0,0 +1,71 @@ +parse: + additional_commands: + pybind11_mkdoc: + kwargs: + OUTPUT: 1 + PYBIND11_MODULE: 1 + HEADERS: "*" + EXTRA_ARGS: "*" + +format: + line_width: 99 + tab_size: 2 + + # If an argument group contains more than this many sub-groups + # (parg or kwarg groups) then force it to a vertical layout. + max_subgroups_hwrap: 2 + + # If a positional argument group contains more than this many + # arguments, then force it to a vertical layout. + max_pargs_hwrap: 6 + + # If a cmdline positional group consumes more than this many + # lines without nesting, then invalidate the layout (and nest) + max_rows_cmdline: 2 + separate_ctrl_name_with_space: false + separate_fn_name_with_space: false + dangle_parens: false + + # If the trailing parenthesis must be 'dangled' on its on + # 'line, then align it to this reference: `prefix`: the start' + # 'of the statement, `prefix-indent`: the start of the' + # 'statement, plus one indentation level, `child`: align to' + # the column of the arguments + dangle_align: prefix + # If the statement spelling length (including space and + # parenthesis) is smaller than this amount, then force reject + # nested layouts. + min_prefix_chars: 4 + + # If the statement spelling length (including space and + # parenthesis) is larger than the tab width by more than this + # amount, then force reject un-nested layouts. + max_prefix_chars: 10 + + # If a candidate layout is wrapped horizontally but it exceeds + # this many lines, then reject the layout. + max_lines_hwrap: 2 + + line_ending: unix + + # Format command names consistently as 'lower' or 'upper' case + command_case: canonical + + # Format keywords consistently as 'lower' or 'upper' case + # unchanged is valid too + keyword_case: "upper" + + # A list of command names which should always be wrapped + always_wrap: [] + + # If true, the argument lists which are known to be sortable + # will be sorted lexicographically + enable_sort: true + + # If true, the parsers may infer whether or not an argument + # list is sortable (without annotation). + autosort: false + +# Reflowing comments destroys hand-made lists and examples +markup: + enable_markup: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f9b0667..410a980 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -47,6 +47,8 @@ repos: additional_dependencies: [pyyaml] types: [file] files: (\.cmake|CMakeLists.txt)(.in)?$ + # These two are written by CMake itself + exclude: ^pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig(Version)?\.cmake$ # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index a76863a..dcb3dd7 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -1,12 +1,11 @@ cmake_minimum_required(VERSION 3.25...4.3) -# Read the version from the Python package; project() accepts numeric components -# only, so any dev/pre-release suffix is dropped. -file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/../pybind11_mkdoc/__init__.py" - version_line REGEX "^__version__ *= *[\"']") +# Read the version from the Python package; project() accepts numeric components only, +# so any dev/pre-release suffix is dropped. +file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/../pybind11_mkdoc/__init__.py" version_line + REGEX "^__version__ *= *[\"']") if(NOT version_line MATCHES "([0-9]+(\\.[0-9]+)*)") - message( - FATAL_ERROR "Could not read __version__ from pybind11_mkdoc/__init__.py") + message(FATAL_ERROR "Could not read __version__ from pybind11_mkdoc/__init__.py") endif() project(pybind11_mkdoc VERSION "${CMAKE_MATCH_1}") @@ -22,8 +21,7 @@ write_basic_package_version_file( # Create config file configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/pybind11_mkdocConfig.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfig.cmake" - INSTALL_DESTINATION pybind11_mkdoc) + "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfig.cmake" INSTALL_DESTINATION pybind11_mkdoc) # Install config + version install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11_mkdocConfig.cmake" diff --git a/cmake/pybind11_mkdoc_functions.cmake b/cmake/pybind11_mkdoc_functions.cmake index 198a25f..adfb66f 100644 --- a/cmake/pybind11_mkdoc_functions.cmake +++ b/cmake/pybind11_mkdoc_functions.cmake @@ -1,27 +1,32 @@ -# This function is used to run pybind11-mkdoc for the headers of a pybind11 -# module. In addition, this will also add target dependencies so the -# pybind11-mkdoc header file is generated before the pybind11 module. Also, this -# will automatically add the current binary directory to the pybind11 module's -# includes, so it can easily be included when compiling the module. +# This function is used to run pybind11-mkdoc for the headers of a pybind11 module. +# In addition, this will also add target dependencies so the pybind11-mkdoc header +# file is generated before the pybind11 module. Also, this will automatically add +# the current binary directory to the pybind11 module's includes, so it can +# easily be included when compiling the module. # -# The required parameters are: * OUTPUT - The name of the output file. * -# PYBIND11_MODULE - The pybind11 module target that these docs will be used for. -# * HEADERS - The header files to create docs for. These can be absolute paths -# or relative to the current source directory. +# The required parameters are: +# * OUTPUT - The name of the output file. +# * PYBIND11_MODULE - The pybind11 module target that these docs will be used for. +# * HEADERS - The header files to create docs for. These can be absolute paths or relative to the +# current source directory. # -# The optional parameters are: * EXTRA_ARGS - A list of arguments that will be -# added verbatim to the pybind11-mkdoc command. +# The optional parameters are: +# * EXTRA_ARGS - A list of arguments that will be added verbatim to the pybind11-mkdoc command. # -# Example usage: pybind11_add_module(my_pybind11_module -# src/my_pybind11_module.cc) pybind11_mkdoc( OUTPUT my_pybind11_module_doc.h -# PYBIND11_MODULE my_pybind11_module HEADERS include/my_header_1.h -# /absolute/path/to/header.h ) +# Example usage: +# pybind11_add_module(my_pybind11_module src/my_pybind11_module.cc) +# pybind11_mkdoc( +# OUTPUT my_pybind11_module_doc.h +# PYBIND11_MODULE my_pybind11_module +# HEADERS +# include/my_header_1.h +# /absolute/path/to/header.h +# ) function(pybind11_mkdoc) set(options) set(oneValueArgs OUTPUT PYBIND11_MODULE) set(multiValueArgs HEADERS EXTRA_ARGS) - cmake_parse_arguments(PARSE_ARGV 0 arg "${options}" "${oneValueArgs}" - "${multiValueArgs}") + cmake_parse_arguments(PARSE_ARGV 0 arg "${options}" "${oneValueArgs}" "${multiValueArgs}") # Include directories for the pybind11 module set(prop "$") @@ -39,24 +44,20 @@ function(pybind11_mkdoc) endif() endforeach() - # Add a custom target and command for the full header file location that runs - # pybind11-mkdoc We automatically include the source directory and - # build/include + # Add a custom target and command for the full header file location that runs pybind11-mkdoc + # We automatically include the source directory and build/include add_custom_target(pybind11_mkdoc_${arg_OUTPUT} DEPENDS ${arg_OUTPUT}) add_custom_command( OUTPUT ${arg_OUTPUT} - COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o - ${arg_OUTPUT} "$<$:-I$>" ${HEADERS} + COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o ${arg_OUTPUT} + "$<$:-I$>" ${HEADERS} DEPENDS ${HEADERS} COMMAND_EXPAND_LISTS) - # Add a dependency so that the pybind11-mkdoc command runs before we try to - # compile the pybind11 module + # Add a dependency so that the pybind11-mkdoc command runs before we try to compile the pybind11 module add_dependencies(${arg_PYBIND11_MODULE} pybind11_mkdoc_${arg_OUTPUT}) - # Add the current binary directory to the pybind11 module so it can be - # included easily - target_include_directories(${arg_PYBIND11_MODULE} - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + # Add the current binary directory to the pybind11 module so it can be included easily + target_include_directories(${arg_PYBIND11_MODULE} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) endfunction() diff --git a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake index d3a91c8..c72741b 100644 --- a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake +++ b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfig.cmake @@ -1,17 +1,14 @@ -# Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### Any -# changes to this file will be overwritten by the next CMake run #### The input -# file was pybind11_mkdocConfig.cmake.in ######## -get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../" - ABSOLUTE) +####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() ####### +####### Any changes to this file will be overwritten by the next CMake run #### +####### The input file was pybind11_mkdocConfig.cmake.in ######## + +get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../" ABSOLUTE) macro(set_and_check _var _file) set(${_var} "${_file}") if(NOT EXISTS "${_file}") - message( - FATAL_ERROR - "File or directory ${_file} referenced by variable ${_var} does not exist !" - ) + message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !") endif() endmacro() @@ -25,7 +22,7 @@ macro(check_required_components _NAME) endforeach() endmacro() -# ############################################################################## +#################################################################################### include("${CMAKE_CURRENT_LIST_DIR}/pybind11_mkdoc_functions.cmake") diff --git a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake index a68d214..df97cb6 100644 --- a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake +++ b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdocConfigVersion.cmake @@ -1,12 +1,13 @@ -# This is a basic version file for the Config-mode of find_package(). It is used -# by write_basic_package_version_file() as input file for configure_file() to -# create a version-file which can be installed along a config.cmake file. +# This is a basic version file for the Config-mode of find_package(). +# It is used by write_basic_package_version_file() as input file for configure_file() +# to create a version-file which can be installed along a config.cmake file. # # The created file sets PACKAGE_VERSION_EXACT if the current version string and # the requested version string are exactly the same and it sets -# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, but -# only if the requested major version is the same as the current one. The -# variable CVF_VERSION must be set before calling configure_file(). +# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version, +# but only if the requested major version is the same as the current one. +# The variable CVF_VERSION must be set before calling configure_file(). + set(PACKAGE_VERSION "2.6.2") @@ -25,22 +26,14 @@ else() if(PACKAGE_FIND_VERSION_RANGE) # both endpoints of the range must have the expected major version - math(EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") - if(NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR - OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" - AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) - OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" - AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL - CVF_VERSION_MAJOR_NEXT) - )) + math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1") + if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT))) set(PACKAGE_VERSION_COMPATIBLE FALSE) - elseif( - PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR - AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" - AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) - OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" - AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX) - )) + elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR + AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX) + OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX))) set(PACKAGE_VERSION_COMPATIBLE TRUE) else() set(PACKAGE_VERSION_COMPATIBLE FALSE) @@ -58,14 +51,13 @@ else() endif() endif() -# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, -# ignore it: + +# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it: if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "") return() endif() -# check that the installed version has the same 32/64bit-ness as the one which -# is currently searching: +# check that the installed version has the same 32/64bit-ness as the one which is currently searching: if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8") math(EXPR installedBits "8 * 8") set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)") diff --git a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake index 198a25f..adfb66f 100644 --- a/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake +++ b/pybind11_mkdoc/share/cmake/pybind11_mkdoc/pybind11_mkdoc_functions.cmake @@ -1,27 +1,32 @@ -# This function is used to run pybind11-mkdoc for the headers of a pybind11 -# module. In addition, this will also add target dependencies so the -# pybind11-mkdoc header file is generated before the pybind11 module. Also, this -# will automatically add the current binary directory to the pybind11 module's -# includes, so it can easily be included when compiling the module. +# This function is used to run pybind11-mkdoc for the headers of a pybind11 module. +# In addition, this will also add target dependencies so the pybind11-mkdoc header +# file is generated before the pybind11 module. Also, this will automatically add +# the current binary directory to the pybind11 module's includes, so it can +# easily be included when compiling the module. # -# The required parameters are: * OUTPUT - The name of the output file. * -# PYBIND11_MODULE - The pybind11 module target that these docs will be used for. -# * HEADERS - The header files to create docs for. These can be absolute paths -# or relative to the current source directory. +# The required parameters are: +# * OUTPUT - The name of the output file. +# * PYBIND11_MODULE - The pybind11 module target that these docs will be used for. +# * HEADERS - The header files to create docs for. These can be absolute paths or relative to the +# current source directory. # -# The optional parameters are: * EXTRA_ARGS - A list of arguments that will be -# added verbatim to the pybind11-mkdoc command. +# The optional parameters are: +# * EXTRA_ARGS - A list of arguments that will be added verbatim to the pybind11-mkdoc command. # -# Example usage: pybind11_add_module(my_pybind11_module -# src/my_pybind11_module.cc) pybind11_mkdoc( OUTPUT my_pybind11_module_doc.h -# PYBIND11_MODULE my_pybind11_module HEADERS include/my_header_1.h -# /absolute/path/to/header.h ) +# Example usage: +# pybind11_add_module(my_pybind11_module src/my_pybind11_module.cc) +# pybind11_mkdoc( +# OUTPUT my_pybind11_module_doc.h +# PYBIND11_MODULE my_pybind11_module +# HEADERS +# include/my_header_1.h +# /absolute/path/to/header.h +# ) function(pybind11_mkdoc) set(options) set(oneValueArgs OUTPUT PYBIND11_MODULE) set(multiValueArgs HEADERS EXTRA_ARGS) - cmake_parse_arguments(PARSE_ARGV 0 arg "${options}" "${oneValueArgs}" - "${multiValueArgs}") + cmake_parse_arguments(PARSE_ARGV 0 arg "${options}" "${oneValueArgs}" "${multiValueArgs}") # Include directories for the pybind11 module set(prop "$") @@ -39,24 +44,20 @@ function(pybind11_mkdoc) endif() endforeach() - # Add a custom target and command for the full header file location that runs - # pybind11-mkdoc We automatically include the source directory and - # build/include + # Add a custom target and command for the full header file location that runs pybind11-mkdoc + # We automatically include the source directory and build/include add_custom_target(pybind11_mkdoc_${arg_OUTPUT} DEPENDS ${arg_OUTPUT}) add_custom_command( OUTPUT ${arg_OUTPUT} - COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o - ${arg_OUTPUT} "$<$:-I$>" ${HEADERS} + COMMAND ${Python_EXECUTABLE} -m pybind11_mkdoc ${arg_EXTRA_ARGS} -o ${arg_OUTPUT} + "$<$:-I$>" ${HEADERS} DEPENDS ${HEADERS} COMMAND_EXPAND_LISTS) - # Add a dependency so that the pybind11-mkdoc command runs before we try to - # compile the pybind11 module + # Add a dependency so that the pybind11-mkdoc command runs before we try to compile the pybind11 module add_dependencies(${arg_PYBIND11_MODULE} pybind11_mkdoc_${arg_OUTPUT}) - # Add the current binary directory to the pybind11 module so it can be - # included easily - target_include_directories(${arg_PYBIND11_MODULE} - PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + # Add the current binary directory to the pybind11 module so it can be included easily + target_include_directories(${arg_PYBIND11_MODULE} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) endfunction()