U
    ª€ljé£  ã                   @   sö  d Z ddlZddlZddlZddlZddlmZ ddlmZmZ zddl	m
Z
 W n ek
rh   dZ
Y nX ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZ dd	lmZ dd
l m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z' G dd„ dƒZ(G dd„ de'ƒZ)G dd„ de'ƒZ*G dd„ de%e'ƒZ+G dd„ de'ƒZ,dd„ Z-dd„ Z.G dd„ de'ƒZ/eeddd d!ƒƒG d"d#„ d#ƒƒZ0G d$d%„ d%ƒZ1eedd&d dƒd'ƒd2d(d)„ƒZ2G d*d+„ d+e'ƒZ3G d,d-„ d-e'ƒZ4G d.d/„ d/e'ƒZ5G d0d1„ d1e'ƒZ6dS )3zI
Tests for Twisted's deprecation framework, L{twisted.python.deprecate}.
é    N)Únormcase)Úcatch_warningsÚsimplefilter)Úinvalidate_caches)ÚVersion)Ú	deprecate)ÚDEPRECATION_WARNING_FORMATÚ_appendToDocstringÚ_fullyQualifiedNameÚ_getDeprecationDocstringÚ_getDeprecationWarningStringÚ_mutuallyExclusiveArgumentsÚ_passedArgSpecÚ_passedSignatureÚ
deprecatedÚdeprecatedKeywordParameterÚdeprecatedPropertyÚgetDeprecationWarningString)ÚFilePath)Úplatform)Údeprecatedattributes)ÚTwistedModulesMixin)ÚSynchronousTestCasec                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú_MockDeprecatedAttributezq
    Mock of L{twisted.python.deprecate._DeprecatedAttribute}.

    @ivar value: The value of the attribute.
    c                 C   s
   || _ d S ©N©Úvalue©Úselfr   © r   úF/tmp/pip-unpacked-wheel-aghyhbke/twisted/python/test/test_deprecate.pyÚ__init__8   s    z!_MockDeprecatedAttribute.__init__c                 C   s   | j S )z$
        Get a known value.
        r   ©r   r   r   r    Úget;   s    z_MockDeprecatedAttribute.getN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r!   r#   r   r   r   r    r   1   s   r   c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚModuleProxyTestszÔ
    Tests for L{twisted.python.deprecate._ModuleProxy}, which proxies
    access to module-level attributes, intercepting access to deprecated
    attributes and passing through access to normal attributes.
    c                 K   s2   t  d¡}| ¡ D ]\}}t|||ƒ qt |¡S )zÀ
        Create a temporary module proxy object.

        @param **kw: Attributes to initialise on the temporary module object

        @rtype: L{twistd.python.deprecate._ModuleProxy}
        Úfoo)ÚtypesÚ
