+
    üÐjh  ã                  óÐ  € R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t ^ RIHt ^ RIHtHtHt ^ RIHt ^ RIHt ^ RIHt ^ R	IHtHtHtHt ^ R
IHt ]! R4      t ! R R]4      t  ! R R]4      t! ! R R]PD                  4      t#Rt$R R lt%R R lt& ! R R]4      t' ! R R]PD                  4      t( ! R R]PD                  4      t) ! R R]PD                  4      t*R# )z"
Tests for Twisted plugin system.
)ÚannotationsN)Úinvalidate_caches)Ú
ModuleType)ÚCallableÚ	TypedDictÚTypeVar)Ú	Interface)Úplugin)ÚFilePath)Ú	EventDictÚaddObserverÚremoveObserverÚtextFromEventDict)ÚunittestÚ_Tc                  ó   € ] tR t^tRtRtR# )ÚITestPluginzG
A plugin for use by the plugin system's unit tests.

Do not use this.
© N©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__static_attributes__r   ó    Ú:/usr/lib/python3/dist-packages/twisted/test/test_plugin.pyr   r      s   † õr   r   c                  ó   € ] tR t^&tRtRtR# )ÚITestPlugin2z
See L{ITestPlugin}.
r   Nr   r   r   r   r   r   &   s   † õr   r   c                  ó  € ] tR t^,tRtR R ltR R ltR R R lltR R	 ltR
 R lt	]	R R l4       t
R R lt]	R R l4       t]	R R l4       t]	R R l4       t]	R R l4       t]	R R l4       t]	R R l4       tR R ltRtR# )!ÚPluginTestszS
Tests which verify the behavior of the current, active Twisted plugins
directory.
c               ó   € V ^8„  d   QhRR/# ©é   ÚreturnÚNoner   )Úformats   "r   Ú__annotate__ÚPluginTests.__annotate__2   s   € ÷  ñ  �tñ  r   c                óÒ  € \         P                  R,          V n        \         P                  P	                  4       V n        \        V P                  4       4      V n        V P                  P                  4        V P                  P                  R4      V n        V P                  P                  4        V P                  P                  R4      P                  R4       \        \        4      P                  R4      P                  V P                  P                  R4      4       RV n        \         P                  P#                  ^ V P                  P                  4       ^ RIpWn        R# )	zF
Save C{sys.path} and C{sys.modules}, and create a package for tests.
ºNNNÚ	mypackageú__init__.pyr   zplugin_basic.pyztestplugin.pyÚ
testpluginN)ÚsysÚpathÚoriginalPathÚmodulesÚcopyÚsavedModulesr
   ÚmktempÚrootÚcreateDirectoryÚchildÚpackageÚ
setContentÚ__file__ÚsiblingÚcopyToÚoriginalPluginÚinsertr+   Úmodule)Úselfr+   s   & r   ÚsetUpÚ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               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   J   ó   € ÷ .ñ .˜$ñ .r   c                óÎ   € V P                   \        P                  R&   \        P                  P	                  4        \        P                  P                  V P                  4       R# ©zB
Restore C{sys.path} and C{sys.modules} to their original values.
r*   N©r0   r.   r/   r1   ÚclearÚupdater3   ©r@   s   &r   ÚtearDownÚPluginTests.tearDownJ   ó?   € ð ×'Ñ'Œ�‰�‰Ü�‰×ÑÔÜ�‰×Ñ˜4×,Ñ,Ö-r   c               ó$   € V ^8„  d   QhRRRRRR/# )r#   r?   r   ÚdeleteSourceÚboolr$   r%   r   )r&   s   "r   r'   r(   R   s$   € ÷ ñ Ø ðØ04ðà	ñr   c                	óÐ  € VP                   f   Q hVP                  P                  R4      pRP                  VR R 4      pVR,          p\	        \
        P                  V,          V4       \
        P                  VP                   RR.T;'       d    R.;'       g    . ,            F+  p \        P                  ! VP                   V,           4       K-  	  R #   \         d     K?  i ; i)NÚ.ÚcÚoÚ éÿÿÿÿ)
