
    ]j_J              	          d dl Z d dlmZ d dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZmZ d dlmZmZmZmZ d dlmZ g dZej*                  Z G d d	      Z e       Z	  G d
 d      ZdedefdZde	eeeef   defdZ G d de      ZdedefdZdedefdZ dddededefdZ!dededefdZ"dedee   fdZ#dedee   fd Z$dddededeeef   fd!Z%d"ed#edefd$Z&y)%    N)partial)JSONEncoder)	DictListOptionalUnioncastAnyTypeCallableTuple)datetimedatetime	timedelta)timezone)NULLAzureJSONEncoderis_generated_modelas_attribute_dictattribute_listTypeHandlerRegistryget_backcompat_attr_namec                       e Zd ZdZdefdZy)_NullzTo create a Falsy objectreturnc                      y)NF selfs    B/root/env/lib/python3.12/site-packages/azure/core/serialization.py__bool__z_Null.__bool__   s        N)__name__
__module____qualname____doc__boolr"   r   r#   r!   r   r      s    "$ r#   r   c            
       0   e Zd ZdZddZdeeeege	f   f   deeege
eef   f   geege
eef   f   f   fdZdeeeege	f   f   deeee
eef   gef   geee
eef   gef   f   fdZdedeeege
eef   f      fd	Zd
edeee
eef   gef      fdZy)r   zUA registry for custom serializers and deserializers for specific types or conditions.r   Nc                 X    i | _         i | _        g | _        g | _        i | _        i | _        y N)_serializer_types_deserializer_types_serializer_predicates_deserializer_predicates_serializer_cache_deserializer_cacher   s    r!   __init__zTypeHandlerRegistry.__init__-   s2    799; TV#VX%ACCE r#   	conditionc                      dt         t        gt        t        t        f   f   dt         t        gt        t        t        f   f   f fd}|S )a  Decorator to register a serializer.

        The handler function is expected to take a single argument, the object to serialize,
        and return a dictionary representation of that object.

        Examples:

        .. code-block:: python

            @registry.register_serializer(CustomModel)
            def serialize_single_type(value: CustomModel) -> dict:
                return value.to_dict()

            @registry.register_serializer(lambda x: isinstance(x, BaseModel))
            def serialize_with_condition(value: BaseModel) -> dict:
                return value.to_dict()

            # Called manually for a specific type
            def custom_serializer(value: CustomModel) -> Dict[str, Any]:
                return {"custom": value.custom}

            registry.register_serializer(CustomModel)(custom_serializer)

        :param condition: A type or a callable predicate function that takes an object and returns a bool.
        :type condition: Union[Type, Callable[[Any], bool]]
        :return: A decorator that registers the handler function.
        :rtype: Callable[[Callable[[Any], Dict[str, Any]]], Callable[[Any], Dict[str, Any]]]
        :raises TypeError: If the condition is neither a type nor a callable.
        handler_funcr   c                     t        t              r| j                  <   n4t              rj                  j                  | f       nt        d      j                  j                          | S Nz:Condition must be a type or a callable predicate function.)	
