cppcheck-py 2.21.0__tar.gz → 2.22.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -180,3 +180,5 @@ install_manifest.txt
180
180
  compile_commands.json
181
181
  CTestTestfile.cmake
182
182
  _deps
183
+
184
+ third_party/
@@ -0,0 +1,42 @@
1
+ ci:
2
+ autoupdate_commit_msg: "chore(deps): update pre-commit hooks"
3
+ autofix_commit_msg: "style: pre-commit fixes"
4
+ autoupdate_schedule: "monthly"
5
+
6
+ repos:
7
+ - repo: https://github.com/pre-commit/pre-commit-hooks
8
+ rev: v6.0.0
9
+ hooks:
10
+ - id: check-added-large-files
11
+ - id: check-case-conflict
12
+ - id: check-merge-conflict
13
+ - id: check-symlinks
14
+ - id: check-yaml
15
+ - id: check-toml
16
+ - id: debug-statements
17
+ - id: end-of-file-fixer
18
+ - id: mixed-line-ending
19
+ - id: trailing-whitespace
20
+
21
+ - repo: https://github.com/astral-sh/ruff-pre-commit
22
+ rev: v0.16.6
23
+ hooks:
24
+ - id: ruff-check
25
+ args: [--fix, --show-fixes]
26
+ # Run the formatter.
27
+ - id: ruff-format
28
+
29
+ - repo: https://github.com/BlankSpruce/gersemi-pre-commit
30
+ rev: 0.28.1
31
+ hooks:
32
+ - id: gersemi
33
+ - repo: https://github.com/adhtruong/mirrors-typos
34
+ rev: v1.50.1
35
+ hooks:
36
+ - id: typos
37
+ - repo: https://github.com/abravalheri/validate-pyproject
38
+ rev: "0.26"
39
+ hooks:
40
+ - id: validate-pyproject
41
+ # Optional extra validations from SchemaStore:
42
+ additional_dependencies: ["validate-pyproject-schema-store[all]"]
@@ -0,0 +1,103 @@
1
+ cmake_minimum_required(VERSION 3.28...4.0)
2
+ project(${SKBUILD_PROJECT_NAME} VERSION ${SKBUILD_PROJECT_VERSION})
3
+
4
+ message(STATUS "cppcheck-wheel version: ${SKBUILD_PROJECT_VERSION}")
5
+ string(
6
+ REGEX MATCH "^([0-9]+)\.([0-9]+)\.([0-9]+)"
7
+ CPPCHECK_VERSION
8
+ "${SKBUILD_PROJECT_VERSION}"
9
+ )
10
+ message(STATUS "cppcheck version: ${CPPCHECK_VERSION}")
11
+
12
+ # Check if the current compiler/linker toolchain supports IPO
13
+ include(CheckIPOSupported)
14
+ check_ipo_supported(RESULT ipo_supported OUTPUT ipo_error)
15
+
16
+ if(ipo_supported)
17
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
18
+ message(STATUS "IPO/LTO enabled")
19
+ else()
20
+ message(WARNING "IPO/LTO not supported: ${ipo_error}")
21
+ endif()
22
+
23
+ # Check for the execinfo header, needed for backtraces support.
24
+ include(CheckIncludeFileCXX)
25
+ check_include_file_cxx("execinfo.h" HAVE_EXECINFO_H)
26
+
27
+ # Values cppcheck's own CMakeLists.txt will pick up as already-set variables
28
+ # (equivalent to the old -DFOO=... CMAKE_ARGS passed to the nested build).
29
+ if(NOT HAVE_EXECINFO_H)
30
+ message(STATUS "execinfo.h not found, disabling backtrace support")
31
+ set(NO_UNIX_BACKTRACE_SUPPORT ON)
32
+ endif()
33
+
34
+ set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
35
+ set(DISABLE_DMAKE ON)
36
+ set(FILESDIR "" CACHE STRING "" FORCE)
37
+
38
+ set(CPPCHECK_ARCHIVE
39
+ "${CMAKE_CURRENT_SOURCE_DIR}/third_party/cppcheck-${CPPCHECK_VERSION}.tar.gz"
40
+ )
41
+ if(NOT EXISTS "${CPPCHECK_ARCHIVE}")
42
+ message(
43
+ FATAL_ERROR
44
+ "${CPPCHECK_ARCHIVE} not found; run scripts/vendor_cppcheck.py "
45
+ "(the PEP 517 backend wrapper normally does this for you)"
46
+ )
47
+ endif()
48
+
49
+ include(FetchContent)
50
+ FetchContent_Declare(cppcheck URL "${CPPCHECK_ARCHIVE}" EXCLUDE_FROM_ALL)
51
+ FetchContent_MakeAvailable(cppcheck)
52
+
53
+ # Force the cppcheck target to build even though its subdirectory is
54
+ # EXCLUDE_FROM_ALL (mirrors the old build-cppcheck ExternalProject step).
55
+ add_custom_target(build-cppcheck ALL DEPENDS cppcheck)
56
+
57
+ # Reduce the size of the executable by executing strip if it is present on the system
58
+ find_program(STRIP_EXECUTABLE strip)
59
+ if(STRIP_EXECUTABLE)
60
+ add_custom_target(
61
+ strip-cppcheck
62
+ ALL
63
+ COMMAND ${STRIP_EXECUTABLE} $<TARGET_FILE:cppcheck>
64
+ COMMENT "Stripping cppcheck executable for size reduction"
65
+ )
66
+ add_dependencies(strip-cppcheck build-cppcheck)
67
+ endif()
68
+
69
+ # Define an installation rule that copies the executable to our Python package
70
+ install(
71
+ PROGRAMS
72
+ $<TARGET_FILE:cppcheck>
73
+ ${cppcheck_SOURCE_DIR}/htmlreport/cppcheck-htmlreport
74
+ DESTINATION cppcheck/data
75
+ )
76
+
77
+ install(
78
+ DIRECTORY ${cppcheck_SOURCE_DIR}/addons
79
+ DESTINATION cppcheck/data
80
+ FILES_MATCHING
81
+ PATTERN "*.py"
82
+ PATTERN "test" EXCLUDE
83
+ )
84
+
85
+ install(
86
+ DIRECTORY ${cppcheck_SOURCE_DIR}/cfg
87
+ DESTINATION cppcheck/data
88
+ FILES_MATCHING
89
+ PATTERN "*.cfg"
90
+ )
91
+
92
+ install(
93
+ DIRECTORY ${cppcheck_SOURCE_DIR}/platforms
94
+ DESTINATION cppcheck/data
95
+ FILES_MATCHING
96
+ PATTERN "*.xml"
97
+ )
98
+
99
+ install(
100
+ FILES ${cppcheck_SOURCE_DIR}/COPYING
101
+ DESTINATION cppcheck
102
+ RENAME COPYING-cppcheck
103
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: cppcheck-py
3
- Version: 2.21.0
3
+ Version: 2.22.0
4
4
  Summary: Static analysis of C/C++ code
5
5
  License: Apache 2.0
6
6
  Classifier: Programming Language :: C
@@ -13,6 +13,7 @@ Project-URL: Homepage, https://cppcheck.sourceforge.io/
13
13
  Project-URL: Documentation, https://cppcheck.sourceforge.io/manual.pdf
14
14
  Project-URL: Download, https://github.com/cppcheck-opensource/cppcheck/releases
15
15
  Project-URL: Source, https://github.com/cconverse711/cppcheck-wheel
16
+ Requires-Python: >=3.9
16
17
  Requires-Dist: pygments
17
18
  Description-Content-Type: text/markdown
18
19
 
@@ -28,11 +29,13 @@ python -m pip install cppcheck-py
28
29
 
29
30
  The tools provided are:
30
31
 
31
- cppcheck: performs static analysis of C/C++ source code
32
- cppcheck-htmlreport: generates an html report of a XML file produced by cppcheck
32
+ * `cppcheck`: performs static analysis of C/C++ source code
33
+ * `cppcheck-htmlreport`: generates an html report of a XML file produced by `cppcheck`
33
34
 
34
35
  This projects intends to release a new PyPI package for each major and minor release of `cppcheck`.
35
36
 
37
+ Note that these tools are GPL-3.0 licensed; source is provided in the accompanying sdist.
38
+
36
39
  ## Use with pipx
37
40
 
38
41
  You can use `pipx` to run cppcheck, as well. For example, `pipx run cppcheck <args>` will run cppcheck without any previous install required on any machine with pipx (including all default GitHub Actions / Azure runners, avoiding requiring a pre-install step or even `actions/setup-python`).
@@ -10,11 +10,13 @@ python -m pip install cppcheck-py
10
10
 
11
11
  The tools provided are:
12
12
 
13
- cppcheck: performs static analysis of C/C++ source code
14
- cppcheck-htmlreport: generates an html report of a XML file produced by cppcheck
13
+ * `cppcheck`: performs static analysis of C/C++ source code
14
+ * `cppcheck-htmlreport`: generates an html report of a XML file produced by `cppcheck`
15
15
 
16
16
  This projects intends to release a new PyPI package for each major and minor release of `cppcheck`.
17
17
 
18
+ Note that these tools are GPL-3.0 licensed; source is provided in the accompanying sdist.
19
+
18
20
  ## Use with pipx
19
21
 
20
22
  You can use `pipx` to run cppcheck, as well. For example, `pipx run cppcheck <args>` will run cppcheck without any previous install required on any machine with pipx (including all default GitHub Actions / Azure runners, avoiding requiring a pre-install step or even `actions/setup-python`).
@@ -0,0 +1,49 @@
1
+ """Thin PEP 517 backend wrapper around scikit-build-core.
2
+
3
+ Ensures cppcheck's source is vendored into third_party/ before the
4
+ sdist is actually assembled, so `python -m build --sdist` (and anything
5
+ that calls this hook -- pip, cibuildwheel, twine, CI) always produces a
6
+ self-contained sdist without a manual pre-step.
7
+ """
8
+
9
+ import subprocess
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ from scikit_build_core.build import build_editable as _build_editable
14
+ from scikit_build_core.build import build_sdist as _build_sdist
15
+ from scikit_build_core.build import build_wheel as _build_wheel
16
+
17
+ # Re-export everything scikit-build-core provides; we only override
18
+ # build_sdist. Anything not overridden here still needs to exist as an
19
+ # attribute for setuptools/pip's PEP 517 hook lookup to find it.
20
+ from scikit_build_core.build import ( # noqa: F401
21
+ get_requires_for_build_editable,
22
+ get_requires_for_build_sdist,
23
+ get_requires_for_build_wheel,
24
+ prepare_metadata_for_build_editable,
25
+ prepare_metadata_for_build_wheel,
26
+ )
27
+
28
+ _ROOT = Path(__file__).resolve().parent
29
+
30
+
31
+ def _vendor_cppcheck():
32
+ vendor_script = _ROOT / "scripts" / "vendor_cppcheck.py"
33
+ print(f"[backend_wrapper] running {vendor_script}", file=sys.stderr)
34
+ subprocess.check_call([sys.executable, str(vendor_script)])
35
+
36
+
37
+ def build_editable(editable_directory, config_settings=None, metadata_directory=None):
38
+ _vendor_cppcheck()
39
+ return _build_editable(editable_directory, config_settings, metadata_directory)
40
+
41
+
42
+ def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
43
+ _vendor_cppcheck()
44
+ return _build_wheel(wheel_directory, config_settings, metadata_directory)
45
+
46
+
47
+ def build_sdist(sdist_directory, config_settings=None):
48
+ _vendor_cppcheck()
49
+ return _build_sdist(sdist_directory, config_settings)
@@ -1,41 +1,31 @@
1
+ import functools
2
+ import os
1
3
  import subprocess
2
4
  import sys
5
+ from importlib.resources import files
3
6
  from pathlib import Path
4
- import functools
5
- import os
6
7
 
7
- if sys.version_info.minor >= 9:
8
- # Only available on 3.9 or later, and required on 3.12
9
- from importlib.resources import files
10
- else:
11
- import pkg_resources
12
8
 
13
- def get_executable(name:str) -> Path:
9
+ def get_executable(name: str) -> Path:
14
10
  return _get_executable(name)
15
11
 
16
12
 
17
- @functools.lru_cache(maxsize=None)
18
- def _get_executable(name:str) -> Path:
19
- if sys.version_info.minor >= 9:
20
- # Only available in 3.9 or later, and required in 3.12
21
- possibles = [
22
- Path(files("cppcheck") / f"data/{name}{s}")
23
- for s in ("", ".exe", ".bin", ".dmg")
24
- ]
25
- else:
26
- possibles = [
27
- Path(pkg_resources.resource_filename("cppcheck", f"data/{name}{s}"))
28
- for s in ("", ".exe", ".bin", ".dmg")
29
- ]
13
+ @functools.cache
14
+ def _get_executable(name: str) -> Path:
15
+ possibles = [
16
+ Path(files("cppcheck") / f"data/{name}{s}")
17
+ for s in ("", ".exe", ".bin", ".dmg")
18
+ ]
30
19
  for exe in possibles:
31
20
  if exe.exists():
32
21
  if os.environ.get("CPPCHECK_WHEEL_VERBOSE", None):
33
- print(f'Found binary: {exe} ')
22
+ print(f"Found binary: {exe}")
34
23
  return exe
35
24
 
36
25
  possibles_str = "\n\t".join(map(str, possibles))
37
26
  raise FileNotFoundError(f"No executable found for {name} at\n\t{possibles_str}")
38
27
 
28
+
39
29
  def _run(name, *args):
40
30
  command = [_get_executable(name)]
41
31
  if args:
@@ -44,6 +34,7 @@ def _run(name, *args):
44
34
  command += sys.argv[1:]
45
35
  return subprocess.call(command)
46
36
 
37
+
47
38
  def _run_python(name, *args):
48
39
  command = [sys.executable, _get_executable(name)]
49
40
  if args:
@@ -55,8 +46,10 @@ def _run_python(name, *args):
55
46
  # we have to call the interpreter and pass the script as parameter
56
47
  return subprocess.call(command)
57
48
 
49
+
58
50
  def cppcheck():
59
51
  raise SystemExit(_run("cppcheck"))
60
52
 
53
+
61
54
  def cppcheck_htmlreport():
62
55
  raise SystemExit(_run_python("cppcheck-htmlreport"))
@@ -0,0 +1 @@
1
+ 2.22.0.0
@@ -1,6 +1,9 @@
1
1
  [build-system]
2
- requires = ["scikit-build-core"]
3
- build-backend = "scikit_build_core.build"
2
+ requires = [
3
+ "scikit-build-core",
4
+ "tomli>=2.0; python_version < '3.11'",]
5
+ build-backend = "backend_wrapper"
6
+ backend-path = ["."]
4
7
 
5
8
  [project]
6
9
  name = "cppcheck-py"
@@ -8,6 +11,7 @@ dynamic = ["version"]
8
11
  license = { text = "Apache 2.0" }
9
12
  description = "Static analysis of C/C++ code"
10
13
  readme = "README.md"
14
+ requires-python = ">=3.9"
11
15
  dependencies = ["pygments"]
12
16
  classifiers = [
13
17
  "Programming Language :: C",
@@ -36,11 +40,12 @@ Source = "https://github.com/cconverse711/cppcheck-wheel"
36
40
 
37
41
  [tool.scikit-build]
38
42
  wheel.packages = ["cppcheck"]
39
- wheel.py-api = "py2.py3"
40
- cmake.version = ">=3.16.0"
43
+ wheel.py-api = "py3"
44
+ cmake.version = ">=3.28.0"
41
45
  ninja.version = ">=1.10.0"
42
46
  build.verbose = true
43
47
  logging.level = "DEBUG"
48
+ sdist.include = ["third_party/cppcheck-*.tar.gz"]
44
49
 
45
50
  [dependency-groups]
46
51
  dev = ["pytest"]
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env python3
2
+ """Run before building an sdist or wheel: vendors cppcheck's source so the sdist
3
+ is self-contained and doesn't require network access to build."""
4
+
5
+ import pathlib
6
+ import re
7
+ import urllib.request
8
+
9
+ from scikit_build_core.metadata.regex import dynamic_metadata
10
+
11
+ try:
12
+ import tomllib
13
+ except ModuleNotFoundError:
14
+ import tomli as tomllib
15
+
16
+ ROOT = pathlib.Path(__file__).resolve().parent.parent
17
+
18
+ with open(ROOT / "pyproject.toml", "rb") as f:
19
+ pyproject = tomllib.load(f)
20
+
21
+ version_entry = next(
22
+ e for e in pyproject["tool"]["dynamic-metadata"] if e["field"] == "version"
23
+ )
24
+ settings = {
25
+ k: v for k, v in version_entry.items() if k not in ("provider", "field")
26
+ }
27
+ project_version = dynamic_metadata("version", settings)
28
+
29
+ cppcheck_version = re.match(r"^(\d+\.\d+\.\d+)", project_version).group(1)
30
+ url = f"https://github.com/cppcheck-opensource/cppcheck/archive/refs/tags/{cppcheck_version}.tar.gz"
31
+ archive_path = ROOT / "third_party" / f"cppcheck-{cppcheck_version}.tar.gz"
32
+ if archive_path.exists():
33
+ print(f"{archive_path} already exists, skipping download.")
34
+ else:
35
+ archive_path.parent.mkdir(parents=True, exist_ok=True)
36
+ print(f"Downloading {url}")
37
+ urllib.request.urlretrieve(url, archive_path)
@@ -1,14 +1,16 @@
1
1
  import os
2
- import pytest
3
2
  import sys
4
3
  import tempfile
5
4
  from pathlib import Path
6
5
 
6
+ import pytest
7
+
7
8
  EXECUTABLES = (
8
9
  "cppcheck",
9
10
  "cppcheck-htmlreport",
10
11
  )
11
12
 
13
+
12
14
  @pytest.fixture(autouse=True)
13
15
  def ensure_cppcheck_from_wheel(monkeypatch):
14
16
  """Test the installed cppcheck package, not the local one."""
@@ -20,12 +22,12 @@ def ensure_cppcheck_from_wheel(monkeypatch):
20
22
  }
21
23
 
22
24
  sys.path[:] = [
23
- path for path in sys.path
24
- if Path(path).resolve() not in paths_to_remove
25
+ path for path in sys.path if Path(path).resolve() not in paths_to_remove
25
26
  ]
26
27
 
27
28
  monkeypatch.delitem(sys.modules, "cppcheck", raising=False)
28
29
 
30
+
29
31
  @pytest.mark.parametrize("executable", EXECUTABLES)
30
32
  def test_executable_file(capsys, executable):
31
33
  import cppcheck
@@ -36,14 +38,17 @@ def test_executable_file(capsys, executable):
36
38
  assert os.access(exe, os.X_OK)
37
39
  assert capsys.readouterr().out == ""
38
40
 
41
+
39
42
  def test_verbose_output(capsys, monkeypatch):
40
43
  import cppcheck
44
+
41
45
  monkeypatch.setenv("CPPCHECK_WHEEL_VERBOSE", "1")
42
46
  # need to clear cache to make sure the function is run again
43
47
  cppcheck._get_executable.cache_clear()
44
48
  cppcheck.get_executable("cppcheck")
45
49
  assert capsys.readouterr().out
46
50
 
51
+
47
52
  def test_cppcheck():
48
53
  import cppcheck
49
54
 
@@ -61,15 +66,17 @@ def test_cppcheck():
61
66
  "--addon=naming",
62
67
  "--library=std",
63
68
  "--xml",
64
- f"--output-file={str(xml_path)}",
69
+ f"--output-file={xml_path!s}",
65
70
  str(compilation_unit),
66
- ) == 0
71
+ )
72
+ == 0
67
73
  )
