Skip to main content

A pytest plugin that runs clang-tidy static analysis on C/C++ source files

Project description

pytest-clang-tidy

PyPI Python License CI

A pytest plugin that runs clang-tidy static analysis on C/C++ source files. Each file is collected as a test item and reported as a pass or failure in the normal pytest output.

Useful for Python projects with C/C++ source where you already run pytest and want clang-tidy findings surfaced in the same test run.

Installation

pip install pytest-clang-tidy

This pulls in clang-tidy automatically via the clang-tidy PyPI package.

Usage

The plugin does nothing unless explicitly enabled:

pytest --clang-tidy

This collects all .c, .cpp, .cc, and .cxx files and runs clang-tidy on each one. Files with errors fail; clean files pass.

PASSED src/clean.c::CLANG_TIDY
FAILED src/buggy.c::CLANG_TIDY
  src/buggy.c:4:8: error: Dereference of null pointer (loaded from
  variable 'p') [clang-analyzer-core.NullDereference]

You can combine --clang-tidy with your normal test run — Python tests and clang-tidy items appear together in the results.

Enabling checks

clang-tidy has no checks enabled by default. You need to configure which checks to run via clang_tidy_checks, otherwise every file will pass without being analyzed. The clang-analyzer-* checks (Clang Static Analyzer) are a good starting point — they catch real bugs like null pointer dereferences, use-after-free, and resource leaks. See the full list of checks for other options.

[pytest]
clang_tidy_checks =
    -*
    clang-analyzer-*

clang_tidy_args = --warnings-as-errors=*

By default, clang-tidy exits 0 even when it finds warnings. Adding --warnings-as-errors=* to clang_tidy_args makes warnings fail the test. Without it, warnings are still surfaced as Python warnings in the pytest output (visible in the warnings summary).

Configuration

All options go in pyproject.toml, pytest.ini, or setup.cfg under [pytest].

clang-tidy also reads settings from a .clang-tidy file if one exists in your project (or a parent directory). Options set via pytest configuration are applied after .clang-tidy and take precedence — for example, clang_tidy_checks appends to the Checks value from .clang-tidy and can override individual checks. In general it's recommended to use either .clang-tidy or clang_tidy_checks but not both.

clang_tidy_checks

Checks to enable. Each entry is joined with commas and passed as -checks=.... Default: none (no checks enabled).

[pytest]
clang_tidy_checks =
    -*
    clang-analyzer-*
    bugprone-*
    -bugprone-easily-swappable-parameters

You can also pass -checks=... directly in clang_tidy_args if you prefer a single-line format.

clang_tidy_args

Extra arguments forwarded to every clang-tidy invocation. Use it for --warnings-as-errors, --config-file, and any other clang-tidy flags.

[pytest]
clang_tidy_args = --warnings-as-errors=* --config-file=tools/clang-tidy.yml

clang_tidy_extensions

File extensions to collect. Default: .c .cpp .cc .cxx.

[pytest]
clang_tidy_extensions = .c .cpp .h

clang_tidy_compiler_args

Extra compiler arguments passed after -- in the clang-tidy invocation. Useful for passing defines, include paths, or language standards.

[pytest]
clang_tidy_compiler_args = -std=c11 -DNDEBUG

clang_tidy_include_python_headers

When set to true, the plugin adds -isystem<python_include> to the compiler flags, where <python_include> is the CPython headers directory from sysconfig.get_path('include'). This allows clang-tidy to parse files that #include <Python.h> without a compile_commands.json. The headers are added as -isystem (not -I) so that clang-tidy does not report warnings from CPython's own headers. Default: false.

[pytest]
clang_tidy_include_python_headers = true

compile_commands.json

If a compile_commands.json file exists in your project root, clang-tidy will use it automatically and the plugin will not append any compiler flags (neither clang_tidy_compiler_args nor -isystem<python_include>).

Markers

All clang-tidy items are marked with clang_tidy, so you can select or exclude them with -m:

pytest --clang-tidy -m clang_tidy           # only clang-tidy
pytest --clang-tidy -m "unit or clang_tidy" # unit tests + clang-tidy
pytest --clang-tidy -m "not clang_tidy"     # everything except clang-tidy

Caching

Results are cached based on file modification time, clang_tidy_checks, clang_tidy_args, and clang_tidy_compiler_args. On subsequent runs, files that previously passed are skipped. The cache is automatically invalidated when a file is modified or arguments change. Caching relies on pytest's built-in cache provider (the .pytest_cache directory). If the cache provider is disabled (for example with -p no:cacheprovider), results will not be cached and all files will be re-checked on each run.

To force a full re-check:

pytest --clang-tidy --cache-clear

Acknowledgements

This plugin relies on the clang-tidy PyPI package, which bundles prebuilt clang-tidy binaries so that no system-level LLVM installation is required.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_clang_tidy-0.2.1.tar.gz (8.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_clang_tidy-0.2.1-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file pytest_clang_tidy-0.2.1.tar.gz.

File metadata

  • Download URL: pytest_clang_tidy-0.2.1.tar.gz
  • Upload date:
  • Size: 8.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pytest_clang_tidy-0.2.1.tar.gz
Algorithm Hash digest
SHA256 03a972b030a546213225ff180e4338aff6cd89c1d4c3d4e29f3d5611bef9adfa
MD5 b71f7760257b5ec8b69c0b2f54cf6697
BLAKE2b-256 4b6ab6c4a318998c1f24a6f5bdaed5cb97aa0b2495effd5a993b779d8a9778f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_clang_tidy-0.2.1.tar.gz:

Publisher: release.yml on alexdej/pytest-clang-tidy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pytest_clang_tidy-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_clang_tidy-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 85397e38f689f9e51d5856783ff4ef05da8ca0f6d30eefd62ed07bd22d165dc0
MD5 d3bdac2189bbbb4f2950bdd892e637db
BLAKE2b-256 5050b28733df6f816b7489ba99fa6c402c6a0bb666d9992c649ce2d55f717e11

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_clang_tidy-0.2.1-py3-none-any.whl:

Publisher: release.yml on alexdej/pytest-clang-tidy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page