o
    2hN                     @  s  U d Z ddlmZ ddlZddlZddlZddlZddlZddlZddlT ddl	m
Z
mZmZmZmZmZmZ ddlmZ e
rEddlmZ g ejZdZd	Zd
ed< edZedZededZed	d	dd	dejddddLdd Zed	d	dd	dejddddMd#d Zed	d	dd	dejddddNd%d Zejejd	d	dd	dejddd&
dOd'd Zed	d	d	d(d(d(d	d(d(d(d)
dPd4d5Zed	d	d	d(d(d(d	d(d(d(d)
dQd7d5Zeefd8	dRd	d	d	d(d(d(d	d(d(d(d)
dSd;d5ZG d<d= d=ee Z d>dd	d	d	d(d(d(d	d(d(d(dejd?dTdJdKZ!dS )Ua  PyTree integration with :mod:`dataclasses`.

This module implements PyTree integration with :mod:`dataclasses` by redefining the :func:`field`,
:func:`dataclass`, and :func:`make_dataclass` functions. Other APIs are re-exported from the
original :mod:`dataclasses` module.

The PyTree integration allows dataclasses to be flattened and unflattened recursively. The fields
are stored in a special attribute named ``__optree_dataclass_fields__`` in the dataclass.

>>> import math
... import optree
...
>>> @optree.dataclasses.dataclass(namespace='my_module')
... class Point:
...     x: float
...     y: float
...     z: float = 0.0
...     norm: float = optree.dataclasses.field(init=False, pytree_node=False)
...
...     def __post_init__(self) -> None:
...         self.norm = math.hypot(self.x, self.y, self.z)
...
>>> point = Point(2.0, 6.0, 3.0)
>>> point
Point(x=2.0, y=6.0, z=3.0, norm=7.0)
>>> # Flatten without specifying the namespace
>>> optree.tree_flatten(point)  # `Point`s are leaf nodes
([Point(x=2.0, y=6.0, z=3.0, norm=7.0)], PyTreeSpec(*))
>>> # Flatten with the namespace
>>> accessors, leaves, treespec = optree.tree_flatten_with_accessor(point, namespace='my_module')
>>> accessors, leaves, treespec  # doctest: +IGNORE_WHITESPACE,ELLIPSIS
(
    [
        PyTreeAccessor(*.x, (DataclassEntry(field='x', type=<class '...Point'>),)),
        PyTreeAccessor(*.y, (DataclassEntry(field='y', type=<class '...Point'>),)),
        PyTreeAccessor(*.z, (DataclassEntry(field='z', type=<class '...Point'>),))
    ],
    [2.0, 6.0, 3.0],
    PyTreeSpec(CustomTreeNode(Point[()], [*, *, *]), namespace='my_module')
)
>>> point == optree.tree_unflatten(treespec, leaves)
True
    )annotationsN)*)TYPE_CHECKINGAnyCallableLiteralProtocolTypeVaroverload)dataclass_transform)Iterable__optree_dataclass_fields__Tbool_PYTREE_NODE_DEFAULT_T_U_TypeT)boundinitreprhashcomparemetadatakw_onlydocpytree_nodedefaultr   r   r   bool | Noner   r   dict[Any, Any] | Noner   #bool | Literal[dataclasses.MISSING]r   
str | Noner   returnc        	   	      C     d S N )	r   r   r   r   r   r   r   r   r   r%   r%   M/var/www/html/chatgem/venv/lib/python3.10/site-packages/optree/dataclasses.pyfield\      r'   default_factoryCallable[[], _T]c        	   	      C  r#   r$   r%   )	r)   r   r   r   r   r   r   r   r   r%   r%   r&   r'   k   r(   r   c                 C  r#   r$   r%   r   r%   r%   r&   r'   z   s   )
r   r)   r   r   r   r   r   r   r   r   c        
         C  s   |pi   }|	du r|dt}	|	|d< | ||||||d}
tjdkr(||
d< n	|tjur1tdtjdkr;||
d< n|durCtd	|sO|	rOtd
t dtj	di |
S )a*  Field factory for :func:`dataclass`.

    This factory function is used to define the fields in a dataclass. It is similar to the field
    factory :func:`dataclasses.field`, but with an additional ``pytree_node`` parameter. If
    ``pytree_node`` is :data:`True` (default), the field will be considered a child node in the
    PyTree structure which can be recursively flattened and unflattened. Otherwise, the field will
    be considered as PyTree metadata.

    Setting ``pytree_node`` in the field factory is equivalent to setting a key ``'pytree_node'`` in
    ``metadata`` in the original field factory. The ``pytree_node`` value can be accessed using
    ``field.metadata['pytree_node']``. If ``pytree_node`` is :data:`None`, the value
    ``metadata.get('pytree_node', True)`` will be used.

    .. note::
        If a field is considered a child node, it must be included in the argument list of the
        :meth:`__init__` method, i.e., passes ``init=True`` in the field factory.

    Args:
        pytree_node (bool or None, optional): Whether the field is a PyTree node.
        **kwargs (optional): Optional keyword arguments passed to :func:`dataclasses.field`.

    Returns:
        dataclasses.Field: The field defined using the provided arguments with
        ``field.metadata['pytree_node']`` set.
    Nr   )r   r)   r   r   r   r   r      
   r   z4field() got an unexpected keyword argument 'kw_only'r,      r   z0field() got an unexpected keyword argument 'doc'zN`pytree_node=True` is not allowed for non-init fields. Please explicitly set `'.field(init=False, pytree_node=False)`.r%   )
copygetr   sysversion_infodataclassesMISSING	TypeError__name__r'   )r   r)   r   r   r   r   r   r   r   r   kwargsr%   r%   r&   r'      s6   &





F
r   r   eqorderunsafe_hashfrozen
match_argsr   slotsweakref_slotr;   r<   r=   r>   r?   r@   rA   	namespacestrCallable[[_TypeT], _TypeT]c                 C  r#   r$   r%   )r   r   r;   r<   r=   r>   r?   r   r@   rA   rB   r%   r%   r&   	dataclass   s   rE   clsc               C  r#   r$   r%   )rF   r   r   r;   r<   r=   r>   r?   r   r@   rA   rB   r%   r%   r&   rE         )field_specifiers_TypeT | None#_TypeT | Callable[[_TypeT], _TypeT]c                 s
  ddl m} ||||||dtjdkr!|d< |d< |	d< n|dur)td	|d
