
    Vhh                       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e      Z  G d de      Z! G d dejD                        Z#dZ$ddZ%	 	 	 	 	 	 	 	 	 	 ddZ& G d de      Z' G d dejD                        Z( G d dejD                        Z) G d dejD                        Z*y) z"
Tests for Twisted plugin system.
    )annotationsN)invalidate_caches)
ModuleType)Callable	TypedDictTypeVar)	Interface)plugin)FilePath)	EventDictaddObserverremoveObservertextFromEventDict)unittest_Tc                      e Zd ZdZy)ITestPluginzS
    A plugin for use by the plugin system's unit tests.

    Do not use this.
    N__name__
__module____qualname____doc__     H/home/dcms/DCMS/lib/python3.12/site-packages/twisted/test/test_plugin.pyr   r      s    r   r   c                      e Zd ZdZy)ITestPlugin2z
    See L{ITestPlugin}.
    Nr   r   r   r   r   r   &   s    r   r   c                      e Zd ZdZddZddZ	 d	 	 	 	 	 ddZddZ	 	 	 	 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y)PluginTestsz_
    Tests which verify the behavior of the current, active Twisted plugins
    directory.
    c                   t         j                  dd | _        t         j                  j	                         | _        t        | j                               | _        | j                  j                          | j                  j                  d      | _        | j                  j                          | j                  j                  d      j                  d       t        t              j                  d      j                  | j                  j                  d             d| _        t         j                  j#                  d| j                  j                         ddl}|| _        y)	zV
        Save C{sys.path} and C{sys.modules}, and create a package for tests.
        N	mypackage__init__.pyr   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!   s     r   setUpzPluginTests.setUp2   s      HHQKKK,,.T[[]+			!!#yy{3$$&=)44S9""#45<<LL/	
 +499>>*r   c                    | j                   t        j                  dd t        j                  j	                          t        j                  j                  | j                         yzR
        Restore C{sys.path} and C{sys.modules} to their original values.
        Nr&   r$   r%   r'   clearupdater)   r6   s    r   tearDownzPluginTests.tearDownJ   ?     ''4,,-r   c                   |j                   J |j                  j                  d      }dj                  |d d       }|d   }t	        t
        j                  |   |       t
        j                  |j                  = ddg|xr dgxs g z   D ]%  }	 t        j                  |j                   |z          ' y # t        $ r Y 4w xY w)N.co )
r0   r   splitjoindelattrr$   r'   osremoveFileNotFoundError)r6   r5   deleteSource
modulePathpackageName
moduleNameexts          r   _unimportPythonModulez!PluginTests._unimportPythonModuleR   s     ***__**3/
hhz#2/^
K(*5KK(:!62$!<"= 	C		&//C/0	 % s   "B44	C ?C c                V    | j                   j                  d      j                          y)z;
        Remove the plugins B{droping.cache} file.
        dropin.cacheN)r.   r-   rJ   r=   s    r   _clearCachezPluginTests._clearCacheb   s     	>*113r   c                D     t        j                         d f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                f     |         |        | j                           |         |        y )N)rT   )r6   meths    r   wrappedz+PluginTests._withCacheness.<locals>.wrappedr   s+    JJJJr   )r6   r   returnNone)	functoolswraps)rW   rX   s   ` r   _withCachenesszPluginTests._withCachenessh   s'     
		 
	 r   c                P   t        j                  | j                        }|| j                     }| j	                  |j
                  d| j                          | j                  d|j                         |j                  D cg c]  }t        |j                  v s| c}d   }| j                  |j                  |       | j	                  |j                  d       | j	                  |j                  j                         d       | j	                  |j                  t        t         j                  g       |j!                         }| j                  |t"        j$                  d| j                      j&                         ddlm} | j                  ||j&                         yc c}w )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.r   
TestPluginz*A plugin used solely for testing purposes.N)r
   getCacher5   r3   assertEqualrO   assertIndescriptionpluginsr   providedassertIsdropinnamestripIPluginloadr$   r'   r_   mypackage.testpluginr#   )r6   cacherg   pp1
realPlugintps          r   
test_cachezPluginTests.test_cache|   sD    ,t**+**j9L9L8M,NO+V-?-?@  EA;!**+DaEaHbii(,/ 	NN  "$P	
 	{FNN&CDWWY
KK*T%8%8$9:;FF	
 	*j"--0) Fs   F#F#c                    t        j                  | j                        | j                     }t	        d |j
                  D              d   }| j                  t        |      d       y)zm
        L{CachedPlugin} has a helpful C{repr} which contains relevant
        information about it.
        c              3  @   K   | ]  }|j                   d k(  s|  yw)r_   Nrh   ).0rn   s     r   	<genexpr>z-PluginTests.test_cacheRepr.<locals>.<genexpr>   s     V!qvv?UAVs   r   zT<CachedPlugin 'TestPlugin'/'mypackage.testplugin' (provides 'ITestPlugin, IPlugin')>N)r
   r`   r5   r3   listrd   ra   repr)r6   cachedDropincachedPlugins      r   test_cacheReprzPluginTests.test_cacheRepr   s\    
 t{{3D4G4GHV|';';VV
 	1	
r   c                    t        t        j                  t        | j                              }| j                  t        |      d       ddg}|D ]-  }|j                  |j                         |j                          / y)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)
rx   r
   