r:   r   ÚsplitÚjoinÚdelattrr.   r1   ÚosÚremoveÚFileNotFoundError)r@   r?   rO   Ú
modulePathÚpackageNameÚ
moduleNameÚexts   &&&    r   Ú_unimportPythonModuleÚ!PluginTests._unimportPythonModuleR   s¾   € ð �‰Ò*Ð*Ð*Ø—_‘_×*Ñ*¨3Ó/ˆ
Ø—h‘h˜z¨#¨2˜Ó/ˆØ •^ˆ
ä”—‘˜KÕ(¨*Ô5Ü�K‰K˜Ÿ™Ð(Ø˜�: ×!6Ð!6°2°$×!<Ð!<¸"×=Ð=ˆCðÜ—	’	˜&Ÿ/™/¨CÕ/Ö0ó >øô %ô Úðús   Â)'CÃC%Ã$C%c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   b   s   € ÷ 4ñ 4˜Tñ 4r   c                óX   € V P                   P                  R4      P                  4        R# )z+
Remove the plugins B{droping.cache} file.
údropin.cacheN)r8   r7   r[   rJ   s   &r   Ú_clearCacheÚPluginTests._clearCacheb   s   € ð 	�‰×Ñ˜>Ó*×1Ñ1Ö3r   c               ó    € V ^8„  d   QhRRRR/# )r#   ÚmethzCallable[[PluginTests], object]r$   zCallable[[PluginTests], None]r   )r&   s   "r   r'   r(   h   s   € ÷ ñ Ø-ðà	&ñr   c                óL   a € \         P                  ! S 4      R V 3R ll4       pV# )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               ó    € V ^8„  d   QhRRRR/# )r#   r@   r    r$   r%   r   )r&   s   "r   r'   Ú0PluginTests._withCacheness.<locals>.__annotate__s   s   € ÷ 	ñ 	˜+ð 	¨$ñ 	r   c                óh   <€ S! V 4       S! V 4       V P                  4        S! V 4       S! V 4       R # )N)rf   )r@   ri   s   &€r   ÚwrappedÚ+PluginTests._withCacheness.<locals>.wrappedr   s+   ø€ á�ŒJÙ�ŒJØ×ÑÔÙ�ŒJÙ�ŽJr   )Ú	functoolsÚwraps)ri   rn   s   f r   Ú_withCachenessÚPluginTests._withCachenessh   s'   ø€ ô 
�Š˜Ó	÷	ó 
ð	ð ˆr   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   }   s   € ÷ "1ñ "1˜Dñ "1r   c                ót  € \         P                  ! V P                  4      pWP                  ,          pV P	                  VP
                  RV P                   24       V P                  RVP                  4       VP                   Uu. uF  p\        VP                  9   g   K  VNK  	  up^ ,          pV P                  VP                  V4       V P	                  VP                  R4       V P	                  VP                  P                  4       R4       V P	                  VP                  \        \         P                  .4       VP!                  4       pV P                  V\"        P$                  RV P                   2,          P&                  4       ^ RIHp V P                  WVP&                  4       R# u upi )zá
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.Ú
TestPluginz*A plugin used solely for testing purposes.N)r	   ÚgetCacher?   r=   ÚassertEqualr_   ÚassertInÚdescriptionÚpluginsr   ÚprovidedÚassertIsÚdropinÚnameÚstripÚIPluginÚloadr.   r1   rv   Úmypackage.testpluginr-   )r@   Úcacher~   ÚpÚp1Ú
realPluginÚtps   &      r   Ú
test_cacheÚPluginTests.test_cache|   sF  € ô —’ §¡Ó,ˆà×*Ñ*Õ+ˆØ×Ñ˜×*Ñ*¨j¸×9LÑ9LÐ8MÐ,NÔOØ�‰Ð+¨V×-?Ñ-?Ô@ð  ŸšÓE™�A¬;¸!¿*¹*Ñ+D�aˆ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   ÂF5Â"F5c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   ¡   s   € ÷ 
ñ 
 ñ 
r   c                óä   € \         P                  ! V P                  4      V P                  ,          p\	        R VP
                   4       4      ^ ,          pV P                  \        V4      R4       R# )zU
