U
    i7gn.                     @  s  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
Z
ddlZddlmZ ddlmZmZ ddlmZ ddlmZ ddlmZ dd	lmZ d
ZdZdZeeehZG dd dZe ZddddZddddZ ddddZ!ddddZ"ddddZ#ddddZdddd d!Z$d"dd#d$d%Z%dd"dd&d'Z&e	'd(Z(e	'd)Z)e	'd*Z*d+d,d-d.d/Z+d0d1 Z,d2d3 Z-d4d5 Z.d6dd7d8d9Z/d6dd7d:d;Z0dd<d7d=d>Z1dd<d7d?d@Z2dd"ddAdBZ3dCd"dDdEdFZ4dGd"dHdIdJZ5dKd"dLdMdNZ6dOd"dPdQdRZ7efdSdTdUdVZ8dWdX Z9dYdZ Z:d[d"d6d\d]d^Z;d_d` Z<dadbdcdddeZ=dadbdcdfdgZ>dhdi Z?djdkd7dldmZ@d6d"dndodpZAdS )qz Utility methods for marshmallow.    )annotationsN)Mapping)format_datetimeparsedate_to_datetime)pprint)FieldABC)FieldInstanceResolutionError)RemovedInMarshmallow4Warningexcludeincluderaisec                   @  s,   e Zd Zdd Zdd Zdd Zdd Zd	S )
_Missingc                 C  s   dS )NF selfr   r   5/tmp/pip-unpacked-wheel-o_a6af_p/marshmallow/utils.py__bool__   s    z_Missing.__bool__c                 C  s   | S Nr   r   r   r   r   __copy__   s    z_Missing.__copy__c                 C  s   | S r   r   )r   _r   r   r   __deepcopy__"   s    z_Missing.__deepcopy__c                 C  s   dS )Nz<marshmallow.missing>r   r   r   r   r   __repr__%   s    z_Missing.__repr__N)__name__
__module____qualname__r   r   r   r   r   r   r   r   r      s   r   bool)returnc                 C  s   t | pt | S )z%Return True if ``obj`` is a generator)inspectisgeneratorfunctionisgeneratorobjr   r   r   is_generator/   s    r"   c                 C  s   t | drt | d pt| S )zAReturn True if ``obj`` is an iterable object that isn't a string.__iter__strip)hasattrr"   r    r   r   r   is_iterable_but_not_string4   s    r&   c                 C  s   t | ot| t S )zGReturn True if ``obj`` is a collection type, e.g list, tuple, queryset.)r&   
isinstancer   r    r   r   r   is_collection9   s    r(   c                 C  s0   zt | |W S  tk
r*   t| | Y S X dS )zFReturn True if ``val`` is either a subclass or instance of ``class_``.N)
issubclass	TypeErrorr'   )valclass_r   r   r   is_instance_or_subclass>   s    r-   c                 C  s   t | tot| dS )zjReturn True if ``obj`` has keyed tuple behavior, such as
    namedtuples or SQLAlchemy's KeyedTuples.
    _fields)r'   tupler%   r    r   r   r   is_keyed_tupleF   s    r0   Nonec                 O  sH   t jdtdd t| tjr4ttj| f|| nt	| f|| dS )zPretty-printing function that can pretty-print OrderedDicts
    like regular dictionaries. Useful for printing the output of
    :meth:`marshmallow.Schema.dump`.

    .. deprecated:: 3.7.0
        marshmallow.pprint will be removed in marshmallow 4.
    zQmarshmallow's pprint function is deprecated and will be removed in marshmallow 4.   )
