class_docstr: Defines a view of a :class:`FeatureStore` that is obtained from a
  specification of attributes on the feature store. The view stores a
  reference to the backing feature store as well as a :class:`TensorAttr`
  object that represents the view's state.
  
  Users can create views either using the :class:`AttrView` constructor,
  :meth:`FeatureStore.view`, or by incompletely indexing a feature store.
  For example, the following calls all create views:
  
  .. code-block:: python
  
      store[group_name]
      store[group_name].feat
      store[group_name, feat]
  
  While the following calls all materialize those views and produce tensors
  by either calling the view or fully-specifying the view:
  
  .. code-block:: python
  
      store[group_name]()
      store[group_name].feat[index]
      store[group_name, feat][index]
class_docstr_tok: ["Defines","a","view","of","a",":","class",":","`","FeatureStore","`","that","is","obtained","from","a","specification","of","attributes","on","the","feature","store",".","The","view","stores","a","reference","to","the","backing","feature","store","as","well","as","a",":","class",":","`","TensorAttr","`","object","that","represents","the","view","'s","state",".","Users","can","create","views","either","using","the",":","class",":","`","AttrView","`","constructor",",",":","meth",":","`","FeatureStore.view","`",",","or","by","incompletely","indexing","a","feature","store",".","For","example",",","the","following","calls","all","create","views",":","..","code-block",":",":","python","store","[","group_name","]","store","[","group_name","]",".feat","store","[","group_name",",","feat","]","While","the","following","calls","all","materialize","those","views","and","produce","tensors","by","either","calling","the","view","or","fully-specifying","the","view",":","..","code-block",":",":","python","store","[","group_name","]","(",")","store","[","group_name","]",".feat","[","index","]","store","[","group_name",",","feat","]","[","index","]"]
docstr: Sets the first unset field of the backing :class:`TensorAttr`
  object to the attribute.
  
  This allows for :class:`AttrView` to be indexed by different values of
  attributes, in order.
  In particular, for a feature store that we want to index by
  :obj:`group_name` and :obj:`attr_name`, the following code will do so:
  
  .. code-block:: python
  
      store[group, attr]
      store[group].attr
      store.group.attr
docstr_tok: ["Sets","the","first","unset","field","of","the","backing",":","class",":","`","TensorAttr","`","object","to","the","attribute",".","This","allows","for",":","class",":","`","AttrView","`","to","be","indexed","by","different","values","of","attributes",",","in","order",".","In","particular",",","for","a","feature","store","that","we","want","to","index","by",":","obj",":","`","group_name","`","and",":","obj",":","`","attr_name","`",",","the","following","code","will","do","so",":","..","code-block",":",":","python","store","[","group",",","attr","]","store","[","group","]",".attr","store.group.attr"]
code: def __getattr__(
      self, key: Any
  ) -> Union["AttrView", FeatureTensorType]:
      r"""Sets the first unset field of the backing :class:`TensorAttr`
      object to the attribute.
  
      This allows for :class:`AttrView` to be indexed by different values of
      attributes, in order.
      In particular, for a feature store that we want to index by
      :obj:`group_name` and :obj:`attr_name`, the following code will do so:
  
      .. code-block:: python
  
          store[group, attr]
          store[group].attr
          store.group.attr
      """
      out = copy.copy(self)
  
      # Find the first attribute name that is UNSET:
      attr_name: Optional[str] = None
      for field in out._attr.__dataclass_fields__:
          if getattr(out._attr, field) == _FieldStatus.UNSET:
              attr_name = field
              break
  
      if attr_name is None:
          raise AttributeError(
              f"Cannot access attribute '{key}' on view "
              f"'{out}' as all attributes have already "
              f"been set in this view"
          )
  
      setattr(out._attr, attr_name, key)
  
      if out._attr.is_fully_specified():
          return out._store.get_tensor(out._attr)
  
      return out
  
imports: import copy
  from abc import abstractmethod
  from dataclasses import dataclass
  from enum import Enum
  from typing import Any, List, Optional, Tuple, Union
  import numpy
  import torch
  from torch_geometric.typing import FeatureTensorType, NodeType
  from torch_geometric.utils.mixin import CastMixin
label_desc: Use image node_id 2 for calling the AttrView obj's underlying member method code with example usage: obj.__getattr__(key) and returns: out, out