pg.ValueSpec¶
Accessible via pg.ValueSpec, pg.typing.ValueSpec.
- class ValueSpec[source]¶
Bases:
pg.Formattable,pg.JSONConvertibleInterface for value specifications.
A value specification defines what values are acceptable for a symbolic field (see
pg.Field). When assignments take place on the attributes for the field, the associated ValueSpec object will kick in to intercept the process and take care of the following aspects:Type check
Noneable check
Value validation and transformation
Default value assignment
See
applyfor more details.Different aspects of assignment interception are handled by the following methods:
Aspect name
Property/Method
Type check
Noneable check
Type-specific value validation and transformation
User transform
Default value lookup
There are many
ValueSpecsubclasses, each correspond to a commonly used Python type, e.g. Bool, Int, Float and etc. PyGlove’s builtin value specifications are:Construction
A value specification is an instance of a
ValueSpecsubclass. Allpg.ValueSpecsubclasses follow a common pattern to construct:pg.typing.<ValueSpecClass>( [validation-rules], [default=<default>], [transform=<transform>])
After creation, a
ValueSpecobject can be modified with chaining. The code below creates an int specification with default value 1 and can accept None:pg.typing.Int().noneable().set_default(1)
Usage
To apply a value specification on an user input to get the accepted value,
pg.ValueSpecshall be used:value == pg.typing.Int(min_value=1).apply(4) assert value == 4
Extension
Besides, a
ValueSpecobject can extend anotherValueSpecobject to obtain a more restrictedValueSpecobject. For example:pg.typing.Int(min_value=1).extend(pg.typing.Int(max_value=5))
will end up with:
pg.typing.Int(min_value=1, max_value=5)
which will be useful when subclass adds additional restrictions to an inherited symbolic attribute from its base class. For some use cases, a value spec can be frozen to avoid subclass extensions:
pg.typing.Int().freeze(1)
ValueSpecobjects can be created and modified with chaining. For example:pg.typing.Int().noneable().set_default(1)
The code above creates an int specification with default value 1 and can accept None.
ValueSpecobject can also be derived from annotations. For example, annotation below- @pg.members([
(‘a’, pg.typing.List(pg.typing.Str)), (‘b’, pg.typing.Dict().set_default(‘key’: ‘value’)), (‘c’, pg.typing.List(pg.typing.Any()).noneable()), (‘x’, pg.typing.Int()), (‘y’, pg.typing.Str().noneable()), (‘z’, pg.typing.Union(pg.typing.Int(), pg.typing.Float()))
])
can be writen as
- @pg.members([
(‘a’, list[str]), (‘b’, {‘key’: ‘value}), (‘c’, Optional[list]), (‘x’, int), (‘y’, Optional[str]), (‘z’, Union[int, float])
])
Classes:
alias of
pg.typing.Dictalias of
pg.typing.Listalias of
pg.typing.ObjectAttributes:
Returns PyType annotation.
Returns the default value.
Returns forward referenes used by the value spec.
Returns True if current value spec is frozen.
Returns True if the default value is provided.
Returns True if current value spec accepts None.
Returns a transform that will be applied on the input before apply.
Returns True if all forward references are resolved.
Returns acceptable (resolved) value type(s).
Methods:
apply(value[, allow_partial, ...])Validates, completes and transforms the input value.
extend(base)Extends a base spec with current spec's rules.
freeze([permanent_value, apply_before_use])Sets the default value using a permanent value and freezes current spec.
from_annotation([auto_typing, ...])Creates a value spec from annotation.
from_json_schema(json_schema[, class_fn, ...])Creates a PyGlove value spec from a JSON schema.
is_compatible(other)Returns True if values acceptable to other is acceptable to this spec.
noneable([is_noneable, use_none_as_default])Marks none-able and returns self.
set_default(default[, use_default_apply, ...])Sets the default value and returns self.
to_json_schema(*[, include_type_name, ...])Converts a value spec to JSON schema.
- DictType[source]¶
alias of
pg.typing.Dict
- ListType[source]¶
alias of
pg.typing.List
- ObjectType[source]¶
alias of
pg.typing.Object
- abstract property annotation: Any[source]¶
Returns PyType annotation. MISSING_VALUE if annotation is absent.
- abstract apply(value, allow_partial=False, child_transform=None, root_path=None)[source]¶
Validates, completes and transforms the input value.
Here is the procedure of
apply:(1). Choose the default value if the input value is ``MISSING_VALUE`` (2). Check whether the input value is None. (2.a) Input value is None and ``value_spec.is_noneable()`` is False, raises Error. (2.b) Input value is not None or ``value_spec.is_noneable()`` is True, goto step (3). (3). Run ``value_spec.custom_apply`` if the input value is a ``CustomTyping`` instance. (3.a). If ``value_spec.custom_apply`` returns a value that indicates to proceed with standard apply, goto step (4). (3.b). Else goto step (6) (4). Check the input value type against the ``value_spec.value_type``. (4.a). If their value type matches, go to step (5) (4.b). Else if there is a converter registered between input value type and the value spec's value type, perform the conversion, and go to step (5). (see pg.typing.register_converter) (4.c) Otherwise raises type mismatch. (5). Perform type-specific and user validation and transformation. For complex types such as Dict, List, Tuple, call `child_spec.apply` recursively on the child fields. (6). Perform user transform and returns final value (invoked at Field.apply.)- Return type:
- Parameters:
value – Input value to apply.
allow_partial – If True, partial value is allowed. This is useful for container types (dict, list, tuple).
child_transform – Function to transform child node values into final values. (NOTE: This transform will not be performed on current value. Instead transform on current value is done by Field.apply, which has adequate information to call transform with both KeySpec and ValueSpec).
root_path – Key path of current node.
- Returns:
When allow_partial is set to False (default), only input value that has no missing values can be applied.
When allow_partial is set to True, missing fields will be placeheld using MISSING_VALUE.
- Return type:
Final value
- Raises:
KeyError – If additional key is found in value, or required key is missing and allow_partial is set to False.
TypeError – If type of value is not the same as spec required.
ValueError – If value is not acceptable, or value is MISSING_VALUE while allow_partial is set to False.
- abstract property default: Any[source]¶
Returns the default value.
If no default is provided, MISSING_VALUE will be returned for non-dict types. For Dict type, a dict that may contains nested MISSING_VALUE will be returned.
- abstract extend(base)[source]¶
Extends a base spec with current spec’s rules.
- Return type:
- Parameters:
base – Base ValueSpec to extend.
- Returns:
ValueSpec itself.
- Raises:
TypeError – When this value spec cannot extend from base.
- abstract property forward_refs: Set[ForwardRef][source]¶
Returns forward referenes used by the value spec.
- abstract freeze(permanent_value=MISSING_VALUE, apply_before_use=True)[source]¶
Sets the default value using a permanent value and freezes current spec.
A frozen value spec will not accept any value that is not the default value. A frozen value spec is useful when a subclass fixes the value of a symoblic attribute and want to prevent it from being modified.
- Return type:
- Parameters:
permanent_value – A permanent value used for current spec. If MISSING_VALUE, freeze the value spec with current default value.
apply_before_use – If True, invoke apply on permanent value when permanent_value is provided, otherwise use it as is.
- Returns:
ValueSpec itself.
- Raises:
ValueError if current default value is MISSING_VALUE and the permanent – value is not specified.
- from_annotation(auto_typing=False, accept_value_as_annotation=False, parent_module=None)[source]¶
Creates a value spec from annotation.
- Return type:
- classmethod from_json_schema(json_schema, class_fn=None, add_json_schema_as_metadata=False)[source]¶
Creates a PyGlove value spec from a JSON schema.
- Return type:
- Parameters:
json_schema – The JSON schema for a value spec.
class_fn – A function that creates a PyGlove class from a class name and a schema. If None, all “object” type properties will be converted to pg.typing.Dict. Otherwise, “object” type properties will be converted to a class.
add_json_schema_as_metadata – Whether to add the JSON schema as field metadata.
- Returns:
A PyGlove value spec.
- abstract is_compatible(other)[source]¶
Returns True if values acceptable to other is acceptable to this spec.
- Return type:
- Parameters:
other – Other value spec.
- Returns:
- True if values that is applicable to the other value spec can be applied
to current spec. Otherwise False.
- abstract noneable(is_noneable=True, use_none_as_default=True)[source]¶
Marks none-able and returns self.
- Return type:
- abstract set_default(default, use_default_apply=True, root_path=None)[source]¶
Sets the default value and returns self.
- Return type:
- Parameters:
default – Default value.
use_default_apply – If True, invoke apply to the value, otherwise use default value as is.
root_path – (Optional) The path of the field.
- Returns:
ValueSpec itself.
- Raises:
ValueError – If default value cannot be applied when use_default_apply is set to True.
- to_json_schema(*, include_type_name=True, include_subclasses=False, inline_nested_refs=False, **kwargs)[source]¶
Converts a value spec to JSON schema.