isinstancetyper,   callabler.   append	TypeErrorr0   clearr5   r3   r    s    r!   	decoratorz:TypeHandlerRegistry.register_serializer.<locals>.decoratorW   sb    )T*4@&&y1)$++22I|3LM \]]""((*r#   )r   r
   r   strr    r3   r?   s   `` r!   register_serializerz'TypeHandlerRegistry.register_serializer6   sN    B		 HcUDcN-B$C 		 RUQVX\]`be]eXfQfHg 		  r#   c                      dt         t        t        t        t        f   gt        f   dt         t        t        t        t        f   gt        f   f fd}|S )a<  Decorator to register a deserializer.

        The handler function is expected to take two arguments: the target type and the data dictionary,
        and return an instance of the target type.

        Examples:

        .. code-block:: python

            @registry.register_deserializer(CustomModel)
            def deserialize_single_type(cls: Type[CustomModel], data: dict) -> CustomModel:
                return cls(**data)

            @registry.register_deserializer(lambda t: issubclass(t, BaseModel))
            def deserialize_with_condition(cls: Type[BaseModel], data: dict) -> BaseModel:
                return cls(**data)

            # Called manually for a specific type
            def custom_deserializer(cls: Type[CustomModel], data: Dict[str, Any]) -> CustomModel:
                return cls(custom=data["custom"])

            registry.register_deserializer(CustomModel)(custom_deserializer)

        :param condition: A type or a callable predicate function that takes an object and returns a bool.
        :type condition: Union[Type, Callable[[Any], bool]]
        :return: A decorator that registers the handler function.
        :rtype: Callable[[Callable[[Type, Dict[str, Any]], Any]], Callable[[Type, Dict[str, Any]], Any]]
        :raises TypeError: If the condition is neither a type nor a callable.
        r5   r   c                     t        t              r| j                  <   n4t              rj                  j                  | f       nt        d      j                  j                          | S r7   )	r8   r9   r-   r:   r/   r;   r<   r1   r=   r>   s    r!   r?   z<TypeHandlerRegistry.register_deserializer.<locals>.decorator   sb    )T*6B((3)$--44i5NO \]]$$**,r#   )r   r   r   r@   r
   rA   s   `` r!   register_deserializerz)TypeHandlerRegistry.register_deserializerd   sT    B		 HdDcN-CS-H$I 		 hX\^bcfhkck^lWmorWrNs 		  r#   objc                     t        |      }|| j                  v r| j                  |   S | j                  j                  t        |            }|s | j                  D ]  \  }} ||      s|} n || j                  |<   |S )a  Gets the appropriate serializer for an object.

        It first checks the type dictionary for a direct type match.
        If no match is found, it iterates through the predicate list to find a match.

        Results of the lookup are cached for performance based on the object's type.

        :param obj: The object to serialize.
        :type obj: any
        :return: The serializer function if found, otherwise None.
        :rtype: Optional[Callable[[Any], Dict[str, Any]]]
        )r9   r0   r,   getr.   )r    rF   obj_typehandler	predicatepred_handlers         r!   get_serializerz"TypeHandlerRegistry.get_serializer   s     9t---))(33((,,T#Y7+/+F+F '	<S>*G
 ,3x(r#   clsc                    || j                   v r| j                   |   S | j                  j                  |      }|s | j                  D ]  \  }} ||      s|} n |rt	        ||      nd| j                   |<   | j                   |   S )aX  Gets the appropriate deserializer for a class.

        It first checks the type dictionary for a direct type match.
        If no match is found, it iterates through the predicate list to find a match.

        Results of the lookup are cached for performance based on the class.

        :param cls: The class to deserialize.
        :type cls: type
        :return: A deserializer function bound to the specified class that takes a dictionary and returns
            an instance of that class, or None if no deserializer is found.
        :rtype: Optional[Callable[[Dict[str, Any]], Any]]
        N)r1   r-   rH   r/   r   )r    rN   rJ   rK   rL   s        r!   get_deserializerz$TypeHandlerRegistry.get_deserializer   s     $***++C00**..s3+/+H+H '	<S>*G
 BI(=d  %'',,r#   )r   N)r$   r%   r&   r'   r2   r   r   r   r
   r(   r   r@   rB   rE   r   rM   rP   r   r#   r!   r   r   *   s/   _F,tXseTk%::;,	8SE4S>123XseT#s(^>S5TT	U,\,tXseTk%::;,	8T4S>2C7898T4PSUXPX>DZ\_D_;``	a,\# (8SE4S><Q3R*S 6-D -XhS#X?OQT?T6U-V -r#   r   tdr   c                 V   | j                         }t        |d      \  }}t        |d      \  }}t        |d      \  }}t        t        t        |||f            \  }}}t        |d      }d}|rd|z  }d}|xs |}|r|dj                  |      z  }|xs |}|r|dj                  |      z  }	 |j                         rd	j                  t	        |            }nd
|z  }|j                  d      }|dj                  |      z  }d|z   |z   S # t        $ r d	j                  |      }Y 8w xY w)au  Converts a datetime.timedelta object into an ISO 8601 formatted string, e.g. 'P4DT12H30M05S'

    Function adapted from the Tin Can Python project: https://github.com/RusticiSoftware/TinCanPython

    :param td: The timedelta object to convert
    :type td: datetime.timedelta
    :return: An ISO 8601 formatted string representing the timedelta object
    :rtype: str
    <          z%sDTz{:02}Hz{:02}Mz{:02}z%09.6f0z{}SP)
