
Ѯh              	   @   s%  d  Z  d d l m Z m Z m Z d d l Z e j e  Z d d l	 m
 Z
 m Z d d l Z d d l m Z d d l m Z d d d	 d
 d d g Z Gd d   d e  Z Gd d   d e  Z d d	   Z Gd d
   d
 e  Z d d d d d d d d d  Z d d d d d d d  Z d S)z7
passlib.utils.decor -- helper decorators & properties
    )absolute_importdivisionprint_functionN)wrapsupdate_wrapper)warn)PY3classpropertyhybrid_methodmemoize_single_valuememoized_propertydeprecated_functiondeprecated_methodc               @   s@   e  Z d  Z d Z d d   Z d d   Z e d d    Z d S)	r	   zjFunction decorator which acts like a combination of classmethod+property (limited to read-only properties)c             C   s   | |  _  d  S)N)im_func)selffunc r   ../../passlib/utils/decor.py__init__#   s    zclassproperty.__init__c             C   s   |  j  |  S)N)r   )r   objclsr   r   r   __get__&   s    zclassproperty.__get__c             C   s   |  j  S)zpy3 compatible alias)r   )r   r   r   r   __func__)   s    zclassproperty.__func__N)__name__
__module____qualname____doc__r   r   propertyr   r   r   r   r   r	       s   c               @   s.   e  Z d  Z d Z d d   Z d d   Z d S)r
   z
    decorator which invokes function with class if called as class method,
    and with object if called at instance level.
    c             C   s   | |  _  t |  |  d  S)N)r   r   )r   r   r   r   r   r   4   s    	zhybrid_method.__init__c             C   sE   | d  k r | } t  r+ t j |  j |  St j |  j | |  Sd  S)N)r   types
MethodTyper   )r   r   r   r   r   r   r   8   s
    zhybrid_method.__get__N)r   r   r   r   r   r   r   r   r   r   r
   .   s   c                sF   i    t       f d d    }   f d d   } | | _ | S)z
    decorator for function which takes no args,
    and memoizes result.  exposes a ``.clear_cache`` method
    to clear the cached value.
    c                 s6   y   d SWn t  k
 r  Yn X   }    d <|  S)NT)KeyError)value)cacher   r   r   wrapperL   s    z%memoize_single_value.<locals>.wrapperc                  s     j  d d   d  S)NT)popr   )r"   r   r   clear_cacheU   s    z)memoize_single_value.<locals>.clear_cache)r   r%   )r   r#   r%   r   )r"   r   r   r   D   s
    !		c               @   sa   e  Z d  Z d Z d d   Z d d   Z e sB e d d    Z d d	   Z	 d
 d d  Z
 d
 S)r   zM
    decorator which invokes method once, then replaces attr with result
    c             C   s%   | |  _  | j |  _ | j |  _ d  S)N)r   r   r   )r   r   r   r   r   r   _   s    	zmemoized_property.__init__c             C   s6   | d  k r |  S|  j  |  } t | |  j |  | S)N)r   setattrr   )r   r   r   r!   r   r   r   r   d   s
    zmemoized_property.__get__c             C   s   |  j  S)z	py2 alias)r   )r   r   r   r   r   m   s    zmemoized_property.im_funcc             C   s   | j  j |  j d  d S)z
        class-level helper to clear stored value (if any).

        usage: :samp:`type(self).{attr}.clear_cache(self)`
        N)__dict__r$   r   )r   r   r   r   r   r%   r   s    zmemoized_property.clear_cacheNc             C   s   | j  j |  j |  S)z
        class-level helper to peek at stored value

        usage: :samp:`value = type(self).{attr}.clear_cache(self)`
        )r'   getr   )r   r   defaultr   r   r   
peek_cachez   s    zmemoized_property.peek_cache)r   r   r   r   r   r   r   r   r   r%   r*   r   r   r   r   r   [   s   TFc                s    d k r_   r d  n d   r1  d 7  rA  d 7  rU  d  7  d 7         f d d	   } | S)
ab  decorator to deprecate a function.

    :arg msg: optional msg, default chosen if omitted
    :kwd deprecated: version when function was first deprecated
    :kwd removed: version when function will be removed
    :kwd replacement: alternate name / instructions for replacing this function.
    :kwd updoc: add notice to docstring (default ``True``)
    Nz5the method %(mod)s.%(klass)s.%(name)s() is deprecatedz-the function %(mod)s.%(name)s() is deprecatedz as of Passlib %(deprecated)sz,, and will be removed in Passlib %(removed)sz, use %s instead.c          	      s   o t    t    r0   j d  t  j   t d  pB   j d   j d  d     r      f d d   } n       f d d   } t |    
 r~ s  r~| j	 r~d | j	 k r~ p d	 }  s 	 r>| d
 7}  r| d  f 7} 	 r4 r&| d 7} | d 	 7} | d 7} | j	 j
 d  j d  sh| j	 d 7_	 | j	 d | f 7_	  rt |  } | S)Nmodname
deprecatedremovedc                 si    j    }  r |  d n
 |  d j } | j d | j d | j  t  | t d d   |  |   S)Nr   klassr,   
stacklevel   )copy	__class__updater   r   r   DeprecationWarning)argskwdstmpr0   )r   is_classmethodmsgoptsr   r   r#      s
    z3deprecated_function.<locals>.build.<locals>.wrapperc                 s    t   t d d   |  |   S)Nr1   r2   )r   r6   )r7   r8   )r   textr   r   r#      s    z.. deprecated:: z
    z!and will be removed in version %sz, zuse %s insteadr+    
z
.. deprecated:: %s
)
isinstanceclassmethodr   typer   dictr   r   r   r   stripendswith)r   r#   Ztxt)
_is_methodr.   func_moduler;   r/   replacementupdoc)r   r:   r<   r=   r   build   s>    		



z"deprecated_function.<locals>.buildr   )r;   r.   r/   rJ   rI   rG   rH   rK   r   )rG   r.   rH   r;   r/   rI   rJ   r   r      s    	


$*c             C   s   t  |  | | | | d d S)aZ  decorator to deprecate a method.

    :arg msg: optional msg, default chosen if omitted
    :kwd deprecated: version when method was first deprecated
    :kwd removed: version when method will be removed
    :kwd replacement: alternate name / instructions for replacing this method.
    :kwd updoc: add notice to docstring (default ``True``)
    rG   T)r   )r;   r.   r/   rJ   rI   r   r   r   r      s    
)r   
__future__r   r   r   logging	getLoggerr   log	functoolsr   r   r   warningsr   passlib.utils.compatr   __all__objectr	   r
   r   r   r   r   r   r   r   r   <module>   s,   	<A