L{CachedPlugin} has a helpful C{repr} which contains relevant
information about it.
c              3  óJ   "  € T F  qP                   R 8X  g   K  Vx € K  	  R# 5i)rv   N©r   )Ú.0r…   s   & r   Ú	<genexpr>Ú-PluginTests.test_cacheRepr.<locals>.<genexpr>§   s   é € ÐVÑ'; !¿v¹vÈÑ?UŸAšAÓ';ùs   ‚#™
#zT<CachedPlugin 'TestPlugin'/'mypackage.testplugin' (provides 'ITestPlugin, IPlugin')>N)r	   rw   r?   r=   Úlistr{   rx   Úrepr)r@   ÚcachedDropinÚcachedPlugins   &  r   Útest_cacheReprÚPluginTests.test_cacheRepr¡   s\   € ô
 —’ t§{¡{Ó3°D×4GÑ4GÕHˆÜÑV |×';Ò';ÓVÓVØõ
ˆð 	×ÑÜ�Óð1ö	
r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   ±   s   € ÷ ñ ˜dñ r   c                ó  € \        \        P                  ! \        V P                  4      4      pV P                  \        V4      ^4       RR.pV F.  pVP                  VP                  4       VP                  4        K0  	  R# )zò
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)
r’   r	   Ú
getPluginsr   r?   rx   Úlenr[   r   Útest)r@   r{   Únamesr…   s   &   r   Útest_pluginsÚPluginTests.test_plugins°   sa   € ô ”v×(Ò(¬°t·{±{ÓCÓDˆà×Ñœ˜W› qÔ)à$Ð&7Ð8ˆÛˆAØ�L‰L˜Ÿ™Ô$Ø�F‰FŽHó r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   Â   s   € ÷ Sñ S Tñ Sr   c                óÞ  € \        \        4      P                  R4      P                  V P                  P                  R4      4        V P                  R\        P                  4       V P                  \        \        P                  R,          R4      R4       \        \        P                  ! \        V P                  4      4      pV P!                  \#        V4      ^4       RR.pV F.  pVP%                  VP&                  4       VP)                  4        K0  	  V P+                  \        P                  R,          R	4       R
#   T P+                  \        P                  R,          R	4       i ; i)zM
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 modulerv   ÚFourthTestPluginTN)r
   r:   r;   r<   r8   r7   ÚfailIfInr.   r1   ÚassertFalseÚhasattrr’   r	   rœ   r   r?   rx   r�   r[   r   Útest1ra   ©r@   ÚplgsrŸ   r…   s   &   r   Útest_detectNewFilesÚ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E Å)E,c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   à   s   € ÷ Sñ S¨ñ Sr   c                ó¦  € \        \        4      P                  R4      P                  V P                  P                  R4      4        \        \        P                  ! \        V P                  4      4      pV P                  \        V4      ^4       \        \        4      P                  R4      P                  V P                  P                  R4      4       V P                  \        P                  R,          4       \        \        P                  ! \        V P                  4      4      pV P                  \        V4      ^4       . ROpV F.  pVP!                  VP"                  4       VP%                  4        K0  	  V P                  \        P                  R,          R4       R#   T P                  \        P                  R,          R4       i ; i)zm
Check that if the content of a plugin change, L{plugin.getPlugins} is
able to detect the new plugins added.
r¤   r¥   zplugin_extra2.pyr¦   TN)rv   r¨   ÚFifthTestPlugin)r
   r:   r;   r<   r8   r7   r’   r	   rœ   r   r?   rx   r�   ra   r.   r1   r[   r   r¬   r­   s   &   r   Útest_detectFilesChangedÚ#PluginTests.test_detectFilesChangedß   sG  € ô 	”Ó×"Ñ"Ð#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   ÁD6F' Æ')Gc               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(     s   € ÷ 'ñ '¨ñ 'r   c                ó(  € \        \        4      P                  R4      P                  V P                  P                  R4      4        \        \        P                  ! \        V P                  4      4       V P                  \        P                  R,          R4       \        \        P                  ! \        V P                  4      4      pV P                  ^\        V4      4       R#   T P                  \        P                  R,          R4       i ; i)z[
Check that when a dropin file is removed, L{plugin.getPlugins} doesn't
return it anymore.
r¤   r¥   r¦   TN)r
   r:   r;   r<   r8   r7   r’   r	   rœ   r   r?   ra   r.   r1   rx   r�   )r@   r®   s   & r   Útest_detectFilesRemovedÚ#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               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(     s   € ÷ .ñ .¨4ñ .r   c                óþ  € V P                  4       pV P                  \        P                  P	                  V4      4       V P
                  P                  P                  V4        \        \        P                  ! \        V P
                  4      4      pV P                  \        V4      ^4       V P
                  P                  P                  V4       R#   T P
                  P                  P                  T4       i ; i)za
