U
    ¹~Hjh  ã                   @  sb  d Z ddlmZ ddlZddl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 ddl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mZmZmZ ddlmZ edƒZG dd„ deƒZ G dd„ deƒZ!G dd„ dej"ƒZ#dZ$dddœdd„Z%ddddddœdd„Z&G dd„ deƒZ'G d d!„ d!ej"ƒZ(G d"d#„ d#ej"ƒZ)G d$d%„ d%ej"ƒZ*dS )&z"
Tests for Twisted plugin system.
é    )ÚannotationsN)Úinvalidate_caches)Ú
ModuleType)ÚCallableÚ	TypedDictÚTypeVar)Ú	Interface)Úplugin)ÚFilePath)Ú	EventDictÚaddObserverÚremoveObserverÚtextFromEventDict)ÚunittestÚ_Tc                   @  s   e Zd ZdZdS )ÚITestPluginzS
    A plugin for use by the plugin system's unit tests.

    Do not use this.
    N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   ú</tmp/pip-unpacked-wheel-ewod1tgb/twisted/test/test_plugin.pyr      s   r   c                   @  s   e Zd ZdZdS )ÚITestPlugin2z
    See L{ITestPlugin}.
    Nr   r   r   r   r   r   &   s   r   c                   @  sø   e Zd ZdZddœdd„Zddœdd„Zd(d	d
ddœdd„Zddœdd„Zdddœdd„Zeddœdd„ƒZ	ddœdd„Z
eddœdd„ƒZeddœdd„ƒZeddœdd„ƒZeddœdd „ƒZeddœd!d"„ƒZeddœd#d$„ƒZddœd%d&„Zd'S ))ÚPluginTestsz_
    Tests which verify the behavior of the current, active Twisted plugins
    directory.
    ÚNone©Úreturnc                 C  s¤   t jdd… | _t j ¡ | _t|  ¡ ƒ| _| j 	¡  | j 
d¡| _| j 	¡  | j 
d¡ d¡ ttƒ d¡ | j 
d¡¡ d| _t j d| jj¡ ddl}|| _dS )	zV
        Save C{sys.path} and C{sys.modules}, and create a package for tests.
        NÚ	mypackageú__init__.pyó    zplugin_basic.pyztestplugin.pyÚ
testpluginr   )ÚsysÚpathÚoriginalPathÚmodulesÚcopyÚsavedModulesr
   ÚmktempÚrootÚcreateDirectoryÚchildÚpackageÚ
setContentÚ__file__ÚsiblingÚcopyToÚoriginalPluginÚinsertr   Úmodule)Úselfr   r   r   r   ÚsetUp2   s    


ÿzPluginTests.setUpc                 C  s,   | j tjdd…< tj ¡  tj | j¡ dS ©zR
        Restore C{sys.path} and C{sys.modules} to their original values.
        N©r$   r"   r#   r%   ÚclearÚupdater'   ©r4   r   r   r   ÚtearDownJ   s    