68
74
 
69
- assert(
75
+ assert (
70
76
  cppcheck._run_python(
71
77
  "cppcheck-htmlreport",
72
- f"--file={str(xml_path)}",
73
- f"--report-dir={tmpdir}/html"
74
- ) == 0
75
- )
78
+ f"--file={xml_path!s}",
79
+ f"--report-dir={tmpdir}/html",
80
+ )
81
+ == 0
82
+ )
@@ -1,74 +0,0 @@
1
- cmake_minimum_required(VERSION 3.16...4.0)
2
- project(${SKBUILD_PROJECT_NAME} VERSION ${SKBUILD_PROJECT_VERSION})
3
-
4
- message(STATUS "cppcheck-wheel version: ${SKBUILD_PROJECT_VERSION}")
5
- string(REGEX MATCH "^([0-9]+)\.([0-9]+)\.([0-9]+)" CPPCHECK_VERSION "${SKBUILD_PROJECT_VERSION}")
6
- message(STATUS "cppcheck version: ${CPPCHECK_VERSION}")
7
-
8
- # Define a build rule for cppcheck
9
- set(CPPCHECK_DOWNLOAD_URL "https://github.com/cppcheck-opensource/cppcheck/archive/refs/tags/${CPPCHECK_VERSION}.tar.gz")
10
- include(ExternalProject)
11
- ExternalProject_add(build-cppcheck
12
- URL "${CPPCHECK_DOWNLOAD_URL}"
13
- SOURCE_DIR ${CMAKE_BINARY_DIR}/cppcheck
14
- BINARY_DIR ${CMAKE_BINARY_DIR}/cppcheck-build
15
- DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/cppcheck-download
16
- UPDATE_COMMAND ""
17
- INSTALL_COMMAND ""
18
- USES_TERMINAL_DOWNLOAD 1
19
- USES_TERMINAL_CONFIGURE 1
20
- USES_TERMINAL_BUILD 1
21
- CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -U FILESDIR -DCMAKE_POLICY_VERSION_MINIMUM=3.5
22
- BUILD_COMMAND ${CMAKE_COMMAND} --build . --target cppcheck --config Release
23
- )
24
- set(config-subfolder "")
25
- if(CMAKE_GENERATOR MATCHES "Visual Studio")
26
- set(config-subfolder "Release")
27
- endif()
28
- set(cppcheck-executable ${CMAKE_BINARY_DIR}/cppcheck-build/${config-subfolder}/bin/cppcheck${CMAKE_EXECUTABLE_SUFFIX})
29
-
30
- # Reduce the size of the executable by executing strip if it is present on the system
31
- find_program(STRIP_EXECUTABLE strip)
32
- if(STRIP_EXECUTABLE)
33
- add_custom_target(
34
- strip-cppcheck
35
- ALL
36
- COMMAND ${STRIP_EXECUTABLE} ${cppcheck-executable}
37
- COMMENT "Stripping cppcheck executable for size reduction"
38
- )
39
- add_dependencies(strip-cppcheck build-cppcheck)
40
- endif()
41
-
42
- # Define an installation rule that copies the executable to our Python package
43
- install(
44
- PROGRAMS
45
- ${cppcheck-executable}
46
- ${CMAKE_BINARY_DIR}/cppcheck/htmlreport/cppcheck-htmlreport
47
- DESTINATION cppcheck/data
48
- )
49
-
50
- install(DIRECTORY
51
- ${CMAKE_BINARY_DIR}/cppcheck/addons
52
- DESTINATION cppcheck/data
53
- FILES_MATCHING PATTERN "*.py"
54
- PATTERN "test" EXCLUDE
55
- )
56
-
57
- install(DIRECTORY
58
- ${CMAKE_BINARY_DIR}/cppcheck/cfg
59
- DESTINATION cppcheck/data
60
- FILES_MATCHING PATTERN "*.cfg"
61
- )
62
-
63
- install(DIRECTORY
64
- ${CMAKE_BINARY_DIR}/cppcheck/platforms
65
- DESTINATION cppcheck/data
66
- FILES_MATCHING PATTERN "*.xml"
67
- )
68
-
69
- # Install the downloaded source archive for GPLv3 compliance.
70
- install(FILES
71
- ${CMAKE_BINARY_DIR}/cppcheck-download/${CPPCHECK_VERSION}.tar.gz
72
- DESTINATION cppcheck
73
- RENAME cppcheck-${CPPCHECK_VERSION}.tar.gz
74
- )
@@ -1 +0,0 @@
1
- 2.21.0.0
File without changes