nestedtext.loads

nestedtext.loads(content, top='dict', *, source=None, on_dup=None)[source]

Loads NestedText from string.

Parameters
  • content (str) – String that contains encoded data.

  • top (str) – Top-level data type. The NestedText format allows for a dictionary, a list, or a string as the top-level data container. By specifying top as ‘dict’, ‘list’, or ‘str’ you constrain both the type of top-level container and the return value of this function. By specifying ‘any’ you enable support for all three data types, with the type of the returned value matching that of top-level container in content.

  • source (str or Path) – If given, this string is attached to any error messages as the culprit. It is otherwise unused. Is often the name of the file that originally contained the NestedText content.

  • on_dup (str or func) –

    Indicates how duplicate keys in dictionaries should be handled. By default they raise exceptions. Specifying ‘ignore’ causes them to be ignored (first wins). Specifying ‘replace’ results in them replacing earlier items (last wins). By specifying a function, the keys can be de-duplicated. This call-back function returns a new key and takes four arguments:

    1. The new key (duplicates an existing key).

    2. The new value.

    3. The entire dictionary as it is at the moment the duplicate key is found.

    4. The state; a dictionary that is created as the loads is called and deleted as it returns. Values placed in this dictionary are retained between multiple calls to this call back function.

Returns

The extracted data. The type of the return value is specified by the top argument. If top is ‘any’, then the return value will match that of top-level data container in the input content. If content is empty, an empty data value is return of the type specified by top. If top is ‘any’ None is returned.

Raises

NestedTextError – if there is a problem in the NextedText content.

Examples

NestedText is specified to loads in the form of a string:

>>> import nestedtext as nt

>>> contents = """
... name: Kristel Templeton
... sex: female
... age: 74
... """

>>> try:
...     data = nt.loads(contents, 'dict')
... except nt.NestedTextError as e:
...     e.terminate()

>>> print(data)
{'name': 'Kristel Templeton', 'sex': 'female', 'age': '74'}

loads() takes an optional argument, source. If specified, it is added to any error messages. It is often used to designate the source of contents. For example, if contents were read from a file, source would be the file name. Here is a typical example of reading NestedText from a file:

>>> filename = 'examples/duplicate-keys.nt'
>>> try:
...     with open(filename, encoding='utf-8') as f:
...         addresses = nt.loads(f.read(), source=filename)
... except nt.NestedTextError as e:
...     print(e.render())
...     print(*e.get_codicil(), sep="\n")
examples/duplicate-keys.nt, 5: duplicate key: name.
   4 «name:»
   5 «name:»

Notice in the above example the encoding is explicitly specified as ‘utf-8’. NestedText files should always be read and written using utf-8 encoding.

The following examples demonstrate the various ways of handling duplicate keys:

>>> content = """
... key: value 1
... key: value 2
... key: value 3
... name: value 4
... name: value 5
... """

>>> print(nt.loads(content))
Traceback (most recent call last):
...
nestedtext.NestedTextError: 3: duplicate key: key.

>>> print(nt.loads(content, on_dup='ignore'))
{'key': 'value 1', 'name': 'value 4'}

>>> print(nt.loads(content, on_dup='replace'))
{'key': 'value 3', 'name': 'value 5'}

>>> def de_dup(key, value, data, state):
...     if key not in state:
...         state[key] = 1
...     state[key] += 1
...     return f"{key}#{state[key]}"

>>> print(nt.loads(content, on_dup=de_dup))
{'key': 'value 1', 'key#2': 'value 2', 'key#3': 'value 3', 'name': 'value 4', 'name#2': 'value 5'}