pg.KeyPath¶
Accessible via pg.KeyPath
, pg.object_utils.KeyPath
.
- class KeyPath(key_or_key_list=None, parent=None)[source]¶
Bases:
pg.Formattable
Represents a path of keys from the root to a node in a tree.
KeyPath
is an important concept in PyGlove, which is used for representing a symbolic object’s location (seepg.Symbolic
) within its symbolic tree. For example:@pg.members([ ('x', pg.typing.Int()), ('y', pg.typing.Str()) ]) class A(pg.Object): pass @pg.members([ ('z', pg.typing.Object(A)) ]) class B(pg.Object): pass a = A(x=1, y='foo') b = B(z=a) assert a.sym_path == 'z' # The path to object `a` is 'z'. assert b.sym_path == '' # The root object's KeyPath is empty.
Since each node in a tree has a unique location, given the root we shall be able to use a
KeyPath
object to locate the node. With the example above, we can query the memberx
of objecta
via:pg.KeyPath.parse('z.x').query(b) # Should return 1.
Similarly, we can modify a symbolic object’s sub-node based on a
KeyPath
object. Seepg.Symbolic
for modifying sub-nodes in a symbolic tree.Attributes:
The depth of this path.
Returns True if this path is the root of a tree.
The rightmost key of this path.
A list of keys in this path.
The
KeyPath
object for current node's parent.JSONPath representation of current path.
Methods:
exists
(src)Returns whether current path exists in source object.
format
(*args, **kwargs)Format current path.
from_value
(value)Returns a KeyPath object from a KeyPath equivalence.
get
(src[, default_value, use_inferred])Gets the value of current path from an object with a default value.
parse
(path_str[, parent])Creates a
KeyPath
object from parsing a JSONPath-like string.path_str
([preserve_complex_keys])Returns JSONPath representation of current path.
query
(src[, use_inferred])Query the value from the source object based on current path.
- classmethod from_value(value)[source]¶
Returns a KeyPath object from a KeyPath equivalence.
- Return type:
- get(src, default_value=None, use_inferred=False)[source]¶
Gets the value of current path from an object with a default value.
- Return type:
- property parent: KeyPath[source]¶
The
KeyPath
object for current node’s parent.Example:
path = pg.KeyPath.parse('a.b.c.') assert path.parent == 'a.b'
- Returns:
A
KeyPath
object for the parent of current node.- Raises:
KeyError – If current path is the root.
- classmethod parse(path_str, parent=None)[source]¶
Creates a
KeyPath
object from parsing a JSONPath-like string.The JSONPath (https://restfulapi.net/json-jsonpath/) like string is defined as following:
<path> := <empty> | {<dict-key>[.<dict-key>]*} <dict-key> := <identifier>['[('<list-key>|<special-dict-key>)']']* <list-key> := <number> <special-dict-key> := <string-with-delimiter-chars> <delimiter_chars> := '[' | ']' | '.'
For example, following keys are valid path strings:
'' : An empty path representing the root of a path. 'a' : A path that contains a dict key 'a'. 'a.b' : A path that contains two dict keys 'a' and 'b'. 'a[0]' : A path that contains a dict key 'a' and a list key 0. 'a.0.' : A path that contains two dict keys 'a' and '0'. 'a[0][1]' : A path that contains a dict key 'a' and two list keys 0 and 1 for a multi-dimension list. 'a[x.y].b' : A path that contains three dict keys: 'a', 'x.y', 'b'. Since 'x.y' has delimiter characters, it needs to be enclosed in brackets.
TODO(daiyip): Support paring
KeyPath
from keys of complex types. Now this method only supports parsing KeyPath of string and int keys. That being said,format
/parse
are not symmetric, whileformat
can convert aKeyPath
that includes complex keys into a string,parse
is not able to convert them back.- Return type:
- Parameters:
path_str – A JSON-path-like string.
parent – Parent KeyPath object.
- Returns:
A KeyPath object.
- Raises:
ValueError – Path string is in bad format.
- path_str(preserve_complex_keys=True)[source]¶
Returns JSONPath representation of current path.
- Return type:
- Parameters:
preserve_complex_keys – if True, complex keys such as ‘x.y’ will be
brackets. (preserved by quoted in)
example (For) – KeyPath([‘a’, ‘x.y’, ‘b’]) will return ‘a[x.y].b’ when
True (preserve_complex_keys is)
when (and a.x.y.b)
False. (preserve_complex_keys is)
- Returns:
Path string.
- query(src, use_inferred=False)[source]¶
Query the value from the source object based on current path.
Example:
@pg.members([ ('x', pg.typing.Int()), ('y', pg.typing.Str()) ]) class A(pg.Object): pass @pg.members([ ('z', pg.typing.Object(A)) ]) class B(pg.Object): pass b = B(z=A(x=1, y='foo')) assert pg.KeyPath.parse('z.x').query(b) == 1
- Return type:
- Parameters:
src – Source value to query.
use_inferred – If True, infer pg.Inferential values. Otherwise returns their symbolic form. Applicable only for symbolic values.
- Returns:
Value from src if path exists.
- Raises:
KeyError – Path doesn’t exist in src.
RuntimeError – Called on a KeyPath that is considered as removed.