ModuleTypeÚitemsÚsetattrr   Z_ModuleProxy)r   ÚattrsÚmodÚkeyr   r   r   r    Ú
_makeProxyI   s    
zModuleProxyTests._makeProxyc                 C   s.   | j dd�}|  |jd¡ |  tt|d¡ dS )zÜ
        Getting a normal attribute on a L{twisted.python.deprecate._ModuleProxy}
        retrieves the underlying attribute's value, and raises C{AttributeError}
        if a non-existent attribute is accessed.
        Zhello)ÚSOME_ATTRIBUTEZDOES_NOT_EXISTN)r1   ÚassertIsr2   ÚassertRaisesÚAttributeErrorÚgetattr©r   Úproxyr   r   r    Útest_getattrPassthroughV   s    z(ModuleProxyTests.test_getattrPassthroughc                 C   s2   |   ¡ }t |d¡}tdƒ|d< |  |jd¡ dS )z¸
        Getting an attribute marked as being deprecated on
        L{twisted.python.deprecate._ModuleProxy} results in calling the
        deprecated wrapper's C{get} method.
        Ú_deprecatedAttributesé*   r)   N)r1   ÚobjectÚ__getattribute__r   ÚassertEqualr)   )r   r8   r:   r   r   r    Útest_getattrIntercept`   s    z&ModuleProxyTests.test_getattrInterceptc                 C   s,   |   ¡ }|  tt|d¡ |  tt|d¡ dS )z�
        Private attributes of L{twisted.python.deprecate._ModuleProxy} are
        inaccessible when regular attribute access is used.
        Ú_moduler:   N)r1   r4   r5   r6   r7   r   r   r    Útest_privateAttributesk   s    z'ModuleProxyTests.test_privateAttributesc                 C   s4   |   ¡ }d|_|  t |d¡d¡ |  |jd¡ dS )z„
        Setting attributes on L{twisted.python.deprecate._ModuleProxy} proxies
        them through to the wrapped module.
        é   r@   N)r1   r@   ÚassertNotEqualr<   r=   r>   r7   r   r   r    Útest_setattrt   s    zModuleProxyTests.test_setattrc                 C   s<   |   ¡ }t |d¡}|  t|ƒdt|ƒj› d|›d�¡ dS )z³
        L{twisted.python.deprecated._ModuleProxy.__repr__} produces a string
        containing the proxy type and a representation of the wrapped module
        object.
        r@   ú<z module=ú>N)r1   r<   r=   r>   ÚreprÚtyper$   )r   r8   Z
realModuler   r   r    Ú	test_repr~   s    zModuleProxyTests.test_reprN)
r$   r%   r&   r'   r1   r9   r?   rA   rD   rI   r   r   r   r    r(   B   s   
	
r(   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚDeprecatedAttributeTestszÄ
    Tests for L{twisted.python.deprecate._DeprecatedAttribute} and
    L{twisted.python.deprecate.deprecatedModuleAttribute}, which issue
    warnings for deprecated module-level attributes.
    c                 C   s   t j| _t j| _td | _d S )Nz.foo)r   ÚversionÚmessager$   Ú_testModuleNamer"   r   r   r    ÚsetUp�   s    zDeprecatedAttributeTests.setUpc                 C   s"   t tjd | tjtd tj ƒS )zJ
        Create the warning string used by deprecated attributes.
        Ú.z: )r   r   r$   rK   r   rL   )r   Úattrr   r   r    Ú_getWarningString•   s
    ýz*DeprecatedAttributeTests._getWarningStringc                    s”   d}t t|dƒ t t|| j| j¡‰ |  ˆ j|¡ ‡ fdd„}|ƒ  |  | j	g¡}|  
|d d t¡ |  |d d |  |¡¡ |  t|ƒd¡ d	S )
zÛ
        L{twisted.python.deprecate._DeprecatedAttribute} correctly sets its
        __name__ to match that of the deprecated attribute and emits a warning
        when the original attribute value is accessed.
        ZANOTHER_DEPRECATED_ATTRIBUTEr;   c                      s   ˆ   ¡  d S r   )r#   r   ©rP   r   r    ÚaddStackLevel¯   s    zNDeprecatedAttributeTests.test_deprecatedAttributeHelper.<locals>.addStackLevelr   ÚcategoryrL   rB   N)r-   r   r   Z_DeprecatedAttributerK   rL   r>   r$   ÚflushWarningsÚtest_deprecatedAttributeHelperr3   ÚDeprecationWarningrQ   Úlen)r   ÚnamerS   ÚwarningsShownr   rR   r    rV   Ÿ   s       ÿz7DeprecatedAttributeTests.test_deprecatedAttributeHelperc                 C   s‚   t j |  | jg¡}|  t|ƒd¡ d}tt |ƒ |  | jg¡}|  t|ƒd¡ |  |d d t¡ |  |d d |  	|¡¡ dS )a  
        L{twisted.python.deprecate.deprecatedModuleAttribute} wraps a
        module-level attribute in an object that emits a deprecation warning
        when it is accessed the first time only, while leaving other unrelated
        attributes alone.
        r   ZDEPRECATED_ATTRIBUTErB   rT   rL   N)
r   ZANOTHER_ATTRIBUTErU   Útest_deprecatedAttributer>   rX   r6   r3   rW   rQ   )r   rZ   rY   r   r   r    r[   ¹   s    
z1DeprecatedAttributeTests.test_deprecatedAttributec                 C   s¨   t  d¡ tj| j< }|  tjj| j¡ t|ddƒ t|ddƒ t 	t
ddddƒd	| jd¡ tj| j }|  ||¡ t 	t
ddddƒd	| jd¡ |  |tj| j ¡ d
S )zï
        Deprecating an attribute in a module replaces and wraps that module
        instance, in C{sys.modules}, with a
        L{twisted.python.deprecate._ModuleProxy} instance but only if it hasn't
        already been wrapped.
        r)   ÚfirstrB   Úsecondé   ÚTwistedé   r   rL   N)r*   r+   ÚsysÚmodulesrM   Ú
addCleanupÚpopr-   r   ZdeprecatedModuleAttributer   rC   r3   )r   r/   r8   r   r   r    Útest_wrappedModuleÐ   s&       ÿ   ÿz+DeprecatedAttributeTests.test_wrappedModuleN)	r$   r%   r&   r'   rN   rQ   rV   r[   re   r   r   r   r    rJ   ‰   s   
rJ   c                   @   s<   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Z	dS )ÚImportedModuleAttributeTestsza
    Tests for L{deprecatedModuleAttribute} which involve loading a module via
    'import'.
    z»from twisted.python.deprecate import deprecatedModuleAttribute
from incremental import Version

deprecatedModuleAttribute(
    Version('Package', 1, 2, 3), 'message', __name__, 'module')
c                    s^   ‡ fdd„‰ t |  ¡  d¡ƒ}| ¡  ˆ ||ƒ}|  |j d¡gtj ¡ |  tj	 
¡ ¡ |S )a_  
        Create some files in a hierarchy, based on a dictionary describing those
        files.  The resulting hierarchy will be placed onto sys.path for the
        duration of the test.

        @param tree: A dictionary representing a directory structure.  Keys are
            strings, representing filenames, dictionary values represent
            directories, string values represent file contents.

        @return: another dictionary similar to the input, with file content
            strings replaced with L{FilePath} objects pointing at where those
            contents are now stored.
        c                    sl   i }|  ¡ D ]Z\}}|  |¡}t|tƒr<|||< | |¡ qt|tƒr^| ¡  ˆ ||ƒ||< qtdƒ‚q|S )Nz(only strings and dicts allowed as values)r,   ÚchildÚ
isinstanceÚbytesÚ
setContentÚdictZcreateDirectoryÚ
ValueError)ÚpathobjZdirdictZpathdictr0   r   rg   ©ÚmakeSomeFilesr   r    ro     s    



zAImportedModuleAttributeTests.pathEntryTree.<locals>.makeSomeFilesúutf-8)r   ÚmktempÚencodeÚmakedirsZreplaceSysPathÚpathÚdecodera   ZreplaceSysModulesrb   Úcopy)r   ÚtreeÚbaseÚresultr   rn   r    ÚpathEntryTreeù   s    
z*ImportedModuleAttributeTests.pathEntryTreec                 C   s(   |   d| j d¡ddœi¡}|d d S )z¢
        Add a sample module and package to the path, returning a L{FilePath}
        pointing at the module which will be loadable as C{package.module}.
        s   packagerp   ó    )s   __init__.pyó	   module.pyr|   )rz   Ú_packageInitrr   )r   Úpathsr   r   r    ÚsimpleModuleEntry  s    
þÿÿz.ImportedModuleAttributeTests.simpleModuleEntryc                 C   sn   ddl m} |  t|j d¡ƒ|¡ |  | jg¡}|  t|ƒd¡ |  |d d d¡ |  |d d t	¡ dS )	zB
        Verification logic for L{test_deprecatedModule}.
        r   ©Úmodulerp   rB   rL   z7package.module was deprecated in Package 1.2.3: messagerT   N)
Úpackager�   r>   r   Ú__file__rr   rU   ÚcheckOneWarningrX   rW   )r   Z
modulePathr�   Zemittedr   r   r    r„   .  s    
þz,ImportedModuleAttributeTests.checkOneWarningc                 C   s   |   |  ¡ ¡ dS )zÇ
        If L{deprecatedModuleAttribute} is used to deprecate a module attribute
        of a package, only one deprecation warning is emitted when the
        deprecated module is imported.
        N)r„   r   r"   r   r   r    Útest_deprecatedModule=  s    z2ImportedModuleAttributeTests.test_deprecatedModulec                 C   s8   |   ¡ }|  |¡ |  |¡ tdƒD ]}|  |¡ q$dS )zÔ
        If L{deprecatedModuleAttribute} is used to deprecate a module attribute
        of a package, only one deprecation warning is emitted when the
        deprecated module is subsequently imported.
        r^   N)r   r„   Úrange)r   ÚmpÚxr   r   r    Ú"test_deprecatedModuleMultipleTimesE  s
    

z?ImportedModuleAttributeTests.test_deprecatedModuleMultipleTimesN)
r$   r%   r&   r'   r}   rz   r   r„   r…   r‰   r   r   r   r    rf   ë   s   &rf   c                   @   sP   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚWarnAboutFunctionTestsz¢
    Tests for L{twisted.python.deprecate.warnAboutFunction} which allows the
    callers of a function to issue a C{DeprecationWarning} about that function.
    c                    s®   t |  ¡ ƒ d¡| _| j ¡  | j d¡ d¡ | j d¡ d¡ | j d¡ d¡ | j ¡ j}tj 	d|¡ |  
tjj|¡ tj ¡ ‰ |  
‡ fd	d
„¡ t ¡ rª|  ¡  dS )zY
        Create a file that will have known line numbers when emitting warnings.
        Útwisted_private_helperz__init__.pyr{   z	module.pys  
"A module string"

from twisted.python import deprecate

def testFunction():
    "A doc string"
    a = 1 + 2
    return a

def callTestFunction():
    b = testFunction()
    if b == 3:
        deprecate.warnAboutFunction(testFunction, "A Warning String")
z	pep626.pysQ  
"A module string"

from twisted.python import deprecate

def noop():
    pass

def testFunction(a=1, b=1):
    "A doc string"
    if a:
        if b:
            noop()
        else:
            pass

def callTestFunction():
    b = testFunction()
    if b is None:
        deprecate.warnAboutFunction(testFunction, "A Warning String")
r   c                      s   t j ¡ t j ˆ ¡fS r   )ra   rb   ÚclearÚupdater   ©rb   r   r    Ú<lambda>•  r{   z.WarnAboutFunctionTests.setUp.<locals>.<lambda>N)r   rq   rg   r‚   rs   rj   Úparentrt   ra   Úinsertrc   Úremoverb   rv   r   Z	isWindowsrU   )r   ZpackagePathr   rŽ   r    rN   `  s     
ÿÿ
zWarnAboutFunctionTests.setUpc                 C   sn   dd„ }t  |d¡ |  ¡ }t}| ¡  d¡r:|dd… }|  t|d d ƒt|ƒ¡ |  |d d	 d¡ dS )
z½
        L{deprecate.warnAboutFunction} emits a warning the file and line number
        of which point to the beginning of the implementation of the function
        passed to it.
        c                   S   s   d S r   r   r   r   r   r    ÚaFunc¤  s    z2WarnAboutFunctionTests.test_warning.<locals>.aFunczA Warning Messagez.pycNéÿÿÿÿr   ÚfilenamerL   )	r   ZwarnAboutFunctionrU   rƒ   ÚlowerÚendswithÚassertSamePathr   r>   )r   r“   rZ   r•   r   r   r    Útest_warning�  s    z#WarnAboutFunctionTests.test_warningc                 C   s„   ddl m} | ¡  |  ¡ }|  t|d d  d¡ƒ| j d¡ 	d¡¡ |  