zPluginTests.tearDownFr   Úbool)r3   ÚdeleteSourcer   c              	   C  s˜   |j d k	st‚|j d¡}d |d d… ¡}|d }ttj| |ƒ tj|j= ddg|r^dgp`g  D ].}zt 	|j | ¡ W qd t
k
r�   Y qdX qdd S )NÚ.éÿÿÿÿÚcÚoÚ )r.   ÚAssertionErrorr   ÚsplitÚjoinÚdelattrr"   r%   ÚosÚremoveÚFileNotFoundError)r4   r3   r=   Z
modulePathÚpackageNameÚ
moduleNameÚextr   r   r   Ú_unimportPythonModuleR   s    
z!PluginTests._unimportPythonModulec                 C  s   | j  d¡ ¡  dS )z;
        Remove the plugins B{droping.cache} file.
        údropin.cacheN)r,   r+   rH   r:   r   r   r   Ú_clearCacheb   s    zPluginTests._clearCachezCallable[[PluginTests], object]zCallable[[PluginTests], None])Úmethr   c                   s"   t  ˆ ¡dddœ‡ fdd„ƒ}|S )zþ
        This is a paranoid test wrapper, that calls C{meth} 2 times, clear the
        cache, and calls it 2 other times. It's supposed to ensure that the
        plugin system behaves correctly no matter what the state of the cache
        is.
        r   r   )r4   r   c                   s,   ˆ | ƒ ˆ | ƒ |   ¡  ˆ | ƒ ˆ | ƒ d S )N)rO   r:   ©rP   r   r   Úwrappedr   s
    z+PluginTests._withCacheness.<locals>.wrapped)Ú	functoolsÚwraps)rP   rR   r   rQ   r   Ú_withCachenessh   s    
zPluginTests._withCachenessc                 C  sÒ   t  | j¡}|| j }|  |jd| j› �¡ |  d|j¡ dd„ |jD ƒd }|  	|j
|¡ |  |jd¡ |  |j ¡ d¡ |  |jtt jg¡ | ¡ }|  	|tjd| j› � j¡ ddlm} |  	||j¡ dS )	a	  
        Check that the cache returned by L{plugin.getCache} hold the plugin
        B{testplugin}, and that this plugin has the properties we expect:
        provide L{TestPlugin}, has the good name and description, and can be
        loaded successfully.
        z
mypackage.zI'm a test drop-in.c                 S  s   g | ]}t |jkr|‘qS r   )r   Úprovided©Ú.0Úpr   r   r   Ú
<listcomp>‹   s     
 z*PluginTests.test_cache.<locals>.<listcomp>r   Ú
TestPluginz*A plugin used solely for testing purposes.N)r	   ÚgetCacher3   r1   ÚassertEqualrK   ÚassertInÚdescriptionÚpluginsZassertIsÚdropinÚnameÚstriprV   r   ZIPluginÚloadr"   r%   r[   Zmypackage.testpluginr!   )r4   Úcachera   Úp1Z
realPluginÚtpr   r   r   Ú
test_cache|   s&    
 ÿþzPluginTests.test_cachec                 C  s>   t  | j¡| j }tdd„ |jD ƒƒd }|  t|ƒd¡ dS )zm
        L{CachedPlugin} has a helpful C{repr} which contains relevant
        information about it.
        c                 s  s   | ]}|j d kr|V  qdS )r[   N©rb   rW   r   r   r   Ú	<genexpr>§   s     
 z-PluginTests.test_cacheRepr.<locals>.<genexpr>r   zT<CachedPlugin 'TestPlugin'/'mypackage.testplugin' (provides 'ITestPlugin, IPlugin')>N)r	   r\   r3   r1   Úlistr`   r]   Úrepr)r4   ZcachedDropinZcachedPluginr   r   r   Útest_cacheRepr¡   s    ÿþzPluginTests.test_cacheReprc                 C  sL   t t t| j¡ƒ}|  t|ƒd¡ ddg}|D ]}| |j¡ | 	¡  q.dS )a  
        L{plugin.getPlugins} should return the list of plugins matching the
        specified interface (here, L{ITestPlugin2}), and these plugins
        should be instances of classes with a C{test} method, to be sure
        L{plugin.getPlugins} load classes correctly.
        é   ZAnotherTestPluginZThirdTestPluginN)
