ó
î6Nc           @   sU  d  Z  d d d d d g Z d d l Z d d l Z d d l m a m Z d d	 l m Z d d
 l	 m
 Z
 d d l m Z d Z d „  Z d e _ d e _ d „  Z d „  Z d d „ Z d „  Z d d d „ Z d d d „ Z d d „ Z d „  Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d „  Z d „  Z d  „  Z  d S(!   s°  
Deprecation framework for Twisted.

To mark a method or function as being deprecated do this::

    from twisted.python.versions import Version
    from twisted.python.deprecate import deprecated

    @deprecated(Version("Twisted", 8, 0, 0))
    def badAPI(self, first, second):
        '''
        Docstring for badAPI.
        '''
        ...

The newly-decorated badAPI will issue a warning when called. It will also have
a deprecation notice appended to its docstring.

To mark module-level attributes as being deprecated you can use::

    badAttribute = "someValue"

    ...

    deprecatedModuleAttribute(
        Version("Twisted", 8, 0, 0),
        "Use goodAttribute instead.",
        "your.full.module.name",
        "badAttribute")

The deprecated attributes will issue a warning whenever they are accessed. If
the attributes being deprecated are in the same module as the
L{deprecatedModuleAttribute} call is being made from, the C{__name__} global
can be used as the C{moduleName} parameter.

See also L{Version}.

@type DEPRECATION_WARNING_FORMAT: C{str}
@var DEPRECATION_WARNING_FORMAT: The default deprecation warning string format
    to use when one is not provided by the user.
t
   deprecatedt   getDeprecationWarningStringt   getWarningMethodt   setWarningMethodt   deprecatedModuleAttributeiÿÿÿÿN(   t   warnt   warn_explicit(   t   findlinestarts(   t   getVersionString(   t   mergeFunctionMetadatas&   %(fqpn)s was deprecated in %(version)sc         C   sn   |  j  } t j |  ƒ s' t j |  ƒ r> |  j } d | | f St j |  ƒ rj t |  j ƒ } d | | f S| S(   s¼   
    Return the fully qualified name of a module, class, method or function.
    Classes and functions need to be module level ones to be correctly
    qualified.

    @rtype: C{str}.
    s   %s.%s(   t   __name__t   inspectt   isclasst
   isfunctiont
   __module__t   ismethodt   _fullyQualifiedNamet   im_class(   t   objt   namet
   moduleNamet	   className(    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR   H   s    		s   twisted.python.reflectt   fullyQualifiedNamec           C   s   t  S(   sR   
    Return the warning method currently used to record deprecation warnings.
    (   R   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR   ^   s    c         C   s
   |  a  d S(   s¨   
    Set the warning method to use to record deprecation warnings.

    The callable should take message, category and stacklevel. The return
    value is ignored.
    N(   R   (   t	   newMethod(    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR   f   s    c         C   s:   d t  |  ƒ f } | r2 d | t | ƒ f } n  | d S(   s  
    Generate an addition to a deprecated object's docstring that explains its
    deprecation.

    @param version: the version it was deprecated.
    @type version: L{Version}

    @param replacement: The replacement, if specified.
    @type replacement: C{str} or callable

    @return: a string like "Deprecated in Twisted 27.2.0; please use
        twisted.timestream.tachyon.flux instead."
    s   Deprecated in %ss   %s; %st   .(   R   t   _getReplacementString(   t   versiont   replacementt   doc(    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   _getDeprecationDocstringr   s    c         C   s&   t  |  ƒ r t |  ƒ }  n  d |  f S(   s
  
    Surround a replacement for a deprecated API with some polite text exhorting
    the user to consider it as an alternative.

    @type replacement: C{str} or callable

    @return: a string like "please use twisted.python.modules.getModule
        instead".
    s   please use %s instead(   t   callableR   (   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR   ‡   s    
c         C   sV   | d k r t } n  | i |  d 6t | ƒ d 6} | rR d | t | ƒ f } n  | S(   ss  
    Return a string indicating that the Python name was deprecated in the given
    version.

    @param fqpn: Fully qualified Python name of the thing being deprecated
    @type fqpn: C{str}

    @param version: Version that C{fqpn} was deprecated in.
    @type version: L{twisted.python.versions.Version}

    @param format: A user-provided format to interpolate warning values into, or
        L{DEPRECATION_WARNING_FORMAT
        <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
        given.
    @type format: C{str}

    @param replacement: what should be used in place of C{fqpn}. Either pass in
        a string, which will be inserted into the warning message, or a
        callable, which will be expanded to its full import path.
    @type replacement: C{str} or callable

    @return: A textual description of the deprecation
    @rtype: C{str}
    t   fqpnR   s   %s; %sN(   t   Nonet   DEPRECATION_WARNING_FORMATR   R   (   R   R   t   formatR   t   warningString(    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   _getDeprecationWarningString—   s    	c         C   s   t  t |  ƒ | | | ƒ S(   s  
    Return a string indicating that the callable was deprecated in the given
    version.

    @type callableThing: C{callable}
    @param callableThing: Callable object to be deprecated

    @type version: L{twisted.python.versions.Version}
    @param version: Version that C{callableThing} was deprecated in

    @type format: C{str}
    @param format: A user-provided format to interpolate warning values into,
        or L{DEPRECATION_WARNING_FORMAT
        <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if C{None} is
        given

    @param callableThing: A callable to be deprecated.

    @param version: The L{twisted.python.versions.Version} that the callable
        was deprecated in.

    @param replacement: what should be used in place of the callable. Either
        pass in a string, which will be inserted into the warning message,
        or a callable, which will be expanded to its full import path.
    @type replacement: C{str} or callable

    @return: A string describing the deprecation.
    @rtype: C{str}
    (   R$   R   (   t   callableThingR   R"   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR   ¼   s    c            s   ‡  ‡ f d †  } | S(   sç  
    Return a decorator that marks callables as deprecated.

    @type version: L{twisted.python.versions.Version}
    @param version: The version in which the callable will be marked as
        having been deprecated.  The decorated function will be annotated
        with this version, having it set as its C{deprecatedVersion}
        attribute.

    @param version: the version that the callable was deprecated in.
    @type version: L{twisted.python.versions.Version}

    @param replacement: what should be used in place of the callable. Either
        pass in a string, which will be inserted into the warning message,
        or a callable, which will be expanded to its full import path.
    @type replacement: C{str} or callable
    c            sY   t  ˆ  ˆ d ˆ ƒ ‰ ‡  ‡ f d †  } t ˆ  | ƒ } t | t ˆ ˆ ƒ ƒ ˆ | _ | S(   sA   
        Decorator that marks C{function} as deprecated.
        c             s    t  ˆ t d d ƒˆ  |  | Ž  S(   Nt
   stackleveli   (   R   t   DeprecationWarning(   t   argst   kwargs(   t   functionR#   (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   deprecatedFunctionù   s
    N(   R   R    R	   t   _appendToDocstringR   t   deprecatedVersion(   R*   R+   (   R   R   (   R*   R#   s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   deprecationDecoratorò   s    	(    (   R   R   R.   (    (   R   R   s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR    à   s    c         C   sª   |  j  r |  j  j ƒ  } n g  } t | ƒ d k rC | j | ƒ nQ t | ƒ d k rn | j d | d g ƒ n& | j ƒ  } | j d | | | g ƒ d j | ƒ |  _  d S(   sv  
    Append the given text to the docstring of C{thingWithDoc}.

    If C{thingWithDoc} has no docstring, then the text just replaces the
    docstring. If it has a single-line docstring then it appends a blank line
    and the message text. If it has a multi-line docstring, then in appends a
    blank line a the message text, and also does the indentation correctly.
    i    i   t    s   
N(   t   __doc__t
   splitlinest   lent   appendt   extendt   popt   join(   t   thingWithDoct   textToAppendt   docstringLinest   spaces(    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR,     s    			
t   _InternalStatec           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   sñ   
    An L{_InternalState} is a helper object for a L{_ModuleProxy}, so that it
    can easily access its own attributes, bypassing its logic for delegating to
    another object that it's proxying for.

    @ivar proxy: a L{ModuleProxy}
    c         C   s   t  j |  d | ƒ d  S(   Nt   proxy(   t   objectt   __setattr__(   t   selfR<   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   __init__.  s    c         C   s   t  j t  j |  d ƒ | ƒ S(   NR<   (   R=   t   __getattribute__(   R?   R   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyRA   2  s    c         C   s   t  j t  j |  d ƒ | | ƒ S(   NR<   (   R=   R>   RA   (   R?   R   t   value(    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR>   7  s    (   R
   R   R0   R@   RA   R>   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR;   &  s   		t   _ModuleProxyc           B   s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   s¬  
    Python module wrapper to hook module-level attribute access.

    Access to deprecated attributes first checks
    L{_ModuleProxy._deprecatedAttributes}, if the attribute does not appear
    there then access falls through to L{_ModuleProxy._module}, the wrapped
    module object.

    @ivar _module: Module on which to hook attribute access.
    @type _module: C{module}

    @ivar _deprecatedAttributes: Mapping of attribute names to objects that
        retrieve the module attribute's original value.
    @type _deprecatedAttributes: C{dict} mapping C{str} to
        L{_DeprecatedAttribute}

    @ivar _lastWasPath: Heuristic guess as to whether warnings about this
        package should be ignored for the next call.  If the last attribute
        access of this module was a C{getattr} of C{__path__}, we will assume
        that it was the import system doing it and we won't emit a warning for
        the next access, even if it is to a deprecated attribute.  The CPython
        import system always tries to access C{__path__}, then the attribute
        itself, then the attribute itself again, in both successful and failed
        cases.
    @type _lastWasPath: C{bool}
    c         C   s+   t  |  ƒ } | | _ i  | _ t | _ d  S(   N(   R;   t   _modulet   _deprecatedAttributest   Falset   _lastWasPath(   R?   t   modulet   state(    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR@   X  s    		c         C   s&   t  |  ƒ } d t |  ƒ j | j f S(   s   
        Get a string containing the type of the module proxy and a
        representation of the wrapped module object.
        s   <%s module=%r>(   R;   t   typeR
   RD   (   R?   RI   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   __repr___  s    c         C   s,   t  |  ƒ } t | _ t | j | | ƒ d S(   s@   
        Set an attribute on the wrapped module object.
        N(   R;   RF   RG   t   setattrRD   (   R?   R   RB   RI   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR>   h  s    	c         C   s‚   t  |  ƒ } | j r d } n | j j | ƒ } | d k	 rK | j ƒ  } n t | j | ƒ } | d k ru t | _ n	 t | _ | S(   sG  
        Get an attribute from the module object, possibly emitting a warning.

        If the specified name has been deprecated, then a warning is issued.
        (Unless certain obscure conditions are met; see
        L{_ModuleProxy._lastWasPath} for more information about what might quash
        such a warning.)
        t   __path__N(	   R;   RG   R    RE   t   gett   getattrRD   t   TrueRF   (   R?   R   RI   t   deprecatedAttributeRB   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyRA   q  s    				(   R
   R   R0   R@   RK   R>   RA   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyRC   =  s
   					t   _DeprecatedAttributec           B   s    e  Z d  Z d „  Z d „  Z RS(   sQ  
    Wrapper for deprecated attributes.

    This is intended to be used by L{_ModuleProxy}. Calling
    L{_DeprecatedAttribute.get} will issue a warning and retrieve the
    underlying attribute's value.

    @type module: C{module}
    @ivar module: The original module instance containing this attribute

    @type fqpn: C{str}
    @ivar fqpn: Fully qualified Python name for the deprecated attribute

    @type version: L{twisted.python.versions.Version}
    @ivar version: Version that the attribute was deprecated in

    @type message: C{str}
    @ivar message: Deprecation message
    c         C   s<   | |  _  | |  _ | j d | |  _ | |  _ | |  _ d S(   s7   
        Initialise a deprecated name wrapper.
        R   N(   RH   R
   R   R   t   message(   R?   RH   R   R   RS   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR@   ¤  s
    			c         C   sO   t  |  j |  j ƒ } t |  j |  j t d |  j ƒ } t | t	 d d ƒ| S(   sU   
        Get the underlying attribute value and issue a deprecation warning.
        s   : R&   i   (
   RO   RH   R
   R$   R   R   R!   RS   R   R'   (   R?   t   resultRS   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyRN   ¯  s
    (   R
   R   R0   R@   RN   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyRR     s   	c         C   sG   t  j |  d ƒ } t | | | | ƒ } t  j |  d ƒ } | | | <d S(   s   
    Mark a module-level attribute as being deprecated.

    @type proxy: L{_ModuleProxy}
    @param proxy: The module proxy instance proxying the deprecated attributes

    @type name: C{str}
    @param name: Attribute name

    @type version: L{twisted.python.versions.Version}
    @param version: Version that the attribute was deprecated in

    @type message: C{str}
    @param message: Deprecation message
    RD   RE   N(   R=   RA   RR   (   R<   R   R   RS   RD   t   attrRE   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   _deprecateAttribute¿  s
    c         C   sO   t  j | } t | t ƒ s8 t | ƒ } | t  j | <n  t | | |  | ƒ d S(   sQ  
    Declare a module-level attribute as being deprecated.

    @type version: L{twisted.python.versions.Version}
    @param version: Version that the attribute was deprecated in

    @type message: C{str}
    @param message: Deprecation message

    @type moduleName: C{str}
    @param moduleName: Fully-qualified Python name of the module containing
        the deprecated attribute; if called from the same module as the
        attributes are being deprecated in, using the C{__name__} global can
        be helpful

    @type name: C{str}
    @param name: Attribute name to deprecate
    N(   t   syst   modulest
   isinstanceRC   RV   (   R   RS   R   R   RH   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyR   Ù  s
    c         C   s»   t  j |  j } t j | ƒ } t t |  j ƒ ƒ } | d d } |  j } t	 d t
 d | d | d | j d | j d i  ƒ d	 d ƒ } t  j d
  d k  rª | j d	 ƒ n  t | |  d S(   sß  
    Issue a warning string, identifying C{offender} as the responsible code.

    This function is used to deprecate some behavior of a function.  It differs
    from L{warnings.warn} in that it is not limited to deprecating the behavior
    of a function currently on the call stack.

    @param function: The function that is being deprecated.

    @param warningString: The string that should be emitted by this warning.
    @type warningString: C{str}

    @since: 11.0
    iÿÿÿÿi   t   categoryt   filenamet   linenoRH   t   registryt   __warningregistry__t   module_globalsi   i   N(   i   i   (   RW   RX   R   R   t
   getabsfilet   listR   t	   func_codet   func_globalst   dictR'   R
   t
   setdefaultR    t   version_infoR5   R   (   t   offenderR#   t   offenderModuleR[   t
   lineStartst
   lastLineNot   globalsR)   (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   warnAboutFunctionô  s    			(!   R0   t   __all__RW   R   t   warningsR   R   t   disR   t   twisted.python.versionsR   t   twisted.python.utilR	   R!   R   R   R
   R   R   R    R   R   R$   R   R    R,   R=   R;   RC   RR   RV   R   Rl   (    (    (    s<   /usr/lib/python2.7/dist-packages/twisted/python/deprecate.pyt   <module>-   s:   							%#+	S/		