getPluginsr   r5   ra   lenrJ   r   test)r6   rd   namesrn   s       r   test_pluginszPluginTests.test_plugins   sf     v((t{{CDWq)$&78 	ALL$FFH	r   c                   t        t              j                  d      j                  | j                  j                  d             	 | j                  dt        j                         | j                  t        t        j                  d   d      d       t        t        j                  t        | j                              }| j!                  t#        |      d       dd	g}|D ]-  }|j%                  |j&                         |j)                          / 	 | j+                  t        j                  d   d
       y# | j+                  t        j                  d   d
       w xY 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 moduler~   r_   FourthTestPluginTN)r   r0   r1   r2   r.   r-   failIfInr$   r'   assertFalsehasattrrx   r
   r   r   r5   ra   r   rJ   r   test1rQ   r6   plgsr   rn   s       r   test_detectNewFileszPluginTests.test_detectNewFiles   s    	""#56==LL/0	
	SMM13;;?K0-@8
 ))+t{{CDD SY*!#56E QZZ(	 &&s{{3J'KTRD&&s{{3J'KTRs   CD8 8%Ec                   t        t              j                  d      j                  | j                  j                  d             	 t        t        j                  t        | j                              }| j                  t        |      d       t        t              j                  d      j                  | j                  j                  d             | j                  t        j                  d          t        t        j                  t        | j                              }| j                  t        |      d       g d}|D ]-  }|j!                  |j"                         |j%                          / 	 | j                  t        j                  d   d       y	# | j                  t        j                  d   d       w xY w)
z
        Check that if the content of a plugin change, L{plugin.getPlugins} is
        able to detect the new plugins added.
        r   r   r~   zplugin_extra2.pyr      )r_   r   FifthTestPluginTN)r   r0   r1   r2   r.   r-   rx   r
   r   r   r5   ra   r   rQ   r$   r'   rJ   r   r   r   s       r   test_detectFilesChangedz#PluginTests.test_detectFilesChanged   sL    	""#56==LL/0	
	S))+t{{CDDSY*X&&'9:AA""#34
 &&s{{3J'KL ))+t{{CDDSY*IE QZZ(	 &&s{{3J'KTRD&&s{{3J'KTRs   D.F %G c                   t        t              j                  d      j                  | j                  j                  d             	 t        t        j                  t        | j                               | j                  t        j                  d   d       t        t        j                  t        | j                              }| j                  dt        |             y# | j                  t        j                  d   d       w xY w)zs
        Check that when a dropin file is removed, L{plugin.getPlugins} doesn't
        return it anymore.
        r   r   r   T   N)r   r0   r1   r2   r.   r-   rx   r
   r   r   r5   rQ   r$   r'   ra   r   )r6   r   s     r   test_detectFilesRemovedz#PluginTests.test_detectFilesRemoved   s     	""#56==LL/0	
	S"";<= &&s{{3J'KTRF%%k4;;?@CI& &&s{{3J'KTRs   -C! !%Dc                   | j                         }| j                  t        j                  j	                  |             | j
                  j                  j                  |       	 t        t        j                  t        | j
                              }| j                  t        |      d       | j
                  j                  j                  |       y# | j
                  j                  j                  |       w xY w)zy
        Test that getCache skips over any entries in a plugin package's
        C{__path__} which do not exist.
        r   N)r*   r   rI   r%   existsr5   __path__appendrx   r
   r   r   ra   r   rJ   )r6   r%   r   s      r   test_nonexistentPathEntryz%PluginTests.test_nonexistentPathEntry  s     {{}-.##D)	.))+t{{CDDSY*KK  ''-DKK  ''-s   %AC 'C:c                D   t        | j                               }| j                  |j                                |j	                          |j                  d      j                  }| j                  j                  j                  |       	 t        t        j                  t        | j                              }| j                  t        |      d       | j                  j                  j!                  |       y# | j                  j                  j!                  |       w xY 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%   r5   r   r   rx   r
   r   r   ra   r   rJ   )r6   r%   r-   r   s       r   test_nonDirectoryChildEntryz'PluginTests.test_nonDirectoryChildEntry"  s     &'



>*//##E*	/))+t{{CDDSY*KK  ''.DKK  ''.s   
AC8 8'Dc                   t        j                  | j                         | j                  j	                  d      }t        t              j                  d      j                  | j                  j	                  d             t                t        j                  | j                  j                  d       t        j                  |j                  d       | j                  t        j                  | j                  j                  d       | j                  t        j                  |j                  d       g }t        |j                         | j                  t         |j                         t        j                  | j                        }| j#                  d|       | j#                  | j$                  |       d|j                  t&        j(                  fz  }|D ]  }t+        |      }|J ||v s y	 | j-                  d
|       y	)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.
        rS   r   r   i@     i  r   3Unable to write to plugin cache %s: error number %dN9Did not observe unwriteable cache warning in log events: )r
   r`   r5   r.   r-   r   r0   r1   r2   invalidateImportCachesrI   chmodr%   
addCleanupr   r   r   rb   r3   errnoEPERMr   fail)r6   	cachepatheventsrm   expectedevent	maybeTexts          r   test_deployedModezPluginTests.test_deployedMode3  s    	$LL&&~6	 	""#56==LL/0	
 	 
""E*
'$,,"3"3U;)..%8 #%FMM"6,mU+d))51 INNKKL
 
  		E)%0I(((9$			 II &)r   NrY   rZ   )F)r5   r   rL   boolrY   rZ   )rW   zCallable[[PluginTests], object]rY   zCallable[[PluginTests], None])r   r   r   r   r7   r>   rQ   rT   r]   rr   r|   r   r   r   r   r   r   r   r   r   r   r   r   ,   s    
 0. 8= 04	 4-	&( "1 "1H
    S S: S S@ ' '" . . / / /r   r   sj   
from twisted.plugin import pluginPackagePaths
__path__.extend(pluginPackagePaths(__name__))
__all__ = []
c                B    dj                  |       j                  d      S )Nzfrom zope.interface import provider
from twisted.plugin import IPlugin
from twisted.test.test_plugin import ITestPlugin

@provider(IPlugin, ITestPlugin)
class {}:
    pass
ascii)formatencoderu   s    r   pluginFileContentsr   m  s      
	r   c                   | j                          | j                  d      }|j                          |r |j                  d      j                  d       |j                  d      }|j                          |r$|j                  d      j                  t               |j                  |dz         j                  |       |S )z'
    Create a plugindummy package.
    plugindummyr"   r   rd   .py)r,   r-   r/   pluginInitFile)	entrypathpluginContentrealpluginModulepkgplugss         r   _createPluginDummyr   }  s     
//-
(C		- ++C0IIi E	M"--n=	KKu$%00?Lr   c                      e Zd ZU ded<   y)_HasBoolLegacyKeyr   legacyN)r   r   r   __annotations__r   r   r   r   r     s    Lr   r   c                  `    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y)DeveloperSetupTestsz
    These tests verify things about the plugin system without actually
    interacting with the deployed 'twisted.plugins' package, instead creating a
    temporary package.
    c                :   t         j                  dd | _        t         j                  j	                         | _        t        | j                               | _        | j                  j                          | j                  j                  d      | _        | j                  j                  d      | _        | j                  j                  d      | _        t        | j                  t        d      dd      | _        t        | j                  t        d      dd      | _        t        | j                  t        d	      d
