U
    
W[h                     @   sH  d Z ddlmZmZ d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dlmZ dZdd Zde_de_de_dd Zd2ddZd3ddZd4ddZdd Zd5ddZd6ddZdd Zd d ZG d!d" d"e Z!G d#d$ d$e Z"G d%d& d&e Z#d'd( Z$d)d Z%d*d+ Z&d,d- Z'd.d/ Z(d0d1 Z)d	S )7am  
Deprecation framework for Twisted.

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

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

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

    @deprecated(Version("Twisted", 16, 0, 0))
    class BadClass(object):
        '''
        Docstring for BadClass.
        '''

The newly-decorated badAPI will issue a warning when called, and BadClass will
issue a warning when instantiated. Both will also have  a deprecation notice
appended to their docstring.

To deprecate properties you can use::

    from incremental import Version
    from twisted.python.deprecate import deprecatedProperty

    class OtherwiseUndeprecatedClass(object):

        @deprecatedProperty(Version('Twisted', 16, 0, 0))
        def badProperty(self):
            '''
            Docstring for badProperty.
            '''

        @badProperty.setter
        def badProperty(self, value):
            '''
            Setter sill also raise the deprecation warning.
            '''


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{incremental.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.
    )divisionabsolute_import
deprecateddeprecatedPropertygetDeprecationWarningStringgetWarningMethodsetWarningMethoddeprecatedModuleAttributeN)warnwarn_explicit)findlinestartswraps)getVersionString)_PY3z&%(fqpn)s was deprecated in %(version)sc                 C   s   z
| j }W n tk
r$   | j}Y nX t| s:t| rL| j}d||f S t| rz
| j}W n$ tk
r   d| j| j f  Y S X t	|}d||f S |S )z
    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}.
    z%s.%s)
__qualname__AttributeError__name__inspectZisclassZ
isfunction
__module__ZismethodZim_class_fullyQualifiedName)objname
moduleNamecls	className r   :/usr/lib/python3/dist-packages/twisted/python/deprecate.pyr   c   s    


r   ztwisted.python.reflectZfullyQualifiedNamec                 C   s   t | rt| } d| f S )a
  
    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".
    zplease use %s instead)callabler   )replacementr   r   r   _getReplacementString   s    
r    c                 C   s*   dt | f }|r"d|t|f }|d S )a  
    Generate an addition to a deprecated object's docstring that explains its
    deprecation.

    @param version: the version it was deprecated.
    @type version: L{incremental.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."
    zDeprecated in %s%s; %s.)r   r    )versionr   docr   r   r   _getDeprecationDocstring   s    r%   c                 C   s6   |dkrt }|| t|d }|r2d|t|f }|S )ag  
    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{incremental.Version}

    @param format: A user-provided format to interpolate warning values into, or
        L{DEPRECATION_WARNING_FORMAT
        <twisted.python.deprecate.DEPRECATION_WARNING_FORMAT>} if L{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}
    N)fqpnr#   r!   )DEPRECATION_WARNING_FORMATr   r    )r&   r#   formatr   warningStringr   r   r   _getDeprecationWarningString   s     r*   c                 C   s   t t| |||S )a  
    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{incremental.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 L{None} is
        given

    @param callableThing: A callable to be deprecated.

    @param version: The L{incremental.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   )ZcallableThingr#   r(   r   r   r   r   r      s       c                 C   sx   | j r| j  }ng }t|dkr.|| n:t|dkrL|d|dg n| }|d|| |g d|| _ dS )av  
    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.
    r       
N)__doc__
splitlineslenappendextendpopjoin)ZthingWithDocZtextToAppendZdocstringLinesZspacesr   r   r   _appendToDocstring   s    	r5   c                    s    fdd}|S )a  
    Return a decorator that marks callables as deprecated. To deprecate a
    property, see L{deprecatedProperty}.

    @type version: L{incremental.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{incremental.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                    s>   t  dt  fdd}t|t |_|S )zA
        Decorator that marks C{function} as deprecated.
        Nc                     s   t tdd  | |S N   
