dirigent-plugin 0.22.0__tar.gz → 0.23.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.
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/PKG-INFO +2 -2
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/pyproject.toml +2 -2
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/pyproject.toml.orig +2 -2
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/src/dirigent_plugin/__init__.py +4 -0
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/src/dirigent_plugin/blocks.py +64 -2
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/LICENSE +0 -0
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/README.md +0 -0
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/src/dirigent_plugin/markers.py +0 -0
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/src/dirigent_plugin/messages.py +0 -0
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/src/dirigent_plugin/py.typed +0 -0
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/src/dirigent_plugin/runners.py +0 -0
- {dirigent_plugin-0.22.0 → dirigent_plugin-0.23.1}/src/dirigent_plugin/transforms.py +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dirigent-plugin
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.23.1
|
|
4
4
|
Summary: The dirigent plugin contract: block specs, protocols, and markers.
|
|
5
5
|
License-Expression: LicenseRef-Proprietary
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Classifier: Programming Language :: Python :: 3
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.13
|
|
9
|
-
Requires-Dist: dirigent-common==0.
|
|
9
|
+
Requires-Dist: dirigent-common==0.23.1
|
|
10
10
|
Requires-Dist: httpx2>=2.12.0
|
|
11
11
|
Requires-Dist: pluginkit>=0.5.0
|
|
12
12
|
Requires-Dist: pydantic>=2.13.5
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dirigent-plugin"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.23.1"
|
|
4
4
|
description = "The dirigent plugin contract: block specs, protocols, and markers."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -11,7 +11,7 @@ classifiers = [
|
|
|
11
11
|
"Programming Language :: Python :: 3.13",
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"dirigent-common==0.
|
|
14
|
+
"dirigent-common==0.23.1",
|
|
15
15
|
"httpx2>=2.12.0",
|
|
16
16
|
"pluginkit>=0.5.0",
|
|
17
17
|
"pydantic>=2.13.5",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "dirigent-plugin"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.23.1"
|
|
4
4
|
description = "The dirigent plugin contract: block specs, protocols, and markers."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.13"
|
|
@@ -11,7 +11,7 @@ classifiers = [
|
|
|
11
11
|
"Programming Language :: Python :: 3.13",
|
|
12
12
|
]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"dirigent-common==0.
|
|
14
|
+
"dirigent-common==0.23.1",
|
|
15
15
|
"httpx2>=2.12.0",
|
|
16
16
|
"pluginkit>=0.5.0",
|
|
17
17
|
"pydantic>=2.13.5",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from dirigent_plugin.blocks import (
|
|
4
4
|
BLOCK_ID_PATTERN,
|
|
5
5
|
MARK_LIMIT,
|
|
6
|
+
REFERENCE_KEYWORD,
|
|
6
7
|
SHELL_VARIABLE_PREFIX,
|
|
7
8
|
SHELL_VARIABLES_FIELD,
|
|
8
9
|
SURFACE_ID_PATTERN,
|
|
@@ -45,6 +46,7 @@ from dirigent_plugin.blocks import (
|
|
|
45
46
|
classify_default,
|
|
46
47
|
mark_refusal,
|
|
47
48
|
merge_contributions,
|
|
49
|
+
reference_fields,
|
|
48
50
|
shell_string_fields,
|
|
49
51
|
)
|
|
50
52
|
from dirigent_plugin.markers import (
|
|
@@ -112,6 +114,7 @@ __all__ = [
|
|
|
112
114
|
"RunnerEngine",
|
|
113
115
|
"Runs",
|
|
114
116
|
"SURFACE_ID_PATTERN",
|
|
117
|
+
"REFERENCE_KEYWORD",
|
|
115
118
|
"SchemaRef",
|
|
116
119
|
"Sensor",
|
|
117
120
|
"SensorSpec",
|
|
@@ -136,5 +139,6 @@ __all__ = [
|
|
|
136
139
|
"formatters",
|
|
137
140
|
"mark_refusal",
|
|
138
141
|
"merge_contributions",
|
|
142
|
+
"reference_fields",
|
|
139
143
|
"shell_string_fields",
|
|
140
144
|
]
|
|
@@ -147,6 +147,14 @@ class ShellString:
|
|
|
147
147
|
return published
|
|
148
148
|
|
|
149
149
|
|
|
150
|
+
#: What :class:`Reference` publishes, and what reading one back looks for.
|
|
151
|
+
REFERENCE_KEYWORD: Final = "x-dirigent-ref"
|
|
152
|
+
|
|
153
|
+
#: The only pointer shape a block's own config schema writes, which pydantic emits for a
|
|
154
|
+
#: field whose type is a named alias.
|
|
155
|
+
_LOCAL_DEFS: Final = "#/$defs/"
|
|
156
|
+
|
|
157
|
+
|
|
150
158
|
class Reference:
|
|
151
159
|
"""Marks a config field whose value is the code of another thing this instance holds.
|
|
152
160
|
|
|
@@ -173,7 +181,7 @@ class Reference:
|
|
|
173
181
|
) -> JsonSchemaValue:
|
|
174
182
|
"""Publish what the marked field's code names, leaving what it validates untouched."""
|
|
175
183
|
published = handler(schema)
|
|
176
|
-
published[
|
|
184
|
+
published[REFERENCE_KEYWORD] = self.kind
|
|
177
185
|
return published
|
|
178
186
|
|
|
179
187
|
|
|
@@ -184,6 +192,55 @@ type ConnectionRef = Annotated[str, Reference("connection")]
|
|
|
184
192
|
type SchemaRef = Annotated[str, Reference("schema")]
|
|
185
193
|
|
|
186
194
|
|
|
195
|
+
def _pointed_at(shape: dict[str, Any], pool: dict[str, Any]) -> dict[str, Any] | None:
|
|
196
|
+
"""The definition a local ``$ref`` names, or nothing where it names none."""
|
|
197
|
+
pointer = shape.get("$ref")
|
|
198
|
+
if not isinstance(pointer, str) or not pointer.startswith(_LOCAL_DEFS):
|
|
199
|
+
return None
|
|
200
|
+
target = pool.get(pointer.removeprefix(_LOCAL_DEFS))
|
|
201
|
+
return cast("dict[str, Any]", target) if isinstance(target, dict) else None
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _shapes(shape: dict[str, Any], pool: dict[str, Any]) -> list[dict[str, Any]]:
|
|
205
|
+
"""One field's own shape, the definition it points at, and each branch of a union."""
|
|
206
|
+
found: list[dict[str, Any]] = [shape]
|
|
207
|
+
target = _pointed_at(shape, pool)
|
|
208
|
+
if target is not None:
|
|
209
|
+
found.append(target)
|
|
210
|
+
for option in cast("list[Any]", shape.get("anyOf") or []):
|
|
211
|
+
if not isinstance(option, dict):
|
|
212
|
+
continue
|
|
213
|
+
branch = cast("dict[str, Any]", option)
|
|
214
|
+
found.append(branch)
|
|
215
|
+
pointed = _pointed_at(branch, pool)
|
|
216
|
+
if pointed is not None:
|
|
217
|
+
found.append(pointed)
|
|
218
|
+
return found
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def reference_fields(schema: JsonMap, kind: str) -> set[str]:
|
|
222
|
+
"""Name the config fields a block publishes as references to one kind of thing.
|
|
223
|
+
|
|
224
|
+
A block says which of its strings hold a code, so nothing here guesses from a value: a
|
|
225
|
+
code and a value of the same shape are not told apart by looking. The marker rides on the
|
|
226
|
+
field's own shape or on the definition that shape points at, because a field typed as a
|
|
227
|
+
named alias is published as a ``$ref``.
|
|
228
|
+
"""
|
|
229
|
+
properties = schema.get("properties")
|
|
230
|
+
if not isinstance(properties, dict):
|
|
231
|
+
return set()
|
|
232
|
+
held = schema.get("$defs")
|
|
233
|
+
pool = cast("dict[str, Any]", held) if isinstance(held, dict) else {}
|
|
234
|
+
named: set[str] = set()
|
|
235
|
+
for field, declared in cast("dict[str, Any]", properties).items():
|
|
236
|
+
if not isinstance(declared, dict):
|
|
237
|
+
continue
|
|
238
|
+
shapes = _shapes(cast("dict[str, Any]", declared), pool)
|
|
239
|
+
if any(one.get(REFERENCE_KEYWORD) == kind for one in shapes):
|
|
240
|
+
named.add(str(field))
|
|
241
|
+
return named
|
|
242
|
+
|
|
243
|
+
|
|
187
244
|
#: What the engine names the variables it substitutes a shell string's references out into.
|
|
188
245
|
SHELL_VARIABLE_PREFIX: Final = "DIRIGENT_V"
|
|
189
246
|
|
|
@@ -602,7 +659,12 @@ class StepContext(Protocol):
|
|
|
602
659
|
...
|
|
603
660
|
|
|
604
661
|
def schema(self, code: str) -> JsonMap:
|
|
605
|
-
"""Resolve
|
|
662
|
+
"""Resolve one of the JSON Schemas this run holds by code; any other code fails the step.
|
|
663
|
+
|
|
664
|
+
A run holds the body of every schema its document named when it was created, so a
|
|
665
|
+
stored schema edited mid-run does not change what the rest of that run checks
|
|
666
|
+
against. A code the document does not name is not one the run holds.
|
|
667
|
+
"""
|
|
606
668
|
...
|
|
607
669
|
|
|
608
670
|
def format_checker(self) -> FormatChecker:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|