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.
- torch_abi_audit-0.0.1/.gitignore +34 -0
- torch_abi_audit-0.0.1/LICENSE +21 -0
- torch_abi_audit-0.0.1/PKG-INFO +159 -0
- torch_abi_audit-0.0.1/README.md +130 -0
- torch_abi_audit-0.0.1/docs/docs/api.md +107 -0
- torch_abi_audit-0.0.1/docs/docs/cli.md +200 -0
- torch_abi_audit-0.0.1/docs/docs/index.md +99 -0
- torch_abi_audit-0.0.1/docs/zensical.toml +18 -0
- torch_abi_audit-0.0.1/pyproject.toml +76 -0
- torch_abi_audit-0.0.1/scripts/check_real_world.py +200 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/__init__.py +25 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/_version.py +24 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/cli.py +115 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/cpython_abi.py +76 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/demangle.py +26 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/inspect.py +144 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/py.typed +0 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/report.py +228 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/symbols.py +122 -0
- torch_abi_audit-0.0.1/src/torch_abi_audit/torch_abi.py +80 -0
- torch_abi_audit-0.0.1/tests/conftest.py +148 -0
- torch_abi_audit-0.0.1/tests/fixtures/src/cpython_stable.c +22 -0
- torch_abi_audit-0.0.1/tests/fixtures/src/cpython_unstable.c +25 -0
- torch_abi_audit-0.0.1/tests/fixtures/src/torch_stable.cpp +6 -0
- torch_abi_audit-0.0.1/tests/fixtures/src/torch_unstable.cpp +7 -0
- torch_abi_audit-0.0.1/tests/test_cli.py +60 -0
- torch_abi_audit-0.0.1/tests/test_cpython_abi.py +46 -0
- torch_abi_audit-0.0.1/tests/test_demangle.py +30 -0
- torch_abi_audit-0.0.1/tests/test_inspect.py +84 -0
- torch_abi_audit-0.0.1/tests/test_report.py +39 -0
- torch_abi_audit-0.0.1/tests/test_symbols.py +51 -0
- 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.
|