stacklevelN)
warningswarnr	   r'   collectionsOrderedDictprintjsondumps	py_pprint)r!   argskwargsr   r   r   r   M   s    r   zdt.datetime)datetimer   c                 C  s   | j d k	o| j | d k	S r   )tzinfo	utcoffsetr>   r   r   r   is_awarea   s    rB   str)
datestringr   c                 C  s   t | S )zParse a RFC822-formatted datetime string and return a datetime object.

    https://stackoverflow.com/questions/885015/how-to-parse-a-rfc-2822-date-time-into-a-python-datetime  # noqa: B950
    )r   )rD   r   r   r   from_rfcg   s    rE   c                 C  s   t | S )zrReturn the RFC822-formatted representation of a datetime object.

    :param datetime datetime: The datetime.
    )r   rA   r   r   r   	rfcformato   s    rF   z(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})[T ](?P<hour>\d{1,2}):(?P<minute>\d{1,2})(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6})\d{0,6})?)?(?P<tzinfo>Z|[+-]\d{2}(?::?\d{2})?)?$z4(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})$zd(?P<hour>\d{1,2}):(?P<minute>\d{1,2})(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6})\d{0,6})?)?zint | float | dt.timedeltazdt.timezone)offsetr   c                 C  sV   t | tjr|  d } | dk r$dnd}dtt| d }|| }ttj| d|S )z6Return a tzinfo instance with a fixed offset from UTC.<   r   -+z%02d%02d)minutes)r'   dt	timedeltatotal_secondsdivmodabstimezone)rG   signZhhmmnamer   r   r   get_fixed_timezone   s    rT   c                 C  s   t | }|std| }|d o4|d dd|d< |d}|dkrVtjj}nZ|dk	rt	|dkrzt
|d	d nd
}dt
|dd  | }|d
 dkr| }t|}dd | D }||d< tjf |S )zParse a string and return a datetime.datetime.

    This function supports time zone offsets. When the input contains one,
    the output uses a timezone with a fixed offset from UTC.
    z-Not a valid ISO8601-formatted datetime stringmicrosecond   0r?   ZN   r   rH      rI   c                 S  s"   i | ]\}}|d k	r|t |qS r   int.0kvr   r   r   
<dictcomp>   s       z%from_iso_datetime.<locals>.<dictcomp>)_iso8601_datetime_rematch
ValueError	groupdictljustpoprL   rQ   utclenr]   rT   itemsr>   )valuerd   kwr?   Zoffset_minsrG   r   r   r   from_iso_datetime   s"    


 rn   c                 C  sX   t | }|std| }|d o4|d dd|d< dd | D }tjf |S )zeParse a string and return a datetime.time.

    This function doesn't support time zone offsets.
    z)Not a valid ISO8601-formatted time stringrU   rV   rW   c                 S  s"   i | ]\}}|d k	r|t |qS r   r\   r^   r   r   r   rb      s       z!from_iso_time.<locals>.<dictcomp>)_iso8601_time_rerd   re   rf   rg   rk   rL   timerl   rd   rm   r   r   r   from_iso_time   s    
rr   c                 C  s8   t | }|stddd |  D }tjf |S )z*Parse a string and return a datetime.date.z)Not a valid ISO8601-formatted date stringc                 S  s   i | ]\}}|t |qS r   r\   r^   r   r   r   rb      s      z!from_iso_date.<locals>.<dictcomp>)_iso8601_date_rerd   re   rf   rk   rL   daterq   r   r   r   from_iso_date   s
    
ru   z
typing.Any)rl   r   c              
   C  s   | dks| dkrt dt| } | dk r0t dztjj| tjjdjd dW S  tk
rz } zt d|W 5 d }~X Y n, t	k
r } zt d|W 5 d }~X Y nX d S )	NTFzNot a valid POSIX timestampr   )tzr?   zTimestamp is too largez"Error converting value to datetime)
re   floatrL   r>   fromtimestamprQ   ri   replaceOverflowErrorOSError)rl   excr   r   r   from_timestamp   s    r~   c                 C  s   t | } t| d S Ni  )rx   r~   rl   r   r   r   from_timestamp_ms   s    r   rx   c                 C  s    t | s| jtjjd} |  S )Nrw   )rB   rz   rL   rQ   ri   	timestampr   r   r   r   r      s    r   c                 C  s   t | d S r   )r   r   r   r   r   timestamp_ms   s    r   c                 C  s   |   S )zsReturn the ISO8601-formatted representation of a datetime object.

    :param datetime datetime: The datetime.
    )	isoformatrA   r   r   r   r      s    r   zdt.time)rp   r   c                 C  s   t j| S r   )rL   rp   r   )rp   r   r   r   to_iso_time   s    r   zdt.date)rt   r   c                 C  s   t j| S r   )rL   rt   r   )rt   r   r   r   to_iso_date   s    r   zstr | bytes)r+   r   c                 C  s   t | tr| d} t| S )Nzutf-8)r'   bytesdecoderC   )r+   r   r   r   ensure_text_type   s    

