pg.ValueSpec

Accessible via pg.ValueSpec, pg.typing.ValueSpec.

class ValueSpec[source]

Bases: pg.Formattable, pg.JSONConvertible

Interface 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 apply for more details.

Different aspects of assignment interception are handled by the following methods:

Aspect name

Property/Method

Type check

value_type

Noneable check

is_noneable

Type-specific value validation and transformation

apply

User transform

transform

Default value lookup

default

There are many ValueSpec subclasses, 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 ValueSpec subclass. All pg.ValueSpec subclasses follow a common pattern to construct:

pg.typing.<ValueSpecClass>(
    [validation-rules],
    [default=<default>],
    [transform=<transform>])

After creation, a ValueSpec object 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.ValueSpec shall be used:

value == pg.typing.Int(min_value=1).apply(4)
assert value == 4

Extension

Besides, a ValueSpec object can extend another ValueSpec object to obtain a more restricted ValueSpec object. 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)

ValueSpec objects 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.

ValueSpec object 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:

Attributes:

annotation

Returns PyType annotation.

default

Returns the default value.

forward_refs

Returns forward referenes used by the value spec.

frozen

Returns True if current value spec is frozen.

has_default

Returns True if the default value is provided.

is_noneable

Returns True if current value spec accepts None.

transform

Returns a transform that will be applied on the input before apply.

type_resolved

Returns True if all forward references are resolved.

value_type

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.

is_compatible(other)

Returns True if values acceptable to other is acceptable to this spec.

noneable()

Marks none-able and returns self.

set_default(default[, use_default_apply])

Sets the default value and returns self.

DictType[source]

alias of pg.typing.Dict Methods:

format([compact, verbose, root_indent, markdown])

Format this object.

noneable()

Override noneable in Dict to always set default value None.

set_default(default[, use_default_apply])

Set default value and returns self.

to_json(**kwargs)

Returns a plain Python value as a representation for this object.

Attributes:

forward_refs

Returns forward references used in this spec.

schema

Returns the schema of this dict spec.

ListType[source]

alias of pg.typing.List Attributes:

element

Returns Field specification of list element.

forward_refs

Returns forward references used in this spec.

max_size

Returns max size of the list.

min_size

Returns max size of the list.

Methods:

format([compact, verbose, root_indent, ...])

Format this object.

to_json(**kwargs)

Returns a plain Python value as a representation for this object.

ObjectType[source]

alias of pg.typing.Object Attributes:

cls

Returns the class of this object spec.

forward_refs

Returns forward references used in this spec.

schema

Returns the schema of object class if available.

value_type

Returns acceptable value type(s) for current value spec.

Methods:

extend(base)

Extend current value spec on top of a base spec.

format([compact, verbose, root_indent, ...])

Format this object.

to_json(**kwargs)

Returns a plain Python value as a representation for this 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:

Any

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:

pg.ValueSpec

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:

pg.ValueSpec

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)[source]

Creates a value spec from annotation.

Return type:

pg.ValueSpec

abstract property frozen: bool[source]

Returns True if current value spec is frozen.

property has_default: bool[source]

Returns True if the default value is provided.

abstract is_compatible(other)[source]

Returns True if values acceptable to other is acceptable to this spec.

Return type:

bool

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 property is_noneable: bool[source]

Returns True if current value spec accepts None.

abstract noneable()[source]

Marks none-able and returns self.

Return type:

pg.ValueSpec

abstract set_default(default, use_default_apply=True)[source]

Sets the default value and returns self.

Return type:

pg.ValueSpec

Parameters:
  • default – Default value.

  • use_default_apply – If True, invoke apply to the value, otherwise use default value as is.

Returns:

ValueSpec itself.

Raises:

ValueError – If default value cannot be applied when use_default_apply is set to True.

abstract property transform: Callable[[Any], Any] | None[source]

Returns a transform that will be applied on the input before apply.

property type_resolved: bool[source]

Returns True if all forward references are resolved.

abstract property value_type: Type[Any] | Tuple[Type[Any], ...][source]

Returns acceptable (resolved) value type(s).