total_secondsdivmodlistmapintroundformat
is_integerrstripAttributeError)	rQ   secondsminuteshoursdaysdate_strtime_strbigger_existsseconds_strings	            r!   _timedelta_as_isostrrl      sN     Ggr*GWGR(NE7#KD%C$w)? @AD%GQG H4< H %MHOOE** ",WMHOOG,,	1$^^CL9N &/N+2237N ^,,H>H$$  1 01s   .AD D('D(dtc                    t        | d      rt        | d      rvt        t        |       } | j                  s%| j	                  t
              j                         }n#| j                  t
              j                         }|j	                  dd      S 	 t        t        t        t        f   |       } | j                         S # t        $ r t        t        |       } t        |       cY S w xY w)aC  Converts a datetime.(datetime|date|time|timedelta) object into an ISO 8601 formatted string.

    :param dt: The datetime object to convert
    :type dt: datetime.datetime or datetime.date or datetime.time or datetime.timedelta
    :return: An ISO 8601 formatted string representing the datetime object
    :rtype: str
    yearhour)tzinfoz+00:00Z)hasattrr	   r   rq   replaceTZ_UTC	isoformat
astimezoner   r   r   rc   r   rl   )rm   iso_formatteds     r!   _datetime_as_isostrry      s     r6wr62(ByyJJfJ5??AMMM&1;;=M$$Xs33(%d
#R(||~ ()R #B''(s   ,B= =$C$#C$c                   ,     e Zd ZdZdedef fdZ xZS )r   zHA JSON encoder that's capable of serializing datetime objects and bytes.or   c                     t        |t        t        f      r#t        j                  |      j                         S 	 t        |      S # t        $ r Y nw xY wt        t        | +  |      S )zOverride the default method to handle datetime and bytes serialization.
        :param o: The object to serialize.
        :type o: any
        :return: A JSON-serializable representation of the object.
        :rtype: any
        )r8   bytes	bytearraybase64	b64encodedecodery   rc   superr   default)r    r{   	__class__s     r!   r   zAzureJSONEncoder.default  sc     a%+,##A&--//	&q)) 		%t4Q77s   
A 	AA)r$   r%   r&   r'   r
   r   __classcell__)r   s   @r!   r   r     s    R8 8 8 8r#   r   rF   c                 J    t        t        | dd      xs t        | d            S )zCheck if the object is a generated SDK model.

    :param obj: The object to check.
    :type obj: any
    :return: True if the object is a generated SDK model, False otherwise.
    :rtype: bool
    	_is_modelF_attribute_map)r(   getattrrs   )rF   s    r!   r   r   /  s%     [%0RGCAQ4RSSr#   pc                 B    	 | j                   dgk(  S # t        $ r Y yw xY w)zCheck if an attribute is readonly.

    :param any p: The property to check.
    :return: True if the property is readonly, False otherwise.
    :rtype: bool
    readF)_visibilityrc   )r   s    r!   _is_readonlyr   :  s*    }}(( s    	Fexclude_readonlyvr   c          	      R   | t        | t              ry t        | t        t        t        f      r t        |       fd| D              S t        | t              r/| j                         D ci c]  \  }}|t        |       c}}S t        |       rt        |       S | S c c}}w )Nc              3   8   K   | ]  }t        |         yw)r   N)_as_attribute_dict_value).0xr   s     r!   	<genexpr>z+_as_attribute_dict_value.<locals>.<genexpr>K  s     aZ[/DTUUas   r   )r8   r   r\   tuplesetr9   dictitemsr   r   r   )r   r   dkdvs    `  r!   r   r   G  s    yJq%(!dE3'(tAwa_`aaa!TbcbibibklX^XZ\^,RBRSSllFXYZF[Q1ABbabb ms   -B#
rest_fielddefault_attr_namec                 F    	 | j                   xs |S # t        $ r |cY S w xY w)a  Get the backcompat name for an attribute.

    :param any rest_field: The rest field to get the backcompat name from.
    :param str default_attr_name: The default attribute name to use if no backcompat name
    :return: The backcompat name.
    :rtype: str
    )_original_tsp_namerc   )r   r   s     r!   _get_backcompat_namer   Q  s.    !,,A0AA !  !s      c           	      p   d}	 t        | t        d t        |       D              d      }|y| j                  j                         D ]O  \  }}	 t        |j                  j                  j                               j                  t        |            r|c S Q y# t        $ r Y yw xY w# t        $ r Y mw xY w)zGet the name of the flattened attribute in a generated TypeSpec model if one exists.

    :param any obj: The object to check.
    :return: The name of the flattened attribute if it exists, otherwise None.
    :rtype: Optional[str]
    Nc              3   *   K   | ]  }d |v s|  yw)__flattened_itemsNr   )r   as     r!   r   z+_get_flattened_attribute.<locals>.<genexpr>h  s     +\!CVZ[C[A+\s   	)r   nextdirStopIteration_attr_to_rest_fieldr   r   _class_typekeysintersectionrc   )rF   flattened_itemskr   s       r!   _get_flattened_attributer   _  s     O!#t+\s3x+\'\^bc ''--/ 1	1==4499;<II#oJ^_ `     		s$   &B AB)	B&%B&)	B54B5c                 d   t        |       st        d      t        | d      r#t        | j                  j                               S t        |       }g }| j                  j                         D ]@  \  }}||k(  r%|j                  t        |j                               0|j                  |       B |S )zGet a list of attribute names for a generated SDK model.

    :param obj: The object to get attributes from.
    :type obj: any
    :return: A list of attribute names.
    :rtype: List[str]
    z$Object is not a generated SDK model.r   )r   r<   rs   r\   r   r   r   r   r   extendr   r   r;   )rF   flattened_attributeretval	attr_namer   s        r!   r   r   y  s     c">??s$%C&&++-..237F!$!8!8!>!>!@ %	:)+MM.)?)?@AMM)$	%
 Mr#   c                   t        |       st        d      t        | d      r| j                  |       S 	 i }t	               }i }t        |       }| j                  j                         D ]}  \  }}|r&t        |      r|j                  |j                         ||k(  r<|j                  j                  j                         D ]  \  }}	|||	j                  <    o|||j                  <    | j                         D ]  \  }
