o
    "i&                     @  s   d Z ddlmZ ddlZddlmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZmZmZ dd	lmZ dd
lmZ d/ddZd0ddZd1ddZededZ			d2d3d%d&Zd4d)d*Zd5d-d.ZdS )6z.Strategies for customizing subclass behaviors.    )annotationsN)collect)AnyCallableTypeVarUnion   )BaseConverter)AttributeOverridemake_dict_structure_fnmake_dict_unstructure_fn)already_generating)
subclassescltypereturn
list[type]c                 C  s&   t | p| }| gdd t|D  S )Nc                 S  s   g | ]}t |D ]}|qqS  )_make_subclasses_tree).0sclssclr   r   ]/var/www/html/premium_crap/venv/lib/python3.10/site-packages/cattrs/strategies/_subclasses.py
<listcomp>   s
    z)_make_subclasses_tree.<locals>.<listcomp>)typing
get_originr   )r   
cls_originr   r   r   r      s   
r   given_subclassestuple[type, ...]boolc                 C  s.   t | p| }tt|}t|}t||@ S )z?Whether the given class has subclasses from `given_subclasses`.)r   r   setr   r   )r   r   r   actualgivenr   r   r   _has_subclasses   s   r#   given_subclasses_treetuple[type]type | Nonec                 C  s8   t t| }t t|t|@ }t|dkrt| S d S )Nr   )tupler   r    lenr   )r   r$   actual_subclass_tree
class_treer   r   r   _get_union_type   s   r+   C)bound	converterr   tuple[type, ...] | Noneunion_strategyCallable[[Any, C], Any] | None	overrides#dict[str, AttributeOverride] | NoneNonec                 C  sT   t   |dur| g|R }ntt| }|du r!t| ||| dS t|||| dS )a`  
    Configure the converter so that the attrs/dataclass `cl` is un/structured as if it
    was a union of itself and all its subclasses that are defined at the time when this
    strategy is applied.

    :param cl: A base `attrs` or `dataclass` class.
    :param converter: The `Converter` on which this strategy is applied. Do note that
        the strategy does not work for a :class:`cattrs.BaseConverter`.
    :param subclasses: A tuple of sublcasses whose ancestor is `cl`. If left as `None`,
        subclasses are detected using recursively the `__subclasses__` method of `cl`
        and its descendents.
    :param union_strategy: A callable of two arguments passed by position
        (`subclass_union`, `converter`) that defines the union strategy to use to
        disambiguate the subclasses union. If `None` (the default), the automatic unique
        field disambiguation is used which means that every single subclass
        participating in the union must have an attribute name that does not exist in
        any other sibling class.
    :param overrides: a mapping of `cl` attribute names to overrides (instantiated with
        :func:`cattrs.gen.override`) to customize un/structuring.

    .. versionadded:: 23.1.0
    .. versionchanged:: 24.1.0
       When overrides are not provided, hooks for individual classes are retrieved from
       the converter instead of generated with no overrides, using converter defaults.
    .. versionchanged:: 25.2.0
       Slotted dataclasses work on Python 3.14 via :func:`cattrs.subclasses.subclasses`,
       which filters out duplicate classes caused by slotting.
    N)r   r'   r   *_include_subclasses_without_union_strategy'_include_subclasses_with_union_strategy)r   r.   r   r0   r2   parent_subclass_treer   r   r   include_subclasses(   s   $r8   r	   r7   c                 C  s   |D ]a} t | |}| fdd}|d ur&t| |fi |}t| |fi |}n
|| }|| }|d u r=| |fddd}n|j||d	}	|| ||	fdd
d}|| |fddd}
||| |||
 qd S )Nc                 S     | |u S Nr   cls_clr   r   r   	cls_is_clm      z=_include_subclasses_without_union_strategy.<locals>.cls_is_clvaldictr   r   c                 S  
   || |S r:   r   )r@   _r=   
_base_hookr   r   r   struct_hooky      
z?_include_subclasses_without_union_strategy.<locals>.struct_hook)r2   c                 S  s&   || }||u r|| |S | | |S )z
                If val is disambiguated to the class `cl`, use its base hook.

                If val is disambiguated to a subclass, dispatch on its exact runtime
                type.
                )	structure)r@   rC   _cr=   rD   _dis_fndis_clr   r   r   rE      s   
parent_subclass_tree[0]c                 S  s"   | j |u r	|| S |j| | j dS )z
            If val is an instance of the class `cl`, use the hook.

            If val is an instance of a subclass, dispatch on its exact runtime type.
            )unstructure_as)	__class__unstructure)r@   rH   r=   rD   r   r   r   unstruct_hook   s   
zA_include_subclasses_without_union_strategy.<locals>.unstruct_hook)r@   rA   r   r   )r@   rK   r   rA   )r+   r   r   get_structure_hookget_unstructure_hook_get_dis_funcregister_structure_hook_funcregister_unstructure_hook_func)r   r.   r7   r2   subclass_unionr>   base_struct_hookbase_unstruct_hookrE   dis_fnrO   r   r   r   r5   \   s.   


r5   union_classesCallable[[Any, C], Any]c              	     s  fddD }|sdS i }i }D ]C t  h t_z+|dur5t | fi |}t | fi |}n| j dd}| j dd}W t  t_nt  t_w || < || < qt }	| D ]\ }
 fdd}| 	||
 q_| D ]\ }
 fdd}| 
||
 qt||	|  | |	}| |	}D ];  fd	d}| 	|| t fd
dD }t|dkrt| }|||  | |}||fddd}| 
|| qdS )a^  
    This function is tricky because we're dealing with what is essentially a circular
    reference.

    We need to generate a structure hook for a class that is both:
    * specific for that particular class and its own fields
    * but should handle specific functions for all its descendants too

    Hence the dance with registering below.
    c                   s   g | ]	}t | r|qS r   )r#   )r   r   )rY   r   r   r      s    z;_include_subclasses_with_union_strategy.<locals>.<listcomp>NF)cache_resultc                 S  r9   r:   r   r;   r   r   r   r>      r?   z:_include_subclasses_with_union_strategy.<locals>.cls_is_clc                 S  r9   r:   r   r;   r   r   r   r>      r?   c                 S  r9   r:   r   r;   r   r   r   r>      r?   c                   s.   g | ]}t t|p|t p r|qS r   )
issubclassr   r   )r   c)r   r   r   r      s       payloadrA   r   r   c                 S  rB   r:   r   )r_   rC   _u_sr   r   r   sh   rF   z3_include_subclasses_with_union_strategy.<locals>.sh)r_   rA   r   r   )r    r   working_setr   r   rQ   rP   r   itemsrT   rS   r'   r(   )r.   rY   r0   r2   parent_classesoriginal_unstruct_hooksoriginal_struct_hooksrO   rE   final_unionhookr>   r   urb   r   )r   rY   r   r6      sV   






r6   )r   r   r   r   )r   r   r   r   r   r   )r   r   r$   r%   r   r&   )NNN)r   r   r.   r,   r   r/   r0   r1   r2   r3   r   r4   )r.   r	   r7   r   r2   r3   )r.   r,   rY   r   r0   rZ   r2   r3   )__doc__
__future__r   r   gcr   r   r   r   r   
convertersr	   genr
   r   r   gen._constsr   r   r   r#   r+   r,   r8   r5   r6   r   r   r   r   <module>   s&    



4K