|d d d¡ |  
|d d	 d
¡ |  
t|ƒd¡ dS )z¨
        L{deprecate.warnAboutFunction} emits a C{DeprecationWarning} with the
        number of a line within the implementation of the function passed to it.
        r   r€   r•   rp   ó   twisted_private_helperr|   Úlinenoé	   rL   úA Warning StringrB   N)r‹   r�   ÚcallTestFunctionrU   r˜   r   rr   r‚   Úsiblingrg   r>   rX   ©r   r�   rZ   r   r   r    Útest_warningLineNumber¯  s    þz-WarnAboutFunctionTests.test_warningLineNumberc                 C   s„   ddl m} | ¡  |  ¡ }|  t|d d  d¡ƒ| j d¡ 	d¡¡ |  
|d d d¡ |  
|d d	 d
¡ |  
t|ƒd¡ dS )zã
        L{deprecate.warnAboutFunction} emits a C{DeprecationWarning} with the
        number of a line within the implementation handling the case in which
        dis.findlinestarts returns the lines in random order.
        r   )Úpep626r•   rp   rš   s	   pep626.pyr›   é   rL   r�   rB   N)r‹   r¢   rž   rU   r˜   r   rr   r‚   rŸ   rg   r>   rX   )r   r¢   rZ   r   r   r    Ú'test_warningLineNumberDisFindlinestartsÂ  s    þz>WarnAboutFunctionTests.test_warningLineNumberDisFindlinestartsc                 C   s*   |   t|jƒt|jƒk|›d|›�¡ dS )a  
        Assert that the two paths are the same, considering case normalization
        appropriate for the current platform.

        @type first: L{FilePath}
        @type second: L{FilePath}

        @raise C{self.failureType}: If the paths are not the same.
        z != N)Ú
