
    '                     &   S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
r
/ SQr " S S\5      rSr\R                  " \\R                   \R"                  -  5      rS r\" S	5      S
 5       rS r " S S\R,                  5      rSS jrg)zCommon utility library.    )with_statementN)Errordecode_datetimeget_package_for_module
positionalTimeZoneOffsettotal_secondsc                       \ rS rSrSrSrg)r   (   z#Base class for protorpc exceptions. N)__name__
__module____qualname____firstlineno____doc____static_attributes__r       2lib/third_party/apitools/base/protorpclite/util.pyr   r   (   s    -r   r   z
  # Examples:
  #   +01:00
  #   -05:30
  #   Z12:00
  ((?P<z>Z) | (?P<sign>[-+])
   (?P<hours>\d\d) :
   (?P<minutes>\d\d))$
c                    ^  U 4S jn[        T [        R                  5      (       a  U$ [        R                  " T 5      tn  p4nUc  [        S5      e[        [        U5      [        U5      -
  5      " T 5      $ )a=  A decorator that declares only the first N arguments may 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):
        ...

  One can omit the argument to 'positional' altogether, and then no
  arguments with default values may be passed positionally. This
  would be equivalent to placing a '*' before the first argument
  with a default value in Python 3. If there are no arguments with
  default values, and no argument is given to 'positional', an error
  is raised.

    @positional
    def fn(arg1, arg2, required_kw1=None, required_kw2=0):
      ...

    fn(1, 3, 5)  # Raises exception.
    fn(1, 3)  # Ok.
    fn(1, 3, required_kw1=5)  # Ok.

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 keyword-only argument is provided as a positional
    parameter.
  ValueError if no maximum number of arguments is provided and the function
    has no arguments with default values.
c                 J   >^  [         R                  " T 5      UU 4S j5       nU$ )z9Creates a function wraper to enforce number of arguments.c            	         > [        U 5      T:  a/  SnTS:w  a  Sn[        STR                  TU[        U 5      4-  5      eT" U 0 UD6$ )N    sz6%s() takes at most %d positional argument%s (%d given))len	TypeErrorr   )argskwargsplural_smax_positional_argswrappeds      r   positional_wrapperDpositional.<locals>.positional_decorator.<locals>.positional_wrapper   si    4y..&!+"H !-070@0@0C08#d)0E!E F F D+F++r   )	functoolswraps)r!   r"   r    s   ` r   positional_decorator(positional.<locals>.positional_decorator   s&    		!		, 
"		, "!r   zDFunctions with no keyword arguments must specify max_positional_args)
isinstancesixinteger_typesinspectgetfullargspec
ValueErrorr   r   )r    r&   r   _defaultss   `    r   r   r   8   sw    Z" %s'8'899###*#9#9:M#N aq&' ' #d)c(m345HIIr   r   c                 z   [        U [        R                  5      (       a   [        R                  U    n  [        R                  " U R                  5      $ ! [
         a     gf = f! [         a    U R                  S:X  a   U R                  n[        R                  R                  U5      n[        R                  R                  U5      n[        U5      S:X  a  [        R                  " U5      s $ SR!                  USS 5      s $ ! [         a     Of = f[        R                  " U R                  5      s $ f = f)a  Get package name for a module.

Helper calculates the package name of a module.

Args:
  module: Module to get name for.  If module is a string, try to find
    module in sys.modules.

Returns:
  If module contains 'package' attribute, uses that as package name.
  Else, if module is not the '__main__' module, the module __name__.
  Else, the base name of the module file name.  Else None.
N__main__r   .)r(   r)   string_typessysmodulesKeyError	text_typepackageAttributeErrorr   __file__ospathbasenamesplitextr   join)module	file_name	base_name
split_names       r   r   r      s    &#**++	[[(F.}}V^^,,	  		
  .??j(	2"OO	 GG,,Y7	WW--i8
z?a'==33yyCR11 "  }}V__--.sM   A A% 
A"!A"%D: DA#D:1D:
DD:D#D:9D:c                 t    U R                   S-  S-  S-  U R                  -   nUS-  U R                  -   nUS-  $ )z4Backport of offset.total_seconds() from python 2.7+.   <   i@B g    .A)dayssecondsmicroseconds)offsetrI   rJ   s      r   r	   r	      sB    kkB#b(6>>9GU?V%8%88L;''r   c                   8   ^  \ rS rSrSrU 4S jrS rS rSrU =r	$ )r      z<Time zone information as encoded/decoded for DateTimeFields.c                    > [         [        U ]  5         [        U[        R
                  5      (       a  [        U5      S-  nXl        g)zInitialize a time zone offset.

Args:
  offset: Integer or timedelta time zone offset, in minutes from UTC.
    This can be negative.
rG   N)superr   __init__r(   datetime	timedeltar	   _TimeZoneOffset__offset)selfrK   	__class__s     r   rP   TimeZoneOffset.__init__   s9     	nd,.fh0011"6*R/Fr   c                 >    [         R                  " U R                  S9$ )zuGet the a timedelta with the time zone's offset from UTC.

Returns:
  The time zone offset from UTC, as a timedelta.
)minutes)rQ   rR   rS   rT   r.   s     r   	utcoffsetTimeZoneOffset.utcoffset   s     !!$--88r   c                 .    [         R                  " S5      $ )zGet the daylight savings time offset.

The formats that ProtoRPC uses to encode/decode time zone
information don't contain any information about daylight
savings time. So this always returns a timedelta of 0.

Returns:
  A timedelta of 0.

r   )rQ   rR   rY   s     r   dstTimeZoneOffset.dst   s     !!!$$r   )__offset)
r   r   r   r   r   rP   rZ   r]   r   __classcell__)rU   s   @r   r   r      s    F
9% %r   r   c                    [         R                  U 5      nU(       a#  U SUR                  S5       R                  5       nOU R                  5       nSU;   a  SnOSn [        R                  R                  UU5      nU(       d  U$ UR                  S	5      (       a  S
n	ORUR                  S5      n
UR                  SS5       Vs/ s H  n[        U5      PM     snu  pUS-  U-   n	U
S:X  a  U	S-  n	[        R                  " UR                  UR                  UR                   UR"                  UR$                  UR&                  UR(                  [+        U	5      5      $ ! [         a    U(       aw  SU;   aq  UR                  S5      u  pg[        U5      S:  aN  SR                  XgSS 5      n[        R                  R                  UU5      n[        R                  " SX85         GNge e f = fs  snf )ap  Decode a DateTimeField parameter from a string to a python datetime.

Args:
  encoded_datetime: A string in RFC 3339 format.
  truncate_time: If true, truncate time string with precision higher than
      microsecs.

Returns:
  A datetime object with the date and time specified in encoded_datetime.

Raises:
  ValueError: If the string is not in a recognized format.
Nr   r2   z%Y-%m-%dT%H:%M:%S.%fz%Y-%m-%dT%H:%M:%S   z{}.{}z,Truncating the datetime string from %s to %szr   signhoursrX   rG   -r3   )_TIME_ZONE_REsearchstartupperrQ   strptimer-   splitr   formatloggingwarninggroupintyearmonthdayhourminutesecondmicrosecondr   )encoded_datetimetruncate_timetime_zone_matchtime_stringformat_stringdecoded_datetimedatetime_stringdecimal_secstruncated_time_stringoffset_minutesrd   valuere   rX   s                 r   r   r      s   " $**+;<O&'@(=(=a(@AGGI&,,.
k.+#,,55k6CE( 
 S!!$$V,)//CEC */#e*CEg-3;b N-22-33-11-22-44-44-99+N;= =E  SK/,7,=,=c,B)O< 1$(/#"1%5)7%#+#4#4#=#=)!$#  B8 !8Es    E G)BG&#G&)F)r   
__future__r   rQ   r$   r+   rn   r<   rer5   r)   __all__	Exceptionr   _TIME_ZONE_RE_STRINGcompile
IGNORECASEVERBOSErg   r   r   r	   tzinfor   r   r   r   r   <module>r      s   "  %     	 	 
 
.I .  

/1KLdJN A#. #.L("%X__ "%JH=r   