stacklevelr
   DeprecationWarningargskwargsfunctionr)   r   r   deprecatedFunction'  s    zDdeprecated.<locals>.deprecationDecorator.<locals>.deprecatedFunction)r   r   r5   r%   deprecatedVersion)r@   rA   r   r#   r?   r   deprecationDecorator   s       z(deprecated.<locals>.deprecationDecoratorr   r#   r   rD   r   rC   r   r     s    c                    s$   G dd dt   fdd}|S )a  
    Return a decorator that marks a property as deprecated. To deprecate a
    regular callable or class, see L{deprecated}.

    @type version: L{incremental.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{incremental.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

    @return: A new property with deprecated setter and getter.
    @rtype: C{property}

    @since: 16.1.0
    c                   @   s    e Zd ZdZdd Zdd ZdS )z/deprecatedProperty.<locals>._DeprecatedPropertyzQ
        Extension of the build-in property to allow deprecated setters.
        c                    s   t   fdd}|S )Nc                     s   t jtdd  | |S r6   )r
   r)   r;   r<   r@   selfr   r   rA   X  s    z^deprecatedProperty.<locals>._DeprecatedProperty._deprecatedWrapper.<locals>.deprecatedFunctionr   )rG   r@   rA   r   rF   r   _deprecatedWrapperW  s    zBdeprecatedProperty.<locals>._DeprecatedProperty._deprecatedWrapperc                 S   s   t | | |S )N)propertysetterrH   )rG   r@   r   r   r   rJ   b  s    z6deprecatedProperty.<locals>._DeprecatedProperty.setterN)r   r   r   r.   rH   rJ   r   r   r   r   _DeprecatedPropertyR  s   rK   c                    s   t rt d n8 j}t d d } j}d|||f }t|d t  fdd}t|t	 |_
|}|_|S )Nr+      z%s.%s.%sc                     s   t tdd  | |S r6   r:   r<   r?   r   r   rA   w  s    zLdeprecatedProperty.<locals>.deprecationDecorator.<locals>.deprecatedFunction)r   r   r   r   stackr   r*   r   r5   r%   rB   r)   )r@   ZfunctionNamer   r   ZfqdnrA   resultrK   r   r#   r?   r   rD   f  s4          z0deprecatedProperty.<locals>.deprecationDecorator)rI   rE   r   rO   r   r   8  s    !c                   C   s   t S )zR
    Return the warning method currently used to record deprecation warnings.
    r
   r   r   r   r   r     s    c                 C   s   | a dS )z
    Set the warning method to use to record deprecation warnings.

    The callable should take message, category and stacklevel. The return
    value is ignored.
    NrP   )Z	newMethodr   r   r   r     s    c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	_InternalStatez
    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 | d| d S Nproxy)object__setattr__)rG   rS   r   r   r   __init__  s    z_InternalState.__init__c                 C   s   t t | d|S rR   )rT   __getattribute__)rG   r   r   r   r   rW     s    z_InternalState.__getattribute__c                 C   s   t t | d||S rR   )rT   rU   rW   )rG   r   valuer   r   r   rU     s     z_InternalState.__setattr__N)r   r   r   r.   rV   rW   rU   r   r   r   r   rQ     s   rQ   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )_ModuleProxya  
    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 |_d|_d S )NF)rQ   _module_deprecatedAttributes_lastWasPath)rG   modulestater   r   r   rV     s    z_ModuleProxy.__init__c                 C   s   t | }dt| j|jf S )z
        Get a string containing the type of the module proxy and a
        representation of the wrapped module object.
        z<%s module=%r>)rQ   typer   rZ   )rG   r^   r   r   r   __repr__  s    z_ModuleProxy.__repr__c                 C   s    t | }d|_t|j|| dS )z@
        Set an attribute on the wrapped module object.
        FN)rQ   r\   setattrrZ   )rG   r   rX   r^   r   r   r   rU     s    z_ModuleProxy.__setattr__c                 C   sX   t | }|jrd}n|j|}|dk	r2| }nt|j|}|dkrNd|_nd|_|S )aG  
        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.)
        N__path__TF)rQ   r\   r[   getgetattrrZ   )rG   r   r^   ZdeprecatedAttributerX   r   r   r   rW     s    	