Test that getCache skips over any entries in a plugin package's
C{__path__} which do not exist.
N)r4   rª   rZ   r/   Úexistsr?   Ú__path__Úappendr’   r	   rœ   r   rx   r�   r[   )r@   r/   r®   s   &  r   Útest_nonexistentPathEntryÚ%PluginTests.test_nonexistentPathEntry  s§   € ð �{‰{‹}ˆØ×ÑœŸ™Ÿ™¨Ó-Ô.à�‰×Ñ×#Ñ# DÔ)ð	.Üœ×)Ò)¬+°t·{±{ÓCÓDˆDØ×ÑœS ›Y¨Ô*à�K‰K× Ñ ×'Ñ'¨Ö-øˆD�K‰K× Ñ ×'Ñ'¨Õ-ús   Á%A	C Ã'C<c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   #  s   € ÷ /ñ /¨Tñ /r   c                óH  € \        V P                  4       4      pV P                  VP                  4       4       VP	                  4        VP                  R4      P                  pV P                  P                  P                  V4        \        \        P                  ! \        V P                  4      4      pV P                  \        V4      ^4       V P                  P                  P!                  V4       R#   T P                  P                  P!                  T4       i ; i)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_packageN)r
   r4   rª   r¼   Útouchr7   r/   r?   r½   r¾   r’   r	   rœ   r   rx   r�   r[   )r@   r/   r7   r®   s   &   r   Útest_nonDirectoryChildEntryÚ'PluginTests.test_nonDirectoryChildEntry"  sÂ   € ô ˜Ÿ™›Ó&ˆØ×Ñ˜Ÿ™›Ô'Ø�
‰
ŒØ—
‘
˜>Ó*×/Ñ/ˆØ�‰×Ñ×#Ñ# EÔ*ð	/Üœ×)Ò)¬+°t·{±{ÓCÓDˆDØ×ÑœS ›Y¨Ô*à�K‰K× Ñ ×'Ñ'¨Ö.øˆD�K‰K× Ñ ×'Ñ'¨Õ.ús   Â
A	C: Ã:'D!c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   r(   3  s   € ÷ /ñ / 4ñ /r   c                ó4  € \         P                  ! V P                  4       V P                  P	                  R4      p\        \        4      P                  R4      P                  V P                  P	                  R4      4       \        4        \        P                  ! V P                  P                  R4       \        P                  ! VP                  R4       V P                  \        P                  V P                  P                  R4       V P                  \        P                  VP                  R4       . p\        VP                  4       V P                  \         VP                  4       \         P                  ! V P                  4      pV P#                  RV4       V P#                  V P$                  V4       RVP                  \&        P(                  3,          pV F  p\+        V4      pVf   Q hWF9   g   K   R	# 	  V P-                  R
V: 24       R	# )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.
re   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	   rw   r?   r8   r7   r
   r:   r;   r<   ÚinvalidateImportCachesrZ   Úchmodr/   Ú
addCleanupr   r¾   r   ry   r=   ÚerrnoÚEPERMr   Úfail)r@   Ú	cachepathÚeventsr„   ÚexpectedÚeventÚ	maybeTexts   &      r   Útest_deployedModeÚ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ØÒ(Ð(Ð(ØÖ$Úñ	 ð �IŠIâ &ð)ör   )r?   r0   r=   r8   r5   r3   N)F)r   r   r   r   r   rA   rK   ra   rf   rr   r‰   r–   r    r¯   r´   r¸   r¿   rÅ   r×   r   r   r   r   r    r    ,   sÁ   † ñõ
 õ0.÷õ 4õð( ô"1ó ð"1õH
ð ôó ðð  ôSó ðSð: ôSó ðSð@ ô'ó ð'ð" ô.ó ð.ð ô/ó ð/÷ /ñ /r   r    sj   
from twisted.plugin import pluginPackagePaths
__path__.extend(pluginPackagePaths(__name__))
__all__ = []
c               ó    € V ^8„  d   QhRRRR/# )r#   r   Ústrr$   Úbytesr   )r&   s   "r   r'   r'   m  s   € ÷ ñ ˜Sð  Uñ r   c                óB   € R P                  V 4      P                  R4      # )z¬from zope.interface import provider
from twisted.plugin import IPlugin
from twisted.test.test_plugin import ITestPlugin

@provider(IPlugin, ITestPlugin)
class {}:
    pass
Úascii)r&   ÚencoderŽ   s   &r   ÚpluginFileContentsrß   m  s    € ð÷ 
‰�‹ß	‰�‹ðr   c          
     ó,   € V ^8„  d   QhRRRRRRRRR	R/# )
