o
    ¯b(¤  ã                   @   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y3   dZ
Y nw 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                   @   ó    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   ó
   || _ d S ©N©Úvalue©Úselfr   © r!   úD/usr/lib/python3/dist-packages/twisted/python/test/test_deprecate.pyÚ__init__8   ó   
z!_MockDeprecatedAttribute.__init__c                 C   ó   | 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   Ú_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.
        Úhello)ÚSOME_ATTRIBUTEÚDOES_NOT_EXISTN)r6   ÚassertIsr8   Ú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)r6   ÚobjectÚ__getattribute__r   ÚassertEqualr-   )r    r?   rA   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.
        Ú_modulerA   N)r6   r;   r<   r=   r>   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.
        é   rG   N)r6   rG   ÚassertNotEqualrC   rD   rE   r>   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.
        rG   ú<z module=ú>N)r6   rC   rD   rE   ÚreprÚtyper(   )r    r?   Ú
realModuler!   r!   r"   Ú	test_repr~   s   (zModuleProxyTests.test_reprN)
r(   r)   r*   r+   r6   r@   rF   rH   rK   rQ   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(   rS   r   rT   )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.
        ÚANOTHER_DEPRECATED_ATTRIBUTErB   c                      s   ˆ   ¡  d S r   )r'   r!   ©rX   r!   r"   ÚaddStackLevel¯   s   zNDeprecatedAttributeTests.test_deprecatedAttributeHelper.<locals>.addStackLevelr   ÚcategoryrT   rI   N)r1   r   r   Ú_DeprecatedAttributerS   rT   rE   r(   ÚflushWarningsÚtest_deprecatedAttributeHelperr:   ÚDeprecationWarningrY   Úlen)r    Únamer\   ÚwarningsShownr!   r[   r"   r`   Ÿ   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   ÚDEPRECATED_ATTRIBUTErI   r]   rT   N)
r   ÚANOTHER_ATTRIBUTEr_   Útest_deprecatedAttributerE   rb   r=   r:   ra   rY   )r    rd   rc   r!   r!   r"   rg   ¹   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-   ÚfirstrI   Úsecondé   ÚTwistedé   r   rT   N)r.   r/   ÚsysÚmodulesrU   Ú
addCleanupÚpopr1   r   ÚdeprecatedModuleAttributer   rJ   r:   )r    r4   r?   r!   r!   r"   Útest_wrappedModuleÐ   s   ÿÿz+DeprecatedAttributeTests.test_wrappedModuleN)	r(   r)   r*   r+   rV   rY   r`   rg   rr   r!   r!   r!   r"   rR   ‰   s    
rR   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                    sj   i }|  ¡ D ],\}}|  |¡}t|tƒr|||< | |¡ qt|tƒr/| ¡  ˆ ||ƒ||< qtdƒ‚|S )Nz(only strings and dicts allowed as values)r0   ÚchildÚ
isinstanceÚbytesÚ
setContentÚdictÚcreateDirectoryÚ
ValueError)ÚpathobjÚdirdictÚpathdictr5   r   rt   ©ÚmakeSomeFilesr!   r"   r     s   


zAImportedModuleAttributeTests.pathEntryTree.<locals>.makeSomeFilesúutf-8)r   ÚmktempÚencodeÚmakedirsÚreplaceSysPathÚpathÚdecoderm   ÚreplaceSysModulesrn   Úcopy)r    ÚtreeÚbaseÚresultr!   r~   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   packager€   ó    )s   __init__.pyó	   module.pyrŽ   )rŒ   Ú_packageInitr‚   )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   ©Úmoduler€   rI   rT   z7package.module was deprecated in Package 1.2.3: messager]   N)
Úpackager“   rE   r   Ú__file__r‚   r_   ÚcheckOneWarningrb   ra   )r    Ú
modulePathr“   Ú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.
        rj   N)r‘   r–   Úrange)r    ÚmpÚxr!   r!   r"   Ú"test_deprecatedModuleMultipleTimesE  s   