r   zlist[dict[str, typing.Any]]Zdictlistkeyc                   s    fdd| D S )zExtracts a list of dictionary values from a list of dictionaries.
    ::

        >>> dlist = [{'id': 1, 'name': 'foo'}, {'id': 2, 'name': 'bar'}]
        >>> pluck(dlist, 'id')
        [1, 2]
    c                   s   g | ]}|  qS r   r   )r_   dr   r   r   
<listcomp>  s     zpluck.<locals>.<listcomp>r   r   r   r   r   pluck   s    r   z	int | strr   c                 C  s4   t |ts$d|kr$t| |d|S t| ||S dS )a  Helper for pulling a keyed value off various types of objects. Fields use
    this method by default to access attributes of the source object. For object `x`
    and attribute `i`, this method first tries to access `x[i]`, and then falls back to
    `x.i` if an exception is raised.

    .. warning::
        If an object `x` does not raise an exception when `x[i]` does not exist,
        `get_value` will never check the value `x.i`. Consider overriding
        `marshmallow.fields.Field.get_value` in this case.
    .N)r'   r]   _get_value_for_keyssplit_get_value_for_keyr!   r   defaultr   r   r   	get_value	  s    r   c                 C  s@   t |dkrt| |d |S tt| |d ||dd  |S d S )Nr[   r   )rj   r   r   )r!   keysr   r   r   r   r     s     
 r   c                 C  sN   t | dst| ||S z
| | W S  ttttfk
rH   t| || Y S X d S )N__getitem__)r%   getattrKeyError
IndexErrorr*   AttributeErrorr   r   r   r   r   #  s    

r   zdict[str, typing.Any])dctr   rl   c                 C  sb   d|krV| dd\}}| |i }t|tsHtd| d| d| t||| n|| |< dS )zSet a value in a dict. If `key` contains a '.', it is assumed
    be a path (i.e. dot-delimited string) to the value's location.

    ::

        >>> d = {}
        >>> set_value(d, 'foo.bar', 42)
        >>> d
        {'foo': {'bar': 42}}
    r   r[   zCannot set z in z due to existing value: N)r   
setdefaultr'   dictre   	set_value)r   r   rl   headresttargetr   r   r   r   -  s    
r   c                 C  s   t | std| d| S )z@Check that an object is callable, else raise a :exc:`TypeError`.Object z is not callable.)callabler*   r    r   r   r   callable_or_raiseD  s    r   ztyping.Callablez	list[str])funcr   c                 C  s   t t| j S r   )listr   	signature
parametersr   r   r   r   r   
_signatureK  s    r   c                 C  s:   t | st | rt| S t| tjr2t| jS t| S )zGiven a callable, return a list of argument names. Handles
    `functools.partial` objects and class-based callables.

    .. versionchanged:: 3.0.0a1
        Do not return bound arguments, eg. ``self``.
    )r   
isfunctionismethodr   r'   	functoolspartialr   r   r   r   r   get_func_argsO  s
    
r   c                 C  s4   t | trt| tst|  S t | ts,t| S dS )zReturn a Schema instance from a Schema class or instance.

    :param type|Schema cls_or_instance: Marshmallow Schema class or instance.
    N)r'   typer)   r   r   )Zcls_or_instancer   r   r   resolve_field_instance^  s    


r   zdt.timedeltar]   c                 C  s   | j d | j d | j S )zCompute the total microseconds of a timedelta

    https://github.com/python/cpython/blob/bb3e0c240bc60fe08d332ff5955d54197f79751c/Lib/datetime.py#L665-L667  # noqa: B950
    iQ i@B )dayssecondsmicrosecondsr   r   r   r   timedelta_to_microsecondsm  s    r   )r!   r   c                 C  s   | t krtd| d| S )Nr   z1 is not a valid value for the 'unknown' parameter)_UNKNOWN_VALUESre   r    r   r   r    validate_unknown_parameter_valueu  s
    
r   )B__doc__
__future__r   r6   r>   rL   r   r   r9   retypingr4   collections.abcr   email.utilsr   r   r   r;   Zmarshmallow.baser   Zmarshmallow.exceptionsr   Zmarshmallow.warningsr	   ZEXCLUDEZINCLUDEZRAISEr   r   missingr"   r&   r(   r-   r0   rB   rE   rF   compilerc   rs   ro   rT   rn   rr   ru   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sx   



			
