You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/api.md
+27-9Lines changed: 27 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
# API Reference
2
2
3
-
The `yaml12` module exposes parsing/formatting helpers plus two small dataclasses. Arguments mirror the Rust bindings and stay strict so type errors surface early.
3
+
The `yaml12` module exposes parsing/formatting helpers plus a single node wrapper `Yaml` (also exported as `Tagged` and `MappingKey` for compatibility). Use plain Python types whenever possible; reach for `Yaml` only when a node is tagged or when a collection appears as a mapping key. Arguments mirror the Rust bindings and stay strict so type errors surface early.
4
4
5
5
## parse_yaml(text, multi=False, handlers=None)
6
6
7
7
-`text`: `str` or sequence of `str`; sequence items are joined with newlines.
8
8
-`multi`: when `True`, parses the whole stream into a list (empty input yields `[]`); otherwise returns only the first document or `None` for empty input.
9
9
-`handlers`: optional `dict[str, Callable]` mapping tag strings to callables; handlers apply to tagged values and keys and run on already-parsed Python values.
10
-
- Returns parsed Python values. Non-core tags (and informative core tags like `!!timestamp`, `!!binary`, `!!set`, `!!omap`, `!!pairs`, or non-specific `!`) become `Tagged`when no handler matches. Scalar core tags (`!!str`, `!!int`, `!!bool`, `!!float`, `!!null`, `!!seq`, `!!map`) are normalized to plain Python types.
11
-
- Unhashable mapping keys (sequences/mappings) are wrapped in `MappingKey` so they can be hashable.
10
+
- Returns parsed Python values. Tagged nodes (non-core tags plus informative core tags like `!!timestamp`, `!!binary`, `!!set`, `!!omap`, `!!pairs`, or non-specific `!`) become `Yaml` objects when no handler matches; scalar core tags (`!!str`, `!!int`, `!!bool`, `!!float`, `!!null`, `!!seq`, `!!map`) are normalized to plain Python types.
11
+
- Unhashable mapping keys (sequences/mappings, or tagged collections) become `Yaml(value, tag=None)` so they remain hashable; tagged scalar keys become `Yaml(value, tag)`.
12
12
- Raises `ValueError` on YAML parse errors or invalid tag strings; `TypeError` on wrong argument types; handler exceptions propagate unchanged.
13
13
14
14
## read_yaml(path, multi=False, handlers=None)
@@ -19,7 +19,7 @@ The `yaml12` module exposes parsing/formatting helpers plus two small dataclasse
19
19
20
20
## format_yaml(value, multi=False)
21
21
22
-
- Serializes a Python value (or list of documents when `multi=True`) into a YAML string. `Tagged` values keep their tags unless they target core scalar tags; `MappingKey` preserves complex mapping keys.
22
+
- Serializes a Python value (or list of documents when `multi=True`) into a YAML string. `Yaml` nodes keep their tags unless they target core scalar tags; wrapping unhashable mapping keys in `Yaml` preserves them.
23
23
- When `multi=False`, the returned string omits the leading document marker and trailing newline. When `multi=True`, the string starts with `---\n` and ends with `...\n`; an empty sequence emits `---\n...\n`.
24
24
- Raises `TypeError` if `multi=True` and `value` is not a sequence, or when unsupported types are provided.
25
25
@@ -30,18 +30,36 @@ The `yaml12` module exposes parsing/formatting helpers plus two small dataclasse
30
30
- Writers are tried with text first and retried as bytes if needed.
31
31
- Raises `IOError` on write failures or `TypeError` when inputs are invalid.
32
32
33
-
## Tagged
33
+
## Yaml (aliases: Tagged, MappingKey)
34
34
35
35
Frozen `dataclass` with fields:
36
36
37
37
-`value`: the parsed Python value.
38
-
-`tag`: the rendered tag string (for example `"!foo"` or `"tag:yaml.org,2002:timestamp"`).
38
+
-`tag`: the rendered tag string (for example `"!foo"` or `"tag:yaml.org,2002:timestamp"`), or `None` when used solely to wrap an unhashable mapping key.
39
39
40
-
Produced for non-core tags (and informative core tags such as timestamps or binary) when no handler applies. You can construct it manually when emitting YAML to preserve tags; core scalar tags are stripped during serialization because they carry no extra information.
40
+
Produced for non-core tags (and informative core tags such as timestamps or binary) when no handler applies, and for any unhashable mapping key. You can construct it manually when emitting YAML to preserve tags or wrap complex keys; core scalar tags are stripped during serialization because they carry no extra information.
41
41
42
-
##MappingKey
42
+
### Usage examples
43
43
44
-
Frozen `dataclass` that wraps unhashable mapping keys (sequences, mappings, or tagged values). Equality and hashing use a frozen structural view of `value`, and it proxies indexing/iteration/len to the wrapped object when applicable. Use it to emit or compare YAML mappings that rely on complex keys.
44
+
```python
45
+
from yaml12 import Yaml, format_yaml, parse_yaml
46
+
47
+
# Tagged scalar
48
+
text = format_yaml({"env": Yaml("prod", "!env")})
49
+
assert"!env"in text
50
+
assertisinstance(parse_yaml(text)["env"], Yaml)
51
+
52
+
# Collection key
53
+
data = {Yaml(["a", "b"]): "val"}
54
+
out = format_yaml(data)
55
+
assert parse_yaml(out)[Yaml(["a", "b"])] =="val"
56
+
57
+
# Tagged collection key
58
+
data = {Yaml(["a", "b"], "!pair"): "val"}
59
+
out = format_yaml(data)
60
+
key =next(iter(parse_yaml(out)))
61
+
assertisinstance(key, Yaml) and key.tag =="!pair"and key.value == ["a", "b"]
Copy file name to clipboardExpand all lines: docs/index.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,10 +1,10 @@
1
1
# yaml12
2
2
3
-
`yaml12` exposes the Rust-based `saphyr` YAML 1.2 parser and emitter to Python through a small, function-first API. The bindings keep conversions lean, support multi-document streams, preserve non-core tags through a lightweight `Tagged` dataclass, and round-trip complex mapping keys via `MappingKey`.
3
+
`yaml12` exposes the Rust-based `saphyr` YAML 1.2 parser and emitter to Python through a small, function-first API. The bindings keep conversions lean, support multi-document streams, and materialize tagged nodes or unhashable mapping keys as a single lightweight `Yaml` dataclass (also exported as `Tagged` and `MappingKey`); otherwise you just use plain Python types.
4
4
5
5
- Parse YAML text or files into familiar Python types with `parse_yaml` and `read_yaml`; handlers apply to both values and keys.
6
6
- Serialize Python values back to YAML with `format_yaml` or write directly to disk/stdout with `write_yaml`, including non-core tags.
7
-
- Round-trip unhashable mapping keys using `MappingKey` to keep tagged collections, sequences, and mappings stable; tagged scalar keys stay plain `Tagged`.
7
+
- Round-trip tagged nodes and unhashable mapping keys using `Yaml`, keeping tagged scalars, tagged collections, and bare collections stable across parse/format.
Copy file name to clipboardExpand all lines: docs/tags.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,22 +2,22 @@
2
2
3
3
YAML 1.2 allows tagging values with custom semantics. `yaml12` preserves those tags by default and lets you plug in your own coercions.
4
4
5
-
## Tagged wrapper
5
+
## Yaml wrapper
6
6
7
-
Non-core tags that do not have a matching handler are wrapped in a frozen `Tagged` dataclass:
7
+
Non-core tags that do not have a matching handler are wrapped in a frozen `Yaml` dataclass (also exported as `Tagged`):
8
8
9
9
```python
10
-
from yaml12 importTagged, parse_yaml
10
+
from yaml12 importYaml, parse_yaml
11
11
12
12
color = parse_yaml("!color red")
13
-
assertisinstance(color, Tagged)
13
+
assertisinstance(color, Yaml)
14
14
assert color.value =="red"
15
15
assert color.tag =="!color"
16
16
```
17
17
18
-
`Tagged` works for both scalar and collection nodes, including keys in mappings. You can serialize tagged values by passing a `Tagged` instance back into `format_yaml` or `write_yaml`. Non-specific tags (`!`) produce `Tagged("value", "!")` unless you supply a handler. Tagged scalar keys stay plain `Tagged`; tagged collections are wrapped in `MappingKey(Tagged(...))` so they remain hashable.
18
+
`Yaml` works for both scalar and collection nodes, including keys in mappings. You can serialize tagged values by passing a `Yaml` instance back into `format_yaml` or `write_yaml`. Non-specific tags (`!`) produce `Yaml("value", "!")` unless you supply a handler. Tagged scalar keys become `Yaml(value, tag)`; tagged collections and untagged collections used as keys are wrapped in `Yaml(value, tag)` (with `tag=None` for untagged collections).
19
19
20
-
Core scalar tags (`!!str`, `!!int`, `!!float`, `!!bool`, `!!null`, `!!seq`, `!!map`) are normalized to plain Python values instead of `Tagged`. Informative core tags (such as `!!timestamp`, `!!binary`, `!!set`, `!!omap`, or `!!pairs`) stay tagged so you can choose whether to handle them or preserve them verbatim. Invalid values for core tags raise `ValueError`.
20
+
Core scalar tags (`!!str`, `!!int`, `!!float`, `!!bool`, `!!null`, `!!seq`, `!!map`) are normalized to plain Python values instead of `Yaml`. Informative core tags (such as `!!timestamp`, `!!binary`, `!!set`, `!!omap`, or `!!pairs`) stay tagged so you can choose whether to handle them or preserve them verbatim. Invalid values for core tags raise `ValueError`.
Copy file name to clipboardExpand all lines: docs/usage.md
+23-4Lines changed: 23 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Usage
2
2
3
-
The Python surface of `yaml12` is intentionally small: four functions that parse and emit YAML plus helpers for non-core tags (`Tagged`) and complex mapping keys (`MappingKey`).
3
+
The Python surface of `yaml12` is intentionally small: four functions that parse and emit YAML plus a single `Yaml` helper (also exported as `Tagged`/`MappingKey`) that you only need for two cases: tagged nodes and collection keys.
- Set `multi=True` to parse a stream of documents into a list; `multi=False` returns only the first document and ignores the rest of the stream.
17
17
- Supply `handlers` (a `dict` mapping tag strings to callables) to coerce specific tags on the fly. Handlers see already-parsed Python values and run for tagged keys as well as values. See [Custom Tags](tags.md) for details.
18
-
- Non-core tags without handlers become `Tagged`. Unhashable mapping keys (lists/dicts or tagged collections) are wrapped in `MappingKey` so they remain usable as dictionary keys; tagged scalar keys remain plain `Tagged`.
18
+
- Non-core tags without handlers become `Yaml(tag=..., value=...)`. Unhashable mapping keys (lists/dicts or tagged collections) become `Yaml(value, tag=None)` so they remain usable as dictionary keys; tagged scalar keys become `Yaml` with the tag preserved.
`format_yaml(value, multi=False)` serializes a Python value (or list of documents when `multi=True`) into YAML text. Tagged values retain their tags unless they target core scalar tags like `!!int` or `!!str`. Unhashable mapping keys stay wrapped in `MappingKey`.
35
+
`format_yaml(value, multi=False)` serializes a Python value (or list of documents when `multi=True`) into YAML text. `Yaml` values retain their tags unless they target core scalar tags like `!!int` or `!!str`. Unhashable mapping keys stay wrapped in `Yaml(value, tag=None)`.
YAML allows sequences, mappings, and tagged scalars as keys. Parsed results wrap any unhashable key (collections or tagged collections) in a `MappingKey` so it can live in a Python `dict` while preserving equality and hashing by structure. Tagged scalar keys remain plain `Tagged`. To emit an unhashable key, wrap it in `MappingKey` (for tagged collections, wrap the `Tagged` value itself) before passing it to `format_yaml` or `write_yaml`.
67
+
YAML allows sequences, mappings, and tagged scalars as keys. Parsed results wrap any unhashable key (collections or tagged collections) in `Yaml(value, tag=None)` so it can live in a Python `dict` while preserving equality and hashing by structure. Tagged scalar keys remain tagged `Yaml` nodes. To emit an unhashable key, wrap it in `Yaml` (for tagged collections, set `Yaml(value, tag)`), then pass it to `format_yaml` or `write_yaml`.
68
+
69
+
## Quick `Yaml` examples
70
+
71
+
```python
72
+
from yaml12 import Yaml, format_yaml, parse_yaml
73
+
74
+
# Tagged value
75
+
text = format_yaml({"mode": Yaml("prod", "!mode")})
0 commit comments