ÿz?ImportedModuleAttributeTests.test_deprecatedModuleMultipleTimesN)
r(   r)   r*   r+   r�   rŒ   r‘   r–   r™   r�   r!   r!   r!   r"   rs   ë   s    &rs   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 ¡ rW|  ¡  dS 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   )rm   rn   ÚclearÚupdater!   ©rn   r!   r"   Ú<lambda>•  s    z.WarnAboutFunctionTests.setUp.<locals>.<lambda>N)r   r�   rt   r”   rƒ   rw   Úparentr…   rm   Úinsertro   Úremovern   rˆ   r   Ú	isWindowsr_   )r    ÚpackagePathr!   r¢   r"   rV   `  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   ó   d S r   r!   r!   r!   r!   r"   ÚaFunc¤  ó   z2WarnAboutFunctionTests.test_warning.<locals>.aFunczA Warning Messagez.pycNéÿÿÿÿr   ÚfilenamerT   )	r   ÚwarnAboutFunctionr_   r•   ÚlowerÚendswithÚassertSamePathr   rE   )r    rª   rd   r­   r!   r!   r"   Útest_warning�  s   z#WarnAboutFunctionTests.test_warningc                 C   ó„   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­   r€   ó   twisted_private_helperrŽ   Úlinenoé	   rT   úA Warning StringrI   N)rŸ   r“   ÚcallTestFunctionr_   r±   r   r‚   r”   Úsiblingrt   rE   rb   ©r    r“   rd   r!   r!   r"   Útest_warningLineNumber¯  s   þz-WarnAboutFunctionTests.test_warningLineNumberc                 C   r³   )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­   r€   r´   s	   pep626.pyrµ   é   rT   r·   rI   N)rŸ   r¼   r¸   r_   r±   r   r‚   r”   r¹   rt   rE   rb   )r    r¼   rd   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   r…   )r    rh   ri   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­   r€   rŽ   rµ   r¶   rT   r·   rI   N)rŸ   r“   rm   rn   r(   r”   ÚmoveTor¹   r   rÀ   ro   rp   r¸   r_   ÚtestFunctionr   r‚   rt   r±   rE   rb   )r    r“   rd   Ú
warnedPathÚ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¸   r_   rE   rb   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’   rI   rT   r]   r­   rµ   z=module.py:9: DeprecationWarning: A Warning String
  return a
zUnexpected warning string: )rÉ   rÊ   rË   rŸ   r“   r¸   r_   rE   rb   Úformatwarningr¿   r°   )r    r“   rd   rT   r]   r­   rµ   Úmsgr!   r!   r"   Útest_filteredOnceWarning  s$   	ÿüz/WarnAboutFunctionTests.test_filteredOnceWarningN)r(   r)   r*   r+   rV   r²   r»   r¾   r±   rÅ   rÌ   rÏ   r!   r!   r!   r"   rž   Z  s    =&rž   c                   C   ó   dS )zK
    Do nothing.

    This is used to test the deprecation decorators.
    Nr!   r!   r!   r!   r"   ÚdummyCallable@  ó    rÑ   c                   C   rÐ   )z[
    Do nothing.

    This is used to test the replacement parameter to L{deprecated}.
    Nr!   r!   r!   r!   r"   ÚdummyReplacementMethodH  rÒ   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.
        rk   rl   r   z\%s.DeprecationWarningsTests.test_getDeprecationWarningString was deprecated in Twisted 8.0.0N)r   rE   r   Ú test_getDeprecationWarningStringr(   ©r    rS   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.
        rk   rl   r   z: This is a messagezo%s.DeprecationWarningsTests.test_getDeprecationWarningString was deprecated in Twisted 8.0.0: This is a messageN)r   r   rE   r   rÕ   r(   )r    rS   Úformatr!   r!   r"   Ú*test_getDeprecationWarningStringWithFormat]  s   ÿÿüzCDeprecationWarningsTests.test_getDeprecationWarningStringWithFormatc                    s°   t ddddƒ}t|ƒtƒ‰ ‡ fdd„}tdd��6}tdƒ |ƒ  |  |d jt¡ |  t|d j	ƒt