assertTruer   rt   )r   r\   r]   r   r   r    r˜   Ö  s    
þz%WarnAboutFunctionTests.assertSamePathc                 C   sð   ddl m} tjd= tj|j= | j | j d¡¡ tr<tƒ  ddl	m} |  
tjjd¡ |  
tjj|j¡ | ¡  |  |jg¡}t|d d  d¡ƒ}| j d¡ d¡}|  ||¡ |  |d d	 d
¡ |  |d d d¡ |  t|ƒd¡ dS )a  
        Even if the implementation of a deprecated function is moved around on
        the filesystem, the line number in the warning emitted by
        L{deprecate.warnAboutFunction} points to a line in the implementation of
        the deprecated function.
        r   r€   r‹   s   twisted_renamed_helperÚtwisted_renamed_helperr•   rp   r|   r›   rœ   rL   r�   rB   N)r‹   r�   ra   rb   r$   r‚   ZmoveTorŸ   r   r¦   rc   rd   rž   rU   ZtestFunctionr   rr   rg   r˜   r>   rX   )r   r�   rZ   Z
warnedPathZexpectedPathr   r   r    Útest_renamedFileå  s&    
ÿz'WarnAboutFunctionTests.test_renamedFilec                 C   sJ   t jdd…= t jddd� ddlm} | ¡  |  ¡ }|  t|ƒd¡ dS )z¾
        L{deprecate.warnAboutFunction} emits a warning that will be filtered if
        L{warnings.filterwarning} is called with the module name of the
        deprecated function.
        NÚignorer‹   ©Úactionr�   r   r€   )	ÚwarningsÚfiltersÚfilterwarningsr‹   r�   rž   rU   r>   rX   r    r   r   r    Útest_filteredWarning  s    	z+WarnAboutFunctionTests.test_filteredWarningc                 C   sª   t jdd…= t jddd� ddlm} | ¡  | ¡  |  ¡ }|  t|ƒd¡ |d d }|d d	 }|d d
 }|d d }t  	||||¡}|  
| d¡d|›�¡ dS )zÙ
        L{deprecate.warnAboutFunction} emits a warning that will be filtered
        once if L{warnings.filterwarning} is called with the module name of the
        deprecated function and an action of once.
        Nr�   r‹   r©   r   r€   rB   rL   rT   r•   r›   z=module.py:9: DeprecationWarning: A Warning String
  return a