ur1td|	d
ur9tdtjdkrC|
d< n|
d
urKtddu rYd/fdd}|S tsitdt ddtj	v rztdt dj d|urt
tstdddkr|tjfi i }i tD ]&}|jdtr|jstd|jdt d |||j< q|jr||j< qt| t|}ttt|f d0 fd$d%}d1 fd*d+}dd,lm} dd-l m} ||||d.S )2a  Dataclass decorator with PyTree integration.

    Args:
        cls (type or None, optional): The class to decorate. If :data:`None`, return a decorator.
        namespace (str): The registry namespace used for the PyTree registration.
        **kwargs (optional): Optional keyword arguments passed to :func:`dataclasses.dataclass`.

    Returns:
        type or callable: The decorated class with PyTree integration or decorator function.
    r   __GLOBAL_NAMESPACEr   r   r;   r<   r=   r>   r+   r?   r   r@   Tz;dataclass() got an unexpected keyword argument 'match_args'Fz8dataclass() got an unexpected keyword argument 'kw_only'z6dataclass() got an unexpected keyword argument 'slots'r,      rA   z=dataclass() got an unexpected keyword argument 'weakref_slot'NrF   r   r"   c                   s   t | fdi S )NrB   )rE   )rF   )r9   rB   r%   r&   	decorator-  s   zdataclass.<locals>.decorator@z0.dataclass() can only be used with classes, not .z".dataclass() cannot be applied to z more than once.$The namespace must be a string, got  r   zPyTree node field z> must be included in `__init__()`. Or you can explicitly set `r0   objr   Ctuple[tuple[_U, ...], tuple[tuple[str, Any], ...], tuple[str, ...]]c                  s6   t  fddD }t  fddD }||fS )Nc                 3  s    | ]}t  |V  qd S r$   getattr.0namerU   r%   r&   	<genexpr>Y  s    z2dataclass.<locals>.flatten_func.<locals>.<genexpr>c                 3  s    | ]
}|t  |fV  qd S r$   rW   rY   r\   r%   r&   r]   Z  s    )tuple)rU   childrenr   )children_field_namesmetadata_fieldsr\   r&   flatten_funcQ  s   
zdataclass.<locals>.flatten_funcr   tuple[tuple[str, Any], ...]r_   tuple[_U, ...]c                  s&   t t |}||  di |S )Nr%   )dictzipupdate)r   r_   r9   )r`   rF   r%   r&   unflatten_func^  s   
z!dataclass.<locals>.unflatten_func)DataclassEntry)register_pytree_node)path_entry_typerB   )rF   r   r"   r   )rU   r   r"   rV   )r   rc   r_   rd   r"   r   )optree.registryrL   r3   r4   r7   inspectisclassr8   _FIELDS__dict__
isinstancerC   r5   rE   fieldsr   r2   r   r   r[   r^   typesMappingProxyTypesetattroptree.accessorsri   rj   )rF   r   r   r;   r<   r=   r>   r?   r   r@   rA   rB   GLOBAL_NAMESPACErP   children_fieldsfrb   rh   ri   rj   r%   )r`   rF   r9   ra   rB   r&   rE      s   
	








c                   @  s.   e Zd Zddddddddddd
dddZdS )_DataclassDecoratorTFr:   rF   r   r   r   r   r;   r<   r=   r>   r?   r   r@   rA   r"   c      
         C  s   t r$   )NotImplementedError)selfrF   r   r   r;   r<   r=   r>   r?   r   r@   rA   r%   r%   r&   __call__p  rG   z_DataclassDecorator.__call__N)rF   r   r   r   r   r   r;   r   r<   r   r=   r   r>   r   r?   r   r   r   r@   r   rA   r   r"   r   )r8   
__module____qualname__r}   r%   r%   r%   r&   rz   o  s    rz   r%   )basesnsr   r   r;   r<   r=   r>   r?   r   r@   rA   modulerP   cls_namerr   6Iterable[str | tuple[str, Any] | tuple[str, Any, Any]]r   tuple[type, ...]r   dict[str, Any] | Noner   rP   _DataclassDecorator[_TypeT]c                C  s>  ddl m} t|ts|du r&||u st|tr||}}n|du r&td||ur7t|ts7td|d|dkr=|}||||||	d}||d	}tjd
kr]|
|d< ||d< ||d< n|
duretd|durmtd|durutdtjdkr||d< n|durtdtjdkr|du rz	tdpd}W n) t	y   t
t	t tdjdd}W d   n1 sw   Y  Y nw ||d< n|durtdd}tjdkr|tjtfv rtjt|d}d}||d< n	|tjurtdtj| fd |i||}|s|dd |dd t|fi |d!|i}|S )"a  Make a new dynamically created dataclass with PyTree integration.

    The dataclass name will be ``cls_name``. ``fields`` is an iterable of either (name), (name, type),
    or (name, type, Field) objects. If type is omitted, use the string :data:`typing.Any`. Field
    objects are created by the equivalent of calling :func:`field` (name, type [, Field-info]).

    The ``namespace`` parameter is the PyTree registration namespace which should be a string. The
    ``namespace`` in the original :func:`dataclasses.make_dataclass` function is renamed to ``ns``
    to avoid conflicts.

    The remaining parameters are passed to :func:`dataclasses.make_dataclass`.
    See :func:`dataclasses.make_dataclass` for more information.

    Args:
        cls_name: The name of the dataclass.
        fields (Iterable[str | tuple[str, Any] | tuple[str, Any, Any]]): An iterable of either
            (name), (name, type), or (name, type, Field) objects.
        namespace (str): The registry namespace used for the PyTree registration.
        ns (dict or None, optional): The namespace used in dynamic type creation.
            See :func:`dataclasses.make_dataclass` and the builtin :func:`type` function for more
            information.
        **kwargs (optional): Optional keyword arguments passed to :func:`dataclasses.make_dataclass`.

    Returns:
        type: The dynamically created dataclass with PyTree integration.
    r   rK   Nz?make_dataclass() missing 1 required keyword-only argument: 'ns'rS   rR   rT   rM   )r   rB   r+   r?   r   r@   Tz@make_dataclass() got an unexpected keyword argument 'match_args'Fz=make_dataclass() got an unexpected keyword argument 'kw_only'z;make_dataclass() got an unexpected keyword argument 'slots'rN   rA   zBmake_dataclass() got an unexpected keyword argument 'weakref_slot')r,         __main__r8   r   z<make_dataclass() got an unexpected keyword argument 'module'r.   )rB   rP   z?make_dataclass() got an unexpected keyword argument 'decorator'rr   rB   )rl   rL   rq   re   rC   r7   r3   r4   _getframemodulenameAttributeError
contextlibsuppress
ValueError	_getframe	f_globalsr2   r5   rE   	functoolspartialmake_dataclasspop)r   rr   r   r   r   r   r;   r<   r=   r>   r?   r   r@   rA   r   rP   rB   rw   dataclass_kwargsmake_dataclass_kwargsregistered_by_decoratorrF   r%   r%   r&   r     s   0	








r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r    r   r!   r   r   r"   r   )r)   r*   r   r   r   r   r   r   r   r   r   r   r   r    r   r!   r   r   r"   r   )r   r   r   r   r   r   r   r   r   r   r   r    r   r!   r   r   r"   r   )r   r   r)   r   r   r   r   r   r   r   r   r   r   r   r   r    r   r!   r   r   r"   r   )r   r   r   r   r;   r   r<   r   r=   r   r>   r   r?   r   r   r   r@   r   rA   r   rB   rC   r"   rD   )rF   r   r   r   r   r   r;   r   r<   r   r=   r   r>   r   r?   r   r   r   r@   r   rA   r   rB   rC   r"   r   r$   )rF   rI   r   r   r   r   r;   r   r<   r   r=   r   r>   r   r?   r   r   r   r@   r   rA   r   rB   rC   r"   rJ   )$r   rC   rr   r   r   r   r   r   r   r   r   r   r;   r   r<   r   r=   r   r>   r   r?   r   r   r   r@   r   rA   r   r   r!   rP   r   rB   rC   r"   r   )"__doc__
__future__r   r   r5   r   rm   r3   rs   typingr   r   r   r   r   r	   r
   typing_extensionsr   collections.abcr   __all__ro   r   __annotations__r   r   typer   r6   r'   rE   rz   r   r%   r%   r%   r&   <module>   s   .$
H
z