
    e=                     <   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Zddl	m
Z
 dZdZeZdZej                  Zd ZefdZd	 Zd
 Zd ZddZddZde_        ddZd Zd Zd ZddZd Zd Zd Z  G d de!      Z"ejF                  dddfdZ$ G d de!      Z%y) z.
Time related utilities and helper functions.
    N)
reflectionz%Y-%m-%dT%H:%M:%S.%fz%Y-%m-%dT%H:%M:%S;   c                     	 t        j                  |       S # t         j                  $ r}t        t	        |            d}~wt
        $ r}t        t	        |            d}~ww xY w)z Parse time from ISO 8601 format.N)iso8601
parse_date
ParseError
ValueErrorstr	TypeError)timestres     6/usr/lib/python3/dist-packages/oslo_utils/timeutils.pyparse_isotimer   +   sU    !!!'** !Q   !Q  !s    A#>A#
AA#c                 B    t         j                   j                  | |      S )z+Turn a formatted time back into a datetime.)datetimestrptime)r   fmts     r   parse_strtimer   5   s    %%gs33    c                 T    | j                         }|| S | j                  d      |z
  S )z9Normalize time in arbitrary timezone to UTC naive object.Ntzinfo)	utcoffsetreplace)	timestampoffsets     r   normalize_timer   :   s4      "F~D)F22r   c                     t        | t              rt        |       } t        |       } t	               | z
  t        j                  |      kD  S )zReturn True if before is older than seconds.

    .. versionchanged:: 1.7
       Accept datetime string with timezone information.
       Fix comparison with timezone aware datetime.
    seconds
isinstancer
   r   r   utcnowr   	timedelta)beforer    s     r   is_older_thanr&   B   s?     &#v&F#F8fx11'BBBr   c                     t        | t              rt        |       } t        |       } | t	               z
  t        j                  |      kD  S )zReturn True if after is newer than seconds.

    .. versionchanged:: 1.7
       Accept datetime string with timezone information.
       Fix comparison with timezone aware datetime.
    r   r!   )afterr    s     r   is_newer_thanr)   Q   s?     %e$5!E68h00AAAr   c                     t         j                  #t        j                         }| st        |      }|S t               }t	        j
                  |j                               }| r|t        |j                        dz  z  }|S )zTimestamp version of our utcnow function.

    See :py:class:`oslo_utils.fixture.TimeFixture`.

    .. versionchanged:: 1.3
       Added optional *microsecond* parameter.
    i@B )	r#   override_timetimeintcalendartimegm	timetuplefloatmicrosecond)r2   r   nows      r   	utcnow_tsr4   `   sk     # IIK	II
(C0IU3??+g55	r   c                    t         j                  r 	 t         j                  j                  d      S | r8t        j                  j                  t        j                  j                        S t        j                  j                  t        j                  j                        j                  d      S # t        $ r t         j                  cY S w xY w)zOverridable version of utils.utcnow that can return a TZ-aware datetime.

    See :py:class:`oslo_utils.fixture.TimeFixture`.

    .. versionchanged:: 1.6
       Added *with_timezone* parameter.
    r   )tzNr   )r#   r+   popAttributeErrorr   r3   r   UTCtimezoneutcr   )with_timezones    r   r#   r#   y   s     	(''++A..   $$(;(;$<<  !2!2!6!67??t?LL	  	('''	(s   B2 2CCc                     | xsG t         j                   j                  t         j                  j                        j	                  d      t
        _        y)a  Overrides utils.utcnow.

    Make it return a constant time or a list thereof, one at a time.

    See :py:class:`oslo_utils.fixture.TimeFixture`.

    :param override_time: datetime instance or list thereof. If not
                          given, defaults to the current UTC time.
    Nr   )r   r3   r:   r;   r   r#   r+   )r+   s    r   set_time_overrider>      sC     	 	Jh//334<<D<I r   c                     t         j                  J 	 t         j                  D ]  }|| z  }	 y# t        $ r t         xj                  | z  c_        Y yw xY w)znAdvance overridden time using a datetime.timedelta.

    See :py:class:`oslo_utils.fixture.TimeFixture`.

    N)r#   r+   r   )r$   dts     r   advance_time_deltarA      sY     +++*&& 	B)OB	 *	)*s   / "AAc                 B    t        t        j                  d|              y)z^Advance overridden time by seconds.

    See :py:class:`oslo_utils.fixture.TimeFixture`.

    r   N)rA   r   r$   r   s    r   advance_time_secondsrC      s     x))!W56r   c                      dt         _        y)zVRemove the overridden time.

    See :py:class:`oslo_utils.fixture.TimeFixture`.

    N)r#   r+    r   r   clear_time_overriderF      s      Fr   c           	      4   | s