d      | _        t         j                  j'                  | j                  | j                  fD cg c]  }|j                   c}       | j)                          | j                  j                  d      j                  d      | _        | j*                  j                  d      | _        t/        j.                         }t1        j2                  | j*                  j                  d      j                  |dz
  fdz         t1        j2                  | j,                  j                  |dz
  fdz         | j5                          | j7                          yc c}w )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_appr   rd   rS   zplugindummy_builtin.pyi  r~   i  )r$   r%   	savedPathr'   r(   r)   r   r*   fakeRootr,   r-   
systemPathdevPathappPathr   r   systemPackage
devPackage
appPackageextendgetAllPluginssysplugsyscachetimerI   utime
lockSystemresetEnvironment)r6   xnows      r   r7   zDeveloperSetupTests.setUp  s    !KK,,. /%%'----m<}}**+=>}}**+=>/OO/94AV
 -LL,U3T;P
 -LL,U3U<M

 	$//4<<)HIAIJ 	,,];AA)L**>: iik
##$<=BBS4ZMTUDUV
##cDj]Q%67 	 Js   9Jc                    t        j                  | j                  j                  d       t        j                  | j                  j                  d       y)zW
        Lock the system directories, as if they were unwritable by this user.
        im  NrI   r   r   r%   r   r=   s    r   r   zDeveloperSetupTests.lockSystem  4     	""E*