rk   r	   Ú
getPluginsr   r3   r]   ÚlenrH   r   Útest)r4   r`   ÚnamesrY   r   r   r   Útest_plugins°   s    zPluginTests.test_pluginsc              
   C  s¨   t tƒ d¡ | j d¡¡ zr|  	dtj¡ |  
ttjd dƒd¡ tt t| j¡ƒ}|  t|ƒd¡ d	d
g}|D ]}| |j¡ | ¡  qrW 5 |  tjd d¡ X dS )ze
        Check that L{plugin.getPlugins} is able to detect plugins added at
        runtime.
        úplugin_extra1.pyúpluginextra.pyúmypackage.pluginextraTr   Úpluginextraz&mypackage still has pluginextra modulern   r[   ÚFourthTestPluginN)r
   r.   r/   r0   r,   r+   rM   r"   r%   ÚfailIfInÚassertFalseÚhasattrrk   r	   ro   r   r3   r]   rp   rH   r   Útest1©r4   Úplgsrr   rY   r   r   r   Útest_detectNewFilesÁ   s     
ÿþzPluginTests.test_detectNewFilesc              
   C  sÒ   t tƒ d¡ | j d¡¡ zœt	t
 t| j¡ƒ}|  t|ƒd¡ t tƒ d¡ | j d¡¡ |  tjd ¡ t	t
 t| j¡ƒ}|  t|ƒd¡ dd	d
g}|D ]}| |j¡ | ¡  qœW 5 |  tjd d¡ X dS )z…
        Check that if the content of a plugin change, L{plugin.getPlugins} is
        able to detect the new plugins added.
        rt   ru   rv   Trn   zplugin_extra2.pyé   r[   rx   ZFifthTestPluginN)r
   r.   r/   r0   r,   r+   rM   r"   r%   rk   r	   ro   r   r3   r]   rp   rH   r   r|   r}   r   r   r   Útest_detectFilesChangedß   s"    
ÿ
ÿ
z#PluginTests.test_detectFilesChangedc              
   C  sn   t tƒ d¡ | j d¡¡ zt	t
 t| j¡ƒ W 5 |  tjd d¡ X t	t
 t| j¡ƒ}|  dt|ƒ¡ dS )zs
        Check that when a dropin file is removed, L{plugin.getPlugins} doesn't
        return it anymore.
        rt   ru   rv   Té   N)r
   r.   r/   r0   r,   r+   rM   r"   r%   rk   r	   ro   r   r3   r]   rp   )r4   r~   r   r   r   Útest_detectFilesRemoved   s    
ÿz#PluginTests.test_detectFilesRemovedc              	   C  sd   |   ¡ }|  tj |¡¡ | jj |¡ z&t	t
 t| j¡ƒ}|  t|ƒd¡ W 5 | jj |¡ X dS )zy
        Test that getCache skips over any entries in a plugin package's
        C{__path__} which do not exist.
        r‚   N)r(   rz   rG   r#   Úexistsr3   Ú__path__ÚappendrH   rk   r	   ro   r   r]   rp   )r4   r#   r~   r   r   r   Útest_nonexistentPathEntry  s    z%PluginTests.test_nonexistentPathEntryc              	   C  sx   t |  ¡ ƒ}|  | ¡ ¡ | ¡  | d¡j}| jj 	|¡ z&tt t| j¡ƒ}|  t|ƒd¡ W 5 | jj 
|¡ X dS )z¡
        Test that getCache skips over any entries in a plugin package's
        C{__path__} which refer to children of paths which are not directories.
        Ztest_packager‚   N)r
   r(   rz   r„   Útouchr+   r#   r3   r…   r†   rH   rk   r	   ro   r   r]   rp   )r4   r#   r+   r~   r   r   r   Útest_nonDirectoryChildEntry"  s    z'PluginTests.test_nonDirectoryChildEntryc                 C  s  t  | j¡ | j d¡}ttƒ d¡ | j d¡¡ t	ƒ  t
 | jjd¡ t
 |jd¡ |  t
j| jjd¡ |  t
j|jd¡ g }t|jƒ |  t|j¡ t  | j¡}|  d|¡ |  | j|¡ d|jtjf }|D ]&}t|ƒ}|d	k	sìt‚||krÔ �qqÔ|  d
|f ¡ d	S )z¿
        The C{dropin.cache} file may not be writable: the cache should still be
        attainable, but an error should be logged to show that the cache
        couldn't be updated.
        rN   rt   ru   i@  é   iÀ  rw   ú3Unable to write to plugin cache %s: error number %dNú;Did not observe unwriteable cache warning in log events: %r)r	   r\   r3   r,   r+   r
   r.   r/   r0   ÚinvalidateImportCachesrG   Úchmodr#   Ú
addCleanupr   r†   r   r^   r1   ÚerrnoÚEPERMr   rC   Úfail)r4   Z	cachepathÚeventsre   ÚexpectedÚeventÚ	maybeTextr   r   r   Útest_deployedMode3  s<    
ÿ
þÿÿzPluginTests.test_deployedModeN)F)r   r   r   r   r5   r;   rM   rO   rU   rh   rm   rs   r   r�   rƒ   r‡   r‰   r—   r   r   r   r   r   ,   s.   	 ÿ$ r   sj   
from twisted.plugin import pluginPackagePaths
__path__.extend(pluginPackagePaths(__name__))
__all__ = []
ÚstrÚbytes)rb   r   c                 C  s   d  | ¡ d¡S )Nz¬from zope.interface import provider
from twisted.plugin import IPlugin
from twisted.test.test_plugin import ITestPlugin

@provider(IPlugin, ITestPlugin)
class {}:
    pass
Úascii)ÚformatÚencoderi   r   r   r   ÚpluginFileContentsm  s    ÿ	÷
öÿr�   úFilePath[str]r<   )Ú	entrypathÚpluginContentÚrealÚpluginModuler   c                 C  sl   |   ¡  |  d¡}|  ¡  |r.| d¡ d¡ | d¡}|  ¡  |rT| d¡ t¡ | |d ¡ |¡ |S )z'
    Create a plugindummy package.
    Úplugindummyr   r    r`   ú.py)r*   r+   r-   ÚpluginInitFile)rŸ   r    r¡   r¢   ÚpkgZplugsr   r   r   Ú_createPluginDummy}  s    

