morphir 0.0.2__tar.gz → 0.1.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.
- {morphir-0.0.2 → morphir-0.1.0}/PKG-INFO +8 -1
- {morphir-0.0.2 → morphir-0.1.0}/README.md +7 -0
- {morphir-0.0.2 → morphir-0.1.0}/pyproject.toml +1 -1
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/__init__.py +2 -2
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/codec.py +228 -26
- {morphir-0.0.2 → morphir-0.1.0}/.gitignore +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/LICENSE +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/__init__.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/access_controlled.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/decorations.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/diagnostics.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/distribution.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/document.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/documented.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/format_version.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/fqname.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/json.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/literal.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/meta.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/migrate.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/module.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/name.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/package.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/path.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/qname.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/ref.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/type.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/type_constraints.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/type_def.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/type_spec.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/__init__.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/_legacy_value.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/access_controlled.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/codec.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/codec_v1.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/codec_v2.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/distribution.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/documented.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/fqname.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/literal.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/module.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/name.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/package.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/path.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/qname.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/type.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v3/value.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/__init__.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/access_controlled.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/annotation.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/decorations.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/distribution.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/document.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/documented.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/fqname.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/incompleteness.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/json.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/literal.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/meta.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/module.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/name.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/package.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/path.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/qname.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/ref.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/type.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/type_constraints.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/type_def.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/type_spec.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/v4/value.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/ir/value.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/py.typed +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/__init__.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/_compare.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/aggregate.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/basics.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/char.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/decimal.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/dict.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/instant.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/int.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/key.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/list.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/local_date.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/local_time.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/maybe.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/number.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/regex.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/result.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/result_list.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/rule.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/set.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/stateful_app.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/string.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/tuple.py +0 -0
- {morphir-0.0.2 → morphir-0.1.0}/src/morphir/sdk/uuid.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: morphir
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: Python port of Morphir - functional domain modeling for the enterprise
|
|
5
5
|
Project-URL: Homepage, https://github.com/finos/morphir-python
|
|
6
6
|
Project-URL: Documentation, https://morphir.finos.org
|
|
@@ -200,6 +200,13 @@ the distribution wrapped by its kind, never a format-3 shape. The module
|
|
|
200
200
|
docstring lists the gaps between the Python v4 model and upstream v4, each of
|
|
201
201
|
which fails with a diagnostic instead of guessing or dropping data.
|
|
202
202
|
|
|
203
|
+
The reader accepts every spelling the pinned schema allows. The writer emits the
|
|
204
|
+
compact canonical spelling that the profile prefers and Rust `morphir-core`
|
|
205
|
+
writes, so `{"Reference": {"fqname": "morphir/SDK:basics#int"}}` is written as
|
|
206
|
+
`"morphir/SDK:basics#int"`. Pass `spelling=v4_codec.Spelling.EXPANDED`, or use
|
|
207
|
+
`with v4_codec.use_spelling(v4_codec.Spelling.EXPANDED):`, to write every node in
|
|
208
|
+
the expanded form. Both spellings decode to the same model.
|
|
209
|
+
|
|
203
210
|
The v4 model follows the upstream reference model at that commit:
|
|
204
211
|
|
|
205
212
|
- A value definition is one of four bodies (`ValueDefinitionBody`): the
|
|
@@ -177,6 +177,13 @@ the distribution wrapped by its kind, never a format-3 shape. The module
|
|
|
177
177
|
docstring lists the gaps between the Python v4 model and upstream v4, each of
|
|
178
178
|
which fails with a diagnostic instead of guessing or dropping data.
|
|
179
179
|
|
|
180
|
+
The reader accepts every spelling the pinned schema allows. The writer emits the
|
|
181
|
+
compact canonical spelling that the profile prefers and Rust `morphir-core`
|
|
182
|
+
writes, so `{"Reference": {"fqname": "morphir/SDK:basics#int"}}` is written as
|
|
183
|
+
`"morphir/SDK:basics#int"`. Pass `spelling=v4_codec.Spelling.EXPANDED`, or use
|
|
184
|
+
`with v4_codec.use_spelling(v4_codec.Spelling.EXPANDED):`, to write every node in
|
|
185
|
+
the expanded form. Both spellings decode to the same model.
|
|
186
|
+
|
|
180
187
|
The v4 model follows the upstream reference model at that commit:
|
|
181
188
|
|
|
182
189
|
- A value definition is one of four bodies (`ValueDefinitionBody`): the
|
|
@@ -9,8 +9,16 @@ The envelope is ``{"formatVersion": 4, "distribution": {"Library": {...}}}``, wi
|
|
|
9
9
|
the distribution wrapped by its kind (``Library``, ``Specs``, or ``Application``).
|
|
10
10
|
The codec never writes a format-3 tagged-array shape.
|
|
11
11
|
|
|
12
|
-
The writer emits
|
|
13
|
-
|
|
12
|
+
The writer emits the compact canonical spelling by default, as the profile asks
|
|
13
|
+
and as Rust ``morphir-core`` writes it: a node without attributes takes its
|
|
14
|
+
shortest form (a type variable or argument-free reference as a string, a literal
|
|
15
|
+
as ``{"Kind": payload}``, a variable as ``{"Variable": "x"}``, a tuple as
|
|
16
|
+
``{"Tuple": [...]}``), and a node with attributes keeps the expanded form
|
|
17
|
+
``{"Kind": {"attributes": ..., members}}``. `Spelling.EXPANDED`, passed as
|
|
18
|
+
``spelling=`` or selected with `use_spelling`, writes every node expanded.
|
|
19
|
+
Documentation is written flattened, ``doc`` first beside the documented type or
|
|
20
|
+
value (decision 0010); a module definition writes its ``doc`` after ``types``
|
|
21
|
+
and ``values``. The profile says that readers MUST accept
|
|
14
22
|
every spelling the v4 JSON Schema marks as valid, so the reader also accepts the
|
|
15
23
|
compact canonical vocabulary that Rust ``morphir-core`` writes, and the legacy
|
|
16
24
|
spellings that the schema itself lists. Each spelling of a node gives the same
|
|
@@ -93,8 +101,6 @@ Known gaps between the Python v4 model and upstream v4, each handled explicitly:
|
|
|
93
101
|
(upstream makes them definition bodies); encoding fails with ``no_v4_spelling``.
|
|
94
102
|
- Structured ``TypeConstraints`` (deprecated) have no spelling; encoding fails
|
|
95
103
|
with ``no_v4_spelling``.
|
|
96
|
-
- The writer emits only the expanded spelling, not the compact canonical one the
|
|
97
|
-
profile prefers.
|
|
98
104
|
- The reader refuses the decision-0006 legacy-window spellings that the pinned
|
|
99
105
|
schema marks invalid (``attrs``, ``thenBranch``, ``argumentType``, a record's
|
|
100
106
|
field map directly under ``Record``, the nested ``{"value": ...}`` wrapper with
|
|
@@ -129,8 +135,11 @@ from __future__ import annotations
|
|
|
129
135
|
|
|
130
136
|
import math
|
|
131
137
|
import re
|
|
132
|
-
from collections.abc import Callable, Collection
|
|
138
|
+
from collections.abc import Callable, Collection, Iterator
|
|
139
|
+
from contextlib import contextmanager
|
|
140
|
+
from contextvars import ContextVar
|
|
133
141
|
from decimal import Decimal, InvalidOperation
|
|
142
|
+
from enum import Enum
|
|
134
143
|
from typing import Any
|
|
135
144
|
|
|
136
145
|
from .. import diagnostics as d
|
|
@@ -809,14 +818,94 @@ def _with_attributes(
|
|
|
809
818
|
return {"attributes": attrs, **members} if attrs else members
|
|
810
819
|
|
|
811
820
|
|
|
821
|
+
class Spelling(Enum):
|
|
822
|
+
"""Which v4 JSON spelling the encoders write.
|
|
823
|
+
|
|
824
|
+
``COMPACT``, the default, is the canonical spelling the v4 JSON profile asks
|
|
825
|
+
writers to emit, as morphir-core writes it: a node without attributes takes
|
|
826
|
+
its shortest schema-valid form. ``EXPANDED`` writes every node as
|
|
827
|
+
``{"Kind": {members}}``. Both decode to the same model, and both write
|
|
828
|
+
documentation flattened beside the node it documents (decision 0010).
|
|
829
|
+
"""
|
|
830
|
+
|
|
831
|
+
COMPACT = "compact"
|
|
832
|
+
EXPANDED = "expanded"
|
|
833
|
+
|
|
834
|
+
|
|
835
|
+
_SPELLING: ContextVar[Spelling] = ContextVar(
|
|
836
|
+
"morphir_ir_v4_spelling", default=Spelling.COMPACT
|
|
837
|
+
)
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
@contextmanager
|
|
841
|
+
def use_spelling(spelling: Spelling | None) -> Iterator[None]:
|
|
842
|
+
"""Use ``spelling`` for the v4 encoders called inside the block.
|
|
843
|
+
|
|
844
|
+
The selection is local to the current thread or task. ``None`` keeps the
|
|
845
|
+
selection already in effect.
|
|
846
|
+
|
|
847
|
+
Example:
|
|
848
|
+
>>> from morphir.ir.v4 import codec
|
|
849
|
+
>>> with codec.use_spelling(codec.Spelling.EXPANDED):
|
|
850
|
+
... codec.encode_type(codec.decode_type("a"))
|
|
851
|
+
{'Variable': {'name': 'a'}}
|
|
852
|
+
"""
|
|
853
|
+
if spelling is None:
|
|
854
|
+
yield
|
|
855
|
+
return
|
|
856
|
+
token = _SPELLING.set(spelling)
|
|
857
|
+
try:
|
|
858
|
+
yield
|
|
859
|
+
finally:
|
|
860
|
+
_SPELLING.reset(token)
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def _compact(attrs: dict[str, Json]) -> bool:
|
|
864
|
+
return not attrs and _SPELLING.get() is Spelling.COMPACT
|
|
865
|
+
|
|
866
|
+
|
|
867
|
+
# The member a compact value or pattern writes directly under its tag.
|
|
868
|
+
_PAYLOAD = {
|
|
869
|
+
"Literal": "literal",
|
|
870
|
+
"Constructor": "fqname",
|
|
871
|
+
"Reference": "fqname",
|
|
872
|
+
"Variable": "name",
|
|
873
|
+
"FieldFunction": "name",
|
|
874
|
+
"Tuple": "elements",
|
|
875
|
+
"List": "items",
|
|
876
|
+
"TuplePattern": "patterns",
|
|
877
|
+
"LiteralPattern": "literal",
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
|
|
812
881
|
# --- Types ---
|
|
813
882
|
|
|
814
883
|
|
|
815
|
-
def encode_type(
|
|
816
|
-
|
|
884
|
+
def encode_type(
|
|
885
|
+
tpe: t.Type, loc: Location = (), *, spelling: Spelling | None = None
|
|
886
|
+
) -> Json:
|
|
887
|
+
"""Encode a v4 type, compact unless ``spelling`` or the caller selects expanded."""
|
|
888
|
+
with use_spelling(spelling):
|
|
889
|
+
return _encode_type(tpe, loc)
|
|
890
|
+
|
|
891
|
+
|
|
892
|
+
def _encode_type(tpe: t.Type, loc: Location) -> Json:
|
|
817
893
|
attrs = _encode_type_attributes(tpe.attributes, loc)
|
|
818
894
|
|
|
819
895
|
def node(tag: str, members: dict[str, Json]) -> Json:
|
|
896
|
+
if _compact(attrs):
|
|
897
|
+
match tag:
|
|
898
|
+
case "Variable" if _TYPE_VARIABLE_STRING.fullmatch(members["name"]):
|
|
899
|
+
return members["name"]
|
|
900
|
+
case "Variable":
|
|
901
|
+
# The bare string grammar is lowercase only; keep the tag.
|
|
902
|
+
return {"Variable": members["name"]}
|
|
903
|
+
case "Reference" if "args" in members:
|
|
904
|
+
return {"Reference": [members["fqname"], *members["args"]]}
|
|
905
|
+
case "Reference":
|
|
906
|
+
return members["fqname"]
|
|
907
|
+
case "Tuple":
|
|
908
|
+
return {"Tuple": members["elements"]}
|
|
820
909
|
return _wrap(tag, _with_attributes(attrs, members))
|
|
821
910
|
|
|
822
911
|
here = (*loc, type(tpe).__name__)
|
|
@@ -1231,12 +1320,21 @@ def _decode_literal_spelling(
|
|
|
1231
1320
|
# --- Patterns ---
|
|
1232
1321
|
|
|
1233
1322
|
|
|
1234
|
-
def encode_pattern(
|
|
1235
|
-
|
|
1323
|
+
def encode_pattern(
|
|
1324
|
+
p: v.Pattern, loc: Location = (), *, spelling: Spelling | None = None
|
|
1325
|
+
) -> Json:
|
|
1326
|
+
"""Encode a v4 pattern, compact unless ``spelling`` or the caller selects expanded."""
|
|
1327
|
+
with use_spelling(spelling):
|
|
1328
|
+
return _encode_pattern(p, loc)
|
|
1329
|
+
|
|
1330
|
+
|
|
1331
|
+
def _encode_pattern(p: v.Pattern, loc: Location) -> Json:
|
|
1236
1332
|
attrs = _encode_value_attributes(p.attributes, loc)
|
|
1237
1333
|
here = (*loc, type(p).__name__)
|
|
1238
1334
|
|
|
1239
1335
|
def node(tag: str, members: dict[str, Json]) -> Json:
|
|
1336
|
+
if _compact(attrs) and tag in _PAYLOAD:
|
|
1337
|
+
return {tag: members[_PAYLOAD[tag]]}
|
|
1240
1338
|
return _wrap(tag, _with_attributes(attrs, members))
|
|
1241
1339
|
|
|
1242
1340
|
def many(items: list[v.Pattern], key: str) -> list[Json]:
|
|
@@ -1336,13 +1434,20 @@ def decode_pattern(j: object, loc: Location = ()) -> v.Pattern:
|
|
|
1336
1434
|
# --- Values ---
|
|
1337
1435
|
|
|
1338
1436
|
|
|
1339
|
-
def encode_value(
|
|
1340
|
-
|
|
1437
|
+
def encode_value(
|
|
1438
|
+
val: v.Value, loc: Location = (), *, spelling: Spelling | None = None
|
|
1439
|
+
) -> Json:
|
|
1440
|
+
"""Encode a v4 value, compact unless ``spelling`` or the caller selects expanded.
|
|
1341
1441
|
|
|
1342
1442
|
Raises:
|
|
1343
1443
|
DiagnosticError: With ``no_v4_spelling`` for ``Native`` and ``External``
|
|
1344
1444
|
nodes, or ``duplicate_member`` for repeated record fields.
|
|
1345
1445
|
"""
|
|
1446
|
+
with use_spelling(spelling):
|
|
1447
|
+
return _encode_value(val, loc)
|
|
1448
|
+
|
|
1449
|
+
|
|
1450
|
+
def _encode_value(val: v.Value, loc: Location) -> Json:
|
|
1346
1451
|
construct = type(val).__name__
|
|
1347
1452
|
here = (*loc, construct)
|
|
1348
1453
|
if isinstance(val, (v.Native, v.External)):
|
|
@@ -1356,6 +1461,8 @@ def encode_value(val: v.Value, loc: Location = ()) -> Json:
|
|
|
1356
1461
|
attrs = _encode_value_attributes(val.attributes, loc)
|
|
1357
1462
|
|
|
1358
1463
|
def node(tag: str, members: dict[str, Json]) -> Json:
|
|
1464
|
+
if _compact(attrs) and tag in _PAYLOAD:
|
|
1465
|
+
return {tag: members[_PAYLOAD[tag]]}
|
|
1359
1466
|
return _wrap(tag, _with_attributes(attrs, members))
|
|
1360
1467
|
|
|
1361
1468
|
def sub(x: v.Value, key: str) -> Json:
|
|
@@ -1833,7 +1940,17 @@ def _decode_externals(j: object, loc: Location) -> list[v.ExternalBinding]:
|
|
|
1833
1940
|
return bindings
|
|
1834
1941
|
|
|
1835
1942
|
|
|
1836
|
-
def encode_value_definition(
|
|
1943
|
+
def encode_value_definition(
|
|
1944
|
+
defn: v.ValueDefinitionBody, loc: Location = (), *, spelling: Spelling | None = None
|
|
1945
|
+
) -> Json:
|
|
1946
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
1947
|
+
with use_spelling(spelling):
|
|
1948
|
+
return _encode_value_definition_body(defn, loc)
|
|
1949
|
+
|
|
1950
|
+
|
|
1951
|
+
def _encode_value_definition_body(
|
|
1952
|
+
defn: v.ValueDefinitionBody, loc: Location = ()
|
|
1953
|
+
) -> Json:
|
|
1837
1954
|
"""Encode a value definition as ``{"<Kind>Body": {...}}``.
|
|
1838
1955
|
|
|
1839
1956
|
Raises:
|
|
@@ -1950,7 +2067,15 @@ def decode_value_definition(j: object, loc: Location = ()) -> v.ValueDefinitionB
|
|
|
1950
2067
|
)
|
|
1951
2068
|
|
|
1952
2069
|
|
|
1953
|
-
def encode_value_specification(
|
|
2070
|
+
def encode_value_specification(
|
|
2071
|
+
spec: v.Specification, loc: Location = (), *, spelling: Spelling | None = None
|
|
2072
|
+
) -> Json:
|
|
2073
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2074
|
+
with use_spelling(spelling):
|
|
2075
|
+
return _encode_value_specification_body(spec, loc)
|
|
2076
|
+
|
|
2077
|
+
|
|
2078
|
+
def _encode_value_specification_body(spec: v.Specification, loc: Location = ()) -> Json:
|
|
1954
2079
|
return _with_annotations(
|
|
1955
2080
|
spec.annotations,
|
|
1956
2081
|
loc,
|
|
@@ -2151,7 +2276,15 @@ def _decode_ctor_args(j: object, loc: Location) -> list[tuple[Name, t.Type]]:
|
|
|
2151
2276
|
return _decode_list(_decode_name_type_pair, j, loc, "Constructor")
|
|
2152
2277
|
|
|
2153
2278
|
|
|
2154
|
-
def encode_type_specification(
|
|
2279
|
+
def encode_type_specification(
|
|
2280
|
+
spec: ts.Specification, loc: Location = (), *, spelling: Spelling | None = None
|
|
2281
|
+
) -> Json:
|
|
2282
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2283
|
+
with use_spelling(spelling):
|
|
2284
|
+
return _encode_type_specification_body(spec, loc)
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
def _encode_type_specification_body(spec: ts.Specification, loc: Location = ()) -> Json:
|
|
2155
2288
|
tag = type(spec).__name__
|
|
2156
2289
|
encoded = _encode_type_specification(spec, loc)
|
|
2157
2290
|
return _wrap(tag, _with_annotations(spec.annotations, (*loc, tag), encoded[tag]))
|
|
@@ -2256,7 +2389,15 @@ def _decode_legacy_type_specification(
|
|
|
2256
2389
|
)
|
|
2257
2390
|
|
|
2258
2391
|
|
|
2259
|
-
def encode_type_definition(
|
|
2392
|
+
def encode_type_definition(
|
|
2393
|
+
defn: td.Definition, loc: Location = (), *, spelling: Spelling | None = None
|
|
2394
|
+
) -> Json:
|
|
2395
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2396
|
+
with use_spelling(spelling):
|
|
2397
|
+
return _encode_type_definition_body(defn, loc)
|
|
2398
|
+
|
|
2399
|
+
|
|
2400
|
+
def _encode_type_definition_body(defn: td.Definition, loc: Location = ()) -> Json:
|
|
2260
2401
|
params = _encode_params(defn.type_params, loc)
|
|
2261
2402
|
match defn:
|
|
2262
2403
|
case td.TypeAliasDefinition(_, tpe):
|
|
@@ -2335,9 +2476,19 @@ def _encode_documented[A](
|
|
|
2335
2476
|
encode: Callable[[A, Location], Json],
|
|
2336
2477
|
) -> Callable[[Documented[A], Location], Json]:
|
|
2337
2478
|
def run(item: Documented[A], loc: Location) -> Json:
|
|
2479
|
+
encoded = encode(item.value, loc)
|
|
2338
2480
|
if item.doc is None:
|
|
2339
|
-
return
|
|
2340
|
-
|
|
2481
|
+
return encoded
|
|
2482
|
+
if not isinstance(encoded, dict):
|
|
2483
|
+
raise fail(
|
|
2484
|
+
d.NO_V4_SPELLING,
|
|
2485
|
+
"doc",
|
|
2486
|
+
loc,
|
|
2487
|
+
"documentation is flattened beside the node it documents, "
|
|
2488
|
+
"so the node must be a JSON object",
|
|
2489
|
+
)
|
|
2490
|
+
# Decision 0010: `doc` is a flattened member placed first.
|
|
2491
|
+
return {"doc": item.doc, **encoded}
|
|
2341
2492
|
|
|
2342
2493
|
return run
|
|
2343
2494
|
|
|
@@ -2471,7 +2622,17 @@ def _decode_doc(obj: dict[str, object], loc: Location) -> str | None:
|
|
|
2471
2622
|
return _expect_str(obj["doc"], (*loc, "doc"), "doc")
|
|
2472
2623
|
|
|
2473
2624
|
|
|
2474
|
-
def encode_module_specification(
|
|
2625
|
+
def encode_module_specification(
|
|
2626
|
+
spec: module.Specification, loc: Location = (), *, spelling: Spelling | None = None
|
|
2627
|
+
) -> Json:
|
|
2628
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2629
|
+
with use_spelling(spelling):
|
|
2630
|
+
return _encode_module_specification_body(spec, loc)
|
|
2631
|
+
|
|
2632
|
+
|
|
2633
|
+
def _encode_module_specification_body(
|
|
2634
|
+
spec: module.Specification, loc: Location = ()
|
|
2635
|
+
) -> Json:
|
|
2475
2636
|
return _with_annotations(
|
|
2476
2637
|
spec.annotations,
|
|
2477
2638
|
loc,
|
|
@@ -2518,7 +2679,15 @@ def decode_module_specification(j: object, loc: Location = ()) -> module.Specifi
|
|
|
2518
2679
|
)
|
|
2519
2680
|
|
|
2520
2681
|
|
|
2521
|
-
def encode_module_definition(
|
|
2682
|
+
def encode_module_definition(
|
|
2683
|
+
defn: module.Definition, loc: Location = (), *, spelling: Spelling | None = None
|
|
2684
|
+
) -> Json:
|
|
2685
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2686
|
+
with use_spelling(spelling):
|
|
2687
|
+
return _encode_module_definition_body(defn, loc)
|
|
2688
|
+
|
|
2689
|
+
|
|
2690
|
+
def _encode_module_definition_body(defn: module.Definition, loc: Location = ()) -> Json:
|
|
2522
2691
|
return _with_doc(
|
|
2523
2692
|
{
|
|
2524
2693
|
"types": _keyed(
|
|
@@ -2563,6 +2732,14 @@ _dec_module_def = _decode_access(decode_module_definition)
|
|
|
2563
2732
|
|
|
2564
2733
|
|
|
2565
2734
|
def encode_package_specification(
|
|
2735
|
+
spec: package.Specification, loc: Location = (), *, spelling: Spelling | None = None
|
|
2736
|
+
) -> Json:
|
|
2737
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2738
|
+
with use_spelling(spelling):
|
|
2739
|
+
return _encode_package_specification_body(spec, loc)
|
|
2740
|
+
|
|
2741
|
+
|
|
2742
|
+
def _encode_package_specification_body(
|
|
2566
2743
|
spec: package.Specification, loc: Location = ()
|
|
2567
2744
|
) -> Json:
|
|
2568
2745
|
return {
|
|
@@ -2594,7 +2771,17 @@ def decode_package_specification(
|
|
|
2594
2771
|
)
|
|
2595
2772
|
|
|
2596
2773
|
|
|
2597
|
-
def encode_package_definition(
|
|
2774
|
+
def encode_package_definition(
|
|
2775
|
+
defn: package.Definition, loc: Location = (), *, spelling: Spelling | None = None
|
|
2776
|
+
) -> Json:
|
|
2777
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2778
|
+
with use_spelling(spelling):
|
|
2779
|
+
return _encode_package_definition_body(defn, loc)
|
|
2780
|
+
|
|
2781
|
+
|
|
2782
|
+
def _encode_package_definition_body(
|
|
2783
|
+
defn: package.Definition, loc: Location = ()
|
|
2784
|
+
) -> Json:
|
|
2598
2785
|
return {
|
|
2599
2786
|
"modules": _keyed(
|
|
2600
2787
|
defn.modules, _path_key, _enc_module_def, (*loc, "modules"), "modules"
|
|
@@ -2651,7 +2838,15 @@ def _decode_entry_point(j: object, loc: Location) -> EntryPoint:
|
|
|
2651
2838
|
)
|
|
2652
2839
|
|
|
2653
2840
|
|
|
2654
|
-
def encode_distribution(
|
|
2841
|
+
def encode_distribution(
|
|
2842
|
+
dist: Distribution, loc: Location = (), *, spelling: Spelling | None = None
|
|
2843
|
+
) -> Json:
|
|
2844
|
+
"""Encode with `Spelling.COMPACT` unless `spelling` or the caller selects otherwise."""
|
|
2845
|
+
with use_spelling(spelling):
|
|
2846
|
+
return _encode_distribution_body(dist, loc)
|
|
2847
|
+
|
|
2848
|
+
|
|
2849
|
+
def _encode_distribution_body(dist: Distribution, loc: Location = ()) -> Json:
|
|
2655
2850
|
"""Encode a distribution wrapped by its kind.
|
|
2656
2851
|
|
|
2657
2852
|
The package release version is not written; the v4 profile has no member for it.
|
|
@@ -2772,17 +2967,24 @@ def decode_distribution(j: object, loc: Location = ()) -> Distribution:
|
|
|
2772
2967
|
)
|
|
2773
2968
|
|
|
2774
2969
|
|
|
2775
|
-
def encode_versioned_distribution(
|
|
2970
|
+
def encode_versioned_distribution(
|
|
2971
|
+
dist: Distribution, *, spelling: Spelling | None = None
|
|
2972
|
+
) -> dict[str, Json]:
|
|
2776
2973
|
"""Encode ``{"formatVersion": 4, "distribution": ...}``, version first.
|
|
2777
2974
|
|
|
2975
|
+
Args:
|
|
2976
|
+
dist: The distribution to encode.
|
|
2977
|
+
spelling: `Spelling.COMPACT`, the default, or `Spelling.EXPANDED`.
|
|
2978
|
+
|
|
2778
2979
|
Raises:
|
|
2779
2980
|
DiagnosticError: When the distribution uses a construct with no draft
|
|
2780
2981
|
spelling.
|
|
2781
2982
|
"""
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2983
|
+
with use_spelling(spelling):
|
|
2984
|
+
return {
|
|
2985
|
+
"formatVersion": write_format_version(V4),
|
|
2986
|
+
"distribution": encode_distribution(dist, ("distribution",)),
|
|
2987
|
+
}
|
|
2786
2988
|
|
|
2787
2989
|
|
|
2788
2990
|
def decode_versioned_distribution(document: str | object) -> Distribution:
|
|
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
|
|
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
|
|
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
|