ckdl Python Package¶
Download and install the ckdl
Python Package using pip:
% pip install ckdl
You can also build and install from source using pip:
% pip install path/to/ckdl/source
or some other PEP 517 compatible tool.
Note
As always, it is recommended to work in a venv
The Python ckdl API¶
A Brief Tour¶
Reading¶
>>> import ckdl
>>> kdl_txt = """
... node1 1 2 "three" (f64)4.0 {
... (some-type)"first child"
... child-2 prop="val"
... }
... """
>>> doc = ckdl.parse(kdl_txt)
>>> doc
<Document; 1 nodes>
>>> doc.nodes
[<Node node1; 4 args; 2 children>]
>>> doc.nodes[0]
<Node node1; 4 args; 2 children>
>>> doc[0].type_annotation
>>> doc[0].args
[1, 2, 'three', <Value (f64)4>]
>>> type(doc[0].args[0])
<class 'int'>
>>> type(doc[0].args[3])
<class 'ckdl._ckdl.Value'>
>>> doc[0].args[3]
<Value (f64)4>
>>> doc[0].args[3].type_annotation
'f64'
>>> doc[0].children
[<Node (some-type)"first child">, <Node child-2; 1 property>]
>>> doc[0].children[0].type_annotation
'some-type'
>>> doc[0].children[1].properties
{'prop': 'val'}
>>>
>>> # KDL v2 can be enabled like this
>>>
>>> doc2 = ckdl.parse("one 2 three #inf", version="detect")
>>> doc2.nodes
[<Node one; 3 args>]
>>> doc2.nodes[0].args
[2, 'three', inf]
>>>
Writing¶
>>> mydoc = ckdl.Document(
... ckdl.Node("node1", args=["argument 1", 2, None],
... properties={"node1-prop": 0xff_ff},
... children=[
... ckdl.Node("child1"),
... ckdl.Node("child2-type", "child2", child2_prop=True)
... ]),
... ckdl.Node(None, "node2", "arg1", "arg2", ckdl.Node("child3"), some_property="foo")
... )
>>> print(str(mydoc))
node1 "argument 1" 2 null node1-prop=65535 {
child1
(child2-type)child2 child2_prop=true
}
node2 "arg1" "arg2" some_property="foo" {
child3
}
>>>
>>> # KDL v2 output
>>>
>>> print(mydoc.dump(ckdl.EmitterOptions(version=2)))
node1 "argument 1" 2 #null node1-prop=65535 {
child1
(child2-type)child2 child2_prop=#true
}
node2 arg1 arg2 some_property=foo {
child3
}
API¶
The ckdl package is relatively simple. It provides one function to parse KDL,
three classes to represent data, and some classes to optionally configure the
emitter.
Parsing¶
- ckdl.parse(kdl_doc, *, version=1)¶
Parse a KDL document
- Parameters:
kdl_doc (str) – The KDL document to parse
version – Which version(s) to accept:
1for KDLv1 only,2for KDLv2 only, or eitherNoneor"detect"to support both.
- Return type:
- Raises:
Data types¶
- class ckdl.Value(type_annotation: str, value)¶
A KDL value with a type annotation.
Values without a type annotation are represented as NoneType, bool, int, float, or str.
- type_annotation¶
The type annotation of the value
- Type:
str
- value¶
The actual value
- class ckdl.Node¶
A KDL node, with its arguments, properties and children
- type_annotation¶
Type annotation as str or NoneType
- name¶
Node name - str
- args¶
Node args - list
- properties¶
Node properties - dict
The Node constructor supports a number of different signatures.
If the first two arguments are strings, or None and a string, they are interpreted as the type annotation and the node tag name. Then, either:
Node([type_annotation,] name, *args, *children, **properties)the remaining positional arguments are all the node arguments, followed by the child nodes, and the keyword arguments are the properties, orNode([type_annotation,] name, [args, [children, ]] *, **properties)the next positional arguments are lists of all the arguments and children, and the keyword arguments are the properties, orNode([type_annotation,] name, [args=..., [children=..., ]] *, [properties=...])the properties are passed as a dict in thepropertieskeyword argument, the arguments are passed as a list either in theargskeyword argument, or the positional argument after the tag name, and the children are similarly passed as a list, either in thechildrenkeyword argument, or in the positional argument following the node arguments.
Note that when the node arguments are given as positional arguments, and the first argument is a string, the type annotation cannot be omitted (
Node("name", "arg", 1)is(name)arg 1, andNode(None, "name", "arg", 1)isname "arg" 1, butNode("name", 1, 2)isname 1 2).
Emitter configuration¶
- class ckdl.EmitterOptions(*, indent=None, escape_mode=None, identifier_mode=None, float_mode=None, version=None)¶
- indent¶
Number of spaces to indent child nodes by (default: 4)
- Type:
int
- escape_mode¶
Which characters should be escaped in regular strings?
- Type:
- identifier_mode¶
How should identifiers (i.e., node names, type annotations and property keys) be rendered?
- Type:
- version¶
Which KDL version to emit? The constructor accepts
KdlVersionandint.- Type:
- class ckdl.FloatMode(*, always_write_decimal_point=None, always_write_decimal_point_or_exponent=None, capital_e=None, exponent_plus=None, plus=None, min_exponent=None)¶
- always_write_decimal_point¶
- Type:
bool
- always_write_decimal_point_or_exponent¶
- Type:
bool
- capital_e¶
- Type:
bool
- exponent_plus¶
- Type:
bool
- plus¶
- Type:
bool
- min_exponent¶
- Type:
int