r#   Ú	entrypathúFilePath[str]ÚpluginContentrÛ   ÚrealrP   ÚpluginModulerÚ   r$   r   )r&   s   "r   r'   r'   }  s4   € ÷ ñ ØðØ-2ðØ:>ðØNQðàñr   c                ó   € V P                  4        V P                  R4      pVP                  4        V'       d!   VP                  R4      P                  R4       VP                  R4      pVP                  4        V'       d%   VP                  R4      P                  \        4       VP                  VR,           4      P                  V4       V# )z
Create a plugindummy package.
Úplugindummyr,   r   r{   ú.py)r6   r7   r9   ÚpluginInitFile)rá   rã   rä   rå   ÚpkgÚplugss   &&&&  r   Ú_createPluginDummyrì   }  s™   € ð ×ÑÔØ
�/‰/˜-Ó
(€CØ×ÑÔßØ�	‰	�-Ó ×+Ñ+¨CÔ0Ø�I‰I�iÓ €EØ	×ÑÔßØ�‰�MÓ"×-Ñ-¬nÔ=Ø	‡K�K�˜uÕ$Ó%×0Ñ0°Ô?Ø€Lr   c                  ó"   € ] tR tRt$ R]R&   RtR# )Ú_HasBoolLegacyKeyi�  rP   Úlegacyr   N)r   r   r   r   Ú__annotations__r   r   r   r   rî   rî   �  s   ‡ Ø‡Lr   rî   c                  ó’   € ] tR tRtRtR R ltR R ltR R ltR	 R
 ltR R lt	R R lt
R R ltR R ltR R ltR R ltRtR# )ÚDeveloperSetupTestsi”  z£
These tests verify things about the plugin system without actually
interacting with the deployed 'twisted.plugins' package, instead creating a
temporary package.
c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   Ú DeveloperSetupTests.__annotate__›  s   € ÷ ( ñ ( �tñ ( r   c                ól  € \         P                  R,          V n        \         P                  P	                  4       V n        \        V P                  4       4      V n        V P                  P                  4        V P                  P                  R4      V n        V P                  P                  R4      V n        V P                  P                  R4      V n        \        V P                  \        R4      RR4      V n        \        V P                  \        R4      RR4      V n        \        V P                  \        R	4      R
R4      V n        \         P                  P'                  V P                  V P                  3 Uu. uF  qP                  NK  	  up4       V P)                  4        V P                  P                  R4      P                  R4      V n        V P*                  P                  R4      V n        \.        P.                  ! 4       p\0        P2                  ! V P*                  P                  R4      P                  VR,
          3^,          4       \0        P2                  ! V P,                  P                  VR,
          3^,          4       V P5                  4        V P7                  4        R# u upi )a  
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.
r*   Úsystem_pathÚdevelopment_pathÚapplication_pathÚsystemTÚplugindummy_builtinÚdevÚappFÚplugindummy_apprç   r{   re   zplugindummy_builtin.pyiˆ  iÐ  N)r.   r/   Ú	savedPathr1   r2   r3   r
   r4   ÚfakeRootr6   r7   Ú
systemPathÚdevPathÚappPathrì   rß   ÚsystemPackageÚ
devPackageÚ
appPackageÚextendÚgetAllPluginsÚsysplugÚsyscacheÚtimerZ   ÚutimeÚ
lockSystemÚresetEnvironment)r@   ÚxÚnows   &  r   rA   Ú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Ñ)H AŸœÑ)HÑ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   Å=J1c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô   Å  s   € ÷ ,ñ ,˜Dñ ,r   c                ó²   € \         P                  ! V P                  P                  R4       \         P                  ! V P                  P                  R4       R# )zG
Lock the system directories, as if they were unwritable by this user.
im  N©rZ   rÍ   r  r/   r	  rJ   s   &r   r  ÚDeveloperSetupTests.lockSystemÅ  ó4   € ô 	�Š�—‘×"Ñ" EÔ*Ü
�Š�—‘×#Ñ# UÖ+r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô   Ì  s   € ÷ ,ñ ,˜dñ ,r   c                ó²   € \         P                  ! V P                  P                  R4       \         P                  ! V P                  P                  R4       R# )zG
Unlock the system directories, as if they were writable by this user.
iÿ  Nr  rJ   s   &r   ÚunlockSystemÚ DeveloperSetupTests.unlockSystemÌ  r  r   c               ó   € V ^8„  d   QhRR/# )r#   r$   z	list[str]r   )r&   s   "r   r'   rô   Ó  s   € ÷ 
-ñ 
-˜yñ 
-r   c                ó¦   € ^ RI p\        \        P                  ! \        VP
                  4      4      pV Uu. uF  q3P                  NK  	  up# u upi )zT
