Skip to content

access

access #

Value-level access nodes that navigate a materialized value.

Navigate a materialized Struct/Array/Map value the way the destination/access path family navigates a Path[...].

Each one is the value twin of a path node: where PathField walks a Path[Struct] to Path[FieldType], StructField reads a struct value and yields the field's value. They compose, so the structured value a node returns can be drilled into — CapturePanorama().frames[1].angle is StructFieldArrayIndexStructField — and the result cached at a path (root.angle &= …).

Like the path family, every node takes the position it descends as source.

operation path-level (destination/access) value-level (here)
struct field PathField StructField
array index PathIndex ArrayIndex
map key PathKey MapKey

A node can return a Map value — CaptureImagesByLabel collects one image sequence per label — so map access has a value twin too: MapKey reads a Map value and yields one entry's value, the way PathKey walks a Path[Map] to Path[V]. A key the map lacks at runtime yields no value rather than aborting the run. .keys() / .values() enumeration stays path-level (PathKeys/PathValues).

ArrayIndex #

Bases: Procedure[CGType]

Select one element of an array value (negative indexes from the end).

Returns the array's element type E. The value-level twin of PathIndex. The element type carries through: indexing an Array[Path[V]] yields a navigable Path[V] (so values()[-1].primary keeps navigating), while indexing an Array[Time] yields a Time value (keys()[0]).

Attributes:

Name Type Description
source Procedure[Array]

A procedure producing the Array to index.

index Setting[int]

The integer position (-1 for the last entry).

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/access.py
@make_procedure
class ArrayIndex(Procedure[CGType]):
    """Select one element of an array value (negative indexes from the end).

    Returns the array's element type ``E``. The value-level twin of
    [PathIndex][capturegraph.procedures.nodes.destination.access.PathIndex]. The
    element type carries through: indexing an ``Array[Path[V]]`` yields a
    navigable ``Path[V]`` (so ``values()[-1].primary`` keeps navigating), while
    indexing an ``Array[Time]`` yields a ``Time`` value (``keys()[0]``).

    Attributes:
        source: A procedure producing the ``Array`` to index.
        index: The integer position (``-1`` for the last entry).
    """

    source: Procedure[Array]
    index: Setting[int]

    def __post_init__(self) -> None:
        """Resolve ``_return_type`` to the source array's element type."""
        super().__post_init__()
        array_type = self.source.return_type
        if not (isinstance(array_type, type) and issubclass(array_type, Array)):
            raise TypeError(
                f"ArrayIndex: 'source' must produce an Array, got "
                f"{getattr(array_type, '__name__', array_type)}"
            )
        if array_type._element is None:
            raise TypeError("ArrayIndex: a schemaless Array has no element type")
        object.__setattr__(self, "_return_type", array_type._element)

__post_init__() #

Resolve _return_type to the source array's element type.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/access.py
def __post_init__(self) -> None:
    """Resolve ``_return_type`` to the source array's element type."""
    super().__post_init__()
    array_type = self.source.return_type
    if not (isinstance(array_type, type) and issubclass(array_type, Array)):
        raise TypeError(
            f"ArrayIndex: 'source' must produce an Array, got "
            f"{getattr(array_type, '__name__', array_type)}"
        )
    if array_type._element is None:
        raise TypeError("ArrayIndex: a schemaless Array has no element type")
    object.__setattr__(self, "_return_type", array_type._element)

MapKey #

Bases: Procedure[CGType]

Select one entry of a map value by key. Returns the map's element type V.

The value-level twin of PathKey: PathKey navigates a Path[Map] to Path[V], while MapKey reads a Map value and yields the entry's value. It is what indexing a map-returning node builds — cg.CaptureImagesByLabel(labels=["A", "B"])["A"].

A key the map lacks at runtime yields no value (the access produces nothing, so caching it stores nothing) and the executing client reports the unknown key, rather than aborting the run.

Attributes:

Name Type Description
source Procedure[Map]

A procedure producing the Map value to read.

key Procedure[CGType]

