o
    id*                     @   s   d 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
 eeZdZdZdZeeeegZeZdZdZd	Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd%ddZ dd  Z!d!d" Z"d#d$ Z#dS )&z-Helper functions for commonly used utilities.    N)urllibWARNING	EXCEPTIONIGNOREzFile: {0}: Is a symbolic link.z{0}: Is a directoryz,Cannot access {0}: No such file or directoryc                    sF    fdd}t  tjr|S t \}}}}tt|t|  S )a  A decorator to declare that only the first N arguments my be positional.

    This decorator makes it easy to support Python 3 style keyword-only
    parameters. For example, in Python 3 it is possible to write::

        def fn(pos1, *, kwonly1=None, kwonly1=None):
            ...

    All named parameters after ``*`` must be a keyword::

        fn(10, 'kw1', 'kw2')  # Raises exception.
        fn(10, kwonly1='kw1')  # Ok.

    Example
    ^^^^^^^

    To define a function like above, do::

        @positional(1)
        def fn(pos1, kwonly1=None, kwonly2=None):
            ...

    If no default value is provided to a keyword argument, it becomes a
    required keyword argument::

        @positional(0)
        def fn(required_kw):
            ...

    This must be called with the keyword parameter::

        fn()  # Raises exception.
        fn(10)  # Raises exception.
        fn(required_kw=10)  # Ok.

    When defining instance or class methods always remember to account for
    ``self`` and ``cls``::

        class MyClass(object):

            @positional(2)
            def my_method(self, pos1, kwonly1=None):
                ...

            @classmethod
            @positional(2)
            def my_method(cls, pos1, kwonly1=None):
                ...

    The positional decorator behavior is controlled by
    ``_helpers.positional_parameters_enforcement``, which may be set to
    ``POSITIONAL_EXCEPTION``, ``POSITIONAL_WARNING`` or
    ``POSITIONAL_IGNORE`` to raise an exception, log a warning, or do
    nothing, respectively, if a declaration is violated.

    Args:
        max_positional_arguments: Maximum number of positional arguments. All
                                  parameters after the this index must be
                                  keyword only.

    Returns:
        A decorator that prevents using arguments after max_positional_args
        from being used as positional parameters.

    Raises:
        TypeError: if a key-word only argument is provided as a positional
                   parameter, but only if
                   _helpers.positional_parameters_enforcement is set to
                   POSITIONAL_EXCEPTION.
    c                    s   t   fdd}|S )Nc                     sd   t |  kr+d} dkrd}djj t | |d}ttkr"t|ttkr+t| | i |S )N    szV{function}() takes at most {args_max} positional argument{plural} ({args_given} given))functionargs_max
args_givenplural)	lenformat__name__!positional_parameters_enforcementPOSITIONAL_EXCEPTION	TypeErrorPOSITIONAL_WARNINGloggerwarning)argskwargsplural_smessage)max_positional_argswrapped P/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/oauth2client/_helpers.pypositional_wrapperu   s    
zDpositional.<locals>.positional_decorator.<locals>.positional_wrapper)	functoolswraps)r   r   r   )r   r   positional_decoratort   s   z(positional.<locals>.positional_decorator)
isinstancesixinteger_typesinspect
getargspec
positionalr   )r   r"   r   _defaultsr   r!   r   r(   ,   s
   Hr(   c                 C   s   t | tjr| S d| S )a_  Converts scope value to a string.

    If scopes is a string then it is simply passed through. If scopes is an
    iterable then a string is returned that is all the individual scopes
    concatenated with spaces.

    Args:
        scopes: string or iterable of strings, the scopes.

    Returns:
        The scopes formatted as a single string.
     )r#   r$   string_typesjoinscopesr   r   r   scopes_to_string   s   
r0   c                 C   s"   | sg S t | tjr| dS | S )a+  Converts stringifed scope value to a list.

    If scopes is a list then it is simply passed through. If scopes is an
    string then a list of each individual scope is returned.

    Args:
        scopes: a string or iterable of strings, the scopes.

    Returns:
        The scopes in a list.
    r+   )r#   r$   r,   splitr.   r   r   r   string_to_scopes   s
   
r2   c                 C   sZ   t j| }i }t|D ]\}}t|dkr$d|d|f }t||d ||< q|S )a  Parses unique key-value parameters from urlencoded content.

    Args:
        content: string, URL-encoded key-value pairs.

    Returns:
        dict, The key-value pairs from ``content``.

    Raises:
        ValueError: if one of the keys is repeated.
    r   z6URL-encoded content contains a repeated value:%s -> %sz, r   )r   parseparse_qsr$   	iteritemsr   r-   