Get all the plugins loadable from our dummy package, and return their
short names.
N)Úplugindummy.pluginsr’   r	   rœ   r   r{   r   )r@   rç   r  Úplugs   &   r   r  Ú!DeveloperSetupTests.getAllPluginsÓ  s>   € ó 	#ä”×"Ò"¤;°×0CÑ0CÓDÓEˆÙ*+Ó,©! $—”©!Ñ,Ð,ùÒ,s   ·Ac               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô   ß  s   € ÷ Yñ Y $ñ Yr   c                óâ   € V P                  4        \        P                  P                  V P                  V P
                  V P                  3 Uu. uF  qP                  NK  	  up4       R# u upi )zK
Change the environment to what it should be just as the test is
starting.
N)ÚunsetEnvironmentr.   r/   r  r  r   r  )r@   r  s   & r   r  Ú$DeveloperSetupTests.resetEnvironmentß  sI   € ð
 	×ÑÔÜ�‰�‰¨$¯,©,¸¿¹ÈÏÉÑ)VÓWÑ)V AŸœÑ)VÑWÖXùÒWs   ÁA,c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô   ç  s   € ÷ %ñ % $ñ %r   c                óâ   € \        4        \        P                  P                  4        \        P                  P	                  V P
                  4       V P                  \        P                  R&   R# )zP
Change the Python environment back to what it was before the test was
started.
r*   N)rÌ   r.   r1   rH   rI   r3   rþ   r/   rJ   s   &r   r!  Ú$DeveloperSetupTests.unsetEnvironmentç  sC   € ô
 	Ô Ü�‰×ÑÔÜ�‰×Ñ˜4×,Ñ,Ô-Ø—n‘nŒ�‰�‹r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô   ñ  s   € ÷ ñ ˜$ñ r   c                óF   € V P                  4        V P                  4        R# )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  rJ   s   &r   rK   ÚDeveloperSetupTests.tearDownñ  s   € ð 	×ÑÔð
 	×ÑÖr   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô   þ  s   € ÷ 4ñ 4°Dñ 4r   c                ó’   € \        ^4       F7  pV P                  4       pVP                  4        V P                  VRR.4       K9  	  R# )zì
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û   N)Úranger  Úsortrx   )r@   r  rŸ   s   &  r   Ú"test_developmentPluginAvailabilityÚ6DeveloperSetupTests.test_developmentPluginAvailabilityþ  s=   € ô �q–ˆAØ×&Ñ&Ó(ˆEØ�J‰JŒLØ×Ñ˜U U¨E NÖ3ó r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô     s   € ÷ 3ñ 3¨dñ 3r   c                óX  € V P                   P                  R4      pVP                  \        R4      4       \        P                  ! 4       R,
          p\
        P                  ! VP                  W"34       VP                  R4      p\        RR7      p\        P                  ! V P                   P                  3R^/VB  \
        P                  ! VP                  W"34       VP                  4        V P                  4        V P                  RV P                  4       4       V P!                  RV P                  4       4       V P                  4        VP                  \        R4      4       V P!                  RV P                  4       4       V P                  RV P                  4       4       R	# )
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ï   ÚquietÚtwoN)r  r7   r9   rß   r
  rZ   r  r/   r;   rî   Ú
