django-spec-cli 0.2.1__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.github/workflows/release.yml +1 -1
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/CHANGELOG.md +14 -1
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/CLAUDE.md +1 -1
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/PKG-INFO +3 -3
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/README.md +1 -1
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/exit_code_for.py +3 -2
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/types/exit_code.py +1 -1
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/version.py +1 -1
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/docs/index.md +2 -2
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/pyproject.toml +9 -9
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/test_exit_code_for.py +18 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/uv.lock +8 -8
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.github/CODEOWNERS +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.github/SECURITY.md +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.github/dependabot.yml +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.github/workflows/tests.yml +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.github/workflows/upstream-drift.yml +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.gitignore +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/.pre-commit-config.yaml +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/LICENSE +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/Makefile +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/apps.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/argv/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/argv/add_spec_arguments.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/argv/describe_parameters.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/argv/parameter_descriptor.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/argv/parsed_arguments.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/argv/utils.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/checks.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/py.typed +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/render/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/render/render_json_lines.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/render/render_result.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/render/render_table.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/render/utils.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/render/wants_table.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/report/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/report/unguarded_message.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/settings.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/spec_command.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/types/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/docs/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/docs/examples/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/docs/examples/commands.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/docs/reference.md +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/mkdocs.yml +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/scripts/check-changelog +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/scripts/release-publish.sh +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/argv/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/argv/test_add_spec_arguments.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/argv/test_describe_parameters.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/argv/test_parameter_descriptor.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/argv/test_parsed_arguments.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/argv/test_utils.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/argv/utils.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/apps.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/notes.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/unguarded_bad_parser.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/unguarded_broken_import.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/unguarded_broken_init.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/unguarded_empty.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/unguarded_no_registry.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/unguarded_plain.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/unguarded_report.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/unguarded_registries.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/conftest.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/conftest_settings.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/dispatch_app/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/dispatch_app/apps.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/dispatch_app/models.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/docs/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/docs/test_commands_examples.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/docs/test_reference.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/render/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/render/test_render_json_lines.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/render/test_render_result.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/render/test_render_table.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/render/test_utils.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/render/test_wants_table.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/render/utils.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/report/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/report/test_unguarded_message.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/test_apps.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/test_checks.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/test_init.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/test_settings.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/test_spec_command.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/types/__init__.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/types/test_exit_code.py +0 -0
- {django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/utils.py +0 -0
|
@@ -43,7 +43,7 @@ jobs:
|
|
|
43
43
|
|
|
44
44
|
- name: Publish to PyPI
|
|
45
45
|
if: steps.prepare.outputs.released == 'true'
|
|
46
|
-
uses: pypa/gh-action-pypi-publish@
|
|
46
|
+
uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
47
47
|
with:
|
|
48
48
|
# Idempotent on purpose. What gates a release is the git tag, not the
|
|
49
49
|
# index (see `prepare`), so re-running this job after a failure in a
|
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.3.0] — 2026-11-04
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- **The kernel floor is `django-service-specs>=0.24.0`, the first kernel
|
|
14
|
+
release with `PermissionCheckDenied` in `REFUSALS`.** The kernel raises it,
|
|
15
|
+
a subclass of `NotPermitted`, when a permission check the spec declares
|
|
16
|
+
answers `False`. A run it refuses still exits `NOT_PERMITTED`, through the
|
|
17
|
+
`NotPermitted` row, as it did on every earlier kernel, so no exit code
|
|
18
|
+
changes. The test holding the exit codes against the kernel's list now
|
|
19
|
+
decides that refusal's code by name, and the lowest-declared-versions job
|
|
20
|
+
runs the suite on 0.24.0.
|
|
21
|
+
|
|
10
22
|
## [0.2.1] — 2026-10-21
|
|
11
23
|
|
|
12
24
|
### Fixed
|
|
@@ -55,7 +67,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
55
67
|
`django-service-specs>=0.10.0`, the first kernel release with every name the
|
|
56
68
|
command reads at its root.
|
|
57
69
|
|
|
58
|
-
[Unreleased]: https://github.com/Artui/django-spec-cli/compare/v0.
|
|
70
|
+
[Unreleased]: https://github.com/Artui/django-spec-cli/compare/v0.3.0...HEAD
|
|
71
|
+
[0.3.0]: https://github.com/Artui/django-spec-cli/compare/v0.2.1...v0.3.0
|
|
59
72
|
[0.2.1]: https://github.com/Artui/django-spec-cli/compare/v0.2.0...v0.2.1
|
|
60
73
|
[0.2.0]: https://github.com/Artui/django-spec-cli/compare/v0.1.0...v0.2.0
|
|
61
74
|
[0.1.0]: https://github.com/Artui/django-spec-cli/compare/v0.0.0...v0.1.0
|
|
@@ -137,7 +137,7 @@ configured and enforced. isort order is stdlib, third party, first party.
|
|
|
137
137
|
| --- | --- | --- |
|
|
138
138
|
| Python | 3.10 | 3.10 through 3.14 |
|
|
139
139
|
| Django | 4.2 | 4.2, 5.0, 5.1, 5.2, 6.0, 6.1 |
|
|
140
|
-
| django-service-specs | 0.
|
|
140
|
+
| django-service-specs | 0.24.0 | the newest release, and the floor in the `floor` job |
|
|
141
141
|
|
|
142
142
|
The Python and Django floors are the kernel's, and cannot sit below them.
|
|
143
143
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: django-spec-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Run a django-service-specs registry from manage.py: one subcommand per spec, options generated from its parameters, exit codes for every refusal.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Artui/django-spec-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/Artui/django-spec-cli
|
|
@@ -30,7 +30,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
30
30
|
Classifier: Programming Language :: Python :: 3.14
|
|
31
31
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
32
32
|
Requires-Python: >=3.10
|
|
33
|
-
Requires-Dist: django-service-specs>=0.
|
|
33
|
+
Requires-Dist: django-service-specs>=0.24.0
|
|
34
34
|
Requires-Dist: django>=4.2
|
|
35
35
|
Description-Content-Type: text/markdown
|
|
36
36
|
|
|
@@ -61,7 +61,7 @@ the import path, the system check ids and the setting key are this package's.
|
|
|
61
61
|
pip install django-spec-cli
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
-
Python 3.10 or later, Django 4.2 or later, and `django-service-specs` 0.
|
|
64
|
+
Python 3.10 or later, Django 4.2 or later, and `django-service-specs` 0.24.0 or
|
|
65
65
|
later, which it installs.
|
|
66
66
|
|
|
67
67
|
## Quickstart
|
|
@@ -25,7 +25,7 @@ the import path, the system check ids and the setting key are this package's.
|
|
|
25
25
|
pip install django-spec-cli
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
Python 3.10 or later, Django 4.2 or later, and `django-service-specs` 0.
|
|
28
|
+
Python 3.10 or later, Django 4.2 or later, and `django-service-specs` 0.24.0 or
|
|
29
29
|
later, which it installs.
|
|
30
30
|
|
|
31
31
|
## Quickstart
|
|
@@ -28,8 +28,9 @@ _CODES: tuple[tuple[type[Exception], ExitCode], ...] = (
|
|
|
28
28
|
"""Each refusal's code, read top to bottom, first match wins.
|
|
29
29
|
|
|
30
30
|
A subclass sits above its base, or the base's row would answer for it. Only
|
|
31
|
-
rows that change the answer are listed: ``InvalidArguments
|
|
32
|
-
``ActionUnavailable`` take their base's code, so
|
|
31
|
+
rows that change the answer are listed: ``InvalidArguments``,
|
|
32
|
+
``PermissionCheckDenied`` and ``ActionUnavailable`` take their base's code, so
|
|
33
|
+
the base's row is theirs.
|
|
33
34
|
Coverage sees one expression, not eight rows, so each row is held by its own
|
|
34
35
|
case of test_every_refusal_the_kernel_raises_has_its_code."""
|
|
35
36
|
|
|
@@ -18,7 +18,7 @@ class ExitCode(IntEnum):
|
|
|
18
18
|
| 1 | `ERROR` | failed in a way nobody declared | anything else, with a traceback |
|
|
19
19
|
| 2 | `USAGE` | never started: the command line was malformed | argparse's own refusals |
|
|
20
20
|
| 3 | `INVALID_ARGUMENTS` | was refused its arguments | `InvalidArguments`, `ServiceValidationError`, any other `DispatchError` |
|
|
21
|
-
| 4 | `NOT_PERMITTED` | was refused to the principal | `NotPermitted` |
|
|
21
|
+
| 4 | `NOT_PERMITTED` | was refused to the principal | `NotPermitted`, `PermissionCheckDenied` |
|
|
22
22
|
| 5 | `PRINCIPAL_UNAVAILABLE` | had nobody to run as | `PrincipalUnavailable` |
|
|
23
23
|
| 6 | `NOT_FOUND` | found no row to act on | a `not_found` result, `ServiceNotFound` |
|
|
24
24
|
| 7 | `CONFLICT` | was refused by the row's current state | `ServiceConflict`, `ActionUnavailable` |
|
|
@@ -27,7 +27,7 @@ pip install django-spec-cli
|
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
It installs [`django-service-specs`](https://artui.github.io/django-service-specs/), the kernel whose specs it serves,
|
|
30
|
-
from 0.
|
|
30
|
+
from 0.24.0, on Python 3.10 and Django 4.2 or later. The command line was the
|
|
31
31
|
kernel's `commands/` subpackage, and moved here so the kernel carries no
|
|
32
32
|
transport.
|
|
33
33
|
|
|
@@ -184,7 +184,7 @@ branch on:
|
|
|
184
184
|
| 1 | `ERROR` | failed in a way nobody declared: the traceback is printed |
|
|
185
185
|
| 2 | `USAGE` | never started: the command line was malformed |
|
|
186
186
|
| 3 | `INVALID_ARGUMENTS` | `InvalidArguments`, `ServiceValidationError`, any other `DispatchError` |
|
|
187
|
-
| 4 | `NOT_PERMITTED` | `NotPermitted` |
|
|
187
|
+
| 4 | `NOT_PERMITTED` | `NotPermitted`, and `PermissionCheckDenied`, a declared check's denial |
|
|
188
188
|
| 5 | `PRINCIPAL_UNAVAILABLE` | `PrincipalUnavailable`: no such user, or a deactivated one |
|
|
189
189
|
| 6 | `NOT_FOUND` | the row named does not exist, or the service raised `ServiceNotFound` |
|
|
190
190
|
| 7 | `CONFLICT` | `ServiceConflict`, and `ActionUnavailable` with its code in the message |
|
|
@@ -40,14 +40,14 @@ dependencies = [
|
|
|
40
40
|
# kernel's specs, so this package cannot support a Django the kernel does
|
|
41
41
|
# not.
|
|
42
42
|
"django>=4.2",
|
|
43
|
-
# The first kernel release
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
"django-service-specs>=0.
|
|
43
|
+
# The first kernel release with ``PermissionCheckDenied`` in ``REFUSALS``.
|
|
44
|
+
# ``tests/test_exit_code_for.py`` holds the exit codes against that list
|
|
45
|
+
# and decides the new refusal's code by name, so the suite, and the floor
|
|
46
|
+
# job running it, cannot import below 0.24.0. The code itself is
|
|
47
|
+
# ``NotPermitted``'s on every kernel. Below 0.11.0 the kernel also still
|
|
48
|
+
# shipped its own copy of the command and registered its own ``W001`` and
|
|
49
|
+
# ``W003``.
|
|
50
|
+
"django-service-specs>=0.24.0",
|
|
51
51
|
]
|
|
52
52
|
|
|
53
53
|
[project.urls]
|
|
@@ -147,7 +147,7 @@ skip-magic-trailing-comma = false
|
|
|
147
147
|
root = ["./django_spec_cli"]
|
|
148
148
|
|
|
149
149
|
[tool.bumpversion]
|
|
150
|
-
current_version = "0.
|
|
150
|
+
current_version = "0.3.0"
|
|
151
151
|
allow_dirty = false
|
|
152
152
|
commit = false
|
|
153
153
|
tag = false
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
3
5
|
from django_service_specs import (
|
|
4
6
|
REFUSALS,
|
|
5
7
|
ActionUnavailable,
|
|
@@ -7,7 +9,11 @@ from django_service_specs import (
|
|
|
7
9
|
DispatchError,
|
|
8
10
|
InvalidArguments,
|
|
9
11
|
NotPermitted,
|
|
12
|
+
PermissionCheck,
|
|
13
|
+
PermissionCheckDenied,
|
|
10
14
|
PrincipalUnavailable,
|
|
15
|
+
SelectorKind,
|
|
16
|
+
SelectorSpec,
|
|
11
17
|
ServiceConflict,
|
|
12
18
|
ServiceError,
|
|
13
19
|
ServiceNotFound,
|
|
@@ -22,6 +28,7 @@ EXPECTED: dict[type[Exception], ExitCode] = {
|
|
|
22
28
|
DispatchError: ExitCode.INVALID_ARGUMENTS,
|
|
23
29
|
InvalidArguments: ExitCode.INVALID_ARGUMENTS,
|
|
24
30
|
NotPermitted: ExitCode.NOT_PERMITTED,
|
|
31
|
+
PermissionCheckDenied: ExitCode.NOT_PERMITTED,
|
|
25
32
|
PrincipalUnavailable: ExitCode.PRINCIPAL_UNAVAILABLE,
|
|
26
33
|
ServiceError: ExitCode.REFUSED,
|
|
27
34
|
ServiceValidationError: ExitCode.INVALID_ARGUMENTS,
|
|
@@ -33,9 +40,20 @@ EXPECTED: dict[type[Exception], ExitCode] = {
|
|
|
33
40
|
"""Every refusal the kernel raises, and its code, decided one by one."""
|
|
34
41
|
|
|
35
42
|
|
|
43
|
+
class _Denies(PermissionCheck):
|
|
44
|
+
def has_permission(self, principal: Any, spec: Any) -> bool:
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
|
|
36
48
|
def _instance(kind: type[Exception]) -> Exception:
|
|
37
49
|
if kind is InvalidArguments:
|
|
38
50
|
return InvalidArguments({"title": ["Required."]})
|
|
51
|
+
if kind is PermissionCheckDenied:
|
|
52
|
+
# Built as ``authorize`` raises it: the check that answered and the
|
|
53
|
+
# spec declaring it.
|
|
54
|
+
check = _Denies()
|
|
55
|
+
spec = SelectorSpec(kind=SelectorKind.LIST, selector=list, permissions=[check])
|
|
56
|
+
return PermissionCheckDenied(check=check, spec=spec)
|
|
39
57
|
if kind is ServiceValidationError:
|
|
40
58
|
return ServiceValidationError("Taken.")
|
|
41
59
|
if kind is ActionUnavailable:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
version = 1
|
|
2
|
-
revision =
|
|
2
|
+
revision = 5
|
|
3
3
|
requires-python = ">=3.10"
|
|
4
4
|
resolution-markers = [
|
|
5
5
|
"python_full_version >= '3.12'",
|
|
@@ -438,16 +438,16 @@ wheels = [
|
|
|
438
438
|
|
|
439
439
|
[[package]]
|
|
440
440
|
name = "django-service-specs"
|
|
441
|
-
version = "0.
|
|
441
|
+
version = "0.25.1"
|
|
442
442
|
source = { registry = "https://pypi.org/simple" }
|
|
443
443
|
dependencies = [
|
|
444
444
|
{ name = "django", version = "5.2.18", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" },
|
|
445
445
|
{ name = "django", version = "6.1.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
|
|
446
446
|
{ name = "typing-extensions" },
|
|
447
447
|
]
|
|
448
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
448
|
+
sdist = { url = "https://files.pythonhosted.org/packages/15/fc/f9d84274df2031d8a954713d68058d11949e29a537c91a4cc4e663badd6f/django_service_specs-0.25.1.tar.gz", hash = "sha256:d1c5ef473ebc3d5bec162b70664895c2493394bbdfdc1447090390071228233c", size = 1172311, upload-time = "2026-11-03T14:45:24.825Z" }
|
|
449
449
|
wheels = [
|
|
450
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
450
|
+
{ url = "https://files.pythonhosted.org/packages/a5/85/27c0da45b031c1080b226b8226e84504d7e1973367380826040db75566a7/django_service_specs-0.25.1-py3-none-any.whl", hash = "sha256:d4d19e64b5a785800a09b81e0b323c6e4acefdabf4694ce297b86493a9560ef8", size = 513779, upload-time = "2026-11-03T14:45:23.115Z" },
|
|
451
451
|
]
|
|
452
452
|
|
|
453
453
|
[package.optional-dependencies]
|
|
@@ -490,7 +490,7 @@ docs = [
|
|
|
490
490
|
[package.metadata]
|
|
491
491
|
requires-dist = [
|
|
492
492
|
{ name = "django", specifier = ">=4.2" },
|
|
493
|
-
{ name = "django-service-specs", specifier = ">=0.
|
|
493
|
+
{ name = "django-service-specs", specifier = ">=0.24.0" },
|
|
494
494
|
]
|
|
495
495
|
|
|
496
496
|
[package.metadata.requires-dev]
|
|
@@ -1761,7 +1761,7 @@ wheels = [
|
|
|
1761
1761
|
|
|
1762
1762
|
[[package]]
|
|
1763
1763
|
name = "virtualenv"
|
|
1764
|
-
version = "21.14.
|
|
1764
|
+
version = "21.14.13"
|
|
1765
1765
|
source = { registry = "https://pypi.org/simple" }
|
|
1766
1766
|
dependencies = [
|
|
1767
1767
|
{ name = "distlib" },
|
|
@@ -1773,9 +1773,9 @@ dependencies = [
|
|
|
1773
1773
|
{ name = "python-discovery" },
|
|
1774
1774
|
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
|
1775
1775
|
]
|
|
1776
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1776
|
+
sdist = { url = "https://files.pythonhosted.org/packages/70/aa/bff50daee0488e16d611258a9b6c5a1d0c9e128f8ca424e9f4e1c0444ef2/virtualenv-21.14.13.tar.gz", hash = "sha256:de5307ba4b9a0001d9c8ea02832d38f63ca432880f416c1bface61c4323fd905", size = 5570301, upload-time = "2026-10-22T20:10:16.952Z" }
|
|
1777
1777
|
wheels = [
|
|
1778
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1778
|
+
{ url = "https://files.pythonhosted.org/packages/bb/a9/c10d8a44a29fb94a18b43fdf11f38caca53ae7c9406f11a72b1cb8f624f1/virtualenv-21.14.13-py3-none-any.whl", hash = "sha256:5fbb04138a4861580b78ba9110d529a26bc48fcc93c8ec36bc0202eeed96a788", size = 5557094, upload-time = "2026-10-22T20:10:15.096Z" },
|
|
1779
1779
|
]
|
|
1780
1780
|
|
|
1781
1781
|
[[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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/django_spec_cli/argv/parameter_descriptor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/__init__.py
RENAMED
|
File without changes
|
{django_spec_cli-0.2.1 → django_spec_cli-0.3.0}/tests/commands_app/management/commands/notes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|