pg.object_utils.canonicalize

Accessible via pg.object_utils.canonicalize.

canonicalize(src, sparse_list_as_dict=True)[source]

Canonicalize (maybe) non-canonical hierarchical value. :rtype: Any

Non-canonical hierarchical values are dicts or nested structures of dicts that contain keys with ‘.’ or ‘[<number>]’. Canonicalization is to unfold ‘.’ and ‘[]’ in their keys (‘.’ or ‘[]’) into multi-level dicts.

For example:

[1, {
  "a.b[0]": {
    "e.f": 1
  }
  "a.b[0].c[x.y].d": 10
}]

will result in:

[1, {
  "a": {
    "b": [{
      "c": {
        "x.y": {
          "d": 10
        }
      }
      "e": {
        "f": 1
      }
    }]
  }
}]

A sparse array indexer can be used in a non-canonical form. e.g:

{
  'a[1]': 123,
  'a[5]': 234
}

This is to accommodate scenarios of list element update/append. When sparse_list_as_dict is set to true (by default), dict above will be converted to:

{
  'a': [123, 234]
}

Otherwise sparse indexer will be kept so the container type will remain as a dict:

{
  'a': {
    1: 123,
    5: 234
  }
}

(Please note that sparse indexer as key is not JSON serializable.)

This is the reverse operation of method flatten. If input value is a simple type, the value itself will be returned.

Parameters:
  • src – A simple type or a nested structure of dict that may contains keys with JSON paths like ‘a.b.c’

  • sparse_list_as_dict – Whether convert sparse list to dict. When this is set to True, indices specified in the key path will be kept. Otherwise, a list will be returned with elements ordered by indices in the path.

Returns:

A nested structure of ordered dict that has only canonicalized keys or src itself if it’s not a nested structure of dict. For dict of int keys whose values form a perfect range(0, N) will be returned as a list.

Raises:

KeyError – If key is empty or the same key yields conflicting values after resolving non-canonical paths. E.g: {‘’: 1} or {‘a.b’: 1, ‘a.b.c’: True}.