zUnexpected warning string: )r«   r¬   r­   r‹   r�   rž   rU   r>   rX   Úformatwarningr¥   r—   )r   r�   rZ   rL   rT   r•   r›   Úmsgr   r   r    Útest_filteredOnceWarning  s$    	ÿüz/WarnAboutFunctionTests.test_filteredOnceWarningN)r$   r%   r&   r'   rN   r™   r¡   r¤   r˜   r§   r®   r±   r   r   r   r    rŠ   Z  s   =&rŠ   c                   C   s   dS )zK
    Do nothing.

    This is used to test the deprecation decorators.
    Nr   r   r   r   r    ÚdummyCallable@  s    r²   c                   C   s   dS )z[
    Do nothing.

    This is used to test the replacement parameter to L{deprecated}.
    Nr   r   r   r   r    ÚdummyReplacementMethodH  s    r³   c                   @   sT   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚDeprecationWarningsTestsc                 C   s,   t ddddƒ}|  t| j|ƒdtf ¡ dS )z 
        L{getDeprecationWarningString} returns a string that tells us that a
        callable was deprecated at a certain released version of Twisted.
        r_   r`   r   z\%s.DeprecationWarningsTests.test_getDeprecationWarningString was deprecated in Twisted 8.0.0N)r   r>   r   Ú test_getDeprecationWarningStringr$   ©r   rK   r   r   r    rµ   Q  s    
ÿþz9DeprecationWarningsTests.test_getDeprecationWarningStringc                 C   s6   t ddddƒ}td }|  t| j||ƒdtf ¡ dS )zð
        L{getDeprecationWarningString} returns a string that tells us that a
        callable was deprecated at a certain released version of Twisted, with
        a message containing additional information about the deprecation.
        r_   r`   r   z: This is a messagezo%s.DeprecationWarningsTests.test_getDeprecationWarningString was deprecated in Twisted 8.0.0: This is a messageN)r   r   r>   r   rµ   r$   )r   rK   Úformatr   r   r    Ú*test_getDeprecationWarningStringWithFormat]  s      ÿÿüzCDeprecationWarningsTests.test_getDeprecationWarningStringWithFormatc              	      sš   t ddddƒ}t|ƒtƒ‰ ‡ fdd„}tdd��`}tdƒ |ƒ  |  |d jt¡ |  t|d j	ƒt
t|ƒ¡ |  |d j d	¡t d	¡¡ W 5 Q R X d
S )zK
        Decorating a callable with L{deprecated} emits a warning.
        r_   r`   r   c                      s
   ˆ ƒ  d S r   r   r   ©Údummyr   r    rS   t  s    zJDeprecationWarningsTests.test_deprecateEmitsWarning.<locals>.addStackLevelT©ÚrecordÚalwaysÚcoN)r   r   r²   r   r   r>   rT   rW   ÚstrrL   r   r•   Úrstriprƒ   )r   rK   rS   Zcaughtr   r¹   r    Útest_deprecateEmitsWarningm  s    þz3DeprecationWarningsTests.test_deprecateEmitsWarningc                 C   sB   t ddddƒ}t|ƒtƒ}|  tj|j¡ |  ttƒt|ƒ¡ dS )zK
        The decorated function has the same name as the original.
        r_   r`   r   N)r   r   r²   r>   r$   ÚfullyQualifiedName©r   rK   rº   r   r   r    Útest_deprecatedPreservesName‚  s    z5DeprecationWarningsTests.test_deprecatedPreservesNamec                 C   s$   t ddddƒ}|  dt|dƒ¡ dS )zr
        L{_getDeprecationDocstring} returns a note about the deprecation to go
        into a docstring.
        r_   r`   r   zDeprecated in Twisted 8.0.0.Ú N)r   r>   r   r¶   r   r   r    Útest_getDeprecationDocstring‹  s
     ÿz5DeprecationWarningsTests.test_getDeprecationDocstringc                 C   sF   dd„ }t ddddƒ}t|ƒ|ƒ}t|t|dƒƒ |  |j|j¡ dS )zv
        The docstring of the deprecated function is appended with information
        about the deprecation.
        c                   S   s   dS )zc
            Do nothing.

            This is used to test the deprecation decorators.
            Nr   r   r   r   r    ÚlocalDummyCallable›  s    zTDeprecationWarningsTests.test_deprecatedUpdatesDocstring.<locals>.localDummyCallabler_   r`   r   rÅ   N)r   r   r	   r   r>   r'   )r   rÇ   rK   rº   r   r   r    Útest_deprecatedUpdatesDocstring•  s
    z8DeprecationWarningsTests.test_deprecatedUpdatesDocstringc                 C   s,   t ddddƒ}t|ƒtƒ}|  ||j¡ dS )zt
        Deprecating a function adds version information to the decorated
        version of that function.
        r_   r`   r   N)r   r   r²   r>   ÚdeprecatedVersionrÃ   r   r   r    Útest_versionMetadata©  s    z-DeprecationWarningsTests.test_versionMetadatac                 C   s:   t ddddƒ}t| j|dd�}|  |dt| jƒf ¡ dS )a  
        L{getDeprecationWarningString} takes an additional replacement parameter
        that can be used to add information to the deprecation.  If the
        replacement parameter is a string, it will be interpolated directly into
        the result.
        r_   r`   r   úsomething.foobar©ÚreplacementzG%s was deprecated in Twisted 8.0.0; please use something.foobar insteadN)r   r   rµ   r>   rÂ   ©r   rK   ZwarningStringr   r   r    Ú+test_getDeprecationWarningStringReplacement²  s    ý
ÿþzDDeprecationWarningsTests.test_getDeprecationWarningStringReplacementc                 C   s<   t ddddƒ}t| j|td�}|  |dt| jƒtf ¡ dS )a  
        L{getDeprecationWarningString} takes an additional replacement parameter
        that can be used to add information to the deprecation. If the
        replacement parameter is a callable, its fully qualified name will be
        interpolated into the result.
        r_   r`   r   rÌ   zP%s was deprecated in Twisted 8.0.0; please use %s.dummyReplacementMethod insteadN)r   r   rµ   r³   r>   rÂ   r$   rÎ   r   r   r    Ú7test_getDeprecationWarningStringReplacementWithCallableÅ  s    ýþþzPDeprecationWarningsTests.test_getDeprecationWarningStringReplacementWithCallableN)r$   r%   r&   rµ   r¸   rÁ   rÄ   rÆ   rÈ   rÊ   rÏ   rÐ   r   r   r   r    r´   P  s   	
	r´   r_   rB   r^   é   c                   @   s   e Zd ZdZdS )ÚDeprecatedClasszJ
    Class which is entirely deprecated without having a replacement.
    N)r$   r%   r&   r'   r   r   r   r    rÒ   Ú  s   rÒ   c                   @   s<   e Zd ZdZdZeeddddƒƒdd„ ƒZejd	d„ ƒZdS )
ÚClassWithDeprecatedPropertyz2
    Class with a single deprecated property.
    Nr_   rB   r^   rÑ   c                 C   s   | j S )zC
        Getter docstring.

        @return: The property.
        ©Ú_someProtectedValuer"   r   r   r    ÚsomePropertyè  s    z(ClassWithDeprecatedProperty.somePropertyc                 C   s
   || _ dS )z#
        Setter docstring.
        NrÔ   r   r   r   r    rÖ   ñ  s    )	r$   r%   r&   r'   rÕ   r   r   rÖ   Úsetterr   r   r   r    rÓ   á  s   
rÓ   é   r)   c                 C   s   dS )z7
    Function with a deprecated keyword parameter.
    Nr   )ÚaÚbÚcr)   Úbarr   r   r    ÚfunctionWithDeprecatedParameterù  s    rÝ   c                   @   sH   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )ÚDeprecatedDecoratorTestsz*
    Tests for deprecated decorators.
    c                 C   s    |   |dd„ |j ¡ D ƒ¡ dS )a8  
        Check that C{target} object has the C{expected} docstring lines.

        @param target: Object which is checked.
        @type target: C{anything}

        @param expected: List of lines, ignoring empty lines or leading or
            trailing spaces.
        @type expected: L{list} or L{str}
        c                 S   s   g | ]}|  ¡ r|  ¡ ‘qS r   )Ústrip)Ú.0rˆ   r   r   r    Ú