r§   c                   @  s   e Zd ZU ded< dS )Ú_HasBoolLegacyKeyr<   ÚlegacyN)r   r   r   Ú__annotations__r   r   r   r   r¨   �  s   
r¨   c                   @  sœ   e Zd ZdZddœdd„Zddœdd„Zddœdd	„Zd
dœdd„Zddœdd„Zddœdd„Z	ddœdd„Z
ddœdd„Zddœdd„Zddœdd„ZdS )ÚDeveloperSetupTestsz³
    These tests verify things about the plugin system without actually
    interacting with the deployed 'twisted.plugins' package, instead creating a
    temporary package.
    r   r   c                 C  s>  t jdd… | _t j ¡ | _t|  ¡ ƒ| _| j 	¡  | j 
d¡| _| j 
d¡| _| j 
d¡| _t| jtdƒddƒ| _t| jtdƒddƒ| _t| jtd	ƒd
dƒ| _t j dd„ | j| jfD ƒ¡ |  ¡  | j 
d¡ 
d¡| _| j 
d¡| _t ¡ }t | j 
d¡j|d fd ¡ t | jj|d fd ¡ |  ¡  |  ¡  dS )a7  
        Create a complex environment with multiple entries on sys.path, akin to
        a developer's environment who has a development (trunk) checkout of
        Twisted, a system installed version of Twisted (for their operating
        system's tools) and a project which provides Twisted plugins.
        NZsystem_pathZdevelopment_pathZapplication_pathÚsystemTZplugindummy_builtinÚdevÚappFZplugindummy_appc                 S  s   g | ]
}|j ‘qS r   ©r#   ©rX   Úxr   r   r   rZ   ´  s     z-DeveloperSetupTests.setUp.<locals>.<listcomp>r£   r`   rN   zplugindummy_builtin.pyiˆ  rn   iÐ  )r"   r#   Ú	savedPathr%   r&   r'   r
   r(   ZfakeRootr*   r+   Ú
systemPathÚdevPathÚappPathr§   r�   ZsystemPackageZ
devPackageÚ
appPackageÚextendÚgetAllPluginsÚsysplugÚsyscacheÚtimerG   ÚutimeÚ
lockSystemÚresetEnvironment)r4   Únowr   r   r   r5   ›  sD    
   ÿ   ÿ   ÿ zDeveloperSetupTests.setUpc                 C  s$   t  | jjd¡ t  | jjd¡ dS )zW
        Lock the system directories, as if they were unwritable by this user.
        im  N©rG   rŽ   r¹   r#   rº   r:   r   r   r   r½   Å  s    zDeveloperSetupTests.lockSystemc                 C  s$   t  | jjd¡ t  | jjd¡ dS )zW
        Unlock the system directories, as if they were writable by this user.
        iÿ  NrÀ   r:   r   r   r   ÚunlockSystemÌ  s    z DeveloperSetupTests.unlockSystemz	list[str]c                 C  s(   ddl }tt t|j¡ƒ}dd„ |D ƒS )zl
        Get all the plugins loadable from our dummy package, and return their
        short names.
        r   Nc                 S  s   g | ]
}|j ‘qS r   ©r   )rX   Zplugr   r   r   rZ   Ý  s     z5DeveloperSetupTests.getAllPlugins.<locals>.<listcomp>)Zplugindummy.pluginsrk   r	   ro   r   r`   )r4   r£   r±   r   r   r   r¸   Ó  s    z!DeveloperSetupTests.getAllPluginsc                 C  s.   |   ¡  tj dd„ | j| j| jfD ƒ¡ dS )zc
        Change the environment to what it should be just as the test is
        starting.
        c                 S  s   g | ]
}|j ‘qS r   r¯   r°   r   r   r   rZ   å  s     z8DeveloperSetupTests.resetEnvironment.<locals>.<listcomp>N)ÚunsetEnvironmentr"   r#   r·   r´   r³   rµ   r:   r   r   r   r¾   ß  s    z$DeveloperSetupTests.resetEnvironmentc                 C  s2   t ƒ  tj ¡  tj | j¡ | jtjdd…< dS )zh
        Change the Python environment back to what it was before the test was
        started.
        N)r�   r"   r%   r8   r9   r'   r²   r#   r:   r   r   r   rÃ   ç  s    
z$DeveloperSetupTests.unsetEnvironmentc                 C  s   |   ¡  |  ¡  dS )zÑ
        Reset the Python environment to what it was before this test ran, and
        restore permissions on files which were marked read-only so that the
        directory may be cleanly cleaned up.
        N)rÃ   rÁ   r:   r   r   r   r;   ñ  s    zDeveloperSetupTests.tearDownc                 C  s2   t dƒD ]$}|  ¡ }| ¡  |  |ddg¡ qdS )a  
        Plugins added in the development path should be loadable, even when
        the (now non-importable) system path contains its own idea of the
        list of plugins for a package.  Inversely, plugins added in the
        system path should not be available.
        r€   r®   r­   N)Úranger¸   Úsortr]   )r4   r±   rr   r   r   r   Ú"test_developmentPluginAvailabilityþ  s    	z6DeveloperSetupTests.test_developmentPluginAvailabilityc                 C  sâ   | j  d¡}| tdƒ¡ t ¡ d }t |j||f¡ | d¡}t	dd�}t
j| j jfddi|—Ž t |j||f¡ | ¡  |  ¡  |  d|  ¡ ¡ |  d	|  ¡ ¡ |  ¡  | td	ƒ¡ |  d|  ¡ ¡ |  d	|  ¡ ¡ d
S )zÜ
        Verify that if a stale .pyc file on the PYTHONPATH is replaced by a
        fresh .py file, the plugins in the new .py are picked up rather than
        the stale .pyc, even if the .pyc is still around.
        zstale.pyÚoneiè  z	stale.pycT)r©   Úquietr‚   ZtwoN)r¶   r+   r-   r�   r»   rG   r¼   r#   r/   r¨   Ú
compileallÚcompile_dirrH   r¾   r^   r¸   ry   )r4   Zmypathr±   ZpycÚextrar   r   r   Útest_freshPyReplacesStalePyc  s     

z0DeveloperSetupTests.test_freshPyReplacesStalePycc                 C  s²   |   ¡  | j d¡ tdƒ¡ |  ¡  tj | j	j¡ g }t
|jƒ |  t|j¡ |  d|  ¡ ¡ d| jjtjf }|D ]$}t|ƒ}|dk	s�t‚||krx q®qx|  d|f ¡ dS )aF  
        Verify that a failure to write the dropin.cache file on a read-only
        path will not affect the list of plugins returned.

        Note: this test should pass on both Linux and Windows, but may not
        provide useful coverage on Windows due to the different meaning of
        "read-only directory".
        znewstuff.pyrÇ   r‹   NrŒ   )rÁ   r¹   r+   r-   r�   r½   r"   r#   rH   r´   r   r†   r�   r   r^   r¸   rº   r�   r‘   r   rC   r’   )r4   r“   r”   r•   r–   r   r   r   Útest_newPluginsOnReadOnlyPath,  s,    	
þÿÿz1DeveloperSetupTests.test_newPluginsOnReadOnlyPathN)r   r   r   r   r5   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œdd„Zddœdd„Zdd	d	dd
œdd„Zddœdd„Zddœdd„ZdS )ÚAdjacentPackageTestsz–
    Tests for the behavior of the plugin system when there are multiple
    installed copies of the package containing the plugins being loaded.
    r   r   c                 C  s    t jdd… | _t j ¡ | _dS )zS
        Save the elements of C{sys.path} and the items of C{sys.modules}.
        N)r"   r#   r$   r%   r&   r'   r:   r   r   r   r5   [  s    zAdjacentPackageTests.setUpc                 C  s,   | j tjdd…< tj ¡  tj | j¡ dS r6   r7   r:   r   r   r   r;   b  s    
zAdjacentPackageTests.tearDownrž   r˜   )r)   rb   Ú
pluginNamer   c                 C  sn   |  |¡}|  d¡}| ¡  |  d¡ d¡ |  d¡}| ¡  |  d¡ t¡ |  |d ¡}| t|ƒ¡ |S )a`  
        Create a directory containing a Python package named I{dummy} with a
        I{plugins} subpackage.

        @type root: L{FilePath}
        @param root: The directory in which to create the hierarchy.

        @type name: C{str}
        @param name: The name of the directory to create which will contain
            the package.

        @type pluginName: C{str}
        @param pluginName: The name of a module to create in the
            I{dummy.plugins} package.

        @rtype: L{FilePath}
        @return: The directory which was created to contain the I{dummy}
            package.
        Údummyr   r    r`   r¤   )r+   Úmakedirsr-   r¥   r�   )r4   r)   rb   rÏ   Ú	directoryr,   r`   r¢   r   r   r   ÚcreateDummyPackagej  s    


