a
    ñâÑ`³  ã                   @   sŠ   d Z ddlZddlZddlZddlmZ dZdZdZdZ	dZ
e e¡Zd	d
„ Zefdd„Zefdd„Zdd„ Zdd„ ZG dd„ deƒZdS )z4Shared utilities used by both downloads and uploads.é    N)ÚcommonÚrangezcontent-rangez¨Currently using crcmod in pure python form. This is a slow implementation. Python 3 has a faster implementation, `google-crc32c`, which will be used if it is installed.zx-goog-hashz·No {checksum_type} checksum was returned from the service while downloading {}
(which happens for composite objects), so client-side content integrity
checking is not being performed.c                   C   s   dS )zSimple default callback.N© r   r   r   úElib/python3.9/site-packages/google/_async_resumable_media/_helpers.pyÚ
do_nothing)   s    r   c                 C   s,   || ƒ}||vr$|ƒ  t  | d|¡‚|| S )aš  Checks that a specific header is in a headers dictionary.

    Args:
        response (object): An HTTP response object, expected to have a
            ``headers`` attribute that is a ``Mapping[str, str]``.
        name (str): The name of a required header.
        get_headers (Callable[Any, Mapping[str, str]]): Helper to get headers
            from an HTTP response.
        callback (Optional[Callable]): A callback that takes no arguments,
            to be executed when an exception is being raised.

    Returns:
        str: The desired header.

    Raises:
        ~google.resumable_media.common.InvalidResponse: If the header
            is missing.
    z$Response headers must contain header©r   ZInvalidResponse)ÚresponseÚnameZget_headersÚcallbackZheadersr   r   r   Úheader_required-   s    ÿr   c                 C   s2   || ƒ}||vr.|ƒ  t j| d|dg|¢R Ž ‚|S )a`  Require a response has a status code among a list.

    Args:
        response (object): The HTTP response object.
        status_codes (tuple): The acceptable status codes.
        get_status_code (Callable[Any, int]): Helper to get a status code
            from a response.
        callback (Optional[Callable]): A callback that takes no arguments,
            to be executed when an exception is being raised.

    Returns:
        int: The status code.

    Raises:
        ~google.resumable_media.common.InvalidResponse: If the status code
            is not one of the values in ``status_codes``.
    zRequest failed with status codezExpected one ofr   )r   Zstatus_codesÚget_status_coder
   Zstatus_coder   r   r   Úrequire_status_codeJ   s    üûr   c                 C   s0   d|  }||kr|}t  dd¡}||d|  fS )aµ  Calculate the amount of time to wait before a retry attempt.

    Wait time grows exponentially with the number of attempts, until
    ``max_sleep``.

    A random amount of jitter (between 0 and 1 seconds) is added to spread out
    retry attempts from different clients.

    Args:
        base_wait (float): The "base" wait time (i.e. without any jitter)
            that will be doubled until it reaches the maximum sleep.
        max_sleep (float): Maximum value that a sleep time is allowed to be.

    Returns:
        Tuple[float, float]: The new base wait time as well as the wait time
        to be applied (with a random amount of jitter between 0 and 1 seconds
        added).
    g       @r   iè  gü©ñÒMbP?)ÚrandomZrandint)Ú	base_waitÚ	max_sleepZnew_base_waitZ	jitter_msr   r   r   Úcalculate_retry_waiti   s
    r   c           
   
   Ã   s¤   d}d}d}d}z| ƒ I dH }W n( t yH } z|}W Y d}~nd}~0 0 ||ƒtjvr\|S | ||¡st|rp|‚|S t||jƒ\}}	|d7 }||	7 }t |	¡ qdS )a[  Attempts to retry a call to ``func`` until success.

    Expects ``func`` to return an HTTP response and uses ``get_status_code``
    to check if the response is retry-able.

    Will retry until :meth:`~.RetryStrategy.retry_allowed` (on the current
    ``retry_strategy``) returns :data:`False`. Uses
    :func:`calculate_retry_wait` to double the wait time (with jitter) after
    each attempt.

    Args:
        func (Callable): A callable that takes no arguments and produces
            an HTTP response which will be checked as retry-able.
        get_status_code (Callable[Any, int]): Helper to get a status code
            from a response.
        retry_strategy (~google.resumable_media.common.RetryStrategy): The
            strategy to use if the request fails and must be retried.

    Returns:
        object: The return value of ``func``.
    g        r   g      à?Né   )ÚConnectionErrorr   Z	RETRYABLEZretry_allowedr   r   ÚtimeÚsleep)
Úfuncr   Zretry_strategyZtotal_sleepZnum_retriesr   Úerrorr   ÚeZ	wait_timer   r   r   Úwait_and_retry„   s$    r   c                   @   s   e Zd ZdZdd„ ZdS )Ú_DoNothingHashz«Do-nothing hash object.

    Intended as a stand-in for ``hashlib.md5`` or a crc32c checksum
    implementation in cases where it isn't necessary to compute the hash.
    c                 C   s   dS )z¸Do-nothing ``update`` method.

        Intended to match the interface of ``hashlib.md5`` and other checksums.
        Args:
            unused_chunk (bytes): A chunk of data.
        Nr   )ÚselfZunused_chunkr   r   r   Úupdate¿   s    z_DoNothingHash.updateN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   ¸   s   r   )r    Úloggingr   r   Zgoogle.resumable_mediar   ZRANGE_HEADERZCONTENT_RANGE_HEADERZ_SLOW_CRC32C_WARNINGZ_HASH_HEADERZ_MISSING_CHECKSUMZ	getLoggerr   Z_LOGGERr   r   r   r   r   Úobjectr   r   r   r   r   Ú<module>   s"   ÿ
4