<listcomp>  s      z<DeprecatedDecoratorTests.assertDocstring.<locals>.<listcomp>N)r>   r'   Ú
splitlines)r   ÚtargetÚexpectedr   r   r    ÚassertDocstring  s     ÿz(DeprecatedDecoratorTests.assertDocstringc                 C   s€   t ƒ }|j |  t jdddg¡ tddddƒt j_d}|  | jg¡}|  dt|ƒ¡ |  t	|d	 d
 ¡ |  ||d	 d ¡ dS )a%  
        When L{deprecatedProperty} is used on a C{property}, accesses raise a
        L{DeprecationWarning} and getter docstring is updated to inform the
        version in which it was deprecated. C{deprecatedVersion} attribute is
        also set to inform the deprecation version.
        zGetter docstring.z@return: The property.úDeprecated in Twisted 1.2.3.r_   rB   r^   rÑ   úktwisted.python.test.test_deprecate.ClassWithDeprecatedProperty.someProperty was deprecated in Twisted 1.2.3r   rT   rL   N)
rÓ   rÖ   rå   r   rÉ   rU   Útest_propertyGetterr>   rX   rW   )r   ÚobjrL   r«   r   r   r    rè     s*    ýþ   ÿÿz,DeprecatedDecoratorTests.test_propertyGetterc                 C   sn   t ƒ }tƒ }||_|  ||j¡ d}|  | jg¡}|  dt|ƒ¡ |  t	|d d ¡ |  ||d d ¡ dS )z}
        When L{deprecatedProperty} is used on a C{property}, setter accesses
        raise a L{DeprecationWarning}.
        rç   rB   r   rT   rL   N)
r<   rÓ   rÖ   r3   rÕ   rU   Útest_propertySetterr>   rX   rW   )r   ZnewValueré   rL   r«   r   r   r    rê   4  s    ÿz,DeprecatedDecoratorTests.test_propertySetterc                 C   st   t ƒ  |  t ddg¡ tddddƒt _d}|  | jg¡}|  dt|ƒ¡ |  t|d d	 ¡ |  ||d d
 ¡ dS )a  
        When L{deprecated} is used on a class, instantiations raise a
        L{DeprecationWarning} and class's docstring is updated to inform the
        version in which it was deprecated. C{deprecatedVersion} attribute is
        also set to inform the deprecation version.
        z@Class which is entirely deprecated without having a replacement.ræ   r_   rB   r^   rÑ   zRtwisted.python.test.test_deprecate.DeprecatedClass was deprecated in Twisted 1.2.3r   rT   rL   N)	rÒ   rå   r   rÉ   rU   Ú
test_classr>   rX   rW   )r   rL   r«   r   r   r    rë   H  s    þþÿz#DeprecatedDecoratorTests.test_classc                 C   s.   t ddddƒ}t|dƒtƒ}|  |jd¡ dS )a  
        L{deprecated} takes an additional replacement parameter that can be used
        to indicate the new, non-deprecated method developers should use.  If
        the replacement parameter is a string, it will be interpolated directly
        into the warning message.
        r_   r`   r   rË   z‚
Do nothing.

This is used to test the deprecation decorators.

Deprecated in Twisted 8.0.0; please use something.foobar instead.
N)r   r   r²   r>   r'   rÃ   r   r   r    Útest_deprecatedReplacementc  s    þz3DeprecatedDecoratorTests.test_deprecatedReplacementc                 C   s:   t ddddƒ}t|td�}|tƒ}|  |jd t¡¡ dS )a)  
        L{deprecated} takes an additional replacement parameter that can be used
        to indicate the new, non-deprecated method developers should use.  If
        the replacement parameter is a callable, its fully qualified name will
        be interpolated into the warning message.
        r_   r`   r   rÌ   z‹
Do nothing.

This is used to test the deprecation decorators.

Deprecated in Twisted 8.0.0; please use {}.dummyReplacementMethod instead.
N)r   r   r³   r²   r>   r'   r·   r$   )r   rK   Ú	decoratorrº   r   r   r    Ú&test_deprecatedReplacementWithCallablev  s    üþz?DeprecatedDecoratorTests.test_deprecatedReplacementWithCallablec              	   C   s  d}t dd��ê}tdƒ tddƒ |  |g ¡ tdddƒ |  |g ¡ tdddd	� |  t|ƒd
¡ |  |d jt¡ |  t|d jƒ|¡ | 	¡  tdddd� |  |g ¡ tddddƒ |  t|ƒd
¡ |  |d jt¡ |  t|d jƒ|¡ W 5 Q R X d S )NzzThe 'foo' parameter to twisted.python.test.test_deprecate.functionWithDeprecatedParameter was deprecated in Twisted 19.2.0Tr»   r½   é
   é   é   é(   )r)   rB   r   é2   )rÜ   )
r   r   rÝ   r>   rX   rT   rW   r¿   rL   rŒ   )r   rL   Úwsr   r   r    Útest_deprecatedKeywordParameter‰  s&    ÿ
z8DeprecatedDecoratorTests.test_deprecatedKeywordParameterN)r$   r%   r&   r'   rå   rè   rê   rë   rì   rî   rõ   r   r   r   r    rÞ      s    rÞ   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚAppendToDocstringTestszk
    Test the _appendToDocstring function.

    _appendToDocstring is used to add text to a docstring.
    c                 C   s$   dd„ }t |dƒ |  d|j¡ dS )zP
        Appending to an empty docstring simply replaces the docstring.
        c                   S   s   d S r   r   r   r   r   r    ÚnoDocstringµ  s    zGAppendToDocstringTests.test_appendToEmptyDocstring.<locals>.noDocstringúAppended text.N©r	   r>   r'   )r   r÷   r   r   r    Útest_appendToEmptyDocstring°  s    
z2AppendToDocstringTests.test_appendToEmptyDocstringc                 C   s@   dd„ }t |dƒ |  dddg|j ¡ ¡ |  |j d¡¡ dS )aŽ  
        Appending to a single line docstring places the message on a new line,
        with a blank line separating it from the rest of the docstring.

        The docstring ends with a newline, conforming to Twisted and PEP 8
        standards. Unfortunately, the indentation is incorrect, since the
        existing docstring doesn't have enough info to help us indent
        properly.
        c                   S   s   dS )ú;This doesn't comply with standards, but is here for a test.Nr   r   r   r   r    ÚsingleLineDocstringÆ  s    zTAppendToDocstringTests.test_appendToSingleLineDocstring.<locals>.singleLineDocstringrø   rû   rÅ   Ú
