
®Ajã  ã            	   @   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