t|ƒ¡ |  |d j d	¡t d	¡¡ W d
  ƒ d
S 1 sQw   Y  d
S )zK
        Decorating a callable with L{deprecated} emits a warning.
        rk   rl   r   c                      s
   ˆ ƒ  d S r   r!   r!   ©Údummyr!   r"   r\   t  r$   zJDeprecationWarningsTests.test_deprecateEmitsWarning.<locals>.addStackLevelT©ÚrecordÚalwaysÚcoN)r   r   rÑ   r   r   rE   r]   ra   ÚstrrT   r   r­   Úrstripr•   )r    rS   r\   Ú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.
        rk   rl   r   N)r   r   rÑ   rE   r(   ÚfullyQualifiedName©r    rS   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.
        rk   rl   r   zDeprecated in Twisted 8.0.0.Ú N)r   rE   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   rÐ   )zc
            Do nothing.

            This is used to test the deprecation decorators.
            Nr!   r!   r!   r!   r"   ÚlocalDummyCallable›  rÒ   zTDeprecationWarningsTests.test_deprecatedUpdatesDocstring.<locals>.localDummyCallablerk   rl   r   ræ   N)r   r   r	   r   rE   r+   )r    rè   rS   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.
        rk   rl   r   N)r   r   rÑ   rE   Ú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.
        rk   rl   r   úsomething.foobar©ÚreplacementzG%s was deprecated in Twisted 8.0.0; please use something.foobar insteadN)r   r   rÕ   rE   rã   ©r    rS   Ú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.
        rk   rl   r   rí   zP%s was deprecated in Twisted 8.0.0; please use %s.dummyReplacementMethod insteadN)r   r   rÕ   rÓ   rE   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Ô   rk   rI   rj   é   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.
    Nrk   rI   rj   ró   c                 C   r%   )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   rÐ   )z7
    Function with a deprecated keyword parameter.
    Nr!   )ÚaÚbÚcr-   Úbarr!   r!   r"   ÚfunctionWithDeprecatedParameterù  rÒ   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)rE   r+   Ú
splitlines)r    ÚtargetÚexpectedr!   r!   r"   ÚassertDocstring  s   ÿz(DeprecatedDecoratorTests.assertDocstringc                 C   s~   t ƒ }|j |  t jg d¢¡ 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.rk   rI   rj   ró   úktwisted.python.test.test_deprecate.ClassWithDeprecatedProperty.someProperty was deprecated in Twisted 1.2.3r   r]   rT   N)
rõ   rø   r  r   rê   r_   Útest_propertyGetterrE   rb   ra   )r    ÚobjrT   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	  rI   r   r]   rT   N)
rC   rõ   rø   r:   r÷   r_   Útest_propertySetterrE   rb   ra   )r    ÚnewValuer  rT   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  rk   rI   rj   ró   zRtwisted.python.test.test_deprecate.DeprecatedClass was deprecated in Twisted 1.2.3r   r]   rT   N)	rô   r  r   rê   r_   Ú
test_classrE   rb   ra   )r    rT   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.
        rk   rl   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Ñ   rE   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f ¡ 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.
        rk   rl   r   rí   z›
    Do nothing.

    This is used to test the deprecation decorators.

    Deprecated in Twisted 8.0.0; please use %s.dummyReplacementMethod instead.
    N)r   r   rÓ   rÑ   rE   r+   r(   )r    rS   Ú	decoratorrÚ   r!   r!   r"   Ú&test_deprecatedReplacementWithCallablew  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 d   ƒ d S 1 s…w   Y  d S )NzzThe 'foo' parameter to twisted.python.test.test_deprecate.functionWithDeprecatedParameter was deprecated in Twisted 19.2.0TrÛ   rÝ   é
   é   é   é(   )r-   rI   r   é2   )rþ   )