N)r	   r>   r'   râ   r¥   r—   )r   rü   r   r   r    Ú test_appendToSingleLineDocstring»  s    
ýúz7AppendToDocstringTests.test_appendToSingleLineDocstringc                 C   s$   dd„ }t |dƒ |  d|j¡ dS )zþ
        Appending to a multi-line docstring places the messade on a new line,
        with a blank line separating it from the rest of the docstring.

        Because we have multiple lines, we have enough information to do
        indentation.
        c                   S   s   dS )z9
            This is a multi-line docstring.
            Nr   r   r   r   r    ÚmultiLineDocstringÝ  s    zRAppendToDocstringTests.test_appendToMultilineDocstring.<locals>.multiLineDocstringrø   z1
This is a multi-line docstring.

Appended text.
Nrù   )r   rÿ   r   r   r    Útest_appendToMultilineDocstringÔ  s    	
þz6AppendToDocstringTests.test_appendToMultilineDocstringN)r$   r%   r&   r'   rú   rþ   r   r   r   r   r    rö   ©  s   rö   c                   @   sh   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ ZdS )ÚMutualArgumentExclusionTestsz2
    Tests for L{mutuallyExclusiveArguments}.
    c                 O   s4   t tddƒrtt |¡||ƒS tt |¡||ƒS dS )aÊ  
        Test an invocation of L{passed} with the given function, arguments, and
        keyword arguments.

        @param func: A function whose argspec will be inspected.
        @type func: A callable.

        @param args: The arguments which could be passed to C{func}.

        @param kw: The keyword arguments which could be passed to C{func}.

        @return: L{_passedSignature} or L{_passedArgSpec}'s return value
        @rtype: L{dict}
        Ú	signatureN)r6   Úinspectr   r  r   Ú