|r|v r|k(  r9|
j                         D ]%  \  }}	t        |	|      ||j                  ||      <   ' Kd}	 t        fd| j                  j                         D              j                   }|r|
nt        |
|      ||j                        <    |S # t"        $ r Y 3w xY w# t$        $ r}t        d      |d}~ww xY w)a  Convert an object to a dictionary of its attributes.

    Made solely for backcompatibility with the legacy `.as_dict()` on msrest models.

    .. deprecated::1.35.0
        This function is added for backcompat purposes only.

    :param any obj: The object to convert to a dictionary
    :keyword bool exclude_readonly: Whether to exclude readonly properties
    :return: A dictionary containing the object's attributes
    :rtype: dict[str, any]
    :raises TypeError: If the object is not a generated model instance
    *Object must be a generated model instance.r   )keep_readonlyr   Fc              3   B   K   | ]  }|j                   k(  s|  y wr+   )
_rest_name)r   rfr   s     r!   r   z$as_attribute_dict.<locals>.<genexpr>  s"      3!Z[I[3s   N)r   r<   rs   as_dictr   r   r   r   r   addr   r   r   rH   r   values_is_multipart_file_inputr   rc   )rF   r   resultreadonly_propsrest_to_attrr   r   r   fkfvr   is_multipart_file_inputexcr   s                @r!   r   r     s    c"DEEs$%{{-=)={>>'O 6s;%(%<%<%B%B%D 		@!IzL$<"":#8#89"i/(44HHNNP 5FB24L/5 7@Z223		@ IIK 	DAqA$7''ggi wFB7OPReu7vF<++B34w +0'.2 3%(%<%<%C%C%E3 /.. , 1A6Nqcs6t |''1-.	$  %   ODE3NOs<   DF6 	6F'?'F6 '	F30F6 2F33F6 6	G?GGmodelr   c                 @   t        |       st        d      t        |       }| j                  j	                         D ]_  \  }}||k(  rt        ||      c S ||k(  s|j                  j                  j	                         D ]  \  }}||k(  st        ||      c c S  a |S )a  Get the backcompat attribute name for a given attribute.

    This function takes an attribute name and returns the backcompat name (original TSP name)
    if one exists, otherwise returns the attribute name itself.

    :param any model: The model instance.
    :param str attr_name: The attribute name to get the backcompat name for.
    :return: The backcompat attribute name (original TSP name) or the attribute name itself.
    :rtype: str
    r   )r   r<   r   r   r   r   r   )r   r   r   field_attr_namer   r   r   s          r!   r   r     s     e$DEE 359','@'@'F'F'H 8#i''
I>> /1$00DDJJL 8B?/B7788 r#   )'r   	functoolsr   jsonr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   __all__utcru   r   r   r   r@   rl   ry   r   r(   r   r   r   r   r   r   r   r   r   r#   r!   <module>r      sx      P P P 4 4  
  w\- \-~4%Y 4%3 4%n(E(D$	"AB (s (88{ 8&TC TD T
C 
D 
 BG c c$ c3 c!S !S !S !# (3- 4 S	 . =B :O3 :OT :Od3PS8n :OzC C C r#   