Pyjo.YAML - Minimal YAML loader and dumper¶
from Pyjo.YAML import dump, dump_all, load, load_all
config = load("""\
foo: bar
list:
- one
- two
""")
documents = load_all('--- first\n--- second\n')
string = dump({'foo': 'bar', 'list': ['one', 'two']})
Pyjo.YAML loads and dumps the YAML that configuration files and
workflows use, a subset of YAML 1.2, which
Pyjoyment.Plugin.YAMLConfig reads, as Python has no YAML in its
standard library:
mappings and sequences in the block style, nested by their indentation, and a mapping or a sequence that starts in an item of a sequence (
- name: value,- - item);flow sequences and mappings,
[a, b]and{a: 1}, nested, and over several lines;scalars, plain, in single quotes (with
''for a quote) and in double quotes (with the escapes\n,\t,\xHH,\uHHHHand the others of YAML), over several lines too, and the literal|and folded>block scalars, with their empty lines, and the indicators-and+that strip and keep the final line breaks;comments, documents that
---starts and...ends, a scalar after---and the directive%YAML.
A plain scalar has the type of the core schema of YAML 1.2: null and ~
are None, true and false are booleans, and numbers, with 0o and
0x too, .inf and .nan, are int and float, as
404: is a key of int. The words and the forms of YAML 1.1, as
yes, off, 0755 for an octal number and an implicit date, are not of
the core schema, and stay strings or decimal numbers. A quoted scalar and a
block scalar are strings.
# {'foo': [1, True, 'yes', '2']}
load("foo:\n - 1\n - true\n - yes\n - '2'\n")
A standard tag gives a scalar its type: !!str, !!int, !!float,
!!bool and !!null of YAML 1.2, and !!binary, Base64 for
bytes, and !!timestamp, ISO 8601 for datetime.date and
datetime.datetime, of YAML 1.1.
# {'port': '8080', 'key': b'hello', 'day': datetime.date(2001, 12, 14)}
load('port: !!str 8080\nkey: !!binary aGVsbG8=\nday: !!timestamp 2001-12-14\n')
An anchor &name names a node, a value or a key, in a block or a flow
collection, and an alias *name after it in the same document is the same
object; an anchor defined again names the node of the aliases after it. The
merge key << of YAML 1.1 puts the keys of the mapping that it names, or of
a sequence of mappings, the earlier ones first, into the mapping, under the
keys of the mapping itself.
# {'base': {'a': 1, 'b': 1}, 'copy': {'a': 1, 'b': 2}}
load('base: &base\n a: 1\n b: 1\ncopy:\n <<: *base\n b: 2\n')
Other tags, complex keys and the indicator of the indentation of a block scalar are not supported, and raise an error, as do lines that the subset does not know.
dump() writes what the loader reads, in the block style of
configuration files: a dict is a mapping, a list and a
tuple are a sequence, {} and [] when they are empty, and a
string is plain where it reads back as the same string, quoted otherwise, and
a literal block scalar when it has several lines. bytes and dates
have the tags !!binary and !!timestamp, and another object is what
Pyjo.JSON encodes, the value of its method __json__ or its string.
A dict or a list that is there more than once has an anchor
where it is first and an alias after it, which the loader reads back as the
same object, and one inside itself raises an error, as the loader cannot read
it back; a tuple has no identity of its own, as the compiler can
share one that is a constant, and it is written again.
# 'name: Pyjoyment\nlist:\n - one\n - 2\nrun: |\n make\n'
dump({'name': 'Pyjoyment', 'list': ['one', 2], 'run': 'make\n'})
See also¶
Pyjoyment.Plugin.YAMLConfig, https://mojolicious.org.
Inspired by CPAN::Meta::YAML of Adam Kennedy and David Golden, which Mojolicious uses, whose regular expressions of scalars and keys it borrows, with thanks.
- Pyjo.YAML.dump(value: Any, *, indent: int = 2, indent_sequences: bool = True, quote: Literal["'", '"'] | None = None, quote_keys: Literal["'", '"'] | None = None, multiline: bool = True, explicit_start: bool = False, version: Literal['1.1', '1.2'] = '1.1', anchors: bool = True) str[source]¶
string = dump(value) string = dump(value, indent=4, indent_sequences=False, quote='"')
Dump a value to a YAML string of one document, with the options:
indent, the number of spaces of a level of the indentation,2by default;indent_sequences, whether a sequence below a key is indented,Trueby default, or has its items at the column of the key;quote, the quotes of every string value,"'"or'"', orNoneby default, for quotes only where a string needs them, single ones unless it needs the escapes of the double ones, which a string gets with any of them;quote_keys, the same for the keys, which are quoted only where they need it by default;multiline, whether a string of several lines is a literal block scalar,Trueby default, or a quoted scalar; a string whose lines a block scalar cannot keep, as one with a first line that starts with a space, is quoted anyway;explicit_start, whether the document starts with---,Falseby default; a scalar document always does;version, the YAML whose reader gets the strings back:'1.1'by default quotes also the strings that YAML 1.1 reads as other types, asyes,off,1_000,12:30and2001-12-14, which PyYAML reads so, and'1.2'only those of the core schema of YAML 1.2, astrue,nulland1.5;anchors, whether adictor alistthat is there more than once has an anchor where it is first and an alias after it,Trueby default, or is written again; an anchor has the name of the key of the collection, or of the sequence of the item, with the characters that are notA-Z,a-z,0-9,_and-as_,idwithout a key, and a number from2for another anchor of the same name.# 'foo:\n- "bar"\n' dump({'foo': ['bar']}, indent_sequences=False, quote='"')
- Pyjo.YAML.dump_all(values: Iterable[Any], *, indent: int = 2, indent_sequences: bool = True, quote: Literal["'", '"'] | None = None, quote_keys: Literal["'", '"'] | None = None, multiline: bool = True, explicit_start: bool = False, version: Literal['1.1', '1.2'] = '1.1', anchors: bool = True) str[source]¶
string = dump_all(values)
Dump values to a YAML string of documents, one for each value, with the options of
dump(), where the documents after the first one start with---.# '--- first\n--- second\n' dump_all(['first', 'second'])