getargspec©r   ÚfuncÚargsÚkwr   r   r    ÚcheckPassedî  s    z(MutualArgumentExclusionTests.checkPassedc                 C   s*   dd„ }|   |  |dd¡tddd�¡ dS )z`
        L{passed} identifies the arguments passed by a simple
        positional test.
        c                 S   s   d S r   r   ©rÙ   rÚ   r   r   r    r  
  s    zGMutualArgumentExclusionTests.test_passed_simplePositional.<locals>.funcrB   r^   r
  N©r>   r	  rk   ©r   r  r   r   r    Útest_passed_simplePositional  s    z9MutualArgumentExclusionTests.test_passed_simplePositionalc                 C   s"   dd„ }|   t| j|ddd¡ dS )z[
        L{passed} raises a L{TypeError} if too many arguments are
        passed.
        c                 S   s   d S r   r   r
  r   r   r    r    s    zBMutualArgumentExclusionTests.test_passed_tooManyArgs.<locals>.funcrB   r^   rÑ   N©r4   Ú	TypeErrorr	  r  r   r   r    Útest_passed_tooManyArgs  s    z4MutualArgumentExclusionTests.test_passed_tooManyArgsc                 C   s"   dd„ }| j t| j|ddd� dS )zs
        L{passed} raises a L{TypeError} if a argument is passed both
        positionally and by keyword.
        c                 S   s   d S r   r   ©rÙ   r   r   r    r     s    zHMutualArgumentExclusionTests.test_passed_doublePassKeyword.<locals>.funcrB   r^   r  Nr  r  r   r   r    Útest_passed_doublePassKeyword  s    z:MutualArgumentExclusionTests.test_passed_doublePassKeywordc                 C   s"   dd„ }| j t| j|ddd� dS )z„
        L{passed} raises a L{TypeError} if a keyword argument not
        present in the function's declaration is passed.
        c                 S   s   d S r   r   r  r   r   r    r  +  s    zIMutualArgumentExclusionTests.test_passed_unspecifiedKeyword.<locals>.funcrB   r^   )ÚzNr  r  r   r   r    Útest_passed_unspecifiedKeyword%  s    z;MutualArgumentExclusionTests.test_passed_unspecifiedKeywordc                 C   s,   dd„ }|   |  |ddd¡tddd�¡ dS )	z|
        L{passed} places additional positional arguments into a tuple
        under the name of the star argument.
        c                 W   s   d S r   r   r
  r   r   r    r  6  s    z;MutualArgumentExclusionTests.test_passed_star.<locals>.funcrB   r^   rÑ   )r^   rÑ   r
  Nr  r  r   r   r    Útest_passed_star0  s    z-MutualArgumentExclusionTests.test_passed_starc              
   C   s:   dd„ }|   | j|ddddd�tdtdddd�d�¡ d	S )
zn
        Additional keyword arguments are passed as a dict to the star star
        keyword argument.
        c                 [   s   d S r   r   r
  r   r   r    r  A  s    z?MutualArgumentExclusionTests.test_passed_starStar.<locals>.funcrB   r^   rÑ   é   )rˆ   Úyr  r
  Nr  r  r   r   r    Útest_passed_starStar;  s
     ÿz1MutualArgumentExclusionTests.test_passed_starStarc                 C   s2   d
dd„}|   | j|dddd�tdddd�¡ d	S )zp
        The results of L{passed} only include arguments explicitly
        passed, not default values.
        rB   r^   rÑ   c                 S   s   d S r   r   ©rÙ   rÚ   rÛ   ÚdÚer   r   r    r  N  s    zFMutualArgumentExclusionTests.test_passed_noDefaultValues.<locals>.funcé   )r  )rÙ   rÚ   r  N)rB   r^   rÑ   r  r  r   r   r    Útest_passed_noDefaultValuesH  s    
z8MutualArgumentExclusionTests.test_passed_noDefaultValuesc                 C   sT   t dgƒddd„ƒ}|  |ddƒd¡ |  |ddd	ƒd
¡ |  |ddd	d�d¡ dS )z¥
        L{mutuallyExclusiveArguments} does not interfere in its
        decoratee's operation, either its receipt of arguments or its return
        value.
        r
  rÑ   r  c                 S   s   | | | | S r   r   )rˆ   r  rÙ   rÚ   r   r   r    r  Z  s    zMMutualArgumentExclusionTests.test_mutualExclusionPrimeDirective.<locals>.funcrB   r^   rï   r  é   ©rÚ   é   N)rÑ   r  )r   r>   r  r   r   r    Ú"test_mutualExclusionPrimeDirectiveS  s
    z?MutualArgumentExclusionTests.test_mutualExclusionPrimeDirectivec                 C   s.   t ddggƒd	dd„ƒ}| jt|ddd� dS )
z‘
        L{mutuallyExclusiveArguments} raises a L{TypeError}n if its
        decoratee is passed a pair of mutually exclusive arguments.
        rÙ   rÚ   rÑ   r  c                 S   s   | | S r   r   r
  r   r   r    r  h  s    zPMutualArgumentExclusionTests.test_mutualExclusionExcludesByKeyword.<locals>.funcr
  N)rÑ   r  )r   r4   r  r  r   r   r    Ú%test_mutualExclusionExcludesByKeywordb  s    zBMutualArgumentExclusionTests.test_mutualExclusionExcludesByKeywordc                 C   sn   G dd„ dƒ}G dd„ dƒ}dd„ }|ddƒ t  |¡j}| ¡ }|d	d	ƒ|d
< ||ƒ}|  tt|di ¡ dS )z²
        Create a fake signature with an invalid parameter
        type to test error handling.  The valid parameter
        types are specified in L{inspect.Parameter}.
        c                   @   s   e Zd Zdd„ ZdS )zMMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeSignaturec                 S   s
   || _ d S r   )Ú
parameters)r   r#  r   r   r    r!   v  s    zVMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeSignature.__init__N©r$   r%   r&   r!   r   r   r   r    ÚFakeSignatureu  s   r%  c                   @   s   e Zd Zdd„ ZdS )zMMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeParameterc                 S   s   || _ || _d S r   )rY   Úkind)r   rY   r&  r   r   r    r!   z  s    zVMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeParameter.__init__Nr$  r   r   r   r    ÚFakeParametery  s   r'  c                 S   s   d S r   r   r
  r   r   r    r  ~  s    zDMutualArgumentExclusionTests.test_invalidParameterType.<locals>.funcrB   r^   ZfakerÛ   ©rB   r^   N)r  r  r#  rv   r4   r  r   )r   r%  r'  r  r#  ZdummyParametersZfakeSigr   r   r    Útest_invalidParameterTypen  s    
z6MutualArgumentExclusionTests.test_invalidParameterTypeN)r$   r%   r&   r'   r	  r  r  r  r  r  r  r  r!  r"  r)  r   r   r   r    r  é  s   r  c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚKeywordOnlyTestsz,
    Keyword only arguments (PEP 3102).
    c                 O   s   t t |¡||ƒS )a°  
        Test an invocation of L{passed} with the given function, arguments, and
        keyword arguments.

        @param func: A function whose argspec to pass to L{_passed}.
        @type func: A callable.

        @param args: The arguments which could be passed to L{func}.

        @param kw: The keyword arguments which could be passed to L{func}.

        @return: L{_passed}'s return value
        @rtype: L{dict}
        )r   r  r  r  r   r   r    r	  Ž  s    zKeywordOnlyTests.checkPassedc                 C   s®   ddœdd„}ddœdd„}|   |  |ddd	¡td
dd�¡ |   | j|ddd	dd�td
dd�¡ |   | j|dddddd	d�tddddd	d�¡ | jt| j|dddddd� dS )z`
        Keyword only arguments follow varargs.
        They are specified in PEP 3102.
        Tr  c                 W   s   dS )zM
            b is a keyword-only argument, with a default value.
            Nr   )rÚ   rÙ   r   r   r    Úfunc1¥  s    z6KeywordOnlyTests.test_passedKeywordOnly.<locals>.func1c                 W   s   dS )zd
            b, c, d, e  are keyword-only arguments.
            b has a default value.
            Nr   )rÚ   rÛ   r  r  rÙ   r   r   r    Úfunc2ª  s    z6KeywordOnlyTests.test_passedKeywordOnly.<locals>.func2rB   r^   rÑ   )rB   r^   rÑ   r
  F)rÚ   rÛ   r  r  r(  r  )rÚ   rÛ   r  N)r>   r	  rk   r4   r  )r   r+  r,  r   r   r    Útest_passedKeywordOnlyŸ  s      
ÿþz'KeywordOnlyTests.test_passedKeywordOnlyN)r$   r%   r&   r'   r	  r-  r   r   r   r    r*  ‰  s   r*  )rB   r^   rÑ   )7r'   r  ra   r*   r«   Úos.pathr   r   r   Ú	importlibr   ÚImportErrorÚincrementalr   Ztwisted.pythonr   Ztwisted.python.deprecater   r	   r
   rÂ   r   r   r   r   r   r   r   r   r   Ztwisted.python.filepathr   Ztwisted.python.runtimer   Ztwisted.python.testr   Z#twisted.python.test.modules_helpersr   Ztwisted.trial.unittestr   r   r(   rJ   rf   rŠ   r²   r³   r´   rÒ   rÓ   rÝ   rÞ   rö   r  r*  r   r   r   r    Ú<module>   sN   
8Gbo g  *@ !