z'AdjacentPackageTests.createDummyPackagec                 C  s‚   t |  ¡ ƒ}| ¡  |  |dd¡}|  |dd¡}tj |j¡ tj |j¡ ddl}tt	 
t|j¡ƒ}|  dgdd„ |D ƒ¡ dS )zê
        Only plugins from the first package in sys.path should be returned by
        getPlugins in the case where there are two Python packages by the same
        name installed, each with a plugin module by a single name.
        ÚfirstZ
somepluginÚsecondr   Nc                 S  s   g | ]
}|j ‘qS r   rÂ   rW   r   r   r   rZ   �  s     zWAdjacentPackageTests.test_hiddenPackageSamePluginModuleNameObscured.<locals>.<listcomp>©r
   r(   rÑ   rÓ   r"   r#   r†   Zdummy.pluginsrk   r	   ro   r   r`   r]   ©r4   r)   ZfirstDirectoryZsecondDirectoryrÐ   r`   r   r   r   Ú.test_hiddenPackageSamePluginModuleNameObscured‹  s    zCAdjacentPackageTests.test_hiddenPackageSamePluginModuleNameObscuredc                 C  s‚   t |  ¡ ƒ}| ¡  |  |dd¡}|  |dd¡}tj |j¡ tj |j¡ ddl}tt	 
t|j¡ƒ}|  dgdd„ |D ƒ¡ dS )	zè
        Plugins from the first package in sys.path should be returned by
        getPlugins in the case where there are two Python packages by the same
        name installed, each with a plugin module by a different name.
        rÔ   Z
thispluginrÕ   Z
thatpluginr   Nc                 S  s   g | ]
}|j ‘qS r   rÂ   rW   r   r   r   rZ   ±  s     z\AdjacentPackageTests.test_hiddenPackageDifferentPluginModuleNameObscured.<locals>.<listcomp>rÖ   r×   r   r   r   Ú3test_hiddenPackageDifferentPluginModuleNameObscuredŸ  s    zHAdjacentPackageTests.test_hiddenPackageDifferentPluginModuleNameObscuredN)	r   r   r   r   r5   r;   rÓ   rØ   rÙ   r   r   r   r   rÎ   U  s   !rÎ   c                   @  sH   e Zd ZdZddœdd„Zddœdd„Zddœdd	„Zddœd
d„ZdS )ÚPackagePathTestszg
    Tests for L{plugin.pluginPackagePaths} which constructs search paths for
    plugin packages.
    r   r   c                 C  s   t jdd… | _dS )z3
        Save the elements of C{sys.path}.
        N)r"   r#   r$   r:   r   r   r   r5   º  s    zPackagePathTests.setUpc                 C  s   | j tjdd…< dS )z<
        Restore C{sys.path} to its original value.
        N)r$   r"   r#   r:   r   r   r   r;   À  s    zPackagePathTests.tearDownc                 C  sT   t dƒ}t dƒ}|j|jgt_|  t d¡| d¡ d¡j| d¡ d¡jg¡ dS )z®
        L{plugin.pluginPackagePaths} should return a list containing each
        directory in C{sys.path} with a suffix based on the supplied package
        name.
        ÚfooÚbarúdummy.pluginsrÐ   r`   N)r
   r#   r"   r]   r	   ÚpluginPackagePathsr+   )r4   rÛ   rÜ   r   r   r   Útest_pluginDirectoriesÆ  s    þþz'PackagePathTests.test_pluginDirectoriesc                 C  s€   t |  ¡ ƒ}| d¡ d¡ d¡}| ¡  | d¡ d¡ | d¡j| d¡jgt_|  t 	d¡| d¡ d¡ d¡jg¡ dS )	a™  
        L{plugin.pluginPackagePaths} should exclude directories which are
        Python packages.  The only allowed plugin package (the only one
        associated with a I{dummy} package which Python will allow to be
        imported) will already be known to the caller of
        L{plugin.pluginPackagePaths} and will most commonly already be in
        the C{__path__} they are about to mutate.
        rÛ   rÐ   r`   r   r    rÜ   rÝ   N)
r
   r(   r+   rÑ   r-   r#   r"   r]   r	   rÞ   )r4   r)   rÛ   r   r   r   Útest_pluginPackagesExcluded×  s    	þz,PackagePathTests.test_pluginPackagesExcludedN)r   r   r   r   r5   r;   rß   rà   r   r   r   r   rÚ   ´  s
   rÚ   )+r   Ú
__future__r   rÉ   r�   rS   rG   r"   r»   Ú	importlibr   r�   Útypesr   Útypingr   r   r   Zzope.interfacer   Ztwistedr	   Ztwisted.python.filepathr
   Ztwisted.python.logr   r   r   r   Ztwisted.trialr   r   r   r   ZTestCaser   r¥   r�   r§   r¨   r«   rÎ   rÚ   r   r   r   r   Ú<module>   s:     < B_