torch-abi-audit 0.0.1__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.
Files changed (32) hide show
  1. torch_abi_audit-0.0.1/.gitignore +34 -0
  2. torch_abi_audit-0.0.1/LICENSE +21 -0
  3. torch_abi_audit-0.0.1/PKG-INFO +159 -0
  4. torch_abi_audit-0.0.1/README.md +130 -0
  5. torch_abi_audit-0.0.1/docs/docs/api.md +107 -0
  6. torch_abi_audit-0.0.1/docs/docs/cli.md +200 -0
  7. torch_abi_audit-0.0.1/docs/docs/index.md +99 -0
  8. torch_abi_audit-0.0.1/docs/zensical.toml +18 -0
  9. torch_abi_audit-0.0.1/pyproject.toml +76 -0
  10. torch_abi_audit-0.0.1/scripts/check_real_world.py +200 -0
  11. torch_abi_audit-0.0.1/src/torch_abi_audit/__init__.py +25 -0
  12. torch_abi_audit-0.0.1/src/torch_abi_audit/_version.py +24 -0
  13. torch_abi_audit-0.0.1/src/torch_abi_audit/cli.py +115 -0
  14. torch_abi_audit-0.0.1/src/torch_abi_audit/cpython_abi.py +76 -0
  15. torch_abi_audit-0.0.1/src/torch_abi_audit/demangle.py +26 -0
  16. torch_abi_audit-0.0.1/src/torch_abi_audit/inspect.py +144 -0
  17. torch_abi_audit-0.0.1/src/torch_abi_audit/py.typed +0 -0
  18. torch_abi_audit-0.0.1/src/torch_abi_audit/report.py +228 -0
  19. torch_abi_audit-0.0.1/src/torch_abi_audit/symbols.py +122 -0
  20. torch_abi_audit-0.0.1/src/torch_abi_audit/torch_abi.py +80 -0
  21. torch_abi_audit-0.0.1/tests/conftest.py +148 -0
  22. torch_abi_audit-0.0.1/tests/fixtures/src/cpython_stable.c +22 -0
  23. torch_abi_audit-0.0.1/tests/fixtures/src/cpython_unstable.c +25 -0
  24. torch_abi_audit-0.0.1/tests/fixtures/src/torch_stable.cpp +6 -0
  25. torch_abi_audit-0.0.1/tests/fixtures/src/torch_unstable.cpp +7 -0
  26. torch_abi_audit-0.0.1/tests/test_cli.py +60 -0
  27. torch_abi_audit-0.0.1/tests/test_cpython_abi.py +46 -0
  28. torch_abi_audit-0.0.1/tests/test_demangle.py +30 -0
  29. torch_abi_audit-0.0.1/tests/test_inspect.py +84 -0
  30. torch_abi_audit-0.0.1/tests/test_report.py +39 -0
  31. torch_abi_audit-0.0.1/tests/test_symbols.py +51 -0
  32. torch_abi_audit-0.0.1/tests/test_torch_abi.py +72 -0
