loads

nestedtext.loads(content, top='dict', *, source=None, on_dup=None, keymap=None, normalize_key=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. As a short-hand, you may specify the dict, list, str, and any built-ins rather than specifying top with a string.

  • 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. Specifying “error” causes them to raise exceptions (the default behavior). 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 two arguments:

    key:

    The new key (duplicates an existing key).

    state:

    A dictionary containing other possibly helpful information:

    value:

    The value associated with the duplicate key.

    dictionary:

    The entire dictionary as it is at the moment the duplicate key is found. You should not change it.

    keys:

    The keys that identify the dictionary.

    This dictionary is created as loads is called and deleted as it returns. Any values placed in it are retained and available on subsequent calls to this function during the load operation.

    This function should return a new key. If the key duplicates an existing key, the value associated with that key is replaced. If None is returned, this key is ignored. If a KeyError is raised, the duplicate key is reported as an error.

    Be aware that de-duplication does not play nicely with keymaps when used to access values using the original keys as it is not possible to use the original keys to distinguish between the duplicate key-sets. If an error occurs in the value of one of the duplicates, it may be reported as occurring in one of the others.

  • keymap (dict) – Specify an empty dictionary or nothing at all for the value of this argument. If you give an empty dictionary it will be filled with location information for the values that are returned. Upon return the dictionary maps a tuple containing the keys for the value of interest to the location of that value in the NestedText source document. The location is contained in a Location object. You can access the line and column number using the Location.as_tuple() method, and the line that contains the value annotated with its location using the Location.as_line() method.

  • normalize_key (func) – A function that takes two arguments; the original key for a value and the tuple of normalized keys for its parent values. It then transforms the given key into the desired normalized form. Only called on dictionary keys, so the key will always be a string.

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 of the type specified by top is returned. If top is “any” None is returned.

Raises

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

Examples

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

>>> import nestedtext as nt

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

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

>>> print(data)
{'name': 'Kristel Templeton', 'gender': '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 NestedText document. 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.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, 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'}