ó
‚¾^Yc           @   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 j e ƒ Z d Z d Z d Z e e e e g ƒ Z e Z d Z d Z d	 Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d d „ Z  d „  Z! d „  Z" d „  Z# d S(   s-   Helper functions for commonly used utilities.iÿÿÿÿN(   t   urllibt   WARNINGt	   EXCEPTIONt   IGNOREs   File: {0}: Is a symbolic link.s   {0}: Is a directorys,   Cannot access {0}: No such file or directoryc            sd   ‡  f d †  } t  ˆ  t j ƒ r% | St j ˆ  ƒ \ } } } } t t | ƒ t | ƒ ƒ ˆ  ƒ Sd S(   sŽ  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  j ˆ  ƒ ‡ ‡  f d †  ƒ } | S(   Nc       	      s¡   t  |  ƒ ˆ  k r” d } ˆ  d k r- d } n  d j d ˆ j d ˆ  d t  |  ƒ d | ƒ } t t k ru t | ƒ ‚ q” t t k r” t j | ƒ q” n  ˆ |  | Ž  S(	   Nt    i   t   ssV   {function}() takes at most {args_max} positional argument{plural} ({args_given} given)t   functiont   args_maxt
   args_givent   plural(	   t   lent   formatt   __name__t!   positional_parameters_enforcementt   POSITIONAL_EXCEPTIONt	   TypeErrort   POSITIONAL_WARNINGt   loggert   warning(   t   argst   kwargst   plural_st   message(   t   max_positional_argst   wrapped(    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   positional_wrapperu   s    				(   t	   functoolst   wraps(   R   R   (   R   (   R   s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   positional_decoratort   s    !N(   t
   isinstancet   sixt   integer_typest   inspectt
   getargspect
   positionalR
   (   R   R   R   t   _t   defaults(    (   R   s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyR"   ,   s
    Hc         C   s'   t  |  t j ƒ r |  Sd j |  ƒ Sd S(   s_  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.
    t    N(   R   R   t   string_typest   join(   t   scopes(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   scopes_to_string   s    c         C   s1   |  s
 g  St  |  t j ƒ r) |  j d ƒ S|  Sd S(   s+  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%   N(   R   R   R&   t   split(   R(   (    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   string_to_scopes¢   s
    c         C   s„   t  j j |  ƒ } i  } xe t j | ƒ D]T \ } } t | ƒ d k rn d | d j | ƒ f } t | ƒ ‚ n  | d | | <q( W| S(   s  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.
    i   s6   URL-encoded content contains a repeated value:%s -> %ss   , i    (   R    t   parset   parse_qsR   t	   iteritemsR
   R'   t
   ValueError(   t   contentt   urlencoded_paramst   paramst   keyt   valuet   msg(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   parse_unique_urlencoded¶   s    c         C   sb   t  j j |  ƒ } t | j ƒ } | j | ƒ t  j j | ƒ } | j d | ƒ } t  j j | ƒ S(   s  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.
    t   query(	   R    R,   t   urlparseR6   R7   t   updatet	   urlencodet   _replacet
   urlunparse(   t   uriR2   t   partst   query_paramst	   new_queryt	   new_parts(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   update_query_paramsÍ   s    c         C   s(   | d k r |  St |  i | | 6ƒ Sd S(   s\  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(   t   NoneRB   (   t   urlt   nameR4   (    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   _add_query_parameteræ   s    c         C   sƒ   t  j j |  ƒ r* t t j |  ƒ ƒ ‚ nU t  j j |  ƒ rT t t j |  ƒ ƒ ‚ n+ t  j j |  ƒ s t	 j
 t j |  ƒ ƒ n  d  S(   N(   t   ost   patht   islinkt   IOErrort   _SYM_LINK_MESSAGER   t   isdirt   _IS_DIR_MESSAGEt   isfilet   warningst   warnt   _MISSING_FILE_MESSAGE(   t   filename(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   validate_fileù   s    c         C   s'   |  j  d ƒ } | d k r# |  | Sd S(   sz  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 iÿÿÿÿN(   t   find(   t   raw_key_inputt   offset(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   _parse_pem_key  s    c         C   s   t  j |  d d ƒS(   Nt
   separatorst   ,t   :(   RY   RZ   (   t   jsont   dumps(   t   data(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   _json_encode  s    t   asciic         C   sV   t  |  t j ƒ r! |  j | ƒ n |  } t  | t j ƒ r= | St d j |  ƒ ƒ ‚ d S(   s4  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.
    s%   {0!r} could not be converted to bytesN(   R   R   t	   text_typet   encodet   binary_typeR/   R   (   R4   t   encodingt   result(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt	   _to_bytes  s    'c         C   sV   t  |  t j ƒ r! |  j d ƒ n |  } t  | t j ƒ r= | St d j |  ƒ ƒ ‚ d S(   sE  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.
    s   utf-8s'   {0!r} could not be converted to unicodeN(   R   R   Rb   t   decodeR`   R/   R   (   R4   Rd   (    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   _from_bytes6  s
    'c         C   s(   t  |  d d ƒ}  t j |  ƒ j d ƒ S(   NRc   s   utf-8t   =(   Re   t   base64t   urlsafe_b64encodet   rstrip(   t	   raw_bytes(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   _urlsafe_b64encodeL  s    c         C   s5   t  |  ƒ }  |  d d t |  ƒ d } t j | ƒ S(   NRh   i   (   Re   R
   Ri   t   urlsafe_b64decode(   t	   b64stringt   padded(    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   _urlsafe_b64decodeQ  s    ($   t   __doc__Ri   R   R    R[   t   loggingRG   RO   R   t	   six.movesR    t	   getLoggerR   R   R   R   t   POSITIONAL_IGNOREt	   frozensett   POSITIONAL_SETR   RK   RM   RQ   R"   R)   R+   R6   RB   RF   RS   RW   R^   Re   Rg   Rm   Rq   (    (    (    s;   /tmp/pip-build-kpPAdC/oauth2client/oauth2client/_helpers.pyt   <module>   s@   		c											