@@ -0,0 +1,34 @@
1
+ # Build artifacts
2
+ build/
3
+ dist/
4
+ *.egg-info/
5
+ src/torch_abi_audit/_version.py
6
+
7
+ # Caches
8
+ __pycache__/
9
+ *.py[cod]
10
+ .pytest_cache/
11
+ .pyrefly/
12
+ .ruff_cache/
13
+ .mypy_cache/
14
+
15
+ # Environments
16
+ .venv/
17
+ .python-version.local
18
+ .pixi/
19
+
20
+ # Editor
21
+ .vscode/
22
+ .idea/
23
+
24
+ # OS
25
+ .DS_Store
26
+
27
+ # Docs build
28
+ docs/site/
29
+ docs/.cache/
30
+
31
+ # Scratch
32
+ *.so
33
+ *.dylib
34
+ *.pyd
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 torch-abi-audit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: torch-abi-audit
3
+ Version: 0.0.1
4
+ Summary: Audit Python extensions for PyTorch (and CPython) Stable ABI compliance.
5
+ Project-URL: Homepage, https://github.com/Quansight/torch-abi-audit
6
+ Project-URL: Documentation, https://quansight.github.io/torch-abi-audit/
7
+ Project-URL: Issues, https://github.com/Quansight/torch-abi-audit/issues
8
+ Author-email: Ralf Gommers <ralf.gommers@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: abi,cpython,extension-modules,limited-api,pytorch,stable-abi
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Operating System :: MacOS
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Software Development :: Build Tools
23
+ Classifier: Topic :: System :: Software Distribution
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.11
26
+ Requires-Dist: abi3info
27
+ Requires-Dist: pycxxfilt
28
+ Description-Content-Type: text/markdown
29
+
30
+ # torch-abi-audit
31
+
32
+ Audit Python extension modules for compliance with the
33
+ [PyTorch Stable ABI](https://docs.pytorch.org/docs/main/notes/libtorch_stable_abi.html)
34
+ (`aoti_torch_*` C shim and `torch::stable::*` / `torch::headeronly::*` C++
35
+ wrappers, introduced in PyTorch 2.9). Walks every `.so` shipped in a
36
+ package — both Python extension modules and bundled internal libraries —
37
+ and reports which stick to the stable surface and which reach into
38
+ `at::` / `c10::` / `torch::jit::` internals.
39
+
40
+ As a side benefit the same symbol-table walk also reports
41
+ [CPython Stable ABI](https://docs.python.org/3/c-api/stable.html) (PEP 384)
42
+ compliance, since the data is right there.
43
+
44
+ 📖 **Documentation:** <https://quansight.github.io/torch-abi-audit/>
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ pip install torch-abi-audit
50
+ ```
51
+
52
+ Linux and macOS only for now (Windows requires `dumpbin` support — not yet implemented).
53
+
54
+ ## CLI usage
55
+
56
+ ```bash
57
+ # Inspect an installed PyTorch ecosystem package by import name
58
+ torch-abi-audit torchaudio
59
+
60
+ # Inspect a path to an installed package or a single .so
61
+ torch-abi-audit /path/to/site-packages/somepkg
62
+
63
+ # Inspect every package in the current environment's site-packages
64
+ torch-abi-audit --env
65
+
66
+ # Inspect a specific site-packages directory
67
+ torch-abi-audit --site-packages /opt/venv/lib/python3.12/site-packages
68
+
69
+ # JSON output for tooling
70
+ torch-abi-audit --env --json | jq '.packages[] | select(.torch.uses_torch)'
71
+ ```
72
+
73
+ ## Example output
74
+
75
+ Run against the three packages tracked by `scripts/check_real_world.py`
76
+ (captured against torch 2.11.0 / torchaudio 2.11.0 / torchcodec 0.11.1):
77
+
78
+ ```text
79
+ Package: torchaudio
80
+ Root: <venv>/lib/python3.11/site-packages/torchaudio
81
+ Torch ABI: STABLE
82
+ CPython ABI: n/a
83
+ Extensions: 0
84
+ Bundled libs: 3
85
+ -- bundled libs --
86
+ [STABLE ] [abi3-tagged-no-capi ] lib/_torchaudio.abi3.so (stable_shim=6, unstable=0)
87
+ [STABLE ] [abi3-tagged-no-capi ] lib/libtorchaudio.abi3.so (stable_shim=80, unstable=0)
88
+ [STABLE ] [abi3-tagged-no-capi ] lib/torchaudio_prefixctc.abi3.so (stable_shim=62, unstable=0)
89
+
90
+ Package: torch
91
+ Root: <venv>/lib/python3.11/site-packages/torch
92
+ Torch ABI: UNSTABLE
93
+ CPython ABI: no
94
+ Extensions: 1
95
+ Bundled libs: 13
96
+ -- extensions --
97
+ [NO-TORCH] [not-abi3 ] _C.cpython-311-aarch64-linux-gnu.so
98
+ -- bundled libs --
99
+ [UNSTABLE] [not-abi3 ] lib/libc10_cuda.so (stable_shim=0, unstable=44)
100
+ [UNSTABLE] [not-abi3 ] lib/libtorch_cpu.so (stable_shim=0, unstable=327)
101
+ [UNSTABLE] [not-abi3 ] lib/libtorch_cuda.so (stable_shim=0, unstable=2515)
102
+ [UNSTABLE] [uses-private-api ] lib/libtorch_python.so (stable_shim=0, unstable=5085)
103
+ ... (9 more, mostly NO-TORCH or UNSTABLE)
104
+
105
+ Package: torchcodec
106
+ Root: <venv>/lib/python3.11/site-packages/torchcodec
107
+ Torch ABI: UNSTABLE
108
+ CPython ABI: no
109
+ Extensions: 5
110
+ Bundled libs: 10
111
+ -- extensions --
112
+ [NO-TORCH] [uses-private-api ] libtorchcodec_pybind_ops4.so
113
+ ... (4 similar)
114
+ -- bundled libs --
115
+ [UNSTABLE] [not-abi3 ] libtorchcodec_core4.so (stable_shim=64, unstable=4)
116
+ ... (4 similar)
117
+ [STABLE ] [uses-private-api ] libtorchcodec_custom_ops4.so (stable_shim=68, unstable=0)
118
+ ... (4 similar)
119
+ ```
120
+
121
+ `torchaudio` is reported as stable because every compiled library it ships
122
+ links against `aoti_torch_*` and `torch::stable::*` only. `torch` lands on
123
+ `UNSTABLE` because its bundled `libtorch_python.so`, `libtorch_cpu.so`, etc.
124
+ naturally reference internal `at::` / `c10::` namespaces (torch *implements*
125
+ those internals, after all). `torchcodec` is mid-migration: the
126
+ `custom_ops*` libs already use the stable surface, but `core*` libs still
127
+ link a handful of `c10::` symbols.
128
+
129
+ ## Python API
130
+
131
+ ```python
132
+ from torch_abi_audit import (
133
+ inspect_extension,
134
+ inspect_package,
135
+ inspect_site_packages,
136
+ )
137
+
138
+ report = inspect_package("torchaudio")
139
+ print(report.torch_verdict) # "torch-stable" | "torch-unstable" | "no-torch"
140
+
141
+ # `extensions` holds Python extension modules; `bundled_libs` holds the
142
+ # rest of the compiled .so files (libtorch_python.so, STABLE_TORCH_LIBRARY
143
+ # plugins, etc.). Both contribute to the verdict.
144
+ for lib in (*report.extensions, *report.bundled_libs):
145
+ print(lib.path, lib.torch.stable, lib.cpython.compliant)
146
+ ```
147
+
148
+ ## Development
149
+
150
+ ```bash
151
+ uv sync # install + dev dependencies in .venv
152
+ uv run pytest # run tests
153
+ uv run pyrefly check # type-check
154
+ uv run zensical serve docs/ # local docs server
155
+ ```
156
+
157
+ ## License
158
+
159
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,130 @@
1
+ # torch-abi-audit
2
+
3
+ Audit Python extension modules for compliance with the
4
+ [PyTorch Stable ABI](https://docs.pytorch.org/docs/main/notes/libtorch_stable_abi.html)
5
+ (`aoti_torch_*` C shim and `torch::stable::*` / `torch::headeronly::*` C++
6
+ wrappers, introduced in PyTorch 2.9). Walks every `.so` shipped in a
7
+ package — both Python extension modules and bundled internal libraries —
8
+ and reports which stick to the stable surface and which reach into
9
+ `at::` / `c10::` / `torch::jit::` internals.
10
+
11
+ As a side benefit the same symbol-table walk also reports
12
+ [CPython Stable ABI](https://docs.python.org/3/c-api/stable.html) (PEP 384)
13
+ compliance, since the data is right there.
14
+
15
+ 📖 **Documentation:** <https://quansight.github.io/torch-abi-audit/>
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pip install torch-abi-audit
21
+ ```
22
+
23
+ Linux and macOS only for now (Windows requires `dumpbin` support — not yet implemented).
24
+
25
+ ## CLI usage
26
+
27
+ ```bash
28
+ # Inspect an installed PyTorch ecosystem package by import name
29
+ torch-abi-audit torchaudio
30
+
31
+ # Inspect a path to an installed package or a single .so
32
+ torch-abi-audit /path/to/site-packages/somepkg
33
+
34
+ # Inspect every package in the current environment's site-packages
35
+ torch-abi-audit --env
36
+
37
+ # Inspect a specific site-packages directory
38
+ torch-abi-audit --site-packages /opt/venv/lib/python3.12/site-packages
39
+
40
+ # JSON output for tooling
41
+ torch-abi-audit --env --json | jq '.packages[] | select(.torch.uses_torch)'
42
+ ```
43
+
44
+ ## Example output
45
+
46
+ Run against the three packages tracked by `scripts/check_real_world.py`
47
+ (captured against torch 2.11.0 / torchaudio 2.11.0 / torchcodec 0.11.1):
48
+
49
+ ```text
50
+ Package: torchaudio
51
+ Root: <venv>/lib/python3.11/site-packages/torchaudio
52
+ Torch ABI: STABLE
53
+ CPython ABI: n/a
54
+ Extensions: 0
55
+ Bundled libs: 3
56
+ -- bundled libs --
57
+ [STABLE ] [abi3-tagged-no-capi ] lib/_torchaudio.abi3.so (stable_shim=6, unstable=0)
58
+ [STABLE ] [abi3-tagged-no-capi ] lib/libtorchaudio.abi3.so (stable_shim=80, unstable=0)
59
+ [STABLE ] [abi3-tagged-no-capi ] lib/torchaudio_prefixctc.abi3.so (stable_shim=62, unstable=0)
60
+
61
+ Package: torch
62
+ Root: <venv>/lib/python3.11/site-packages/torch
63
+ Torch ABI: UNSTABLE
64
+ CPython ABI: no
65
+ Extensions: 1
66
+ Bundled libs: 13
67
+ -- extensions --
68
+ [NO-TORCH] [not-abi3 ] _C.cpython-311-aarch64-linux-gnu.so
69
+ -- bundled libs --
70
+ [UNSTABLE] [not-abi3 ] lib/libc10_cuda.so (stable_shim=0, unstable=44)
71
+ [UNSTABLE] [not-abi3 ] lib/libtorch_cpu.so (stable_shim=0, unstable=327)
72
+ [UNSTABLE] [not-abi3 ] lib/libtorch_cuda.so (stable_shim=0, unstable=2515)
73
+ [UNSTABLE] [uses-private-api ] lib/libtorch_python.so (stable_shim=0, unstable=5085)
74
+ ... (9 more, mostly NO-TORCH or UNSTABLE)
75
+
76
+ Package: torchcodec
77
+ Root: <venv>/lib/python3.11/site-packages/torchcodec
78
+ Torch ABI: UNSTABLE
79
+ CPython ABI: no
80
+ Extensions: 5
81
+ Bundled libs: 10
82
+ -- extensions --
83
+ [NO-TORCH] [uses-private-api ] libtorchcodec_pybind_ops4.so
84
+ ... (4 similar)
85
+ -- bundled libs --
86
+ [UNSTABLE] [not-abi3 ] libtorchcodec_core4.so (stable_shim=64, unstable=4)
87
+ ... (4 similar)
88
+ [STABLE ] [uses-private-api ] libtorchcodec_custom_ops4.so (stable_shim=68, unstable=0)
89
+ ... (4 similar)
90
+ ```
91
+
92
+ `torchaudio` is reported as stable because every compiled library it ships
93
+ links against `aoti_torch_*` and `torch::stable::*` only. `torch` lands on
94
+ `UNSTABLE` because its bundled `libtorch_python.so`, `libtorch_cpu.so`, etc.
95
+ naturally reference internal `at::` / `c10::` namespaces (torch *implements*
96
+ those internals, after all). `torchcodec` is mid-migration: the
97
+ `custom_ops*` libs already use the stable surface, but `core*` libs still
98
+ link a handful of `c10::` symbols.
99
+
100
+ ## Python API
101
+
102
+ ```python
103
+ from torch_abi_audit import (
104
+ inspect_extension,
105
+ inspect_package,
106
+ inspect_site_packages,
107
+ )
108
+
109
+ report = inspect_package("torchaudio")
110
+ print(report.torch_verdict) # "torch-stable" | "torch-unstable" | "no-torch"
111
+
112
+ # `extensions` holds Python extension modules; `bundled_libs` holds the
113
+ # rest of the compiled .so files (libtorch_python.so, STABLE_TORCH_LIBRARY
114
+ # plugins, etc.). Both contribute to the verdict.
115
+ for lib in (*report.extensions, *report.bundled_libs):
116
+ print(lib.path, lib.torch.stable, lib.cpython.compliant)
117
+ ```
118
+
119
+ ## Development
120
+
121
+ ```bash
122
+ uv sync # install + dev dependencies in .venv
123
+ uv run pytest # run tests
124
+ uv run pyrefly check # type-check
125
+ uv run zensical serve docs/ # local docs server
126
+ ```
127
+
128
+ ## License
129
+
130
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,107 @@
1
+ ---
2
+ icon: lucide/code-2
3
+ ---
4
+
5
+ # Python API
6
+
7
+ The package exposes a small typed API for programmatic use.
8
+
9
+ ## Inspection entry points
10
+
11
+ ```python
12
+ from torch_abi_audit import (
13
+ inspect_extension,
14
+ inspect_package,
15
+ inspect_site_packages,
16
+ )
17
+ ```
18
+
19
+ ### `inspect_extension(path) -> ExtensionReport`
20
+
21
+ Inspect a single extension module file. Returns an `ExtensionReport` even for
22
+ unreadable files (the `error` field carries the message).
23
+
24
+ ### `inspect_package(name_or_path) -> PackageReport`
25
+
26
+ Inspect an installed package. `name_or_path` is either:
27
+
28
+ - An import name string (e.g. `"torchaudio"`) — resolved via the import system.
29
+ - A `Path` (or path-string with a separator) — treated as a file or directory.
30
+
31
+ The returned `PackageReport` separates Python extension modules
32
+ (`.extensions`) from bundled internal libraries (`.bundled_libs`); both
33
+ contribute to the torch ABI verdict.
34
+
35
+ ### `inspect_site_packages(directory=None) -> EnvironmentReport`
36
+
37
+ Walk a site-packages directory, returning one `PackageReport` per package that
38
+ contains compiled libraries — extension modules, bundled libraries, or both.
39
+ `directory=None` defaults to the active interpreter's `purelib`.
40
+
41
+ ## Result types
42
+
43
+ All result dataclasses are frozen, slotted, and fully typed.
44
+
45
+ ```python
46
+ @dataclass(frozen=True, slots=True)
47
+ class CPythonABIVerdict:
48
+ intent: bool # filename carries an `abi3` tag
49
+ compliant: bool # all Py*/_Py* symbols are in the stable set
50
+ violations: tuple[str, ...]
51
+
52
+
53
+ @dataclass(frozen=True, slots=True)
54
+ class TorchABIVerdict:
55
+ uses_torch: bool
56
+ stable: bool
57
+ unstable_symbols: tuple[str, ...]
58
+ stable_shim_count: int
59
+
60
+
61
+ @dataclass(frozen=True, slots=True)
62
+ class ExtensionReport:
63
+ path: Path
64
+ cpython: CPythonABIVerdict
65
+ torch: TorchABIVerdict
66
+ error: str | None
67
+
68
+
69
+ @dataclass(frozen=True, slots=True)
70
+ class PackageReport:
71
+ name: str
72
+ root: Path
73
+ extensions: tuple[ExtensionReport, ...] # PyInit_*-bearing .so files
74
+ bundled_libs: tuple[ExtensionReport, ...] # other compiled .so files in the package
75
+ error: str | None
76
+ # @property torch_verdict -> "torch-stable" | "torch-unstable" | "no-torch" | "error"
77
+ # @property cpython_verdict -> "abi3-compliant" | "not-abi3" | "mixed" | "no-extensions"
78
+
79
+
80
+ @dataclass(frozen=True, slots=True)
81
+ class EnvironmentReport:
82
+ site_packages: Path
83
+ packages: tuple[PackageReport, ...]
84
+ ```
85
+
86
+ ## Formatters
87
+
88
+ ```python
89
+ from torch_abi_audit.report import (
90
+ format_json,
91
+ format_package_table,
92
+ format_environment_table,
93
+ )
94
+ ```
95
+
96
+ `format_json` accepts any of the three top-level report types and emits
97
+ indented JSON. The table formatters are package- and environment-specific.
98
+
99
+ ## Example
100
+
101
+ ```python
102
+ from torch_abi_audit import inspect_site_packages
103
+
104
+ env = inspect_site_packages()
105
+ unstable = [p.name for p in env.packages if p.torch_verdict == "torch-unstable"]
106
+ print("Packages using unstable libtorch ABI:", unstable)
107
+ ```
@@ -0,0 +1,200 @@
1
+ ---
2
+ icon: lucide/terminal
3
+ ---
4
+
5
+ # CLI reference
6
+
7
+ ```text
8
+ usage: torch-abi-audit [-h] [--version] [--env | --site-packages PATH]
9
+ [--json] [--all] [-v]
10
+ [TARGET ...]
11
+ ```
12
+
13
+ ## Modes
14
+
15
+ The CLI selects exactly one inspection mode:
16
+
17
+ | Mode | Flag(s) | What it inspects |
18
+ |------|---------|------------------|
19
+ | Targets | `TARGET ...` (positional) | One or more import names or filesystem paths. |
20
+ | Active env | `--env` | Every package in the running interpreter's site-packages. |
21
+ | Specific env | `--site-packages PATH` | Every package under the given site-packages directory. |
22
+
23
+ A `TARGET` can be:
24
+
25
+ - An importable name like `torchvision` — resolved via `importlib.util.find_spec`.
26
+ - A path to an installed package directory (recursive scan).
27
+ - A path to a single `.so` / `.pyd` / `.dylib` file.
28
+
29
+ ## Output
30
+
31
+ By default the CLI prints a human-readable table.
32
+
33
+ - `--json` switches to JSON. With multiple targets the output is wrapped
34
+ in an `EnvironmentReport`-shaped envelope so the JSON shape is consistent.
35
+ - `--verbose` (`-v`) shows the offending symbol list for unstable / non-compliant
36
+ extensions.
37
+ - `--all` makes env-scan output include packages with no torch use (hidden
38
+ by default to keep the table focused on potentially-problematic packages).
39
+
40
+ ## Output examples
41
+
42
+ All three samples below were captured against `torch 2.11.0`,
43
+ `torchaudio 2.11.0`, and `torchcodec 0.11.1` on Linux aarch64.
44
+
45
+ ### Default table — multi-package
46
+
47
+ `torch-abi-audit torchaudio torch torchcodec`:
48
+
49
+ ```text
50
+ Package: torchaudio
51
+ Root: <venv>/lib/python3.11/site-packages/torchaudio
52
+ Torch ABI: STABLE
53
+ CPython ABI: n/a
54
+ Extensions: 0
55
+ Bundled libs: 3
56
+ -- bundled libs --
57
+ [STABLE ] [abi3-tagged-no-capi ] lib/_torchaudio.abi3.so (stable_shim=6, unstable=0)
58
+ [STABLE ] [abi3-tagged-no-capi ] lib/libtorchaudio.abi3.so (stable_shim=80, unstable=0)
59
+ [STABLE ] [abi3-tagged-no-capi ] lib/torchaudio_prefixctc.abi3.so (stable_shim=62, unstable=0)
60
+
61
+ Package: torch
62
+ Root: <venv>/lib/python3.11/site-packages/torch
63
+ Torch ABI: UNSTABLE
64
+ CPython ABI: no
65
+ Extensions: 1
66
+ Bundled libs: 13
67
+ -- extensions --
68
+ [NO-TORCH] [not-abi3 ] _C.cpython-311-aarch64-linux-gnu.so
69
+ -- bundled libs --
70
+ [NO-TORCH] [not-abi3 ] lib/libarm_compute.so
71
+ [NO-TORCH] [not-abi3 ] lib/libarm_compute_graph.so
72
+ [NO-TORCH] [not-abi3 ] lib/libc10.so
73
+ [UNSTABLE] [not-abi3 ] lib/libc10_cuda.so (stable_shim=0, unstable=44)
74
+ [NO-TORCH] [not-abi3 ] lib/libcaffe2_nvrtc.so
75
+ [UNSTABLE] [not-abi3 ] lib/libshm.so (stable_shim=0, unstable=9)
76
+ [NO-TORCH] [not-abi3 ] lib/libtorch.so
77
+ [UNSTABLE] [not-abi3 ] lib/libtorch_cpu.so (stable_shim=0, unstable=327)
78
+ [UNSTABLE] [not-abi3 ] lib/libtorch_cuda.so (stable_shim=0, unstable=2515)
79
+ [UNSTABLE] [not-abi3 ] lib/libtorch_cuda_linalg.so (stable_shim=0, unstable=143)
80
+ [NO-TORCH] [not-abi3 ] lib/libtorch_global_deps.so
81
+ [UNSTABLE] [not-abi3 ] lib/libtorch_nvshmem.so (stable_shim=0, unstable=66)
82
+ [UNSTABLE] [uses-private-api ] lib/libtorch_python.so (stable_shim=0, unstable=5085)
83
+
84
+ Package: torchcodec
85
+ Root: <venv>/lib/python3.11/site-packages/torchcodec
86
+ Torch ABI: UNSTABLE
87
+ CPython ABI: no
88
+ Extensions: 5
89
+ Bundled libs: 10
90
+ -- extensions --
91
+ [NO-TORCH] [uses-private-api ] libtorchcodec_pybind_ops4.so
92
+ [NO-TORCH] [uses-private-api ] libtorchcodec_pybind_ops5.so
93
+ [NO-TORCH] [uses-private-api ] libtorchcodec_pybind_ops6.so
94
+ [NO-TORCH] [uses-private-api ] libtorchcodec_pybind_ops7.so
95
+ [NO-TORCH] [uses-private-api ] libtorchcodec_pybind_ops8.so
96
+ -- bundled libs --
97
+ [UNSTABLE] [not-abi3 ] libtorchcodec_core4.so (stable_shim=64, unstable=4)
98
+ [UNSTABLE] [not-abi3 ] libtorchcodec_core5.so (stable_shim=64, unstable=4)
99
+ [UNSTABLE] [not-abi3 ] libtorchcodec_core6.so (stable_shim=64, unstable=4)
100
+ [UNSTABLE] [not-abi3 ] libtorchcodec_core7.so (stable_shim=64, unstable=4)
101
+ [UNSTABLE] [not-abi3 ] libtorchcodec_core8.so (stable_shim=64, unstable=4)
102
+ [STABLE ] [uses-private-api ] libtorchcodec_custom_ops4.so (stable_shim=68, unstable=0)
103
+ [STABLE ] [uses-private-api ] libtorchcodec_custom_ops5.so (stable_shim=68, unstable=0)
104
+ [STABLE ] [uses-private-api ] libtorchcodec_custom_ops6.so (stable_shim=68, unstable=0)
105
+ [STABLE ] [uses-private-api ] libtorchcodec_custom_ops7.so (stable_shim=68, unstable=0)
106
+ [STABLE ] [uses-private-api ] libtorchcodec_custom_ops8.so (stable_shim=68, unstable=0)
107
+ ```
108
+
109
+ The per-row labels:
110
+
111
+ | Torch | CPython | Meaning |
112
+ |---|---|---|
113
+ | `STABLE` / `UNSTABLE` / `NO-TORCH` | — | Per-library torch verdict. |
114
+ | — | `abi3-ok` | Filename tagged abi3 *and* every Py\* symbol is in the limited API. |
115
+ | — | `abi3-tagged-violations` | Filename tagged abi3 but the file references private CPython symbols. |
116
+ | — | `abi3-tagged-no-capi` | Filename tagged abi3, file has no CPython API references at all (e.g. a STABLE_TORCH_LIBRARY plugin). |
117
+ | — | `uses-private-api` | Not abi3-tagged, references private CPython symbols. |
118
+ | — | `not-abi3` | Not abi3-tagged, no Py\* references. |
119
+
120
+ ### Verbose excerpt — `--verbose` surfaces offending symbols
121
+
122
+ `torch-abi-audit torch -v` (first 28 lines):
123
+
124
+ ```text
125
+ Package: torch
126
+ Root: <venv>/lib/python3.11/site-packages/torch
127
+ Torch ABI: UNSTABLE
128
+ CPython ABI: no
129
+ Extensions: 1
130
+ Bundled libs: 13
131
+ -- extensions --
132
+ [NO-TORCH] [not-abi3 ] _C.cpython-311-aarch64-linux-gnu.so
133
+ -- bundled libs --
134
+ [NO-TORCH] [not-abi3 ] lib/libarm_compute.so
135
+ [NO-TORCH] [not-abi3 ] lib/libarm_compute_graph.so
136
+ [NO-TORCH] [not-abi3 ] lib/libc10.so
137
+ [UNSTABLE] [not-abi3 ] lib/libc10_cuda.so (stable_shim=0, unstable=44)
138
+ torch unstable: c10::SetAllocator(c10::DeviceType, c10::Allocator*, unsigned char)
139
+ torch unstable: c10::WarningUtils::get_warnAlways()
140
+ torch unstable: c10::MessageLogger::stream[abi:cxx11]()
141
+ torch unstable: c10::MessageLogger::MessageLogger(c10::SourceLocation, int, bool)
142
+ torch unstable: c10::MessageLogger::~MessageLogger()
143
+ torch unstable: c10::DeviceAllocator::DeviceAllocator()
144
+ torch unstable: c10::DeviceAllocator::~DeviceAllocator()
145
+ torch unstable: c10::SmallVectorBase<unsigned int>::grow_pod(void const*, unsigned long, unsigned long)
146
+ torch unstable: c10::CachingAllocator::AcceleratorAllocatorConfig::roundup_power2_divisions(unsigned long)
147
+ torch unstable: c10::CachingAllocator::AcceleratorAllocatorConfig::instance()
148
+ torch unstable: c10::reportMemoryUsageToProfiler(void*, long, unsigned long, unsigned long, c10::Device)
149
+ torch unstable: c10::reportOutOfMemoryToProfiler(long, unsigned long, unsigned long, c10::Device)
150
+ torch unstable: c10::ApproximateClockToUnixTimeConverter::makeConverter()
151
+ torch unstable: c10::ApproximateClockToUnixTimeConverter::ApproximateClockToUnixTimeConverter()
152
+ torch unstable: c10::impl::DeviceGuardImplRegistrar::DeviceGuardImplRegistrar(...)
153
+ ... 29 more
154
+ ```
155
+
156
+ The first 15 unstable symbols per library are listed inline; anything past
157
+ that becomes a `... N more` summary so the table doesn't blow up.
158
+
159
+ ### JSON shape — `--json`
160
+
161
+ `torch-abi-audit torchaudio --json`:
162
+
163
+ ```json
164
+ {
165
+ "name": "torchaudio",
166
+ "root": "<venv>/lib/python3.11/site-packages/torchaudio",
167
+ "extensions": [],
168
+ "bundled_libs": [
169
+ {
170
+ "path": "<venv>/.../torchaudio/lib/_torchaudio.abi3.so",
171
+ "cpython": { "intent": true, "compliant": false, "violations": [] },
172
+ "torch": {
173
+ "uses_torch": true,
174
+ "stable": true,
175
+ "unstable_symbols": [],
176
+ "stable_shim_count": 6
177
+ },
178
+ "error": null
179
+ },
180
+ { "path": "<venv>/.../torchaudio/lib/libtorchaudio.abi3.so", "...": "..." },
181
+ { "path": "<venv>/.../torchaudio/lib/torchaudio_prefixctc.abi3.so", "...": "..." }
182
+ ],
183
+ "error": null
184
+ }
185
+ ```
186
+
187
+ The verdict roll-ups (`torch_verdict`, `cpython_verdict`) are `@property`
188
+ on `PackageReport`, so they're computed on access and don't appear in the
189
+ JSON dump. Compute them yourself by looking at the `extensions` and
190
+ `bundled_libs` lists, or use the Python API.
191
+
192
+ ## Exit codes
193
+
194
+ The CLI reports verdicts via stdout / JSON; it returns:
195
+
196
+ - `0` on inspection success regardless of verdict.
197
+ - `2` on operational errors (missing `nm`, unknown import name, unreadable path).
198
+
199
+ This makes the tool safe to run interactively without `set -e` surprises.
200
+ For CI gating, parse the JSON output.