Utilities

Extras that are useful when using NestedText.

nestedtext.get_keys(keys, keymap, *, original=True, strict=True, sep=None)[source]

Returns a key sequence given a normalized key sequence.

Keys in the dataset output by the load functions are referred to as normalized keys, even though no key normalization may have occurred. This distinguishes them from the original keys, which are the keys given in the NestedText document read by the load functions. The original keys are mapped to normalized keys by the normalize_key argument to the load function. If normalization is not performed, the normalized keys are the same as the original keys.

By default this function returns the original key sequence that corresponds to keys, a normalized key sequence.

Parameters:
  • keys – The sequence of normalized keys that identify a value in the dataset.

  • keymap – The keymap returned from load() or loads().

  • original – If true, return keys as originally given in the NestedText document (pre-normalization). Otherwise return keys as they exist in the dataset (post-normalization). The value of this argument has no effect if the keys were not normalized.

  • strict

    strict controls what happens if the given keys are not found in keymap.

    The various options can be helpful when reporting errors on key sequences that do not exist in the data set. Since they are not in the dataset, the original keys are not available.

    True or “error”:

    A KeyError is raised.

    False or “all”:

    All keys given in keys are returned.

    ”found”:

    Only the initial available keys are returned.

    ”missing”:

    Only the missing final keys are returned.

    When returning keys, the initial available keys are converted to their original form if original is true, The missing keys are always returned as given.

Returns:

A tuple containing the desired keys.

Examples

>>> import nestedtext as nt

>>> contents = """
... Names:
...     Given: Fumiko
... """

>>> def normalize_key(key, keys):
...     return key.lower()

>>> data = nt.loads(contents, "dict", normalize_key=normalize_key, keymap=(keymap:={}))

>>> print(get_keys(("names", "given"), keymap))
('Names', 'Given')

>>> print(get_keys(("names", "given"), keymap, sep="❭"))
Names❭Given

>>> print(get_keys(("names", "given"), keymap, original=False))
('names', 'given')

>>> keys = get_keys(("names", "surname"), keymap, strict=True)
Traceback (most recent call last):
...
KeyError: ('names', 'surname')

>>> print(get_keys(("names", "surname"), keymap, strict="found"))
('Names',)

>>> print(get_keys(("names", "surname"), keymap, strict="missing"))
('surname',)

>>> print(get_keys(("names", "surname"), keymap, strict="all"))
('Names', 'surname')
nestedtext.get_value(data, keys)[source]

Get value from keys.

Parameters:
  • data – Your data set as returned by load() or loads().

  • keys – The sequence of normalized keys that identify a value in the dataset.

Returns:

The value that corresponds to a tuple of keys from a keymap.

Examples

>>> import nestedtext as nt

>>> contents = """
... names:
...     given: Fumiko
...     surname: Purvis
... """

>>> data = nt.loads(contents, "dict")

>>> get_value_from_keys(data, ("names", "given"))
'Fumiko'
nestedtext.get_line_numbers(keys, keymap, kind='value', *, strict=True, sep=None)[source]

Get line numbers from normalized key sequence.

This function returns the line numbers of the key or value selected by keys. It is used when reporting an error in a value that is possibly a multiline string. If the location contained in a keymap were used the user would only see the line number of the first line, which may confuse some users into believing the error is actually contained in the first line. Using this function gives both the starting and ending line number so the user focuses on the whole string and not just the first line. This only happens for multiline keys and multiline strings.

If sep is given, either one line number or both the beginning and ending line numbers are returned, joined with the separator. In this case the line numbers start from line 1.

If sep is not given, the line numbers are returned as a tuple containing a pair of integers that is tailored to be suitable to be arguments to the Python slice function (see example). The beginning line number and 1 plus the ending line number is returned as a tuple. In this case the line numbers start at 0.

If keys corresponds to a composite value (a dictionary or list), the line on which it ends cannot be easily determined, so the value is treated as if it consists of a single line. This is considered tolerable as it is expected that this function is primarily used to return the line number of leaf values, which are always strings.

Parameters:
  • keys – The sequence of normalized keys that identify a value in the dataset.

  • keymap – The keymap returned from load() or loads().

  • kind – Specify either “key” or “value” depending on which token is desired.

  • strict – If strict is true, a KeyError is raised if keys is not found. Otherwise the line number that corresponds to composite value that would contain keys if it existed. This composite value corresponds to the largest sequence of keys that does actually exist in the dataset.

  • sep – The separator string. If given a string is returned and sep is inserted between two line numbers. Otherwise a tuple is returned.

Raises:

KeyError – If keys are not in keymap and strict is true.

Example

>>> import nestedtext as nt
>>> doc = """
... key:
...     > this is line 1
...     > this is line 2
...     > this is line 3
... """
>>> data = nt.loads(doc, keymap=(keymap:={}))
>>> keys = ("key",)
>>> lines = nt.get_line_numbers(keys, keymap, sep="-")
>>> text = doc.splitlines()
>>> print(
...     f"Lines {lines}:",
...     *text[slice(*nt.get_line_numbers(keys, keymap))],
...     sep="\n"
... )
Lines 3-5:
    > this is line 1
    > this is line 2
    > this is line 3
nestedtext.get_location(keys, keymap)[source]

Returns Location information from the keys. None is returned if location is unknown.

Parameters:
  • keys – The sequence of normalized keys that identify a value in the dataset.

  • keymap – The keymap returned from load() or loads().

Deprecated functions

These functions are to be removed in future versions.

nestedtext.get_value_from_keys(data, keys)[source]