compileallÚcompile_dirr[   r  ry   r  r©   )r@   Úmypathr  ÚpycÚextras   &    r   Útest_freshPyReplacesStalePycÚ0DeveloperSetupTests.test_freshPyReplacesStalePyc  s1  € ð —‘×&Ñ& zÓ2ˆØ×ÑÔ,¨UÓ3Ô4ä�IŠI‹K˜$ÕˆÜ
�Š�—‘˜q˜fÔ%Ø�n‰n˜[Ó)ˆô "¨Ô.ˆÜ×Ò˜tŸ™×3Ñ3ÑF¸1ÐFÀÒFÜ
�Š�—‘˜A˜6Ô"à�‰Œà×ÑÔà�‰�e˜T×/Ñ/Ó1Ô2Ø�‰�e˜T×/Ñ/Ó1Ô2Ø×ÑÔØ×ÑÔ,¨UÓ3Ô4Ø�‰�e˜T×/Ñ/Ó1Ô2Ø�‰�e˜T×/Ñ/Ó1Ö2r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rô   ,  s   € ÷ &ñ &¨tñ &r   c                óŠ  € V P                  4        V P                  P                  R4      P                  \	        R4      4       V P                  4        \        P                  P                  V P                  P                  4       . p\        VP                  4       V P                  \        VP                  4       V P                  RV P                  4       4       RV P                   P                  \"        P$                  3,          pV F  p\'        V4      pVf   Q hW$9   g   K   R# 	  V P)                  RV: 24       R# )a  
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.pyr1  rÊ   NrË   )r  r  r7   r9   rß   r  r.   r/   r[   r  r   r¾   rÎ   r   ry   r  r	  rÏ   rÐ   r   rÑ   )r@   rÓ   rÔ   rÕ   rÖ   s   &    r   Útest_newPluginsOnReadOnlyPathÚ1DeveloperSetupTests.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ØÒ(Ð(Ð(ØÖ$Úñ	 ð �IŠIâ &ð)ör   )r  r  r  r  rÿ   r3   rþ   r	  r  r  r   N)r   r   r   r   r   rA   r  r  r  r  r!  rK   r-  r9  r=  r   r   r   r   rò   rò   ”  sA   † ñõ( õT,õ,õ
-õYõ%õõ4õ3÷@&ñ &r   rò   c                  óV   € ] tR tRtRtR R ltR R ltR R ltR	 R
 ltR R lt	Rt
R# )ÚAdjacentPackageTestsiU  zŠ
Tests for the behavior of the plugin system when there are multiple
installed copies of the package containing the plugins being loaded.
c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   Ú!AdjacentPackageTests.__annotate__[  s   € ÷ /ñ /�tñ /r   c                ó„   € \         P                  R,          V n        \         P                  P	                  4       V n        R# )zC
Save the elements of C{sys.path} and the items of C{sys.modules}.
r*   N)r.   r/   r0   r1   r2   r3   rJ   s   &r   rA   ÚAdjacentPackageTests.setUp[  s)   € ô  ŸH™H Q�KˆÔÜŸK™K×,Ñ,Ó.ˆÖr   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rB  b  rD   r   c                óÎ   € V P                   \        P                  R&   \        P                  P	                  4        \        P                  P                  V P                  4       R# rF   rG   rJ   s   &r   rK   ÚAdjacentPackageTests.tearDownb  rM   r   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r#   r5   râ   r   rÚ   Ú
pluginNamer$   r   )r&   s   "r   r'   rB  j  s,   € ÷ ñ Ø!ðØ),ðØ:=ðà	ñr   c                ó˜  € VP                  V4      pVP                  R4      pVP                  4        VP                  R4      P                  R4       VP                  R4      pVP                  4        VP                  R4      P                  \        4       VP                  VR,           4      pVP                  \	        V4      4       V# )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è   )r7   Úmakedirsr9   ré   rß   )r@   r5   r   rI  Ú	directoryr8   r{   rå   s   &&&&    r   ÚcreateDummyPackageÚ'AdjacentPackageTests.createDummyPackagej  s¡   € ð, —J‘J˜tÓ$ˆ	Ø—/‘/ 'Ó*ˆØ×ÑÔØ�‰�mÓ$×/Ñ/°Ô4Ø—-‘- 	Ó*ˆØ×ÑÔØ�‰�mÓ$×/Ñ/´Ô?Ø—}‘} Z°%Õ%7Ó8ˆØ×ÑÔ 2°4Ó 8Ô9ØÐr   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rB  ‹  s   € ÷ Cñ CÀñ Cr   c                ó  € \        V P                  4       4      pVP                  4        V P                  VRR4      pV P                  VRR4      p\        P
                  P                  VP
                  4       \        P
                  P                  VP
                  4       ^ RIp\        \        P                  ! \        VP                  4      4      pT P                  R.V Uu. uF  qfP                  NK  	  up4       R# u upi )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ÚsecondN©r
   r4   rL  rN  r.   r/   r¾   Údummy.pluginsr’   r	   rœ   r   r{   rx   r   ©r@   r5   ÚfirstDirectoryÚsecondDirectoryrK  r{   r…   s   &      r   Ú.test_hiddenPackageSamePluginModuleNameObscuredÚCAdjacentPackageTests.test_hiddenPackageSamePluginModuleNameObscured‹  óµ   € ô ˜Ÿ™›Ó&ˆØ�‰Œà×0Ñ0°°wÀÓMˆØ×1Ñ1°$¸À,ÓOˆä�‰�‰˜×+Ñ+Ô,Ü�‰�‰˜×,Ñ,Ô-ãä”v×(Ò(¬°e·m±mÓDÓEˆØ×Ñ˜'˜¹Ó$A¹°A§Z¤Z¹Ñ$AÖBùÒ$Aó   Ã%D
c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rB  Ÿ  s   € ÷ Cñ CÀTñ Cr   c                ó  € \        V P                  4       4      pVP                  4        V P                  VRR4      pV P                  VRR4      p\        P
                  P                  VP
                  4       \        P
                  P                  VP
                  4       ^ RIp\        \        P                  ! \        VP                  4      4      pT P                  R.V Uu. uF  qfP                  NK  	  up4       R# u upi )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.
rR  Ú
thispluginrT  Ú
thatpluginNrU  rW  s   &      r   Ú3test_hiddenPackageDifferentPluginModuleNameObscuredÚHAdjacentPackageTests.test_hiddenPackageDifferentPluginModuleNameObscuredŸ  r\  r]  )r0   r3   N)r   r   r   r   r   rA   rK   rN  rZ  rb  r   r   r   r   r@  r@  U  s)   † ñõ
/õ.õõBC÷(Cñ Cr   r@  c                  óJ   € ] tR tRtRtR R ltR R ltR R ltR	 R
 ltRt	R# )ÚPackagePathTestsi´  z[