t               } t        | j                  | j                  | j                  | j
                  | j                  | j                  | j                        }| j                  r'| j                  j                  d      }|dk(  rdn||d<   |S )zMake an rpc-safe datetime with microseconds.

    .. versionchanged:: 1.6
       Timezone information is now serialized instead of being stripped.
    daymonthyearhourminutesecondr2   N	UTC+00:00r9   tzname)r#   dictrI   rJ   rK   rL   rM   rN   r2   r   rP   )r3   drP   s      r   marshall_nowrS      sx     h		sxxJJszz	*A zz""4(%4e&(Hr   c           
      j   t        | d   t              }t        j                  | d   | d   | d   | d   | d   || d         }| j                  d	      }|r^|d
k(  rdn|}t        r)t        j                  |      }|j                  |      }|S t        j                  |      }|j                  |      }|S )zUnmarshall a datetime dict.

    .. versionchanged:: 1.5
       Drop leap second.

    .. versionchanged:: 1.6
       Added support for timezone information.
    rN   rI   rJ   rK   rL   rM   r2   rH   rP   rO   r9   r   )
min_MAX_DATETIME_SECr   getzoneinfoZoneInfor   pytzr:   localize)tymerN   r@   rP   r   s        r   unmarshall_timer]      s     h!23F			tE{!%g $V $V"&x."('+M':
<B XXhF K/V&&v.F6*B
 I ]]6*F$BIr   c                 ,    || z
  }|j                         S )zReturn the difference between two timing objects.

    Compute the difference in seconds between two date, time, or
    datetime objects (as a float, to microsecond resolution).
    )total_seconds)r%   r(   deltas      r   delta_secondsra      s     FNE  r   c                 `    t               t        j                  |      z   }t        |       |k  S )zDetermines if time is going to happen in the next window seconds.

    :param dt: the time
    :param window: minimum seconds to remain to consider the time not soon

    :return: True if expiration is within the given duration
    r   )r#   r   r$   r   )r@   windowsoons      r   is_soonre      s+     Hx))&99D"%%r   c                   D    e Zd ZdZddgZd Zed        Zed        Zd Z	y)	SplitzA *immutable* stopwatch split.

    See: http://en.wikipedia.org/wiki/Stopwatch for what this is/represents.

    .. versionadded:: 1.4
    _elapsed_lengthc                      || _         || _        y N)rh   ri   selfelapsedlengths      r   __init__zSplit.__init__  s    r   c                     | j                   S )zDuration from stopwatch start.)rh   rm   s    r   rn   zSplit.elapsed  s     }}r   c                     | j                   S )z@Seconds from last split (or the elapsed time if no prior split).)ri   rr   s    r   ro   zSplit.length       ||r   c                 t    t        j                  | d      }|d| j                  d| j                  dz  }|S )NF)fully_qualifiedz	(elapsed=z	, length=))r   get_class_namerh   ri   )rm   rs     r   __repr__zSplit.__repr__!  s0    %%dEB	$--FFr   N)
__name__
__module____qualname____doc__	__slots__rp   propertyrn   ro   rz   rE   r   r   rg   rg   	  sE     Y'I    r   rg   z>It took %(seconds).02f seconds to run function '%(func_name)s'Tg{Gz?c                 "      fd}|S )a  Decorator that will log how long its decorated function takes to run.

    This does **not** output a log if the decorated function fails
    with an exception.

    :param logger: logger instance to use when logging elapsed time
    :param log_level: logger logging level to use when logging elapsed time
    :param message: customized message to use when logging elapsed time,
                    the message may use automatically provide values
                    ``%(seconds)`` and ``%(func_name)`` if it finds those
                    values useful to record
    :param enabled: whether to enable or disable this decorator (useful to
                    decorate a function with this decorator, and then easily
                    be able to switch that decoration off by some config or
                    other value)
    :param min_duration: argument that determines if logging is triggered
                         or not, it is by default set to 0.01 seconds to avoid
                         logging when durations and/or elapsed function call
                         times are less than 0.01 seconds, to disable
                         any ``min_duration`` checks this value should be set
                         to less than or equal to zero or set to none
    c                 T     s S t        j                          fd       }|S )Nc                      t               5 } | i |}d d d        j                         }	|	k\  r)j                  |t        j                        d       S # 1 sw Y   KxY w)N)r    	func_name)	StopWatchrn   logr   get_callable_name)
argskwargswresult
time_takenfunc	log_levelloggermessagemin_durations
        r   wrapperz+time_it.<locals>.decorator.<locals>.wrapperF  su     /t.v./J#z\'A

9g'1)3)E)Ed)KMN M/ /s   	AA()	functoolswraps)r   r   enabledr   r   r   r   s   ` r   	decoratorztime_it.<locals>.decoratorB  s-    K			 
	 r   rE   )r   r   r   r   r   r   s   ````` r   time_itr   '  s    6 " r   c                       e Zd ZdZdZdZddZd Zed        Z	d Z
d	 Zed
        ZddZd Zd ZddZd Zd Zd Zd Zd Zy)r   a  A simple timer/stopwatch helper class.

    Inspired by: apache-commons-lang java stopwatch.

    Not thread-safe (when a single watch is mutated by multiple threads at
    the same time). Thread-safe when used by a single thread (not shared) or
    when operations are performed in a thread-safe manner on these objects by
    wrapping those operations with locks.

    .. versionadded:: 1.4
    STARTEDSTOPPEDNc                 t    ||dk  rt        d|z        || _        d | _        d | _        d | _        d| _        y )Nr   z4Duration must be greater or equal to zero and not %srE   )r	   	_duration_started_at_stopped_at_state_splits)rm   durations     r   rp   zStopWatch.__init__e  sM    HqL 02:; < <!r   c                     | j                   | j                  k(  r| S t               | _        d| _        | j                  | _         d| _        | S )z|Starts the watch (if not already started).

        NOTE(harlowja): resets any splits previously captured (if any).
        NrE   )r   _STARTEDr3   r   r   r   rr   s    r   startzStopWatch.starto  sB    
 ;;$--'K5mmr   c                     | j                   S )z3Accessor to all/any splits that have been captured.)r   rr   s    r   splitszStopWatch.splits|  rt   r   c                 6   | j                   | j                  k(  rv| j                         }| j                  r*| j	                  | j                  d   j                  |      }n|}| j                  t        ||      fz   | _        | j                  d   S t        d      )z=Captures a split/elapsed since start time (and doesn't stop).z_Can not create a split time of a stopwatch if it has not been started or if it has been stopped)r   r   rn   r   _delta_secondsrg   RuntimeErrorrl   s      r   splitzStopWatch.split  s    ;;$--'llnG||,,T\\"-=-E-EwO <<5&+A*CCDL<<##  * + +r   c                 x    | j                   | j                  k(  r| j                          | j                          | S )z0Restarts the watch from a started/stopped state.)r   r   stopr   rr   s    r   restartzStopWatch.restart  s)    ;;$--'IIK

r   c                      t        d|| z
        S )N        )max)earlierlaters     r   r   zStopWatch._delta_seconds  s     3((r   c                 R   | j                   | j                  | j                  fvrt        d      | j                   | j                  k(  r'| j	                  | j
                  | j                        }n$| j	                  | j
                  t                     }|||kD  rt        d|      }|S )z&Returns how many seconds have elapsed.zNCan not get the elapsed time of a stopwatch if it has not been started/stoppedr   )	r   r   _STOPPEDr   r   r   r   r3   r   )rm   maximumrn   s      r   rn   zStopWatch.elapsed  s    ;;t}}dmm<<  E F F;;$--'))$*:*:D<L<LMG))$*:*:CEBG7W#4#w'Gr   c                 &    | j                          | S )zStarts the watch.)r   rr   s    r   	__enter__zStopWatch.__enter__  s    

r   c                 D    	 | j                          y# t        $ r Y yw xY w)z0Stops the watch (ignoring errors if stop fails).N)r   r   )rm   typevalue	tracebacks       r   __exit__zStopWatch.__exit__  s"    	IIK 		s    	c                     | j                   | j                  k7  rt        d      | j                  |st        d      yt	        d| j                  | j                         z
        S )a5  Returns how many seconds are left until the watch expires.

        :param return_none: when ``True`` instead of raising a ``RuntimeError``
                            when no duration has been set this call will
                            return ``None`` instead.
        :type return_none: boolean
        zFCan not get the leftover time of a stopwatch that has not been startedNz=Can not get the leftover time of a watch that has no durationr   )r   r   r   r   r   rn   )rm   return_nones     r   leftoverzStopWatch.leftover  sd     ;;$--'  < = =>>!" $; < <3788r   c                     | j                   | j                  | j                  fvrt        d      | j                  y| j                         | j                  kD  S )zAReturns if the watch has expired (ie, duration provided elapsed).zKCan not check if a stopwatch has expired if it has not been started/stoppedF)r   r   r   r   r   rn   rr   s    r   expiredzStopWatch.expired  sR    ;;t}}dmm<<  E F F>>!||~..r   c                 4    | j                   | j                  k(  S )z0Returns True if the watch is in a started state.)r   r   rr   s    r   has_startedzStopWatch.has_started      {{dmm++r   c                 4    | j                   | j                  k(  S )z0Returns True if the watch is in a stopped state.)r   r   rr   s    r   has_stoppedzStopWatch.has_stopped  r   r   c                 p    | j                   | j                  k(  r| j                  | _         | S t        d      )z'Resumes the watch from a stopped state.z4Can not resume a stopwatch that has not been stopped)r   r   r   r   rr   s    r   resumezStopWatch.resume  s4    ;;$--'--DKK  * + +r   c                     | j                   | j                  k(  r| S | j                   | j                  k7  rt        d      t	               | _        | j                  | _         | S )zStops the watch.z2Can not stop a stopwatch that has not been started)r   r   r   r   r3   r   rr   s    r   r   zStopWatch.stop  sS    ;;$--'K;;$--'  * + +5mmr   rk   F)r{   r|   r}   r~   r   r   rp   r   r   r   r   r   staticmethodr   rn   r   r   r   r   r   r   r   r   rE   r   r   r   r   V  s|    
 HH  + ) )
9$/,,+	r   r   r   rk   )&r~   r.   r   r   loggingr,   r   rZ   rX   
oslo_utilsr   _ISO8601_TIME_FORMAT_SUBSECOND_ISO8601_TIME_FORMATPERFECT_TIME_FORMATrV   	monotonicr3   r   r   r   r&   r)   r4   r#   r+   r>   rA   rC   rF   rS   r]   ra   re   objectrg   DEBUGr   r   rE   r   r   <module>r      s            ! "8 * 4  
nn!  3 4
3CB2M$  K*7 $!H!	&F < &mm4t,^T Tr   