A procedure producing the key value (a keyable scalar matching the map's key type).

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/access.py
@make_procedure
class MapKey(Procedure[CGType]):
    """Select one entry of a map value by key. Returns the map's element type ``V``.

    The value-level twin of
    [PathKey][capturegraph.procedures.nodes.destination.access.PathKey]: ``PathKey``
    navigates a ``Path[Map]`` to ``Path[V]``, while ``MapKey`` reads a ``Map``
    *value* and yields the entry's *value*. It is what indexing a map-returning
    node builds — ``cg.CaptureImagesByLabel(labels=["A", "B"])["A"]``.

    A key the map lacks at runtime yields no value (the access produces nothing,
    so caching it stores nothing) and the executing client reports the unknown
    key, rather than aborting the run.

    Attributes:
        source: A procedure producing the ``Map`` value to read.
        key: A procedure producing the key value (a keyable scalar matching the
            map's key type).
    """

    source: Procedure[Map]
    key: Procedure[CGType]

    def __post_init__(self) -> None:
        """Resolve ``_return_type`` to the source map's element type."""
        super().__post_init__()
        map_type = self.source.return_type
        if not (isinstance(map_type, type) and issubclass(map_type, Map)):
            raise TypeError(
                f"MapKey: 'source' must produce a Map, got "
                f"{getattr(map_type, '__name__', map_type)}"
            )
        if map_type._key is None or map_type._element is None:
            raise TypeError("MapKey: a schemaless Map has no key or element type")
        key_type = self.key.return_type
        if not (is_keyable(key_type) and structural_eq(key_type, map_type._key)):
            raise TypeError(
                f"MapKey: key {getattr(key_type, '__name__', key_type)} does not match "
                f"the map's key {map_type._key.__name__}"
            )
        object.__setattr__(self, "_return_type", map_type._element)

__post_init__() #

Resolve _return_type to the source map's element type.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/access.py
def __post_init__(self) -> None:
    """Resolve ``_return_type`` to the source map's element type."""
    super().__post_init__()
    map_type = self.source.return_type
    if not (isinstance(map_type, type) and issubclass(map_type, Map)):
        raise TypeError(
            f"MapKey: 'source' must produce a Map, got "
            f"{getattr(map_type, '__name__', map_type)}"
        )
    if map_type._key is None or map_type._element is None:
        raise TypeError("MapKey: a schemaless Map has no key or element type")
    key_type = self.key.return_type
    if not (is_keyable(key_type) and structural_eq(key_type, map_type._key)):
        raise TypeError(
            f"MapKey: key {getattr(key_type, '__name__', key_type)} does not match "
            f"the map's key {map_type._key.__name__}"
        )
    object.__setattr__(self, "_return_type", map_type._element)

StructField #

Bases: Procedure[CGType]

Read a named field of a struct value. Returns the field's type.

The value-level twin of PathField: PathField navigates a Path[Struct] to Path[FieldType], while StructField reads a struct value and yields the field's value.

Attributes:

Name Type Description
source Procedure[Struct]

A procedure producing the Struct value to read.

field Setting[str]

The field name to read.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/access.py
@make_procedure
class StructField(Procedure[CGType]):
    """Read a named field of a struct value. Returns the field's type.

    The value-level twin of
    [PathField][capturegraph.procedures.nodes.destination.access.PathField]:
    ``PathField`` navigates a ``Path[Struct]`` to ``Path[FieldType]``, while
    ``StructField`` reads a struct *value* and yields the field's *value*.

    Attributes:
        source: A procedure producing the ``Struct`` value to read.
        field: The field name to read.
    """

    source: Procedure[Struct]
    field: Setting[str]

    def __post_init__(self) -> None:
        """Resolve ``_return_type`` to the source struct's field type."""
        super().__post_init__()
        struct_type = self.source.return_type
        if not (isinstance(struct_type, type) and issubclass(struct_type, Struct)):
            raise TypeError(
                f"StructField: 'source' must produce a Struct, got "
                f"{getattr(struct_type, '__name__', struct_type)}"
            )
        if self.field not in struct_type._fields:
            raise TypeError(f"StructField: {struct_type.__name__} has no field {self.field!r}")
        object.__setattr__(self, "_return_type", struct_type._fields[self.field])

__post_init__() #

Resolve _return_type to the source struct's field type.

Source code in capturegraph-lib/capturegraph/procedures/nodes/process/access.py
def __post_init__(self) -> None:
    """Resolve ``_return_type`` to the source struct's field type."""
    super().__post_init__()
    struct_type = self.source.return_type
    if not (isinstance(struct_type, type) and issubclass(struct_type, Struct)):
        raise TypeError(
            f"StructField: 'source' must produce a Struct, got "
            f"{getattr(struct_type, '__name__', struct_type)}"
        )
    if self.field not in struct_type._fields:
        raise TypeError(f"StructField: {struct_type.__name__} has no field {self.field!r}")
    object.__setattr__(self, "_return_type", struct_type._fields[self.field])