##U+r   c                    t        j                  | j                  j                  d       t        j                  | j                  j                  d       y)zW
        Unlock the system directories, as if they were writable by this user.
        i  Nr   r=   s    r   unlockSystemz DeveloperSetupTests.unlockSystem  r   r   c                    ddl }t        t        j                  t        |j
                              }|D cg c]  }|j                   c}S c c}w )zl
        Get all the plugins loadable from our dummy package, and return their
        short names.
        r   N)plugindummy.pluginsrx   r
   r   r   rd   r   )r6   r   r   plugs       r   r   z!DeveloperSetupTests.getAllPlugins  s<     	#"";0C0CDE*+,$,,,s   Ac                    | j                          t        j                  j                  | j                  | j
                  | j                  fD cg c]  }|j                   c}       yc c}w )zc
        Change the environment to what it should be just as the test is
        starting.
        N)unsetEnvironmentr$   r%   r   r   r   r   )r6   r   s     r   r   z$DeveloperSetupTests.resetEnvironment  sE    
 	$,,)VWAWXWs   A*c                    t                t        j                  j                          t        j                  j	                  | j
                         | j                  t        j                  dd y)zh
        Change the Python environment back to what it was before the test was
        started.
        N)r   r$   r'   r;   r<   r)   r   r%   r=   s    r   r   z$DeveloperSetupTests.unsetEnvironment  sC    
 	 4,,-nnr   c                D    | j                          | j                          y)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=   s    r   r>   zDeveloperSetupTests.tearDown  s     	
 	r   c                    t        d      D ]6  }| j                         }|j                          | j                  |ddg       8 y)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   sortra   )r6   r   r   s      r   "test_developmentPluginAvailabilityz6DeveloperSetupTests.test_developmentPluginAvailability  sB     q 	4A&&(EJJLUUEN3	4r   c                J   | j                   j                  d      }|j                  t        d             t	        j                         dz
  }t        j                  |j                  ||f       |j                  d      }t        d      }t        j                  | j                   j                  fddi| t        j                  |j                  ||f       |j                          | j                          | j                  d| j                                | j!                  d	| j                                | j                          |j                  t        d	             | j!                  d| j                                | j                  d	| j                                y
)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   twoN)r   r-   r/   r   r   rI   r   r%   r1   r   
compileallcompile_dirrJ   r   rb   r   r   )r6   mypathr   pycextras        r   test_freshPyReplacesStalePycz0DeveloperSetupTests.test_freshPyReplacesStalePyc  s5    &&z2,U34IIK$
q!f%nn[) ".t33F1FF
Aq6"eT//12eT//12,U34eT//12eT//12r   c                p   | j                          | j                  j                  d      j                  t	        d             | j                          t        j                  j                  | j                  j                         g }t        |j                         | j                  t        |j                         | j                  d| j                                d| j                   j                  t"        j$                  fz  }|D ]  }t'        |      }|J ||v s y | j)                  d|       y)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%   rJ   r   r   r   r   r   rb   r   r   r   r   r   r   )r6   r   r   r   r   s        r   test_newPluginsOnReadOnlyPathz1DeveloperSetupTests.test_newPluginsOnReadOnlyPath,  s    	=)445G5NO 	))* #%FMM"6eT//12 IMMKKL
 
  		E)%0I(((9$			 II &)r   Nr   )rY   z	list[str])r   r   r   r   r7   r   r   r   r   r   r>   r   r   r  r   r   r   r   r     s<    ( T,,
-Y%43@&r   r   c                  H    e Zd ZdZddZddZ	 	 	 	 	 	 	 	 d	dZddZddZy)
AdjacentPackageTestsz
    Tests for the behavior of the plugin system when there are multiple
    installed copies of the package containing the plugins being loaded.
    c                z    t         j                  dd | _        t         j                  j	                         | _        y)zS
        Save the elements of C{sys.path} and the items of C{sys.modules}.
        N)r$   r%   r&   r'   r(   r)   r=   s    r   r7   zAdjacentPackageTests.setUp[  s)      HHQKKK,,.r   c                    | j                   t        j                  dd t        j                  j	                          t        j                  j                  | j                         yr9   r:   r=   s    r   r>   zAdjacentPackageTests.tearDownb  r?   r   c                   |j                  |      }|j                  d      }|j                          |j                  d      j                  d       |j                  d      }|j                          |j                  d      j                  t               |j                  |dz         }|j                  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   rd   r   )r-   makedirsr/   r   r   )r6   r+   rh   
