Ë
    oj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__© ó    ú:/usr/lib/python3/dist-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ë   € ô  ŸH™H¡Q˜KˆÔÜŸK™K×,Ñ,Ó.ˆÔä˜TŸ[™[›]Ó+ˆŒ	Ø�	‰	×!Ñ!Ô#Ø—y‘y—‘ {Ó3ˆŒØ�‰×$Ñ$Ô&Ø�‰×Ñ˜=Ó)×4Ñ4°SÔ9ä”Ó×"Ñ"Ð#4Ó5×<Ñ<Ø�L‰L×Ñ˜Ó/ô	
ð +ˆÔä�‰�‰˜˜4Ÿ9™9Ÿ>™>Ô*Ûàˆ�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Ó/ˆ
Ø—h‘h˜z¨#¨2˜Ó/ˆØ ‘^ˆ
ä”—‘˜KÑ(¨*Ô5Ü�K‰K˜Ÿ™Ð(Ø˜�: Ò!6°2°$Ò!<¸"Ñ=ò 	ˆ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¸×9LÑ9LÐ8MÐ,NÔOØ�‰Ð+¨V×-?Ñ-?Ô@ð  Ÿ™ÖE�A¬;¸!¿*¹*Ò+DŠaÒEÀaÑHˆØ�‰�b—i‘i Ô(Ø×Ñ˜Ÿ™ ,Ô/ð 	×ÑØ�N‰N× Ñ Ó"Ð$Pô	
ð 	×Ñ˜Ÿ™¤{´F·N±NÐ&CÔDØ—W‘W“Yˆ
à�‰ØÜ�K‰K˜* 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 !¸q¿v¹vÈÓ?UœAÑVùs   ‚—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§{¡{Ó3°D×4GÑ4GÑ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Ø�L‰L˜Ÿ™Ô$Ø�F‰F�Hñ	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×=Ñ=Ø�L‰L×ÑÐ/Ó0ô	
ð	Sà�M‰MÐ1´3·;±;Ô?Ø×ÑÜœŸ™ KÑ0°-Ó@Ø8ôô
 œ×)Ñ)¬+°t·{±{ÓCÓDˆDð ×ÑœS ›Y¨Ô*à!Ð#5Ð6ˆEØò �Ø—‘˜QŸZ™ZÔ(Ø—‘•	ñð ×&Ñ&¤s§{¡{Ð3JÑ'KÈTÕRøˆD×&Ñ&¤s§{¡{Ð3JÑ'KÈTÕRús   Á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×=Ñ=Ø�L‰L×ÑÐ/Ó0ô	
ð	SÜœ×)Ñ)¬+°t·{±{ÓCÓDˆDà×ÑœS ›Y¨Ô*ä”XÓ×&Ñ&Ð'9Ó:×AÑAØ—‘×"Ñ"Ð#3Ó4ôð
 ×&Ñ&¤s§{¡{Ð3JÑ'KÔLô œ×)Ñ)¬+°t·{±{ÓCÓDˆDà×ÑœS ›Y¨Ô*âIˆEØò �Ø—‘˜QŸZ™ZÔ(Ø—‘•	ñð ×&Ñ&¤s§{¡{Ð3JÑ'KÈTÕRøˆD×&Ñ&¤s§{¡{Ð3JÑ'KÈTÕRús   Á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×=Ñ=Ø�L‰L×ÑÐ/Ó0ô	
ð	Sä”×"Ñ"¤;°·±Ó<Ô=ð ×&Ñ&¤s§{¡{Ð3JÑ'KÈTÔRÜ”F×%Ñ%¤k°4·;±;Ó?Ó@ˆØ×Ñ˜œC ›IÕ&øð ×&Ñ&¤s§{¡{Ð3JÑ'KÈTÕRús   Á-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ÓDˆDØ×ÑœS ›Y¨Ô*à�K‰K× Ñ ×'Ñ'¨Õ-øˆD�K‰K× Ñ ×'Ñ'¨Õ-ú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ÓDˆDØ×ÑœS ›Y¨Ô*à�K‰K× Ñ ×'Ñ'¨Õ.øˆD�K‰K× Ñ ×'Ñ'¨Õ.ú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 %dNú9Did 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†  € ô 	�‰˜Ÿ™Ô$à—L‘L×&Ñ& ~Ó6ˆ	ô 	”Ó×"Ñ"Ð#5Ó6×=Ñ=Ø�L‰L×ÑÐ/Ó0ô	
ô 	Ô ä
�‰�—‘×"Ñ" EÔ*ä
�‰�—‘ Ô'Ø�‰œŸ™ $§,¡,×"3Ñ"3°UÔ;Ø�‰œŸ™ )§.¡.°%Ô8ð #%ˆÜ�F—M‘MÔ"Ø�‰œ¨¯©Ô6ä—‘ §¡Ó,ˆà�‰�m UÔ+Ø�‰�d×)Ñ)¨5Ô1ð IØ�N‰NÜ�K‰KðL
ñ 
ˆð ò 		ˆEÜ)¨%Ó0ˆIØÐ(Ð(Ð(Ø˜9Ò$Ùð			ð �IŠIá &ð)õ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ó ð"1óH
ð òó ðð  òSó ðSð: òSó ðSð@ ò'ó ð'ð" ò.ó ð.ð ò/ó ð/ô /r   r   sj   
from twisted.plugin import pluginPackagePaths
__path__.extend(pluginPackagePaths(__name__))
__all__ = []
c                óB   — dj                  | «      j                  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Ú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Ø�I‰I�iÓ €EØ	×ÑÔÙØ�‰�MÓ"×-Ñ-¬nÔ=Ø	‡K�K�˜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ä  € ô Ÿ™¡!˜ˆŒÜŸK™K×,Ñ,Ó.ˆÔÜ  §¡£Ó/ˆŒØ�‰×%Ñ%Ô'ØŸ-™-×-Ñ-¨mÓ<ˆŒØ—}‘}×*Ñ*Ð+=Ó>ˆŒØ—}‘}×*Ñ*Ð+=Ó>ˆŒÜ/Ø�O‰OÔ/°Ó9¸4ÐAVó
ˆÔô -Ø�L‰LÔ,¨UÓ3°TÐ;Pó
ˆŒô -Ø�L‰LÔ,¨UÓ3°UÐ<Mó
ˆŒô
 	�‰�‰¨$¯/©/¸4¿<¹<Ð)HÖI A˜Ÿ›ÒIÔJð 	×ÑÔØ—‘×,Ñ,¨]Ó;×AÑAÀ)ÓLˆŒØŸ™×*Ñ*¨>Ó:ˆŒô �i‰i‹kˆÜ
�‰�—‘×#Ñ#Ð$<Ó=×BÑBÀSÈ4ÁZÀMÐTUÑDUÔVÜ
�‰�—‘×#Ñ# c¨D¡j ]°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<   € ó 	#ä”×"Ñ"¤;°×0CÑ0CÓ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ÖW A˜Ÿ›Ò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×,Ñ,Ô-Ø—n‘nŒ�‰‘‰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“ò 	4ˆAØ×&Ñ&Ó(ˆEØ�J‰JŒLØ×Ñ˜U U¨E NÕ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ä�I‰I‹K˜$ÑˆÜ
�‰�—‘˜q !˜fÔ%Ø�n‰n˜[Ó)ˆô "¨Ô.ˆÜ×Ñ˜tŸ™×3Ñ3ÑF¸1ÐFÀÒFÜ
�‰�—‘˜A˜q˜6Ô"à�‰Œà×ÑÔà�‰�e˜T×/Ñ/Ó1Ô2Ø�‰�e˜T×/Ñ/Ó1Ô2Ø×ÑÔØ×ÑÔ,¨UÓ3Ô4Ø�‰�e˜T×/Ñ/Ó1Ô2Ø�‰�e˜T×/Ñ/Ó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Ñ4Ô5GÈÓ5NÔOØ�‰Ôô 	�‰�‰˜Ÿ™×)Ñ)Ô*ð #%ˆÜ�F—M‘MÔ"Ø�‰œ¨¯©Ô6à�‰�e˜T×/Ñ/Ó1Ô2ð IØ�M‰M×ÑÜ�K‰KðL
ñ 
ˆð ò 		ˆEÜ)¨%Ó0ˆIØÐ(Ð(Ð(Ø˜9Ò$Ùð			ð �IŠIá &ð)õ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)   € ô  ŸH™H¡Q˜KˆÔÜŸK™K×,Ñ,Ó.ˆÕ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¡   € ð, —J‘J˜tÓ$ˆ	Ø—/‘/ 'Ó*ˆØ×ÑÔØ�‰�mÓ$×/Ñ/°Ô4Ø—-‘- 	Ó*ˆØ×ÑÔØ�‰�mÓ$×/Ñ/´Ô?Ø—}‘} Z°%Ñ%7Ó8ˆØ×ÑÔ 2°4Ó 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×(Ñ(¬°e·m±mÓDÓEˆØ×Ñ˜'˜¸Ö$A°A Q§Z£ZÒ$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   € ô  ŸH™H¡Q˜KˆÕ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…   € ô �u‹oˆÜ�u‹oˆØ—H‘H˜cŸh™hÐ'ŒŒØ×ÑÜ×%Ñ% 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É   € ô ˜Ÿ™›Ó&ˆØ�j‰j˜Ó×%Ñ% gÓ.×4Ñ4°YÓ?ˆØ�‰ŒØ�	‰	�-Ó ×+Ñ+¨CÔ0Ø—J‘J˜uÓ%×*Ñ*¨D¯J©J°uÓ,=×,BÑ,BÐCŒŒØ×ÑÜ×%Ñ% oÓ6Ø�Z‰Z˜Ó×$Ñ$ WÓ-×3Ñ3°IÓ>×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   