pg.Symbolic¶
Accessible via pg.Symbolic, pg.symbolic.Symbolic.
- class Symbolic(*, allow_partial, accessor_writable, sealed, root_path, init_super=True)[source]¶
Bases:
TopologyAware,pg.Formattable,pg.JSONConvertible,pg.MaybePartial,pg.views.HtmlConvertibleBase for all symbolic types.
Symbolic types are types that provide interfaces for symbolic programming, based on which symbolic objects can be created. In PyGlove, there are three categories of symbolic types:
Symbolic classes: Defined by
pg.Objectsubclasses, including symbolic classes created frompg.symbolize, which inheritpg.ClassWrapper, a subclass ofpg.Object.Symbolic functions: Defined by
pg.Functor.
Classes:
Methods:
Get converter from source type to a JSON simple type.
__copy__()Overridden shallow copy.
__deepcopy__(memo)Overridden deep copy.
add_module_alias(module, alias)Adds a module alias so previous serialized objects could be loaded.
class_from_typename(type_name)Gets the class for a registered type name.
clone([deep, memo, override])Clones current object symbolically.
format([compact, verbose, root_indent])Formats this object into a string representation.
from_json(json_value, **kwargs)Creates an instance of this class from a plain Python value.
inspect([path_regex, where, ...])Inspects current object by printing out selected values.
is_registered(type_name)Returns True if a type name is registered.
load(*args, **kwargs)Loads an instance of this type using the global load handler.
Context manager for loading unregistered types for deserialization.
missing_values([flatten])Alias for sym_missing.
non_default_values([flatten])Alias for sym_nondefault.
rebind([path_value_pairs, ...])Alias for sym_rebind.
register(type_name, subclass[, ...])Registers a class with a type name.
Returns an iterator of registered (serialization key, class) tuples.
save(*args, **kwargs)Saves current object using the global save handler.
seal([sealed])Alias for sym_seal.
set_accessor_writable([writable])Sets accessor writable.
sym_ancestor([where])Returns the nearest ancestor of specific classes.
sym_attr_field(key)Returns the field definition for a symbolic attribute.
sym_clone([deep, memo, override])Clones current object symbolically.
sym_contains([value, type])Returns True if the object contains sub-nodes of given value or type.
sym_descendants([where, option, include_self])Returns all descendants of specific classes.
sym_eq(other)Returns if this object equals to another object symbolically.
sym_get(path[, default, use_inferred])Returns a sub-node by path.
sym_getattr(key[, default])Gets a symbolic attribute.
sym_gt(other)Returns if this object is symbolically greater than another object.
sym_has(path)Returns True if a path exists in the sub-tree.
sym_hasattr(key)Returns if a symbolic attribute exists.
sym_hash()Computes the symbolic hash of current object.
sym_inferrable(key, **kwargs)Returns True if the attribute under key can be inferred.
sym_inferred(key[, default])Returns the inferred value of the attribute under key.
Iterates the (key, value) pairs of symbolic attributes.
sym_jsonify(*[, hide_default_values])Converts representation of current object to a plain Python object.
sym_keys()Iterates the keys of symbolic attributes.
sym_lt(other)Returns True if this object is symbolically less than other object.
sym_missing([flatten])Returns missing values.
sym_ne(other)Returns if this object does not equal to another object symbolically.
sym_nondefault([flatten])Returns missing values.
sym_rebind([path_value_pairs, ...])Mutates the sub-nodes of current object.
sym_seal([is_seal])Seals or unseals current object from further modification.
sym_setorigin(source, tag[, stacktrace, ...])Sets the symbolic origin of current object.
sym_setparent(parent)Sets the parent of current node in the symbolic tree.
sym_setpath(path)Sets the path of current node in its symbolic tree.
Iterates the values of symbolic attributes.
to_html(**kwargs)Returns the HTML representation of the object.
to_html_str(*[, content_only])Returns the HTML str of the object.
to_json(**kwargs)Alias for sym_jsonify.
to_json_dict(fields, *[, exclude_default, ...])Helper method to create JSON dict from class and field.
to_json_str([json_indent])Serializes current object into a JSON string.
Attributes:
Returns True if mutation can be made by attribute assignment.
Returns True if partial binding is allowed.
Alias for sym_abstract.
Returns if current object is deterministic.
Alias for sym_partial.
Alias for sym_puresymbolic.
Alias for sym_sealed.
Returns True if current value is abstract (partial or pure symbolic).
Returns the symbolic field for current object.
Returns the symbolic origin of current object.
Returns the containing symbolic object.
Returns True if current value is partial.
Returns the path of current object from the root of its symbolic tree.
Returns True if current value is or contains subnodes of PureSymbolic.
Returns the root of the symbolic tree.
Returns True if current object is sealed.
- property accessor_writable: bool[source]¶
Returns True if mutation can be made by attribute assignment.
- classmethod add_module_alias(module, alias)[source]¶
Adds a module alias so previous serialized objects could be loaded.
- Return type:
- classmethod class_from_typename(type_name)[source]¶
Gets the class for a registered type name.
- Return type:
- Parameters:
type_name – A string as the global unique type identifier for requested class.
- Returns:
A type object if registered, otherwise None.
- clone(deep=False, memo=None, override=None)[source]¶
Clones current object symbolically.
- Return type:
- Parameters:
deep – If True, perform deep copy (equivalent to copy.deepcopy). Otherwise shallow copy (equivalent to copy.copy).
memo – Memo object for deep clone.
override – An optional dict of key path to new values to override cloned value.
- Returns:
A copy of self.
- abstract format(compact=False, verbose=True, root_indent=0, **kwargs)[source]¶
Formats this object into a string representation.
- Return type:
- Parameters:
compact – If True, this object will be formatted into a single line.
verbose – If True, this object will be formatted with verbosity. Subclasses should define verbosity on their own.
root_indent – The start indent level for this object if the output is a multi-line string.
**kwargs – Subclass specific keyword arguments.
- Returns:
A string of formatted object.
- classmethod from_json(json_value, **kwargs)[source]¶
Creates an instance of this class from a plain Python value.
NOTE(daiyip):
pg.Symbolicoverridesfrom_jsonclass method.- Return type:
- Parameters:
json_value – JSON value type.
**kwargs – Keyword arguments as flags to control object creation.
- Returns:
An instance of cls.
- inspect(path_regex=None, where=None, custom_selector=None, file=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, **kwargs)[source]¶
Inspects current object by printing out selected values.
Example:
@pg.members([ ('x', pg.typing.Int(0)), ('y', pg.typing.Str()) ]) class A(pg.Object): pass value = { 'a1': A(x=0, y=0), 'a2': [A(x=1, y=1), A(x=1, y=2)], 'a3': { 'p': A(x=2, y=1), 'q': A(x=2, y=2) } } # Inspect without constraint, # which is equivalent as `print(value.format(hide_default_values=True))` # Shall print: # { # a1 = A(y=0) # a2 = [ # 0: A(x=1, y=1) # 1: A(x=1, y=2) # a3 = { # p = A(x=2, y=1) # q = A(x=2, y=2) # } # } value.inspect(hide_default_values=True) # Inspect by path regex. # Shall print: # {'a3.p': A(x=2, y=1)} value.inspect(r'.*p') # Inspect by value. # Shall print: # { # 'a3.p.x': 2, # 'a3.q.x': 2, # 'a3.q.y': 2, # } value.inspect(where=lambda v: v==2) # Inspect by path, value and parent. # Shall print: # { # 'a2[1].y': 2 # } value.inspect( r'.*y', where=lambda v, p: v > 1 and isinstance(p, A) and p.x == 1)) # Inspect by custom_selector. # Shall print: # { # 'a2[0].x': 1, # 'a2[0].y': 1, # 'a3.q.x': 2, # 'a3.q.y': 2 # } value.inspect( custom_selector=lambda k, v, p: ( len(k) == 3 and isinstance(p, A) and p.x == v))
- Return type:
- Parameters:
path_regex – Optional regex expression to constrain path.
where – Optional callable to constrain value and parent when path matches path_regex or path_regex is not provided. The signature is: (value) -> should_select, or (value, parent) -> should_select.
custom_selector – Optional callable object as custom selector. When custom_selector is provided, path_regex and where must be None. The signature of custom_selector is: (key_path, value) -> should_select or (key_path, value, parent) -> should_select.
file – Output file stream. This can be any object with a write(str) method.
**kwargs – Wildcard keyword arguments to pass to format.
- classmethod is_registered(type_name)[source]¶
Returns True if a type name is registered. Otherwise False.
- Return type:
- classmethod load(*args, **kwargs)[source]¶
Loads an instance of this type using the global load handler.
- Return type:
- classmethod load_types_for_deserialization(*types_to_deserialize)[source]¶
Context manager for loading unregistered types for deserialization.
Example:
class A(pg.Object): auto_register = False x: int class B(A): y: str with pg.JSONConvertile.load_types_for_deserialization(A, B): pg.from_json_str(A(1).to_json_str()) pg.from_json_str(B(1, 'hi').to_json_str())
- Return type:
ContextManager[Dict[str,Type[Any]]]- Parameters:
*types_to_deserialize – A list of types to be loaded for deserialization.
- Returns:
- A context manager within which the objects of the requested types
could be deserialized.
- rebind(path_value_pairs=None, *, raise_on_no_change=True, notify_parents=True, skip_notification=None, **kwargs)[source]¶
Alias for sym_rebind.
Alias for sym_rebind. rebind is the recommended way for mutating symbolic objects in PyGlove: :rtype:
pg.SymbolicIt allows mutations not only on immediate child nodes, but on the entire sub-tree.
It allows mutations by rules via passing a callable object as the value for path_value_pairs.
It batches the updates from multiple sub-nodes, which triggers the _on_change or _on_bound event once for recomputing the parent object’s internal states.
It respects the “sealed” flag of the object or the pg.seal context manager to trigger permission error.
Example:
# # Rebind on pg.Object subclasses. # @pg.members([ ('x', pg.typing.Dict([ ('y', pg.typing.Int(default=0)) ])), ('z', pg.typing.Int(default=1)) ]) class A(pg.Object): pass a = A() # Rebind using path-value pairs. a.rebind({ 'x.y': 1, 'z': 0 }) # Rebind using **kwargs. a.rebind(x={y: 1}, z=0) # Rebind using rebinders. # Rebind based on path. a.rebind(lambda k, v: 1 if k == 'x.y' else v) # Rebind based on key. a.rebind(lambda k, v: 1 if k and k.key == 'y' else v) # Rebind based on value. a.rebind(lambda k, v: 0 if v == 1 else v) # Rebind baesd on value and parent. a.rebind(lambda k, v, p: (0 if isinstance(p, A) and isinstance(v, int) else v)) # Rebind on pg.Dict. # d = pg.Dict(value_spec=pg.typing.Dict([ ('a', pg.typing.Dict([ ('b', pg.typing.Int()), ])), ('c', pg.typing.Float()) ]) # Rebind using **kwargs. d.rebind(a={b: 1}, c=1.0) # Rebind using key path to value dict. d.rebind({ 'a.b': 2, 'c': 2.0 }) # NOT OKAY: **kwargs and dict/rebinder cannot be used at the same time. d.rebind({'a.b': 2}, c=2) # Rebind with rebinder by path (on subtree). d.rebind(lambda k, v: 1 if k.key == 'b' else v) # Rebind with rebinder by value (on subtree). d.rebind(lambda k, v: 0 if isinstance(v, int) else v) # # Rebind on pg.List. # l = pg.List([{ 'a': 'foo', 'b': 0, } ], value_spec = pg.typing.List(pg.typing.Dict([ ('a', pg.typing.Str()), ('b', pg.typing.Int()) ]), max_size=10)) # Rebind using integer as list index: update semantics on list[0]. l.rebind({ 0: { 'a': 'bar', 'b': 1 } }) # Rebind: trigger append semantics when index is larger than list length. l.rebind({ 999: { 'a': 'fun', 'b': 2 } }) # Rebind using key path. l.rebind({ '[0].a': 'bar2' '[1].b': 3 }) # Rebind using function (rebinder). # Change all integers to 0 in sub-tree. l.rebind(lambda k, v: v if not isinstance(v, int) else 0)
- Parameters:
path_value_pairs –
A dictionary of key/or key path to new field value, or a function that generate updates based on the key path, value and parent of each node under current object. We use terminology ‘rebinder’ for this type of functions. The signature of a rebinder is:
(key_path: pg.KeyPath, value: Any) or (key_path: pg.KeyPath, value: Any, parent: pg.Symbolic)
raise_on_no_change – If True, raises
ValueErrorwhen there are no values to change. This is useful when rebinder is used, which may or may not generate any updates.notify_parents – If True (default), parents will be notified upon change. Otherwisee only the current object and the impacted children will be notified. A most common use case for setting this flag to False is when users want to rebind a child within the parent _on_bound method.
skip_notification – If True, there will be no
_on_changeevent triggered from current rebind. If None, the default value will be inferred from thepg.notify_on_changecontext manager. Use it only when you are certain that current rebind does not invalidate internal states of its object tree.**kwargs – For
pg.Dictandpg.Objectsubclasses, user can use keyword arguments (in format of <field_name>=<field_value>) to directly modify immediate child nodes.
- Returns:
Self.
- Raises:
WritePermissionError – If object is sealed.
KeyError – If update location specified by key or key path is not aligned with the schema of the object tree.
TypeError – If updated field value type does not conform to field spec.
ValueError – If updated field value is not acceptable according to field spec, or nothing is updated and raise_on_no_change is set to True.
- classmethod register(type_name, subclass, override_existing=False)[source]¶
Registers a class with a type name.
The type name will be used as the key for class lookup during deserialization. A class can be registered with multiple type names, but a type name should be uesd only for one class.
- Return type:
- Parameters:
type_name – A global unique string identifier for subclass.
subclass – A subclass of JSONConvertible.
override_existing – If True, override the class if the type name is already present in the registry. Otherwise an error will be raised.
- classmethod registered_types()[source]¶
Returns an iterator of registered (serialization key, class) tuples.
- Return type:
- property sym_abstract: bool[source]¶
Returns True if current value is abstract (partial or pure symbolic).
- sym_contains(value=None, type=None)[source]¶
Returns True if the object contains sub-nodes of given value or type.
- Return type:
- sym_descendants(where=None, option=DescendantQueryOption.ALL, include_self=False)[source]¶
Returns all descendants of specific classes.
- Return type:
- Parameters:
where – Optional callable object as the filter of descendants to return.
option – Descendant query options, indicating whether all matched, immediate matched or only the matched leaf nodes will be returned.
include_self – If True, self will be included in the query, otherwise only strict descendants are included.
- Returns:
A list of objects that match the descendant_cls.
- sym_get(path, default=(MISSING_VALUE,), use_inferred=False)[source]¶
Returns a sub-node by path.
NOTE: there is no sym_set, use sym_rebind.
- Return type:
- Parameters:
path – A KeyPath object or equivalence.
default – Default value if path does not exists. If absent, KeyError will be thrown.
use_inferred – If True, return inferred value instead of the symbolic form of pg.Inferential objects.
- Returns:
Value of symbolic attribute specified by path if found, otherwise the default value if it’s specified.
- Raises:
KeyError if path does not exist and default is not specified. –
- sym_getattr(key, default=(MISSING_VALUE,))[source]¶
Gets a symbolic attribute.
- Return type:
- Parameters:
key – Key of symbolic attribute.
default – Default value if attribute does not exist. If absent,
- Returns:
Value of symbolic attribute if found, otherwise the default value if it’s specified.
- Raises:
AttributeError if key does not exist and default is not provided. –
- sym_gt(other)[source]¶
Returns if this object is symbolically greater than another object.
- Return type:
- sym_has(path)[source]¶
Returns True if a path exists in the sub-tree.
- Return type:
- Parameters:
path – A KeyPath object or equivalence.
- Returns:
True if the path exists in current sub-tree, otherwise False.
- sym_inferrable(key, **kwargs)[source]¶
Returns True if the attribute under key can be inferred.
- Return type:
- sym_inferred(key, default=(MISSING_VALUE,), **kwargs)[source]¶
Returns the inferred value of the attribute under key.
- Return type:
- abstract sym_jsonify(*, hide_default_values=False, **kwargs)[source]¶
Converts representation of current object to a plain Python object.
- sym_lt(other)[source]¶
Returns True if this object is symbolically less than other object.
- Return type:
- sym_ne(other)[source]¶
Returns if this object does not equal to another object symbolically.
- Return type:
- property sym_path: KeyPath[source]¶
Returns the path of current object from the root of its symbolic tree.
- property sym_puresymbolic: bool[source]¶
Returns True if current value is or contains subnodes of PureSymbolic.
- sym_rebind(path_value_pairs=None, *, raise_on_no_change=True, notify_parents=True, skip_notification=None, **kwargs)[source]¶
Mutates the sub-nodes of current object. Please see rebind.
- Return type:
- sym_seal(is_seal=True)[source]¶
Seals or unseals current object from further modification.
- Return type:
- sym_setorigin(source, tag, stacktrace=None, stacklimit=None, stacktop=-1)[source]¶
Sets the symbolic origin of current object.
- Parameters:
source – Source value for current object.
tag – A descriptive tag of the origin. Built-in tags are: __init__, clone, deepclone, return. Users can manually call sym_setorigin with custom tag value.
stacktrace – If True, enable stack trace for the origin. If None, enable stack trace if pg.tracek_origin() is called. Otherwise stack trace is disabled.
stacklimit – An optional integer to limit the stack depth. If None, it’s determined by the value passed to pg.set_origin_stacktrace_limit, which is 10 by default.
stacktop – A negative or zero-value integer indicating the stack top among the stack frames that we want to present to user, by default it’s 1-level up from the stack within current sym_setorigin call.
Example:
def foo(): return bar() def bar(): s = MyObject() t = s.build() t.sym_setorigin(s, 'builder', stacktrace=True, stacklimit=5, stacktop=-1)
This example sets the origin of t using s as its source with tag ‘builder’. We also record the callstack where the sym_setorigin is called, so users can call t.sym_origin.stacktrace to get the call stack later. The stacktop -1 indicates that we do not need the stack frame within
sym_setorigin, so users will see the stack top within the function bar. We also set the max number of stack frames to display to 5, not including the stack frame insidesym_setorigin.
- to_html_str(*, content_only=False, **kwargs)[source]¶
Returns the HTML str of the object.
- Return type: