o
    ¯b(c  ã                   @   s  d 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 ddlmZ ddlmZ ddlmZmZmZ dd	lmZ G d
d„ deƒZG dd„ deƒZG dd„ dejƒZdZdd„ Zdd„ 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.
é    N)Úinvalidate_caches)ÚCallable)Ú	Interface)Úplugin)ÚFilePath)ÚaddObserverÚremoveObserverÚtextFromEventDict)Úunittestc                   @   ó   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   ú:/usr/lib/python3/dist-packages/twisted/test/test_plugin.pyr      ó    r   c                   @   r   )ÚITestPlugin2z
    See L{ITestPlugin}.
    Nr   r   r   r   r   r   #   r   r   c                   @   s¤   e Zd ZdZdd„ Zdd„ Zd!dd„Zd	d
„ Zdefdd„Z	e	dd„ ƒZ
dd„ Ze	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZe	dd„ ƒZdd„ Zd S )"ÚPluginTestsz_
    Tests which verify the behavior of the current, active Twisted plugins
    directory.
    c                 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   ÚsetUp/   s   


ÿ
zPluginTests.setUpc                 C   ó,   | 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    ©r-   r   r   r   ÚtearDownG   ó   
zPluginTests.tearDownFc                 C   s¦   |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 q+ t	yP } z|j
t
jkrF‚ W Y d }~q+d }~ww d S )NÚ.éÿÿÿÿÚcÚoÚ )r   ÚsplitÚjoinÚdelattrr   r   ÚosÚremover'   ÚOSErrorÚerrnoÚENOENT)r-   r,   ÚdeleteSourceÚ
modulePathÚpackageNameÚ
moduleNameÚextÚoser   r   r   Ú_unimportPythonModuleO   s   
ÿ€ÿýz!PluginTests._unimportPythonModulec                 C   s   | j  d¡ ¡  dS )z;
        Remove the plugins B{droping.cache} file.
        údropin.cacheN)r%   r$   r@   r4   r   r   r   Ú_clearCache]   ó   zPluginTests._clearCacheÚmethc                    s   t  ˆ ¡‡ 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.
        c                    s,   ˆ | ƒ ˆ | ƒ |   ¡  ˆ | ƒ ˆ | ƒ d S )N)rL   r4   ©rN   r   r   Úwrappedk   s
   z+PluginTests._withCacheness.<locals>.wrapped)Ú	functoolsÚwraps)rN   rP   r   rO   r   Ú_withCachenessc   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v 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   ÚgetCacher,   r*   ÚassertEqualrG   ÚassertInÚdescriptionÚpluginsÚassertIsÚdropinÚnameÚstriprT   r   ÚIPluginÚloadr   r   rY   Úmypackage.testpluginr   )r-   Úcacher`   Úp1Ú
realPluginÚtpr   r   r   Ú
test_cacheu   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 )rY   N©ra   rU   r   r   r   Ú	<genexpr>    s   € z-PluginTests.test_cacheRepr.<locals>.<genexpr>r   zT<CachedPlugin 'TestPlugin'/'mypackage.testplugin' (provides 'ITestPlugin, IPlugin')>N)r   rZ   r,   r*   Úlistr^   r[   Úrepr)r-   ÚcachedDropinÚ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.
        é   ÚAnotherTestPluginÚThirdTestPluginN)
rm   r   Ú
getPluginsr   r,   r[   Úlenr@   r   Útest)r-   r^   ÚnamesrW   r   r   r   Útest_plugins©   s   
þzPluginTests.test_pluginsc              
   C   s¸   t tƒ d¡ | j d¡¡ zC|  dtj¡ |  	t
tjd dƒd¡ tt t| j¡ƒ}|  t|ƒd¡ dd	g}|D ]}| |j¡ | ¡  q9W |  tjd d
¡ dS |  tjd d
¡ w )ze
        Check that L{plugin.getPlugins} is able to detect plugins added at
        runtime.
        úplugin_extra1.pyúpluginextra.pyúmypackage.pluginextrar   Úpluginextraz&mypackage still has pluginextra modulerr   rY   ÚFourthTestPluginTN)r   r'   r(   r)   r%   r$   ÚfailIfInr   r   ÚassertFalseÚhasattrrm   r   ru   r   r,   r[   rv   r@   r   Útest1rJ   ©r-   Úplgsrx   rW   r   r   r   Útest_detectNewFilesº   s"   
ÿþ
þ*zPluginTests.test_detectNewFilesc              
   C   sà   t tƒ d¡ | j d¡¡ zWtt t	| j
¡ƒ}|  t|ƒd¡ t tƒ d¡ | j d¡¡ |  tjd ¡ tt t	| j
¡ƒ}|  t|ƒd¡ g d¢}|D ]}| |j¡ | ¡  qMW |  tjd d¡ d	S |  tjd d¡ w )
z…
        Check that if the content of a plugin change, L{plugin.getPlugins} is
        able to detect the new plugins added.
        rz   r{   rr   zplugin_extra2.pyr|   é   )rY   r~   ÚFifthTestPluginTN)r   r'   r(   r)   r%   r$   rm   r   ru   r   r,   r[   rv   rJ   r   r   r@   r   r‚   rƒ   r   r   r   Útest_detectFilesChangedØ   s$   
ÿ
ÿ
þ*z#PluginTests.test_detectFilesChangedc              
   C   s€   t tƒ d¡ | j d¡¡ ztt t	| j
¡ƒ W |  tjd d¡ n
|  tjd d¡ w 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.
        rz   r{   r|   Té   N)r   r'   r(   r)   r%   r$   rm   r   ru   r   r,   rJ   r   r   r[   rv   )r-   r„   r   r   r   Útest_detectFilesRemovedù   s   
ÿ(z#PluginTests.test_detectFilesRemovedc              	   C   sp   |   ¡ }|  tj |¡¡ | jj |¡ ztt	 
t| j¡ƒ}|  t|ƒd¡ W | jj |¡ dS | jj |¡ w )zy
        Test that getCache skips over any entries in a plugin package's
        C{__path__} which do not exist.
        r‰   N)r!   r€   r?   r   Úexistsr,   Ú__path__Úappendrm   r   ru   r   r[   rv   r@   )r-   r   r„   r   r   r   Útest_nonexistentPathEntry  s   "z%PluginTests.test_nonexistentPathEntryc              	   C   s„   t |  ¡ ƒ}|  | ¡ ¡ | ¡  | d¡j}| jj 	|¡ zt
t t| j¡ƒ}|  t|ƒd¡ W | jj |¡ dS | jj |¡ w )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.
        Útest_packager‰   N)r   r!   r€   r‹   Útouchr$   r   r,   rŒ   r   rm   r   ru   r   r[   rv   r@   )r-   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|ƒv ru d
S qj|  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.
        rK   rz   r{   i@  é   iÀ  r}   ú3Unable to write to plugin cache %s: error number %dú;Did not observe unwriteable cache warning in log events: %rN)r   rZ   r,   r%   r$   r   r'   r(   r)   ÚinvalidateImportCachesr?   Úchmodr   Ú
addCleanupr   r   r   r\   r*   rB   ÚEPERMr	   Úfail)r-   Ú	cachepathÚeventsrf   ÚexpectedÚeventr   r   r   Útest_deployedMode,  s:   
ÿ
þÿÿÿzPluginTests.test_deployedModeN)F)r   r   r   r   r.   r5   rJ   rL   r   rS   rj   rq   ry   r…   rˆ   rŠ   rŽ   r‘   rž   r   r   r   r   r   )   s.    

$


 


r   sj   
from twisted.plugin import pluginPackagePaths
__path__.extend(pluginPackagePaths(__name__))
__all__ = []
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Úencoderk   r   r   r   ÚpluginFileContentsd  s   õr¢   c                 C   sl   |   ¡  |  d¡}|  ¡  |r| d¡ d¡ | d¡}|  ¡  |r*| d¡ t¡ | |d ¡ |¡ |S )z'
    Create a plugindummy package.
    Úplugindummyr   r   r^   ú.py)r#   r$   r&   ÚpluginInitFile)Ú	entrypathÚpluginContentÚrealÚpluginModuleÚpkgÚplugsr   r   r   Ú_createPluginDummyt  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d„ Z
dd„ Zdd„ Z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.
    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.
        NÚsystem_pathÚdevelopment_pathÚapplication_pathÚsystemTÚplugindummy_builtinÚdevÚappFÚplugindummy_appc                 S   ó   g | ]}|j ‘qS r   ©r   ©rV   Úxr   r   r   rX   ¥  ó    z-DeveloperSetupTests.setUp.<locals>.<listcomp>r£   r^   rK   zplugindummy_builtin.pyiˆ  rr   iÐ  )r   r   Ú	savedPathr   r   r    r   r!   ÚfakeRootr#   r$   Ú
systemPathÚdevPathÚappPathr¬   r¢   ÚsystemPackageÚ
devPackageÚ
appPackageÚextendÚgetAllPluginsÚsysplugÚsyscacheÚtimer?   ÚutimeÚ
lockSystemÚresetEnvironment)r-   Únowr   r   r   r.   Œ  s2   
ÿÿÿ zDeveloperSetupTests.setUpc                 C   ó$   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©r?   r–   rÅ   r   rÆ   r4   r   r   r   rÉ   ¶  ó   zDeveloperSetupTests.lockSystemc                 C   rÌ   )zW
        Unlock the system directories, as if they were writable by this user.
        iÿ  NrÍ   r4   r   r   r   ÚunlockSystem½  rÎ   z DeveloperSetupTests.unlockSystemc                 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   r¶   r   ©r   )rV   Úplugr   r   r   rX   Î  rº   z5DeveloperSetupTests.getAllPlugins.<locals>.<listcomp>)Úplugindummy.pluginsrm   r   ru   r   r^   )r-   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   r¶   r   r·   r¸   r   r   r   rX   Ö  rº   z8DeveloperSetupTests.resetEnvironment.<locals>.<listcomp>N)ÚunsetEnvironmentr   r   rÃ   r¾   r½   r¿   r4   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   r2   r3   r    r»   r   r4   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Ï   r4   r   r   r   r5   â  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[   )r-   r¹   rx   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)ÚlegacyÚquietr‰   ÚtwoN)rÂ   r$   r&   r¢   rÇ   r?   rÈ   r   r(   ÚdictÚ
compileallÚcompile_dirr@   rÊ   r\   rÄ   r   )r-   Úmypathr¹   Ú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|ƒv rG dS q<|  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“   r”   N)rÏ   rÅ   r$   r&   r¢   rÉ   r   r   r@   r¾   r   r   r—   r   r\   rÄ   rÆ   rB   r˜   r	   r™   )r-   r›   rœ   r   r   r   r   Útest_newPluginsOnReadOnlyPath  s*   	
þÿÿÿz1DeveloperSetupTests.test_newPluginsOnReadOnlyPathN)r   r   r   r   r.   rÉ   rÏ   rÄ   rÊ   rÓ   r5   rÖ   rá   râ   r   r   r   r   r­   …  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 )ÚAdjacentPackageTestsz–
    Tests for the behavior of the plugin system when there are multiple
    installed copies of the package containing the plugins being loaded.
    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    r4   r   r   r   r.   J  s   zAdjacentPackageTests.setUpc                 C   r/   r0   r1   r4   r   r   r   r5   Q  r6   zAdjacentPackageTests.tearDownc                 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¢   )r-   r"   ra   Ú
pluginNameÚ	directoryr%   r^   r©   r   r   r   ÚcreateDummyPackageY  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.
        ÚfirstÚ
somepluginÚsecondr   Nc                 S   r¶   r   rÐ   rU   r   r   r   rX   Š  rº   zWAdjacentPackageTests.test_hiddenPackageSamePluginModuleNameObscured.<locals>.<listcomp>©r   r!   rå   rè   r   r   r   Údummy.pluginsrm   r   ru   r   r^   r[   ©r-   r"   ÚfirstDirectoryÚsecondDirectoryrä   r^   r   r   r   Ú.test_hiddenPackageSamePluginModuleNameObscuredx  ó   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é   Ú
thispluginrë   Ú
thatpluginr   Nc                 S   r¶   r   rÐ   rU   r   r   r   rX   ž  rº   z\AdjacentPackageTests.test_hiddenPackageDifferentPluginModuleNameObscured.<locals>.<listcomp>rì   rî   r   r   r   Ú3test_hiddenPackageDifferentPluginModuleNameObscuredŒ  rò   zHAdjacentPackageTests.test_hiddenPackageDifferentPluginModuleNameObscuredN)	r   r   r   r   r.   r5   rè   rñ   rõ   r   r   r   r   rã   D  s    rã   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚPackagePathTestszg
    Tests for L{plugin.pluginPackagePaths} which constructs search paths for
    plugin packages.
    c                 C   s   t jdd… | _dS )z3
        Save the elements of C{sys.path}.
        N)r   r   r   r4   r   r   r   r.   §  rM   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   r4   r   r   r   r5   ­  rM   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$   )r-   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ú   )r-   r"   r÷   r   r   r   Útest_pluginPackagesExcludedÄ  s   	þz,PackagePathTests.test_pluginPackagesExcludedN)r   r   r   r   r.   r5   rû   rü   r   r   r   r   rö   ¡  s    rö   )"r   rÜ   rB   rQ   r?   r   rÇ   Ú	importlibr   r•   Útypingr   Úzope.interfacer   Útwistedr   Útwisted.python.filepathr   Útwisted.python.logr   r   r	   Útwisted.trialr
   r   r   ÚTestCaser   r¥   r¢   r¬   r­   rã   rö   r   r   r   r   Ú<module>   s4     6 @]