z_ModuleProxy.__getattribute__N)r   r   r   r.   rV   r`   rU   rW   r   r   r   r   rY     s
   		rY   c                   @   s    e Zd ZdZdd Zdd ZdS )_DeprecatedAttributeaE  
    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{incremental.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 )z7
        Initialise a deprecated name wrapper.
        r"   N)r]   r   r&   r#   message)rG   r]   r   r#   rf   r   r   r   rV     s
    z_DeprecatedAttribute.__init__c                 C   s:   t | j| j}t| j| jtd | j }t|t	dd |S )zU
        Get the underlying attribute value and issue a deprecation warning.
        z: rL   r8   )
rd   r]   r   r*   r&   r#   r'   rf   r
   r;   )rG   rN   rf   r   r   r   rc   (  s    
z_DeprecatedAttribute.getN)r   r   r   r.   rV   rc   r   r   r   r   re   	  s   re   c                 C   s2   t | d}t||||}t | d}|||< dS )a  
    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{incremental.Version}
    @param version: Version that the attribute was deprecated in

    @type message: C{str}
    @param message: Deprecation message
    rZ   r[   N)rT   rW   re   )rS   r   r#   rf   rZ   attrr[   r   r   r   _deprecateAttribute8  s     rh   c                 C   s8   t j| }t|ts&t|}|t j|< t||| | dS )aE  
    Declare a module-level attribute as being deprecated.

    @type version: L{incremental.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)sysmodules
isinstancerY   rh   )r#   rf   r   r   r]   r   r   r   r	   R  s
    


c              	   C   sd   t j| j }t|}tt| j}|d d }| j}t	t
|||j|di dd}t|f| dS )a  
    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
    r+   Z__warningregistry__N)categoryfilenamelinenor]   registrymodule_globals)ri   rj   r   r   Z
getabsfilelistr   __code____globals__dictr;   r   
setdefaultr   )Zoffenderr)   ZoffenderModulern   Z
lineStartsZ
lastLineNoglobalsr>   r   r   r   warnAboutFunctionm  s    

rx   c                 C   s   i }t | jt | }| jdk	r.i  }|| j< |dk rb| jdkrJtdn|t | jd || j< t| j|D ]\}}|||< qn| D ]H\}}|| jkr||krtd|||< q| jdk	r|||< qtdq|S )a  
    Take an I{inspect.ArgSpec}, a tuple of positional arguments, and a dict of
    keyword arguments, and return a mapping of arguments that were actually
    passed to their passed values.

    @param argspec: The argument specification for the function to inspect.
    @type argspec: I{inspect.ArgSpec}

    @param positional: The positional arguments that were passed.
    @type positional: L{tuple}

    @param keyword: The keyword arguments that were passed.
    @type keyword: L{dict}

    @return: A dictionary mapping argument names (those declared in C{argspec})
        to values that were passed explicitly by the user.
    @rtype: L{dict} mapping L{str} to L{object}
    Nr   Too many arguments.Already passed.no such param)r0   r=   keywordsZvarargs	TypeErrorzipitems)Zargspec
positionalkeywordrN   Zunpassedr>   r   rX   r   r   r   _passedArgSpec  s&    








r   c           
      C   st  i }d}d}t | j D ]\}\}}|jtjjkrV||d ||< t|| d }q|jtjjkrri  }||< q|jtjj	tjj
fkr|t|k r|| ||< |d7 }q|jtjjkr||kr|jtjjkrtd|q|j||< qtd||jqt||krtd| D ]R\}}	|| j krP||krFtd|	||< n|dk	rd|	||< ntdq|S )	a  
    Take an L{inspect.Signature}, a tuple of positional arguments, and a dict of
    keyword arguments, and return a mapping of arguments that were actually
    passed to their passed values.

    @param signature: The signature of the function to inspect.
    @type signature: L{inspect.Signature}

    @param positional: The positional arguments that were passed.
    @type positional: L{tuple}

    @param keyword: The keyword arguments that were passed.
    @type keyword: L{dict}

    @return: A dictionary mapping argument names (those declared in
        C{signature}) to values that were passed explicitly by the user.
    @rtype: L{dict} mapping L{str} to L{object}
    Nr   r+   zmissing keyword arg {}z"'{}' parameter is invalid kind: {}ry   rz   r{   )	enumerateZ
parametersr   Zkindr   Z	ParameterZVAR_POSITIONALr0   ZVAR_KEYWORDZPOSITIONAL_OR_KEYWORDZPOSITIONAL_ONLYZKEYWORD_ONLYdefaultemptyr}   r(   keys)
	signaturer   r   rN   r>   ZnumPositionalnr   ZparamrX   r   r   r   _passedSignature  sF    

 



r   c                    s    fdd}|S )a  
    Decorator which causes its decoratee to raise a L{TypeError} if two of the
    given arguments are passed at the same time.

    @param argumentPairs: pairs of argument identifiers, each pair indicating
        an argument that may not be passed in conjunction with another.
    @type argumentPairs: sequence of 2-sequences of L{str}

    @return: A decorator, used like so::

            @_mutuallyExclusiveArguments([["tweedledum", "tweedledee"]])
            def function(tweedledum=1, tweedledee=2):
                "Don't pass tweedledum and tweedledee at the same time."

    @rtype: 1-argument callable taking a callable and returning a callable.
    c                    sH   t tdd rtt ntt t fdd}|S )Nr   c                     s<    | |}D ] \}}||kr||krt dq| |S )NZnope)r}   )r=   r>   Z	argumentsthisthat)_passedargumentPairsspecwrappeer   r   wrapped  s
    
z=_mutuallyExclusiveArguments.<locals>.wrapper.<locals>.wrapped)rd   r   r   r   Z
getargspecr   r   )r   r   r   )r   r   r   r   wrapper  s    

z,_mutuallyExclusiveArguments.<locals>.wrapperr   )r   r   r   r   r   _mutuallyExclusiveArguments  s    r   )N)NN)NN)N)N)*r.   Z
__future__r   r   __all__ri   r   warningsr
   r   disr   	functoolsr   Zincrementalr   Ztwisted.python.compatr   r'   r   r   r   r   r    r%   r*   r   r5   r   r   r   r   rT   rQ   rY   re   rh   r	   rx   r   r   r   r   r   r   r   <module>   sN   E


%  
$
+
SS/#+<