ValueError)contenturlencoded_paramsparamskeyvaluemsgr   r   r   parse_unique_urlencoded   s   r=   c                 C   sD   t j| }t|j}|| t j|}|j|d}t j|S )a  Updates a URI with new query parameters.

    If a given key from ``params`` is repeated in the ``uri``, then
    the URI will be considered invalid and an error will occur.

    If the URI is valid, then each value from ``params`` will
    replace the corresponding value in the query parameters (if
    it exists).

    Args:
        uri: string, A valid URI, with potential existing query parameters.
        params: dict, A dictionary of query parameters.

    Returns:
        The same URI but with the new query parameters added.
    )query)	r   r3   urlparser=   r>   update	urlencode_replace
urlunparse)urir9   partsquery_params	new_query	new_partsr   r   r   update_query_params   s   

rI   c                 C   s   |du r| S t | ||iS )a\  Adds a query parameter to a url.

    Replaces the current value if it already exists in the URL.

    Args:
        url: string, url to add the query parameter to.
        name: string, query parameter name.
        value: string, query parameter value.

    Returns:
        Updated query parameter. Does not update the url if value is None.
    N)rI   )urlnamer;   r   r   r   _add_query_parameter   s   rL   c                 C   sX   t j| rtt| t j| rtt| t j| s*t	
t|  d S d S )N)ospathislinkIOError_SYM_LINK_MESSAGEr   isdir_IS_DIR_MESSAGEisfilewarningswarn_MISSING_FILE_MESSAGE)filenamer   r   r   validate_file   s   rY   c                 C   s"   |  d}|dkr| |d S dS )az  Identify and extract PEM keys.

    Determines whether the given key is in the format of PEM key, and extracts
    the relevant part of the key if it is.

    Args:
        raw_key_input: The contents of a private key file (either PEM or
                       PKCS12).

    Returns:
        string, The actual key if the contents are from a PEM file, or
        else None.
    s   -----BEGIN N)find)raw_key_inputoffsetr   r   r   _parse_pem_key  s   
r^   c                 C   s   t j| ddS )N),:)
separators)jsondumps)datar   r   r   _json_encode  s   re   asciic                 C   s8   t | tjr| |n| }t |tjr|S td| )a4  Converts a string value to bytes, if necessary.

    Unfortunately, ``six.b`` is insufficient for this task since in
    Python2 it does not modify ``unicode`` objects.

    Args:
        value: The string/bytes value to be converted.
        encoding: The encoding to use to convert unicode to bytes. Defaults
                  to "ascii", which will not allow any characters from ordinals
                  larger than 127. Other useful values are "latin-1", which
                  which will only allows byte ordinals (up to 255) and "utf-8",
                  which will encode any unicode that needs to be.

    Returns:
        The original value converted to bytes (if unicode) or as passed in
        if it started out as bytes.

    Raises:
        ValueError if the value could not be converted to bytes.
    z%{0!r} could not be converted to bytes)r#   r$   	text_typeencodebinary_typer6   r   )r;   encodingresultr   r   r   	_to_bytes  s   
rl   c                 C   s8   t | tjr| dn| }t |tjr|S td| )aE  Converts bytes to a string value, if necessary.

    Args:
        value: The string/bytes value to be converted.

    Returns:
        The original value converted to unicode (if bytes) or as passed in
        if it started out as unicode.

    Raises:
        ValueError if the value could not be converted to unicode.
    utf-8z'{0!r} could not be converted to unicode)r#   r$   ri   decoderg   r6   r   )r;   rk   r   r   r   _from_bytes6  s   
ro   c                 C   s   t | dd} t| dS )Nrm   )rj      =)rl   base64urlsafe_b64encoderstrip)	raw_bytesr   r   r   _urlsafe_b64encodeL  s   ru   c                 C   s*   t | } | ddt| d    }t|S )Nrp      )rl   r   rq   urlsafe_b64decode)	b64stringpaddedr   r   r   _urlsafe_b64decodeQ  s   
rz   )rf   )$__doc__rq   r   r&   rb   loggingrM   rU   r$   	six.movesr   	getLoggerr   r   r   r   POSITIONAL_IGNORE	frozensetPOSITIONAL_SETr   rQ   rS   rW   r(   r0   r2   r=   rI   rL   rY   r^   re   rl   ro   ru   rz   r   r   r   r   <module>   sD   
c	