r   r   rÿ   rE   rb   r]   ra   rß   rT   r    )r    rT   Ú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   r©   r   r!   r!   r!   r!   r"   ÚnoDocstring¸  r«   zGAppendToDocstringTests.test_appendToEmptyDocstring.<locals>.noDocstringúAppended text.N©r	   rE   r+   )r    r  r!   r!   r"   Útest_appendToEmptyDocstring³  s   
z2AppendToDocstringTests.test_appendToEmptyDocstringc                 C   s>   dd„ }t |dƒ |  g d¢|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   rÐ   )ú;This doesn't comply with standards, but is here for a test.Nr!   r!   r!   r!   r"   ÚsingleLineDocstringÉ  rÒ   zTAppendToDocstringTests.test_appendToSingleLineDocstring.<locals>.singleLineDocstringr  )r  ræ   r  Ú
N)r	   rE   r+   r  r¿   r°   )r    r  r!   r!   r"   Ú test_appendToSingleLineDocstring¾  s   
úz7AppendToDocstringTests.test_appendToSingleLineDocstringc                 C   s.   dd„ }dd„ }t |dƒ |  |j|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   rÐ   )z9
            This is a multi-line docstring.
            Nr!   r!   r!   r!   r"   ÚmultiLineDocstringà  rÒ   zRAppendToDocstringTests.test_appendToMultilineDocstring.<locals>.multiLineDocstringc                   S   rÐ   )zU
            This is a multi-line docstring.

            Appended text.
            Nr!   r!   r!   r!   r"   ÚexpectedDocstringå  rÒ   zQAppendToDocstringTests.test_appendToMultilineDocstring.<locals>.expectedDocstringr  Nr  )r    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   s0   t tddƒrtt |¡||ƒ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 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)r=   Ú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   r©   r   r!   ©rû   rü   r!   r!   r"   r*    r«   zGMutualArgumentExclusionTests.test_passed_simplePositional.<locals>.funcrI   rj   r.  N©rE   r-  rx   ©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   r©   r   r!   r.  r!   r!   r"   r*    r«   zBMutualArgumentExclusionTests.test_passed_tooManyArgs.<locals>.funcrI   rj   ró   N©r;   Ú	TypeErrorr-  r0  r!   r!   r"   Útest_passed_tooManyArgs  ó   z4MutualArgumentExclusionTests.test_passed_tooManyArgsc                 C   ó"   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   r©   r   r!   ©rû   r!   r!   r"   r*  '  r«   zHMutualArgumentExclusionTests.test_passed_doublePassKeyword.<locals>.funcrI   rj   r7  Nr2  r0  r!   r!   r"   Útest_passed_doublePassKeyword!  r5  z:MutualArgumentExclusionTests.test_passed_doublePassKeywordc                 C   r6  )z„
        L{passed} raises a L{TypeError} if a keyword argument not
        present in the function's declaration is passed.
        c                 S   r©   r   r!   r7  r!   r!   r"   r*  2  r«   zIMutualArgumentExclusionTests.test_passed_unspecifiedKeyword.<locals>.funcrI   rj   )ÚzNr2  r0  r!   r!   r"   Útest_passed_unspecifiedKeyword,  r5  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   r©   r   r!   r.  r!   r!   r"   r*  =  r«   z;MutualArgumentExclusionTests.test_passed_star.<locals>.funcrI   rj   ró   )rj   ró   r.  Nr/  r0  r!   r!   r"   Útest_passed_star7  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                 [   r©   r   r!   r.  r!   r!   r"   r*  H  r«   z?MutualArgumentExclusionTests.test_passed_starStar.<locals>.funcrI   rj   ró   é   )rœ   Úyr9  r.  Nr/  r0  r!   r!   r"   Útest_passed_starStarB  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.
        rI   rj   ró   c                 S   r©   r   r!   ©rû   rü   rý   ÚdÚer!   r!   r"   r*  U  r«   zFMutualArgumentExclusionTests.test_passed_noDefaultValues.<locals>.funcé   )rA  )rû   rü   rA  N©rI   rj   ró   r/  r0  r!   r!   r"   Útest_passed_noDefaultValuesO  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*  a  s   zMMutualArgumentExclusionTests.test_mutualExclusionPrimeDirective.<locals>.funcrI   rj   r  rB  é   ©rü   é   N©ró   r<  )r   rE   r0  r!   r!   r"   Ú"test_mutualExclusionPrimeDirectiveZ  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*  o  s   zPMutualArgumentExclusionTests.test_mutualExclusionExcludesByKeyword.<locals>.funcr.  NrH  )r   r;   r3  r0  r!   r!   r"   Ú%test_mutualExclusionExcludesByKeywordi  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                   @   ó   e Zd Zdd„ ZdS )zMMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeSignaturec                 S   r   r   )Ú
