dcccpy 0.1.2__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.
- dcccpy-0.1.2/MANIFEST.in +2 -0
- dcccpy-0.1.2/PKG-INFO +152 -0
- dcccpy-0.1.2/README.md +131 -0
- dcccpy-0.1.2/pyproject.toml +49 -0
- dcccpy-0.1.2/setup.cfg +4 -0
- dcccpy-0.1.2/setup.py +34 -0
- dcccpy-0.1.2/src/dcccpy/__init__.py +42 -0
- dcccpy-0.1.2/src/dcccpy/cli.py +21 -0
- dcccpy-0.1.2/src/dcccpy/core.py +361 -0
- dcccpy-0.1.2/src/dcccpy/py.typed +1 -0
- dcccpy-0.1.2/src/dcccpy/runtime.py +237 -0
- dcccpy-0.1.2/src/dcccpy.egg-info/PKG-INFO +152 -0
- dcccpy-0.1.2/src/dcccpy.egg-info/SOURCES.txt +17 -0
- dcccpy-0.1.2/src/dcccpy.egg-info/dependency_links.txt +1 -0
- dcccpy-0.1.2/src/dcccpy.egg-info/entry_points.txt +2 -0
- dcccpy-0.1.2/src/dcccpy.egg-info/requires.txt +4 -0
- dcccpy-0.1.2/src/dcccpy.egg-info/top_level.txt +1 -0
- dcccpy-0.1.2/tests/test_core.py +171 -0
- dcccpy-0.1.2/tests/test_testpypi_centiloid.py +185 -0
dcccpy-0.1.2/MANIFEST.in
ADDED
dcccpy-0.1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dcccpy
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Python wrapper for the DCCCcore PET biomarker command-line tool
|
|
5
|
+
Author: DCCCSlicer contributors
|
|
6
|
+
License-Expression: CC-BY-NC-ND-4.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/tctco/DCCCSlicer
|
|
8
|
+
Project-URL: Repository, https://github.com/tctco/DCCCSlicer
|
|
9
|
+
Project-URL: Issues, https://github.com/tctco/DCCCSlicer/issues
|
|
10
|
+
Keywords: PET,neuroimaging,centiloid,DCCC,DCCCSlicer
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: nibabel>=5
|
|
19
|
+
Provides-Extra: linux-runtime
|
|
20
|
+
Requires-Dist: dcccpy-linux-runtime==0.1.0; extra == "linux-runtime"
|
|
21
|
+
|
|
22
|
+
# dcccpy
|
|
23
|
+
|
|
24
|
+
`dcccpy` is a Python wrapper for the `DCCCcore` command-line tool from
|
|
25
|
+
DCCCSlicer. It keeps the native C++ core as the execution engine and provides a
|
|
26
|
+
small Python API for running common PET biomarker workflows.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
The default package is slim:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install dcccpy
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The first call downloads the matching `DCCCcore` release package into the local
|
|
37
|
+
user cache if no native runtime is otherwise available. The slim package also
|
|
38
|
+
installs `nibabel` for image loading and nibabel-style image inputs.
|
|
39
|
+
|
|
40
|
+
For Linux users who prefer `pip install` to include the native runtime and avoid
|
|
41
|
+
first-run download:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install "dcccpy[linux-runtime]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Python API
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
import dcccpy
|
|
51
|
+
|
|
52
|
+
result = dcccpy.centiloid("amyloid_pet.nii", skip_normalization=True)
|
|
53
|
+
print(result.metrics)
|
|
54
|
+
print(result.output)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The `output` argument is optional for single-image Python calls. When omitted,
|
|
58
|
+
`dcccpy` creates a temporary output NIfTI path and returns it in the result.
|
|
59
|
+
Relative input and output paths are resolved from the current Python working
|
|
60
|
+
directory before `DCCCcore` is invoked.
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
result = dcccpy.centiloid("amyloid_pet.nii")
|
|
64
|
+
print(result.output) # temporary output path
|
|
65
|
+
print(result.metrics.get("fbp"))
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The wrapper accepts nibabel-style image objects with `to_filename()`:
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
import nibabel as nib
|
|
72
|
+
import dcccpy
|
|
73
|
+
|
|
74
|
+
image = nib.load("amyloid_pet.nii.gz")
|
|
75
|
+
result = dcccpy.centiloid(image, skip_normalization=True)
|
|
76
|
+
output_image = result.load_output()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Common helpers mirror `DCCCcore` subcommands:
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
dcccpy.centiloid("amyloid.nii", suvr=True)
|
|
83
|
+
dcccpy.centaurz("tau.nii", report_detailed_regions=True)
|
|
84
|
+
dcccpy.fillstates("fdg.nii", tracer="fdg")
|
|
85
|
+
dcccpy.normalize("pet.nii", iterative=True)
|
|
86
|
+
dcccpy.run(["centiloid", "--input", "a.nii", "--output", "b.nii"])
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Each helper returns `DCCCResult` with:
|
|
90
|
+
|
|
91
|
+
- `returncode`
|
|
92
|
+
- `stdout` / `stderr`
|
|
93
|
+
- `output`
|
|
94
|
+
- `metrics`, parsed from numeric lines in stdout
|
|
95
|
+
- `load_output()`, which loads the output with nibabel
|
|
96
|
+
|
|
97
|
+
## Command Line
|
|
98
|
+
|
|
99
|
+
`dcccpy` also forwards raw arguments to `DCCCcore`:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
dcccpy --help
|
|
103
|
+
dcccpy centiloid --input amyloid_pet.nii --output result.nii
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Runtime lookup
|
|
107
|
+
|
|
108
|
+
At runtime, `dcccpy` looks for `DCCCcore` in this order:
|
|
109
|
+
|
|
110
|
+
1. `DCCCPY_DCCCCORE` environment variable.
|
|
111
|
+
2. A vendored binary inside the installed `dcccpy` wheel.
|
|
112
|
+
3. A binary from `dcccpy-linux-runtime`, installed by `dcccpy[linux-runtime]`.
|
|
113
|
+
4. The local dcccpy cache populated by automatic download.
|
|
114
|
+
5. `DCCCcore` on `PATH`.
|
|
115
|
+
6. Automatic download from GitHub releases, unless disabled.
|
|
116
|
+
|
|
117
|
+
Useful environment variables:
|
|
118
|
+
|
|
119
|
+
- `DCCCPY_DCCCCORE`: exact path to a `DCCCcore` executable.
|
|
120
|
+
- `DCCCPY_AUTO_DOWNLOAD=0`: disable first-run automatic download.
|
|
121
|
+
- `DCCCPY_CACHE_DIR`: override the runtime cache directory.
|
|
122
|
+
- `DCCCPY_RELEASE_REPO`: override the GitHub release repository.
|
|
123
|
+
- `DCCCPY_DCCCCORE_URL`: override the release asset URL.
|
|
124
|
+
|
|
125
|
+
## Runtime Packaging
|
|
126
|
+
|
|
127
|
+
Release wheels should vendor the matching `DCCCcore` runtime tree before build:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
python scripts/vendor_dccccore.py --version 4.2.3 --release-platform ubuntu-latest-x64
|
|
131
|
+
python -m build --wheel
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The source tree intentionally does not commit the vendored runtime because it
|
|
135
|
+
contains large ONNX model and NIfTI runtime assets.
|
|
136
|
+
|
|
137
|
+
The preferred distribution layout is:
|
|
138
|
+
|
|
139
|
+
- `dcccpy`: slim Python package with nibabel; downloads runtime on first use.
|
|
140
|
+
- `dcccpy-linux-runtime`: optional Linux runtime wheel.
|
|
141
|
+
- `dcccpy[linux-runtime]`: installs both packages.
|
|
142
|
+
|
|
143
|
+
## Packaging note
|
|
144
|
+
|
|
145
|
+
The Linux `DCCCcore-4.2.3-ubuntu-latest-x64.zip` release asset contains the
|
|
146
|
+
native executable, `libtbb`, ONNX registration/decoupling models, configuration
|
|
147
|
+
files, and NIfTI template/mask assets. That full runtime is the correct unit to
|
|
148
|
+
vendor for a wheel that works immediately after `pip install dcccpy`.
|
|
149
|
+
|
|
150
|
+
The full Linux runtime wheel is about 167 MB for version 4.2.3, so a public
|
|
151
|
+
PyPI upload may require a file size limit increase unless a future release
|
|
152
|
+
splits a smaller runtime profile from the full `DCCCcore` package.
|
dcccpy-0.1.2/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# dcccpy
|
|
2
|
+
|
|
3
|
+
`dcccpy` is a Python wrapper for the `DCCCcore` command-line tool from
|
|
4
|
+
DCCCSlicer. It keeps the native C++ core as the execution engine and provides a
|
|
5
|
+
small Python API for running common PET biomarker workflows.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
The default package is slim:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install dcccpy
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The first call downloads the matching `DCCCcore` release package into the local
|
|
16
|
+
user cache if no native runtime is otherwise available. The slim package also
|
|
17
|
+
installs `nibabel` for image loading and nibabel-style image inputs.
|
|
18
|
+
|
|
19
|
+
For Linux users who prefer `pip install` to include the native runtime and avoid
|
|
20
|
+
first-run download:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install "dcccpy[linux-runtime]"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Python API
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
import dcccpy
|
|
30
|
+
|
|
31
|
+
result = dcccpy.centiloid("amyloid_pet.nii", skip_normalization=True)
|
|
32
|
+
print(result.metrics)
|
|
33
|
+
print(result.output)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The `output` argument is optional for single-image Python calls. When omitted,
|
|
37
|
+
`dcccpy` creates a temporary output NIfTI path and returns it in the result.
|
|
38
|
+
Relative input and output paths are resolved from the current Python working
|
|
39
|
+
directory before `DCCCcore` is invoked.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
result = dcccpy.centiloid("amyloid_pet.nii")
|
|
43
|
+
print(result.output) # temporary output path
|
|
44
|
+
print(result.metrics.get("fbp"))
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The wrapper accepts nibabel-style image objects with `to_filename()`:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
import nibabel as nib
|
|
51
|
+
import dcccpy
|
|
52
|
+
|
|
53
|
+
image = nib.load("amyloid_pet.nii.gz")
|
|
54
|
+
result = dcccpy.centiloid(image, skip_normalization=True)
|
|
55
|
+
output_image = result.load_output()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Common helpers mirror `DCCCcore` subcommands:
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
dcccpy.centiloid("amyloid.nii", suvr=True)
|
|
62
|
+
dcccpy.centaurz("tau.nii", report_detailed_regions=True)
|
|
63
|
+
dcccpy.fillstates("fdg.nii", tracer="fdg")
|
|
64
|
+
dcccpy.normalize("pet.nii", iterative=True)
|
|
65
|
+
dcccpy.run(["centiloid", "--input", "a.nii", "--output", "b.nii"])
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Each helper returns `DCCCResult` with:
|
|
69
|
+
|
|
70
|
+
- `returncode`
|
|
71
|
+
- `stdout` / `stderr`
|
|
72
|
+
- `output`
|
|
73
|
+
- `metrics`, parsed from numeric lines in stdout
|
|
74
|
+
- `load_output()`, which loads the output with nibabel
|
|
75
|
+
|
|
76
|
+
## Command Line
|
|
77
|
+
|
|
78
|
+
`dcccpy` also forwards raw arguments to `DCCCcore`:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
dcccpy --help
|
|
82
|
+
dcccpy centiloid --input amyloid_pet.nii --output result.nii
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Runtime lookup
|
|
86
|
+
|
|
87
|
+
At runtime, `dcccpy` looks for `DCCCcore` in this order:
|
|
88
|
+
|
|
89
|
+
1. `DCCCPY_DCCCCORE` environment variable.
|
|
90
|
+
2. A vendored binary inside the installed `dcccpy` wheel.
|
|
91
|
+
3. A binary from `dcccpy-linux-runtime`, installed by `dcccpy[linux-runtime]`.
|
|
92
|
+
4. The local dcccpy cache populated by automatic download.
|
|
93
|
+
5. `DCCCcore` on `PATH`.
|
|
94
|
+
6. Automatic download from GitHub releases, unless disabled.
|
|
95
|
+
|
|
96
|
+
Useful environment variables:
|
|
97
|
+
|
|
98
|
+
- `DCCCPY_DCCCCORE`: exact path to a `DCCCcore` executable.
|
|
99
|
+
- `DCCCPY_AUTO_DOWNLOAD=0`: disable first-run automatic download.
|
|
100
|
+
- `DCCCPY_CACHE_DIR`: override the runtime cache directory.
|
|
101
|
+
- `DCCCPY_RELEASE_REPO`: override the GitHub release repository.
|
|
102
|
+
- `DCCCPY_DCCCCORE_URL`: override the release asset URL.
|
|
103
|
+
|
|
104
|
+
## Runtime Packaging
|
|
105
|
+
|
|
106
|
+
Release wheels should vendor the matching `DCCCcore` runtime tree before build:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
python scripts/vendor_dccccore.py --version 4.2.3 --release-platform ubuntu-latest-x64
|
|
110
|
+
python -m build --wheel
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The source tree intentionally does not commit the vendored runtime because it
|
|
114
|
+
contains large ONNX model and NIfTI runtime assets.
|
|
115
|
+
|
|
116
|
+
The preferred distribution layout is:
|
|
117
|
+
|
|
118
|
+
- `dcccpy`: slim Python package with nibabel; downloads runtime on first use.
|
|
119
|
+
- `dcccpy-linux-runtime`: optional Linux runtime wheel.
|
|
120
|
+
- `dcccpy[linux-runtime]`: installs both packages.
|
|
121
|
+
|
|
122
|
+
## Packaging note
|
|
123
|
+
|
|
124
|
+
The Linux `DCCCcore-4.2.3-ubuntu-latest-x64.zip` release asset contains the
|
|
125
|
+
native executable, `libtbb`, ONNX registration/decoupling models, configuration
|
|
126
|
+
files, and NIfTI template/mask assets. That full runtime is the correct unit to
|
|
127
|
+
vendor for a wheel that works immediately after `pip install dcccpy`.
|
|
128
|
+
|
|
129
|
+
The full Linux runtime wheel is about 167 MB for version 4.2.3, so a public
|
|
130
|
+
PyPI upload may require a file size limit increase unless a future release
|
|
131
|
+
splits a smaller runtime profile from the full `DCCCcore` package.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=69", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dcccpy"
|
|
7
|
+
version = "0.1.2"
|
|
8
|
+
description = "Python wrapper for the DCCCcore PET biomarker command-line tool"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = "CC-BY-NC-ND-4.0"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "DCCCSlicer contributors" }
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"nibabel>=5",
|
|
17
|
+
]
|
|
18
|
+
keywords = ["PET", "neuroimaging", "centiloid", "DCCC", "DCCCSlicer"]
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 3 - Alpha",
|
|
21
|
+
"Intended Audience :: Science/Research",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
+
"Topic :: Scientific/Engineering :: Medical Science Apps.",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/tctco/DCCCSlicer"
|
|
29
|
+
Repository = "https://github.com/tctco/DCCCSlicer"
|
|
30
|
+
Issues = "https://github.com/tctco/DCCCSlicer/issues"
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
linux-runtime = ["dcccpy-linux-runtime==0.1.0"]
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
dcccpy = "dcccpy.cli:main"
|
|
37
|
+
|
|
38
|
+
[tool.setuptools]
|
|
39
|
+
package-dir = {"" = "src"}
|
|
40
|
+
include-package-data = true
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.package-data]
|
|
46
|
+
dcccpy = ["py.typed", "vendor/**/*"]
|
|
47
|
+
|
|
48
|
+
[tool.pytest.ini_options]
|
|
49
|
+
testpaths = ["tests"]
|
dcccpy-0.1.2/setup.cfg
ADDED
dcccpy-0.1.2/setup.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from setuptools import setup
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
from wheel.bdist_wheel import bdist_wheel
|
|
8
|
+
except Exception: # pragma: no cover - wheel is provided by build-system.requires
|
|
9
|
+
bdist_wheel = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if bdist_wheel is not None:
|
|
13
|
+
def has_vendored_runtime() -> bool:
|
|
14
|
+
vendor_root = Path(__file__).resolve().parent / "src" / "dcccpy" / "vendor" / "dccccore"
|
|
15
|
+
return vendor_root.exists() and any(vendor_root.rglob("DCCCcore*"))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class BinaryWheel(bdist_wheel):
|
|
19
|
+
"""Mark wheels as platform-specific when vendored DCCCcore is present."""
|
|
20
|
+
|
|
21
|
+
def finalize_options(self):
|
|
22
|
+
super().finalize_options()
|
|
23
|
+
if has_vendored_runtime():
|
|
24
|
+
self.root_is_pure = False
|
|
25
|
+
|
|
26
|
+
def get_tag(self):
|
|
27
|
+
if not has_vendored_runtime():
|
|
28
|
+
return super().get_tag()
|
|
29
|
+
_, _, platform_tag = super().get_tag()
|
|
30
|
+
return "py3", "none", platform_tag
|
|
31
|
+
|
|
32
|
+
setup(cmdclass={"bdist_wheel": BinaryWheel})
|
|
33
|
+
else:
|
|
34
|
+
setup()
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Python wrapper for the native DCCCcore executable."""
|
|
2
|
+
|
|
3
|
+
from .core import (
|
|
4
|
+
DCCCResult,
|
|
5
|
+
adad,
|
|
6
|
+
abetaindex,
|
|
7
|
+
abetaload,
|
|
8
|
+
adni_pet_core,
|
|
9
|
+
centaur,
|
|
10
|
+
centaurz,
|
|
11
|
+
centiloid,
|
|
12
|
+
dccccore_path,
|
|
13
|
+
fillstates,
|
|
14
|
+
normalize,
|
|
15
|
+
parse_metrics,
|
|
16
|
+
rigid,
|
|
17
|
+
run,
|
|
18
|
+
suvr,
|
|
19
|
+
)
|
|
20
|
+
from .runtime import DCCCCORE_VERSION, DCCCcoreDownloadError, DCCCcoreNotFoundError, download_dccccore
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"DCCCResult",
|
|
24
|
+
"DCCCCORE_VERSION",
|
|
25
|
+
"DCCCcoreDownloadError",
|
|
26
|
+
"DCCCcoreNotFoundError",
|
|
27
|
+
"adad",
|
|
28
|
+
"abetaindex",
|
|
29
|
+
"abetaload",
|
|
30
|
+
"adni_pet_core",
|
|
31
|
+
"centaur",
|
|
32
|
+
"centaurz",
|
|
33
|
+
"centiloid",
|
|
34
|
+
"dccccore_path",
|
|
35
|
+
"download_dccccore",
|
|
36
|
+
"fillstates",
|
|
37
|
+
"normalize",
|
|
38
|
+
"parse_metrics",
|
|
39
|
+
"rigid",
|
|
40
|
+
"run",
|
|
41
|
+
"suvr",
|
|
42
|
+
]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from .core import run
|
|
6
|
+
from .runtime import DCCCcoreDownloadError, DCCCcoreNotFoundError
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main(argv: list[str] | None = None) -> int:
|
|
10
|
+
args = list(sys.argv[1:] if argv is None else argv)
|
|
11
|
+
try:
|
|
12
|
+
result = run(args, check=False)
|
|
13
|
+
except (DCCCcoreDownloadError, DCCCcoreNotFoundError) as exc:
|
|
14
|
+
print(str(exc), file=sys.stderr)
|
|
15
|
+
return 127
|
|
16
|
+
|
|
17
|
+
if result.stdout:
|
|
18
|
+
print(result.stdout, end="")
|
|
19
|
+
if result.stderr:
|
|
20
|
+
print(result.stderr, file=sys.stderr, end="")
|
|
21
|
+
return result.returncode
|