Get value from keys.

Deprecated in version 3.7 and is to be removed in future versions. get_value_from_keys() is replaced get_value(), which is identical.

Parameters:
  • data – Your data set as returned by load() or loads().

  • keys – The sequence of normalized keys that identify a value in the dataset.

Returns:

The value that corresponds to a tuple of keys from a keymap.

Examples

>>> import nestedtext as nt

>>> contents = """
... names:
...     given: Fumiko
...     surname: Purvis
... """

>>> data = nt.loads(contents, "dict")

>>> get_value_from_keys(data, ("names", "given"))
'Fumiko'
nestedtext.get_lines_from_keys(data, keys, keymap, kind='value', sep=None)[source]

Get line numbers from normalized keys.

Deprecated in version 3.7 and is to be removed in future versions. Use get_line_numbers() as a replacement.

This function returns the line numbers of the key or value selected by keys. It is used when reporting an error in a value that is possibly a multiline string. If the location contained in a keymap were used the user would only see the line number of the first line, which may confuse some users into believing the error is actually contained in the first line. Using this function gives both the starting and ending line number so the user focuses on the whole string and not just the first line.

If sep is given, either one line number or both the beginning and ending line numbers are returned, joined with the separator. In this case the line numbers start from line 1.

If sep is not given, the line numbers are returned as a tuple containing a pair of integers that is tailored to be suitable to be arguments to the Python slice function (see example). The beginning line number and 1 plus the ending line number is returned as a tuple. In this case the line numbers start at 0.

If the value is requested and it is a composite (a dictionary or list), the line on which it ends cannot be easily determined, so the value is treated as if it consists of a single line. This is considered tolerable as it is expected that this function is primarily used to return the line number of leaf values, which are always strings.

Parameters:
  • data – Your data set as returned by load() or loads().

  • keys – The collection of keys that identify a value in the dataset.

  • keymap – The keymap returned from load() or loads().

  • kind (str) – Specify either “key” or “value” depending on which token is desired.

  • sep – The separator string. If given a string is returned and sep is inserted between two line numbers. Otherwise a tuple is returned.

Example

>>> import nestedtext as nt
>>> doc = """
... key:
...     > this is line 1
...     > this is line 2
...     > this is line 3
... """
>>> data = nt.loads(doc, keymap=(keymap:={}))
>>> keys = ("key",)
>>> lines = nt.get_lines_from_keys(data, keys, keymap, sep="-")
>>> text = doc.splitlines()
>>> print(
...     f"Lines {lines}:",
...     *text[slice(*nt.get_lines_from_keys(data, keys, keymap))],
...     sep="\n"
... )
Lines 3-5:
    > this is line 1
    > this is line 2
    > this is line 3
nestedtext.get_original_keys(keys, keymap, strict=False)[source]

Get original keys from normalized keys.

Deprecated in version 3.7 and is to be removed in future versions. Use get_keys() as a replacement.

This function is used when the normalize_key argument is used with load() or loads() to transform the keys to a standard form. Given a set of normalized keys that point to a particular value in the returned dataset, this function returns the original keys for that value.

Parameters:
  • keys – The collection of normalized keys that identify a value in the dataset.

  • keymap – The keymap returned from load() or loads().

  • strict – If true, a KeyError is raised if the given keys are not found in keymap. Otherwise, the given normalized keys will be returned rather than the original keys. This is helpful when reporting errors on required keys that do not exist in the data set. Since they are not in the dataset, the original keys are not available.

Returns:

A tuple containing the original keys names.

Examples

>>> import nestedtext as nt

>>> contents = """
... Names:
...     Given: Fumiko
... """

>>> def normalize_key(key, keys):
...     return key.lower()

>>> data = nt.loads(contents, "dict", normalize_key=normalize_key, keymap=(keymap:={}))

>>> print(get_original_keys(("names", "given"), keymap))
('Names', 'Given')

>>> print(get_original_keys(("names", "surname"), keymap))
('Names', 'surname')

>>> keys = get_original_keys(("names", "surname"), keymap, strict=True)
Traceback (most recent call last):
...
KeyError: ('names', 'surname')
nestedtext.join_keys(keys, sep=', ', keymap=None, strict=False)[source]

Joins the keys into a string.

Deprecated in version 3.7 and is to be removed in future versions. Use get_keys() as a replacement.

Parameters:
  • keys – A tuple of keys.

  • sep – The separator string. It is inserted between each key during the join.

  • keymap – The keymap returned from load() or loads(). It is optional. If given the given keys are converted to the original keys before the joining.

  • strict – If true, a KeyError is raised if the given keys are not found in keymap. Otherwise, the given normalized keys will be returned rather than the original keys. This is helpful when reporting errors on required keys that do not exist in the data set. Since they are not in the dataset, the original keys are not available.

Returns:

A string containing the joined keys.

Examples

>>> import nestedtext as nt

>>> contents = """
... Names:
...     Given: Fumiko
... """

>>> def normalize_key(key, keys):
...     return key.lower()

>>> data = nt.loads(contents, "dict", normalize_key=normalize_key, keymap=(keymap:={}))

>>> join_keys(("names", "given"))
'names, given'

>>> join_keys(("names", "given"), sep=".")
'names.given'

>>> join_keys(("names", "given"), keymap=keymap)
'Names, Given'

>>> join_keys(("names", "surname"), keymap=keymap)
'Names, surname'

>>> join_keys(("names", "surname"), keymap=keymap, strict=True)
Traceback (most recent call last):
    ...
KeyError: ('names', 'surname')