fancy-subprocess 2.0__tar.gz → 2.3__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.
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/.editorconfig +4 -2
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/PKG-INFO +16 -15
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/README.md +11 -10
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/_run_core.py +7 -3
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/_run_param.py +1 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/_utils.py +5 -7
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/grab_output.py +1 -1
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/pyproject.toml +7 -7
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/uv.lock +22 -10
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/.gitignore +0 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/LICENSE +0 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/__init__.py +0 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/_compat.py +0 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/_print.py +0 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/_reconfigure.py +0 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/_run_wrappers.py +0 -0
- {fancy_subprocess-2.0 → fancy_subprocess-2.3}/fancy_subprocess/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
|
-
Name:
|
|
3
|
-
Version: 2.
|
|
2
|
+
Name: fancy-subprocess
|
|
3
|
+
Version: 2.3
|
|
4
4
|
Summary: subprocess.run() with formatted output, detailed error messages and retry capabilities
|
|
5
5
|
Project-URL: Homepage, https://github.com/petamas/python-fancy-subprocess
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/petamas/python-fancy-subprocess/issues
|
|
@@ -18,9 +18,9 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
20
|
Requires-Python: >=3.10
|
|
21
|
-
Requires-Dist: ntstatus<2
|
|
22
|
-
Requires-Dist: oslex<2
|
|
23
|
-
Requires-Dist: pathext<2,>=1.
|
|
21
|
+
Requires-Dist: ntstatus<3,>=2.0
|
|
22
|
+
Requires-Dist: oslex<2,>=0.1.3
|
|
23
|
+
Requires-Dist: pathext<2,>=1.5
|
|
24
24
|
Requires-Dist: typeguard<5,>=4.4.2
|
|
25
25
|
Requires-Dist: typing-extensions<5,>=4.14
|
|
26
26
|
Description-Content-Type: text/markdown
|
|
@@ -40,19 +40,19 @@ Key differences compared to `subprocess.run()`:
|
|
|
40
40
|
- The output of the command is always captured, but it is also immediately printed using `print_output`.
|
|
41
41
|
- The exit code of the command is checked, and an exception is raised on failure, like `subprocess.run(check=True)`, but the list of exit codes treated as success is customizable, and the raised exception is `RunError` instead of `CalledProcessError`.
|
|
42
42
|
- `OSError` is never raised, it gets converted to `RunError`.
|
|
43
|
-
- `RunResult` is returned instead of `CompletedProcess` on success
|
|
43
|
+
- `RunResult` is returned instead of `CompletedProcess` on success.
|
|
44
44
|
|
|
45
45
|
Arguments (all of them except `cmd` are optional):
|
|
46
46
|
- `cmd: Sequence[str | Path]` - Command to run. See `subprocess.run()`'s documentation for the interpretation of `cmd[0]`. It is recommended to use `fancy_subprocess.which()` to produce `cmd[0]`.
|
|
47
47
|
- `print_message: Callable[[str], None]` - Function used to print informational messages. If unspecified or set to `None`, defaults to `fancy_subprocess.default_print`. Use `message_quiet=True` to disable printing informational messages.
|
|
48
|
-
|
|
48
|
+
- The type of this argument is also aliased as `fancy_subprocess.PrintFunction`.
|
|
49
49
|
- `print_output: Callable[[str], None]` - Function used to print a line of the output of the command. If unspecified or set to `None`, defaults to `fancy_subprocess.default_print`. Use `output_quiet=True` to disable printing the command's output.
|
|
50
|
-
|
|
50
|
+
- The type of this argument is also aliased as `fancy_subprocess.PrintFunction`.
|
|
51
51
|
- `message_quiet: bool` - If `True`, `print_message` is ignored, and no informational messages are printed. If unspecified or set to `None`, defaults to `False`.
|
|
52
52
|
- `output_quiet: bool` - If `True`, `print_output` is ignored, and the command's output it not printed. If unspecified or set to `None`, defaults to `False`. Note that this parameter also affects the default value of `description`.
|
|
53
53
|
- `description: str` - Description printed before running the command. If unspecified or set to `None`, defaults to `Running command: ...` when `output_quiet` is `False`, and `Running command (output silenced): ...` when `output_quiet` is `True`.
|
|
54
54
|
- `success: Sequence[int] | AnyExitCode` - List of exit codes that should be considered successful. If set to `fancy_subprocess.ANY_EXIT_CODE`, then all exit codes are considered successful. If unspecified or set to `None`, defaults to `[0]`. Note that 0 is not automatically included in the list of successful exit codes, so if a list without 0 is specified, then the function will consider 0 a failure.
|
|
55
|
-
|
|
55
|
+
- The type of this argument is also aliased as `fancy_subprocess.Success`.
|
|
56
56
|
- `flush_before_subprocess: bool` - If `True`, flushes both the standard output and error streams before running the command. If unspecified or set to `None`, defaults to `True`.
|
|
57
57
|
- `trim_output_lines: bool` - If `True`, remove trailing whitespace from the lines of the output of the command before calling `print_output` and adding them to the `output` field of `RunResult`. If unspecified or set to `None`, defaults to `True`.
|
|
58
58
|
- `max_output_size: int` - Maximum number of characters to be recorded in the `output` field of `RunResult`. If the command produces more than `max_output_size` characters, only the last `max_output_size` will be recorded. If unspecified or set to `None`, defaults to 10,000,000.
|
|
@@ -60,10 +60,11 @@ Arguments (all of them except `cmd` are optional):
|
|
|
60
60
|
- `retry_initial_sleep_seconds: float` - Number of seconds to wait before retrying for the first time. If unspecified or set to `None`, defaults to 10.
|
|
61
61
|
- `retry_backoff: float` - Factor used to increase wait times before subsequent retries. If unspecified or set to `None`, defaults to 2.
|
|
62
62
|
- `env_overrides: Mapping[str, str]` - Dictionary used to set environment variables. Note that unline the `env` argument of `subprocess.run()`, `env_overrides` does not need to contain all environment variables, only the ones you want to add/modify compared to os.environ. If unspecified or set to `None`, defaults to empty dictionary, i.e. no change to the environment.
|
|
63
|
-
|
|
63
|
+
- The type of this argument is also aliased as `fancy_subprocess.EnvOverrides`.
|
|
64
64
|
- `cwd: str | Path` - If not `None`, change current working directory to `cwd` before running the command.
|
|
65
65
|
- `encoding: str` - This encoding will be used to open stdout and stderr of the command. If unspecified or set to `None`, see default behaviour in `io.TextIOWrapper`'s documentation.
|
|
66
|
-
- `errors: str` - This specifies how text decoding errors will be handled. See
|
|
66
|
+
- `errors: str` - This specifies how text decoding errors will be handled. (See possible options in `io.TextIOWrapper`'s documentation.) If unspecified or set to `None`, defaults to `replace`. Note that this differs from `io.TextIOWrapper`'s default behaviour, which is to use `strict`.
|
|
67
|
+
- `replace_fffd_with_question_mark: bool` - Replace Unicode Replacement Character U+FFFD (`�`, usually introduced by `errors='replace'`) with ASCII question mark (`?`) in lines of the output of the command before calling `print_output` and adding them to the `output` field of `RunResult`. If unspecified or set to `None`, defaults to `True`.
|
|
67
68
|
|
|
68
69
|
### Return value: `fancy_subprocess.RunResult`
|
|
69
70
|
|
|
@@ -119,7 +120,7 @@ import fancy_subprocess
|
|
|
119
120
|
from typing import Unpack
|
|
120
121
|
|
|
121
122
|
def grab_output(cmd: list[str], **kwargs: Unpack[fancy_subprocess.RunParams]) -> str:
|
|
122
|
-
|
|
123
|
+
# Raises ValueError if there are unknown parameters in kwargs or if a keyword argument's type is incorrect
|
|
123
124
|
fancy_subprocess.check_run_params(**kwargs)
|
|
124
125
|
|
|
125
126
|
# Make a copy of keyword arguments to be edited
|
|
@@ -127,7 +128,7 @@ def grab_output(cmd: list[str], **kwargs: Unpack[fancy_subprocess.RunParams]) ->
|
|
|
127
128
|
# Make sure nothing's printed, raise ValueError if caller tries to specify "output_quiet" or "message_quiet"
|
|
128
129
|
fancy_subprocess.force_run_params(forwarded_args, message_quiet=True, output_quiet=True)
|
|
129
130
|
# Handle encoding/decoding errors by replacing them with placeholder character by default, but allow callers to still customize behaviour
|
|
130
|
-
fancy_subprocess.change_default_run_params(forwarded_args, errors='
|
|
131
|
+
fancy_subprocess.change_default_run_params(forwarded_args, errors='backslashreplace')
|
|
131
132
|
|
|
132
133
|
# Run command, raise fancy_subprocess.RunError on failure
|
|
133
134
|
result = fancy_subprocess.run(cmd, **forwarded_args)
|
|
@@ -136,7 +137,7 @@ def grab_output(cmd: list[str], **kwargs: Unpack[fancy_subprocess.RunParams]) ->
|
|
|
136
137
|
return result.output
|
|
137
138
|
```
|
|
138
139
|
|
|
139
|
-
The `grab_output()` function supports all `fancy_subprocess.run()` arguments (eg. `retry`), except for `message_quiet` and `output_quiet`. If `errors` is unspecified or set to `None`, it uses `errors='
|
|
140
|
+
The `grab_output()` function supports all `fancy_subprocess.run()` arguments (eg. `retry`), except for `message_quiet` and `output_quiet`. If `errors` is unspecified or set to `None`, it uses `errors='backslashreplace'` instead of the default `errors='replace'` behaviour. It also passes `mypy --strict`.
|
|
140
141
|
|
|
141
142
|
(Using `typing.Unpack` requires Python 3.11 or later. In Python 3.10, use the `typing_extensions` module from PyPI.)
|
|
142
143
|
|
|
@@ -223,7 +224,7 @@ except fancy_subprocess.RunError as e:
|
|
|
223
224
|
print(e)
|
|
224
225
|
```
|
|
225
226
|
|
|
226
|
-
Running the script on Windows will produce the following output
|
|
227
|
+
Running the script on Windows will produce the following output (-1072103376 is the signed integer interpretation of 0xC0190030, i.e. `STATUS_LOG_CORRUPTION_DETECTED`):
|
|
227
228
|
|
|
228
229
|
```
|
|
229
230
|
Demonstrating failure...
|
|
@@ -13,19 +13,19 @@ Key differences compared to `subprocess.run()`:
|
|
|
13
13
|
- The output of the command is always captured, but it is also immediately printed using `print_output`.
|
|
14
14
|
- The exit code of the command is checked, and an exception is raised on failure, like `subprocess.run(check=True)`, but the list of exit codes treated as success is customizable, and the raised exception is `RunError` instead of `CalledProcessError`.
|
|
15
15
|
- `OSError` is never raised, it gets converted to `RunError`.
|
|
16
|
-
- `RunResult` is returned instead of `CompletedProcess` on success
|
|
16
|
+
- `RunResult` is returned instead of `CompletedProcess` on success.
|
|
17
17
|
|
|
18
18
|
Arguments (all of them except `cmd` are optional):
|
|
19
19
|
- `cmd: Sequence[str | Path]` - Command to run. See `subprocess.run()`'s documentation for the interpretation of `cmd[0]`. It is recommended to use `fancy_subprocess.which()` to produce `cmd[0]`.
|
|
20
20
|
- `print_message: Callable[[str], None]` - Function used to print informational messages. If unspecified or set to `None`, defaults to `fancy_subprocess.default_print`. Use `message_quiet=True` to disable printing informational messages.
|
|
21
|
-
|
|
21
|
+
- The type of this argument is also aliased as `fancy_subprocess.PrintFunction`.
|
|
22
22
|
- `print_output: Callable[[str], None]` - Function used to print a line of the output of the command. If unspecified or set to `None`, defaults to `fancy_subprocess.default_print`. Use `output_quiet=True` to disable printing the command's output.
|
|
23
|
-
|
|
23
|
+
- The type of this argument is also aliased as `fancy_subprocess.PrintFunction`.
|
|
24
24
|
- `message_quiet: bool` - If `True`, `print_message` is ignored, and no informational messages are printed. If unspecified or set to `None`, defaults to `False`.
|
|
25
25
|
- `output_quiet: bool` - If `True`, `print_output` is ignored, and the command's output it not printed. If unspecified or set to `None`, defaults to `False`. Note that this parameter also affects the default value of `description`.
|
|
26
26
|
- `description: str` - Description printed before running the command. If unspecified or set to `None`, defaults to `Running command: ...` when `output_quiet` is `False`, and `Running command (output silenced): ...` when `output_quiet` is `True`.
|
|
27
27
|
- `success: Sequence[int] | AnyExitCode` - List of exit codes that should be considered successful. If set to `fancy_subprocess.ANY_EXIT_CODE`, then all exit codes are considered successful. If unspecified or set to `None`, defaults to `[0]`. Note that 0 is not automatically included in the list of successful exit codes, so if a list without 0 is specified, then the function will consider 0 a failure.
|
|
28
|
-
|
|
28
|
+
- The type of this argument is also aliased as `fancy_subprocess.Success`.
|
|
29
29
|
- `flush_before_subprocess: bool` - If `True`, flushes both the standard output and error streams before running the command. If unspecified or set to `None`, defaults to `True`.
|
|
30
30
|
- `trim_output_lines: bool` - If `True`, remove trailing whitespace from the lines of the output of the command before calling `print_output` and adding them to the `output` field of `RunResult`. If unspecified or set to `None`, defaults to `True`.
|
|
31
31
|
- `max_output_size: int` - Maximum number of characters to be recorded in the `output` field of `RunResult`. If the command produces more than `max_output_size` characters, only the last `max_output_size` will be recorded. If unspecified or set to `None`, defaults to 10,000,000.
|
|
@@ -33,10 +33,11 @@ Arguments (all of them except `cmd` are optional):
|
|
|
33
33
|
- `retry_initial_sleep_seconds: float` - Number of seconds to wait before retrying for the first time. If unspecified or set to `None`, defaults to 10.
|
|
34
34
|
- `retry_backoff: float` - Factor used to increase wait times before subsequent retries. If unspecified or set to `None`, defaults to 2.
|
|
35
35
|
- `env_overrides: Mapping[str, str]` - Dictionary used to set environment variables. Note that unline the `env` argument of `subprocess.run()`, `env_overrides` does not need to contain all environment variables, only the ones you want to add/modify compared to os.environ. If unspecified or set to `None`, defaults to empty dictionary, i.e. no change to the environment.
|
|
36
|
-
|
|
36
|
+
- The type of this argument is also aliased as `fancy_subprocess.EnvOverrides`.
|
|
37
37
|
- `cwd: str | Path` - If not `None`, change current working directory to `cwd` before running the command.
|
|
38
38
|
- `encoding: str` - This encoding will be used to open stdout and stderr of the command. If unspecified or set to `None`, see default behaviour in `io.TextIOWrapper`'s documentation.
|
|
39
|
-
- `errors: str` - This specifies how text decoding errors will be handled. See
|
|
39
|
+
- `errors: str` - This specifies how text decoding errors will be handled. (See possible options in `io.TextIOWrapper`'s documentation.) If unspecified or set to `None`, defaults to `replace`. Note that this differs from `io.TextIOWrapper`'s default behaviour, which is to use `strict`.
|
|
40
|
+
- `replace_fffd_with_question_mark: bool` - Replace Unicode Replacement Character U+FFFD (`�`, usually introduced by `errors='replace'`) with ASCII question mark (`?`) in lines of the output of the command before calling `print_output` and adding them to the `output` field of `RunResult`. If unspecified or set to `None`, defaults to `True`.
|
|
40
41
|
|
|
41
42
|
### Return value: `fancy_subprocess.RunResult`
|
|
42
43
|
|
|
@@ -92,7 +93,7 @@ import fancy_subprocess
|
|
|
92
93
|
from typing import Unpack
|
|
93
94
|
|
|
94
95
|
def grab_output(cmd: list[str], **kwargs: Unpack[fancy_subprocess.RunParams]) -> str:
|
|
95
|
-
|
|
96
|
+
# Raises ValueError if there are unknown parameters in kwargs or if a keyword argument's type is incorrect
|
|
96
97
|
fancy_subprocess.check_run_params(**kwargs)
|
|
97
98
|
|
|
98
99
|
# Make a copy of keyword arguments to be edited
|
|
@@ -100,7 +101,7 @@ def grab_output(cmd: list[str], **kwargs: Unpack[fancy_subprocess.RunParams]) ->
|
|
|
100
101
|
# Make sure nothing's printed, raise ValueError if caller tries to specify "output_quiet" or "message_quiet"
|
|
101
102
|
fancy_subprocess.force_run_params(forwarded_args, message_quiet=True, output_quiet=True)
|
|
102
103
|
# Handle encoding/decoding errors by replacing them with placeholder character by default, but allow callers to still customize behaviour
|
|
103
|
-
fancy_subprocess.change_default_run_params(forwarded_args, errors='
|
|
104
|
+
fancy_subprocess.change_default_run_params(forwarded_args, errors='backslashreplace')
|
|
104
105
|
|
|
105
106
|
# Run command, raise fancy_subprocess.RunError on failure
|
|
106
107
|
result = fancy_subprocess.run(cmd, **forwarded_args)
|
|
@@ -109,7 +110,7 @@ def grab_output(cmd: list[str], **kwargs: Unpack[fancy_subprocess.RunParams]) ->
|
|
|
109
110
|
return result.output
|
|
110
111
|
```
|
|
111
112
|
|
|
112
|
-
The `grab_output()` function supports all `fancy_subprocess.run()` arguments (eg. `retry`), except for `message_quiet` and `output_quiet`. If `errors` is unspecified or set to `None`, it uses `errors='
|
|
113
|
+
The `grab_output()` function supports all `fancy_subprocess.run()` arguments (eg. `retry`), except for `message_quiet` and `output_quiet`. If `errors` is unspecified or set to `None`, it uses `errors='backslashreplace'` instead of the default `errors='replace'` behaviour. It also passes `mypy --strict`.
|
|
113
114
|
|
|
114
115
|
(Using `typing.Unpack` requires Python 3.11 or later. In Python 3.10, use the `typing_extensions` module from PyPI.)
|
|
115
116
|
|
|
@@ -196,7 +197,7 @@ except fancy_subprocess.RunError as e:
|
|
|
196
197
|
print(e)
|
|
197
198
|
```
|
|
198
199
|
|
|
199
|
-
Running the script on Windows will produce the following output
|
|
200
|
+
Running the script on Windows will produce the following output (-1072103376 is the signed integer interpretation of 0xC0190030, i.e. `STATUS_LOG_CORRUPTION_DETECTED`):
|
|
200
201
|
|
|
201
202
|
```
|
|
202
203
|
Demonstrating failure...
|
|
@@ -113,7 +113,7 @@ def run(
|
|
|
113
113
|
- The output of the command is always captured, but it is also immediately printed using `print_output`.
|
|
114
114
|
- The exit code of the command is checked, and an exception is raised on failure, like `subprocess.run(check=True)`, but the list of exit codes treated as success is customizable, and the raised exception is `RunError` instead of `CalledProcessError`.
|
|
115
115
|
- `OSError` is never raised, it gets converted to `RunError`.
|
|
116
|
-
- `RunResult` is returned instead of `CompletedProcess` on success
|
|
116
|
+
- `RunResult` is returned instead of `CompletedProcess` on success.
|
|
117
117
|
|
|
118
118
|
Arguments (all of them except `cmd` are optional):
|
|
119
119
|
- `cmd: Sequence[str | Path]` - Command to run. See `subprocess.run()`'s documentation for the interpretation of `cmd[0]`. It is recommended to use `fancy_subprocess.which()` to produce `cmd[0]`.
|
|
@@ -132,7 +132,8 @@ def run(
|
|
|
132
132
|
- `env_overrides: Mapping[str, str]` - Dictionary used to set environment variables. Note that unline the `env` argument of `subprocess.run()`, `env_overrides` does not need to contain all environment variables, only the ones you want to add/modify compared to os.environ. If unspecified or set to `None`, defaults to empty dictionary, i.e. no change to the environment.
|
|
133
133
|
- `cwd: str | Path` - If not `None`, change current working directory to `cwd` before running the command.
|
|
134
134
|
- `encoding: str` - This encoding will be used to open stdout and stderr of the command. If unspecified or set to `None`, see default behaviour in `io.TextIOWrapper`'s documentation.
|
|
135
|
-
- `errors: str` - This specifies how text decoding errors will be handled. See
|
|
135
|
+
- `errors: str` - This specifies how text decoding errors will be handled. (See possible options in `io.TextIOWrapper`'s documentation.) If unspecified or set to `None`, defaults to `replace`. Note that this differs from `io.TextIOWrapper`'s default behaviour, which is to use `strict`.
|
|
136
|
+
- `replace_fffd_with_question_mark: bool` - Replace Unicode Replacement Character U+FFFD (`�`, usually introduced by `errors='replace'`) with ASCII question mark (`?`) in lines of the output of the command before calling `print_output` and adding them to the `output` field of `RunResult`. If unspecified or set to `None`, defaults to `True`.
|
|
136
137
|
"""
|
|
137
138
|
|
|
138
139
|
check_run_params(**kwargs)
|
|
@@ -154,7 +155,8 @@ def run(
|
|
|
154
155
|
env_overrides = value_or(kwargs.get('env_overrides'), dict())
|
|
155
156
|
cwd = kwargs.get('cwd')
|
|
156
157
|
encoding = kwargs.get('encoding')
|
|
157
|
-
errors = kwargs.get('errors')
|
|
158
|
+
errors = value_or(kwargs.get('errors'), 'replace')
|
|
159
|
+
replace_fffd_with_question_mark = value_or(kwargs.get('replace_fffd_with_question_mark'), True)
|
|
158
160
|
|
|
159
161
|
if message_quiet:
|
|
160
162
|
print_message = silenced_print
|
|
@@ -188,6 +190,8 @@ def run(
|
|
|
188
190
|
line = line.removesuffix('\n')
|
|
189
191
|
if trim_output_lines:
|
|
190
192
|
line = line.rstrip()
|
|
193
|
+
if replace_fffd_with_question_mark:
|
|
194
|
+
line = line.replace('\ufffd', '?')
|
|
191
195
|
|
|
192
196
|
print_output(line)
|
|
193
197
|
|
|
@@ -28,19 +28,17 @@ def oslex_join(cmd: Sequence[str | Path]) -> str:
|
|
|
28
28
|
def stringify_exit_code(exit_code: int) -> Optional[str]:
|
|
29
29
|
if sys.platform=='win32':
|
|
30
30
|
# Windows
|
|
31
|
-
|
|
32
|
-
bits = ThirtyTwoBits(exit_code)
|
|
33
|
-
except ValueError:
|
|
31
|
+
if not ThirtyTwoBits.check(exit_code):
|
|
34
32
|
return None
|
|
35
33
|
|
|
36
34
|
try:
|
|
37
|
-
|
|
38
|
-
if
|
|
39
|
-
return
|
|
35
|
+
status = NtStatus.decode(exit_code)
|
|
36
|
+
if NtStatus.severity(status) != NtStatusSeverity.STATUS_SEVERITY_SUCCESS:
|
|
37
|
+
return status.name
|
|
40
38
|
except ValueError:
|
|
41
39
|
pass
|
|
42
40
|
|
|
43
|
-
return f'0x{
|
|
41
|
+
return f'0x{ThirtyTwoBits(exit_code).unsigned_value:08X}'
|
|
44
42
|
else:
|
|
45
43
|
# POSIX
|
|
46
44
|
if exit_code<0:
|
|
@@ -2,7 +2,7 @@ import fancy_subprocess
|
|
|
2
2
|
from typing import Unpack
|
|
3
3
|
|
|
4
4
|
def grab_output(cmd: list[str], **kwargs: Unpack[fancy_subprocess.RunParams]) -> str:
|
|
5
|
-
|
|
5
|
+
# Raises ValueError if there are unknown parameters in kwargs or if a keyword argument's type is incorrect
|
|
6
6
|
fancy_subprocess.check_run_params(**kwargs)
|
|
7
7
|
|
|
8
8
|
# Make a copy of keyword arguments to be edited
|
|
@@ -3,8 +3,8 @@ requires = ["hatchling"]
|
|
|
3
3
|
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
|
-
name = "
|
|
7
|
-
version = "2.
|
|
6
|
+
name = "fancy-subprocess"
|
|
7
|
+
version = "2.3"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Tamás PEREGI", email="petamas@gmail.com" },
|
|
10
10
|
]
|
|
@@ -26,11 +26,11 @@ classifiers = [
|
|
|
26
26
|
license = "MIT"
|
|
27
27
|
license-files = ["LICENSE"]
|
|
28
28
|
dependencies = [
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
"ntstatus>=2.0,<3",
|
|
30
|
+
"oslex>=0.1.3,<2",
|
|
31
|
+
"pathext>=1.5,<2",
|
|
32
|
+
"typeguard>=4.4.2,<5",
|
|
33
|
+
"typing_extensions>=4.14,<5",
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
[project.urls]
|
|
@@ -4,7 +4,7 @@ requires-python = ">=3.10"
|
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "fancy-subprocess"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.2"
|
|
8
8
|
source = { editable = "." }
|
|
9
9
|
dependencies = [
|
|
10
10
|
{ name = "ntstatus" },
|
|
@@ -16,13 +16,22 @@ dependencies = [
|
|
|
16
16
|
|
|
17
17
|
[package.metadata]
|
|
18
18
|
requires-dist = [
|
|
19
|
-
{ name = "ntstatus", specifier = "
|
|
20
|
-
{ name = "oslex", specifier = "
|
|
21
|
-
{ name = "pathext", specifier = ">=1.
|
|
19
|
+
{ name = "ntstatus", specifier = ">=2.0,<3" },
|
|
20
|
+
{ name = "oslex", specifier = ">=0.1.3,<2" },
|
|
21
|
+
{ name = "pathext", specifier = ">=1.5,<2" },
|
|
22
22
|
{ name = "typeguard", specifier = ">=4.4.2,<5" },
|
|
23
23
|
{ name = "typing-extensions", specifier = ">=4.14,<5" },
|
|
24
24
|
]
|
|
25
25
|
|
|
26
|
+
[[package]]
|
|
27
|
+
name = "more-itertools"
|
|
28
|
+
version = "10.7.0"
|
|
29
|
+
source = { registry = "https://pypi.org/simple" }
|
|
30
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ce/a0/834b0cebabbfc7e311f30b46c8188790a37f89fc8d756660346fe5abfd09/more_itertools-10.7.0.tar.gz", hash = "sha256:9fddd5403be01a94b204faadcff459ec3568cf110265d3c54323e1e866ad29d3", size = 127671 }
|
|
31
|
+
wheels = [
|
|
32
|
+
{ url = "https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl", hash = "sha256:d43980384673cb07d2f7d2d918c616b30c659c089ee23953f601d6609c67510e", size = 65278 },
|
|
33
|
+
]
|
|
34
|
+
|
|
26
35
|
[[package]]
|
|
27
36
|
name = "mslex"
|
|
28
37
|
version = "1.3.0"
|
|
@@ -34,11 +43,11 @@ wheels = [
|
|
|
34
43
|
|
|
35
44
|
[[package]]
|
|
36
45
|
name = "ntstatus"
|
|
37
|
-
version = "
|
|
46
|
+
version = "2.0"
|
|
38
47
|
source = { registry = "https://pypi.org/simple" }
|
|
39
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
48
|
+
sdist = { url = "https://files.pythonhosted.org/packages/d1/5d/e1caf3dc856bf17421707d43db640b25c51547a045966d08460feb4eab32/ntstatus-2.0.tar.gz", hash = "sha256:b5956961d3e723ed2e429b1817d74ab925ef9eea523089a5dbcc59e3185e7c3d", size = 263733 }
|
|
40
49
|
wheels = [
|
|
41
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
50
|
+
{ url = "https://files.pythonhosted.org/packages/18/39/b9608ead33d92d4ec7f8148744160c736efe625d18ff5f8d72068e79e93d/ntstatus-2.0-py3-none-any.whl", hash = "sha256:df4cecb8f6a4052ea01871f36c5445fb2e945e6ceee72c6369c1669e06de47d1", size = 260611 },
|
|
42
51
|
]
|
|
43
52
|
|
|
44
53
|
[[package]]
|
|
@@ -55,11 +64,14 @@ wheels = [
|
|
|
55
64
|
|
|
56
65
|
[[package]]
|
|
57
66
|
name = "pathext"
|
|
58
|
-
version = "1.
|
|
67
|
+
version = "1.5"
|
|
59
68
|
source = { registry = "https://pypi.org/simple" }
|
|
60
|
-
|
|
69
|
+
dependencies = [
|
|
70
|
+
{ name = "more-itertools" },
|
|
71
|
+
]
|
|
72
|
+
sdist = { url = "https://files.pythonhosted.org/packages/09/b3/cd7d7282c1640300630e963b84b6e202862206f5ac24959015d83372e16c/pathext-1.5.tar.gz", hash = "sha256:cbfd6f697a4874be7ea37109dbf60f108d451b44bb3df290f1560c75fa16bb87", size = 6424 }
|
|
61
73
|
wheels = [
|
|
62
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
74
|
+
{ url = "https://files.pythonhosted.org/packages/d0/d0/aab254e2ba1e2a390261ef746c4129ef81b2d13289850380c5273026915d/pathext-1.5-py3-none-any.whl", hash = "sha256:3aedc261736dc714881676847dcc20ce2246b09d331ec09276b478477a469530", size = 7325 },
|
|
63
75
|
]
|
|
64
76
|
|
|
65
77
|
[[package]]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|