parameters)r    rL  r!   r!   r"   r#   }  r$   zVMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeSignature.__init__N©r(   r)   r*   r#   r!   r!   r!   r"   ÚFakeSignature|  ó    rN  c                   @   rK  )zMMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeParameterc                 S   s   || _ || _d S r   )rc   Úkind)r    rc   rP  r!   r!   r"   r#   �  s   
zVMutualArgumentExclusionTests.test_invalidParameterType.<locals>.FakeParameter.__init__NrM  r!   r!   r!   r"   ÚFakeParameter€  rO  rQ  c                 S   r©   r   r!   r.  r!   r!   r"   r*  …  r«   zDMutualArgumentExclusionTests.test_invalidParameterType.<locals>.funcrI   rj   Úfakerý   ©rI   rj   N)r'  r&  rL  rˆ   r;   r3  r   )r    rN  rQ  r*  rL  ÚdummyParametersÚfakeSigr!   r!   r"   Útest_invalidParameterTypeu  s   
z6MutualArgumentExclusionTests.test_invalidParameterTypeN)r(   r)   r*   r+   r-  r1  r4  r8  r:  r;  r>  rD  rI  rJ  rV  r!   r!   r!   r"   r%  ð  s    r%  c                   @   r   )Ú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.
        TrF  c                 W   rÐ   )zM
            b is a keyword-only argument, with a default value.
            Nr!   )rü   rû   r!   r!   r"   Úfunc1¬  rÒ   z6KeywordOnlyTests.test_passedKeywordOnly.<locals>.func1c                 W   rÐ   )zd
            b, c, d, e  are keyword-only arguments.
            b has a default value.
            Nr!   )rü   rý   r@  rA  rû   r!   r!   r"   Úfunc2±  rÒ   z6KeywordOnlyTests.test_passedKeywordOnly.<locals>.func2rI   rj   ró   rC  r.  F)rü   rý   r@  rA  rS  r?  )rü   rý   r@  N)rE   r-  rx   r;   r3  )r    rX  rY  r!   r!   r"   Útest_passedKeywordOnly¦  s    ÿþ z'KeywordOnlyTests.test_passedKeywordOnlyN)r(   r)   r*   r+   r-  rZ  r!   r!   r!   r"   rW  �  s    rW  rC  )7r+   r'  rm   r.   rÉ   Úos.pathr   r   r   Ú	importlibr   ÚImportErrorÚincrementalr   Útwisted.pythonr   Útwisted.python.deprecater   r	   r
   rã   r   r   r   r   r   r   r   r   r   Útwisted.python.filepathr   Útwisted.python.runtimer   Útwisted.python.testr   Ú#twisted.python.test.modules_helpersr   Útwisted.trial.unittestr   r   r,   rR   rs   rž   rÑ   rÓ   rÔ   rô   rõ   rÿ   r   r  r%  rW  r!   r!   r!   r"   Ú<module>   sR   ÿ8Gbo g  -D !