pluginName	directoryr.   rd   r   s           r   createDummyPackagez'AdjacentPackageTests.createDummyPackagej  s    , JJt$	//'*m$//4--	*m$//?}}Z%%78 24 89r   c                   t        | j                               }|j                          | j                  |dd      }| j                  |dd      }t        j
                  j                  |j
                         t        j
                  j                  |j
                         ddl}t        t        j                  t        |j                              }| j                  dg|D cg c]  }|j                   c}       yc c}w )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   Nr   r*   r  r  r$   r%   r   dummy.pluginsrx   r
   r   r   rd   ra   r   r6   r+   firstDirectorysecondDirectoryr  rd   rn   s          r   .test_hiddenPackageSamePluginModuleNameObscuredzCAdjacentPackageTests.test_hiddenPackageSamePluginModuleNameObscured       &00wM11$,O++,,,-v((emmDE'$AAQZZ$AB$A   $C?
c                   t        | j                               }|j                          | j                  |dd      }| j                  |dd      }t        j
                  j                  |j
                         t        j
                  j                  |j
                         ddl}t        t        j                  t        |j                              }| j                  dg|D cg c]  }|j                   c}       yc c}w )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   Nr  r  s          r   3test_hiddenPackageDifferentPluginModuleNameObscuredzHAdjacentPackageTests.test_hiddenPackageDifferentPluginModuleNameObscured  r  r  Nr   )r+   FilePath[str]rh   strr	  r  rY   r  )	r   r   r   r   r7   r>   r  r  r  r   r   r   r  r  U  sC    
/.!),:=	BC(Cr   r  c                  0    e Zd ZdZddZddZddZddZy)PackagePathTestszg
    Tests for L{plugin.pluginPackagePaths} which constructs search paths for
    plugin packages.
    c                4    t         j                  dd | _        y)z3
        Save the elements of C{sys.path}.
        N)r$   r%   r&   r=   s    r   r7   zPackagePathTests.setUp  s      HHQKr   c                >    | j                   t        j                  dd y)z<
        Restore C{sys.path} to its original value.
        N)r&   r$   r%   r=   s    r   r>   zPackagePathTests.tearDown  s     ''r   c                `   t        d      }t        d      }|j                  |j                  gt        _        | j                  t	        j
                  d      |j                  d      j                  d      j                  |j                  d      j                  d      j                  g       y)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  rd   N)r   r%   r$   ra   r
   pluginPackagePathsr-   )r6   r#  r$  s      r   test_pluginDirectoriesz'PackagePathTests.test_pluginDirectories  s     uouoHHchh'%%o6		'"((388		'"((388	
r   c                ,   t        | j                               }|j                  d      j                  d      j                  d      }|j                          |j                  d      j	                  d       |j                  d      j
                  |j                  d      j
                  gt        _        | j                  t        j                  d      |j                  d      j                  d      j                  d      j
                  g       y)	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  rd   r"   r   r$  r%  N)
r   r*   r-   r  r/   r%   r$   ra   r
   r&  )r6   r+   r#  s      r   test_pluginPackagesExcludedz,PackagePathTests.test_pluginPackagesExcluded  s     &jj%%g.44Y?		- ++C0JJu%**DJJu,=,B,BC%%o6ZZ$$W-33I>CCD	
r   Nr   )r   r   r   r   r7   r>   r'  r)  r   r   r   r  r    s    
((
"
r   r  )rh   r  rY   bytes)
r   r  r   r*  r   r   r   r  rY   r  )+r   
__future__r   r   r   r[   rI   r$   r   	importlibr   r   typesr   typingr   r   r   zope.interfacer	   twistedr
   twisted.python.filepathr   twisted.python.logr   r   r   r   twisted.trialr   r   r   r   TestCaser   r   r   r   r   r   r  r  r   r   r   <module>r5     s   
 #    	 
  A  / / $  , X X "T]) 9 v(## vt	 -2:>NQ&	 ~(++ ~B\C8,, \C~4
x(( 4
r   