o
    ̳i                     @   sR   d dl Z d dlmZmZmZmZmZ e eZ	edddZ
G dd dee
 ZdS )    N)AnyDictIteratorOptionalTypeVarTT)	covariantc                   @   sv   e Zd ZdZdd Zdd Zddee fdd	Zd
e	e
ef fddZd
efddZdd Zd
e	e
ef fddZdS )BaseNodea  BaseNodes are the base class for creating composable dataloading DAGs in ``torchdata.nodes``.

    Most end-users will not iterate over a BaseNode instance directly, but instead
    wrap it in a :class:`torchdata.nodes.Loader` which converts the DAG into a more familiar Iterable.

    .. code-block:: python

        node = MyBaseNodeImpl()
        loader = Loader(node)
        # loader supports state_dict() and load_state_dict()

        for epoch in range(5):
            for idx, batch in enumerate(loader):
                ...

        # or if using node directly:
        node = MyBaseNodeImpl()
        for epoch in range(5):
            node.reset()
            for idx, batch in enumerate(loader):
                ...
    c                 O   
   d| _ dS )zPSubclasses must implement this method and call super().__init__(*args, **kwargs)FN_BaseNode__initialized)selfargskwargs r   M/home/ubuntu/.local/lib/python3.10/site-packages/torchdata/nodes/base_node.py__init__(   s   
zBaseNode.__init__c                 C   s   | S Nr   r   r   r   r   __iter__,   s   zBaseNode.__iter__Ninitial_statec                 C   r
   )a  Resets the iterator to the beginning, or to the state passed in by initial_state.

        Reset is a good place to put expensive initialization, as it will be lazily called when ``next()`` or ``state_dict()`` is called.
        Subclasses must call ``super().reset(initial_state)``.

        Args:
            initial_state: Optional[dict] - a state dict to pass to the node. If None, reset to the beginning.
        TNr   )r   r   r   r   r   reset/   s   

zBaseNode.resetreturnc                 C      t t| )zSubclasses must implement this method, instead of ``state_dict()``. Should only be called by BaseNode.

        Returns:
            Dict[str, Any] - a state dict that may be passed to ``reset()`` at some point in the future
        NotImplementedErrortyper   r   r   r   	get_state;      zBaseNode.get_statec                 C   r   )zSubclasses must implement this method, instead of ``__next__``. Should only be called by BaseNode.

        Returns:
            T - the next value in the sequence, or throw StopIteration
        r   r   r   r   r   nextC   r   zBaseNode.nextc                 C   s\   z| j  W n ty   tdt| w | j s*| d  | j s*tdt| |  S )NJself.__initialized not found, did you call super().__init__()? type(self)=fFailed to initialize after .reset(), did you call super().reset() in your .reset() method? type(self)=)r   AttributeErrorr   r   r   r   r   r   r   r   __next__K   s   

zBaseNode.__next__c                 C   s\   z| j  W n ty   tdt| w | j s*| d | j s*tdt| |  S )zGet a state_dict for this BaseNode.

        Returns:
            Dict[str, Any] - a state dict that may be passed to ``reset()`` at some point in the future.
        r    Nr!   )r   r"   r   r   r   r   r   r   r   r   
state_dictX   s   

zBaseNode.state_dictr   )__name__
__module____qualname____doc__r   r   r   dictr   r   strr   r   r   r   r#   r$   r   r   r   r   r	      s    r	   )loggingtypingr   r   r   r   r   	getLoggerr%   loggerr   r	   r   r   r   r   <module>   s
   