Tests for L{plugin.pluginPackagePaths} which constructs search paths for
plugin packages.
c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   ÚPackagePathTests.__annotate__º  s   € ÷ (ñ (�tñ (r   c                ó>   € \         P                  R,          V n        R# )z#
Save the elements of C{sys.path}.
r*   N)r.   r/   r0   rJ   s   &r   rA   ÚPackagePathTests.setUpº  s   € ô  ŸH™H Q�KˆÖr   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rg  À  s   € ÷ (ñ (˜$ñ (r   c                ó@   € V P                   \        P                  R&   R# )z,
Restore C{sys.path} to its original value.
r*   N)r0   r.   r/   rJ   s   &r   rK   ÚPackagePathTests.tearDownÀ  s   € ð ×'Ñ'Œ�‰�‹r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rg  Æ  s   € ÷ 
ñ 
¨ñ 
r   c                ód  € \        R4      p\        R4      pVP                  VP                  .\        n        V P                  \        P
                  ! R4      VP                  R4      P                  R4      P                  VP                  R4      P                  R4      P                  .4       R# )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.pluginsrK  r{   N)r
   r/   r.   rx   r	   ÚpluginPackagePathsr7   )r@   ro  rp  s   &  r   Útest_pluginDirectoriesÚ'PackagePathTests.test_pluginDirectoriesÆ  s…   € ô �u‹oˆÜ�u‹oˆØ—H‘H˜cŸh™hÐ'ŒŒØ×ÑÜ×%Ò% oÓ6à—	‘	˜'Ó"×(Ñ(¨Ó3×8Ñ8Ø—	‘	˜'Ó"×(Ñ(¨Ó3×8Ñ8ðö	
r   c               ó   € V ^8„  d   QhRR/# r"   r   )r&   s   "r   r'   rg  ×  s   € ÷ 
ñ 
¨Tñ 
r   c                ó0  € \        V P                  4       4      pVP                  R4      P                  R4      P                  R4      pVP                  4        VP                  R4      P	                  R4       VP                  R4      P
                  VP                  R4      P
                  .\        n        V P                  \        P                  ! R4      VP                  R4      P                  R4      P                  R4      P
                  .4       R# )	aa  
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.
ro  rK  r{   r,   r   rp  rq  N)
r
   r4   r7   rL  r9   r/   r.   rx   r	   rr  )r@   r5   ro  s   &  r   Útest_pluginPackagesExcludedÚ,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   )r0   N)
r   r   r   r   r   rA   rK   rs  rw  r   r   r   r   re  re  ´  s    † ñõ
(õ(õ
÷"
ñ 
r   re  )+r   Ú
__future__r   r4  rÏ   rp   rZ   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@  re  r   r   r   Ú<module>rƒ     sÐ   ðñ
õ #ã Û Û Û 	Û 
Û Ý AÝ ß /Ñ /å $å Ý ,ß XÓ XÝ "áˆTƒ]€ô�)ô ô�9ô ôv�(×#Ñ#ô vðt	€õõ ô&˜	ô ô~˜(×+Ñ+ô ~ôB\C˜8×,Ñ,ô \Cô~4
�x×(Ñ(ö 4
r   