Ë
    —~ªbBU  ã                   óH  — 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mZ d„ Z	 G d„ de«      Z
 e e	«        d«       G d„ de
«      «       Z e e	«        d«       G d	„ d
e
«      «       Z e e	«        d«       G d„ de«      «       Z e e	«        d«       G d„ de
«      «       Zy)é    N)ÚskipIfÚTestCasec                  ó:   — 	 t        d«       y# t        $ r Y yw xY w)NÚtwistedTF)Ú
__import__ÚImportError© ó    ú=/usr/lib/python3/dist-packages/automat/_test/test_discover.pyÚisTwistedInstalledr   	   s(   € ðÜ�9Ôð øô ò Ùðús   ‚ Ž	™c                   óP   ‡ — e Zd ZdZˆ fd„Zˆ fd„Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zˆ xZS )
Ú_WritesPythonModuleszG
    A helper that enables generating Python module test fixtures.
    c                 ó`  •— t         t        | �  «        ddlm}m} ddlm} || _        || _        || _        t        t        j                  j                  «       «      | _        t        j                  d d  | _        t        j                   «       | _        | j%                  | j"                  «       y )Nr   )Ú	getModuleÚ
PythonPath)ÚFilePath)Úsuperr   ÚsetUpÚtwisted.python.modulesr   r   Útwisted.python.filepathr   ÚsetÚsysÚmodulesÚkeysÚoriginalSysModulesÚpathÚsavedSysPathÚtempfileÚmkdtempÚpathDirÚmakeImportable)Úselfr   r   r   Ú	__class__s       €r   r   z_WritesPythonModules.setUp   sx   ø€ ÜÔ" DÑ/Ô1ç@Ý4à"ˆŒØ$ˆŒØ ˆŒä"%¤c§k¡k×&6Ñ&6Ó&8Ó"9ˆÔÜŸH™H¡Q˜KˆÔä×'Ñ'Ó)ˆŒØ×Ñ˜DŸL™LÕ)r
   c                 ó(  •— t         t        | �  «        | j                  t        j
                  d d  t        j                  j                  «       | j                  z
  }|D ]  }t        j                  |= Œ t        j                  | j                  «       y ©N)r   r   ÚtearDownr   r   r   r   r   r   ÚshutilÚrmtreer    )r"   ÚmodulesToDeleteÚmoduler#   s      €r   r&   z_WritesPythonModules.tearDown'   sn   ø€ ÜÔ" DÑ2Ô4à×'Ñ'Œ�‰‘ˆÜŸ+™+×*Ñ*Ó,¨t×/FÑ/FÑFˆØ%ò 	$ˆFÜ—‘˜FÑ#ð	$ô 	�‰�d—l‘lÕ#r
   c                 óB   — t         j                  j                  |«       y r%   )r   r   Úappend)r"   r   s     r   r!   z#_WritesPythonModules.makeImportable1   s   € Ü�‰�‰˜Õr
   c                 ó  — | j                  |«      }|j                  |«      }t        |j                  d«      5 }|j	                  t        j                  |«      «       d d d «       | j                  |j                  g«      S # 1 sw Y   Œ%xY w)NÚw)r   ÚchildÚopenr   ÚwriteÚtextwrapÚdedentr   )r"   Úsourcer   Ú
moduleNameÚ	directoryr*   Úfs          r   ÚwriteSourceIntoz$_WritesPythonModules.writeSourceInto4   sr   € Ø—M‘M $Ó'ˆ	à—‘ Ó,ˆô �&—+‘+˜sÓ#ð 	- qØ�G‰G”H—O‘O FÓ+Ô,÷	-ð �‰ 	§¡Ð/Ó0Ð0÷	-ð 	-ús   ¹%BÂBc                 ór   — t         j                  j                  |«      \  }}| j                  |||«      |   S r%   )Úosr   Úsplitextr8   )r"   r4   r   r5   ÚpythonModuleNameÚ_s         r   Ú
makeModulez_WritesPythonModules.makeModule?   s7   € Ü Ÿg™g×.Ñ.¨zÓ:ÑÐ˜!Ø×#Ñ# F¨D°*Ó=Ð>NÑOÐOr
   c                 ó^   — |j                  «       D �ci c]  }|j                  |“Œ c}S c c}w r%   )ÚiterAttributesÚname)r"   ÚhasIterAttributesÚattrs      r   ÚattributesAsDictz%_WritesPythonModules.attributesAsDictC   s'   € Ø,=×,LÑ,LÓ,NÖO D�—	‘	˜4‘ÒOÐOùÒOs   “*c                 óD   — |j                  «        | j                  |«      S r%   )ÚloadrD   )r"   r*   s     r   ÚloadModuleAsDictz%_WritesPythonModules.loadModuleAsDictF   s   € Ø�‰ŒØ×$Ñ$ VÓ,Ð,r
   c                 óF   — | j                  | j                  |||«      «      S r%   )rG   r>   )r"   r4   r   rA   s       r   ÚmakeModuleAsDictz%_WritesPythonModules.makeModuleAsDictJ   s    € Ø×$Ñ$ T§_¡_°V¸TÀ4Ó%HÓIÐIr
   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r&   r!   r8   r>   rD   rG   rI   Ú__classcell__©r#   s   @r   r   r      s3   ø„ ñô*ô $òò	1òPòPò-öJr
   r   zTwisted is not installed.c                   ó4   ‡ — e Zd ZdZˆ fd„Zd„ Zd„ Zd„ Zˆ xZS )ÚOriginalLocationTestsa˜  
    Tests that L{isOriginalLocation} detects when a
    L{PythonAttribute}'s FQPN refers to an object inside the module
    where it was defined.

    For example: A L{twisted.python.modules.PythonAttribute} with a
    name of 'foo.bar' that refers to a 'bar' object defined in module
    'baz' does *not* refer to bar's original location, while a
    L{PythonAttribute} with a name of 'baz.bar' does.

    c                 óD   •— t         t        | �  «        ddlm} || _        y )Né   )ÚisOriginalLocation)r   rQ   r   Ú	_discoverrT   )r"   rT   r#   s     €r   r   zOriginalLocationTests.setUp[   s   ø€ ÜÔ# TÑ0Ô2Ý2Ø"4ˆÕr
   c                 óˆ   — d}| j                  || j                  d«      }| j                  | j                  |d   «      «       y)zŽ
        L{isOriginalLocation} returns False when the attribute refers to an
        object whose source module cannot be determined.
        z~        class Fake(object):
            pass
        hasEmptyModule = Fake()
        hasEmptyModule.__module__ = None
        zempty_module_attr.pyz empty_module_attr.hasEmptyModuleN)rI   r    ÚassertFalserT   )r"   r4   Ú
moduleDicts      r   Útest_failsWithNoModulez,OriginalLocationTests.test_failsWithNoModule`   sN   € ð
ˆð ×*Ñ*¨6Ø+/¯<©<Ø+AóCˆ
ð 	×Ñ˜×0Ñ0ØÐ9Ñ:ó<õ 	=r
   c                 ó‚  — d}d}| j                  || j                  d«       | j                  || j                  d«      }| j                  | j	                  |d   «      «       | j                  | j	                  |d   «      «       |d   }| j                  |«      }|d   }| j                  | j	                  |«      «       y	)
z™
        L{isOriginalLocation} returns False when the attribute refers to
        an object outside of the module where that object was defined.
        zâ        class ImportThisClass(object):
            pass
        importThisObject = ImportThisClass()
        importThisNestingObject = ImportThisClass()
        importThisNestingObject.nestedObject = ImportThisClass()
        zž        from original import (ImportThisClass,
                              importThisObject,
                              importThisNestingObject)
        úoriginal.pyúimporting.pyzimporting.ImportThisClasszimporting.importThisObjectz!importing.importThisNestingObjectz.importing.importThisNestingObject.nestedObjectN)r>   r    rI   rW   rT   rD   )r"   ÚoriginalSourceÚimportingSourceÚimportingDictÚnestingObjectÚnestingObjectDictÚnestedObjects          r   Útest_failsWithDifferentModulez3OriginalLocationTests.test_failsWithDifferentModules   sÖ   € ð
ˆðˆð 	�‰˜¨¯©°mÔDØ×-Ñ-¨oØ.2¯l©lØ.<ó>ˆð 	×ÑØ×#Ñ#ØÐ9Ñ:ó<ô	=ð 	×ÑØ×#Ñ#ØÐ:Ñ;ó=ô	>ð &Ð&IÑJˆØ ×1Ñ1°-Ó@ÐØ(Ø<ñ>ˆð 	×Ñ˜×0Ñ0°Ó>Õ?r
   c                 ój  — t        j                  d«      }| j                  || j                  d«      }| j	                  | j                  |d   «      «       | j	                  | j                  |d   «      «       |d   }| j                  |«      }|d   }| j	                  | j                  |«      «       y)z”
        L{isOriginalLocation} returns True when the attribute refers to an
        object inside the module where that object was defined.
        zé
        class ThisClassWasDefinedHere(object):
            pass
        anObject = ThisClassWasDefinedHere()
        aNestingObject = ThisClassWasDefinedHere()
        aNestingObject.nestedObject = ThisClassWasDefinedHere()
        zm.pyzm.ThisClassWasDefinedHerezm.aNestingObjectzm.aNestingObject.nestedObjectN)r2   r3   rI   r    Ú
assertTruerT   rD   )r"   ÚmSourceÚmDictr`   ra   rb   s         r   Útest_succeedsWithSameModulez1OriginalLocationTests.test_succeedsWithSameModule˜   s®   € ô
 —/‘/ð #ó ˆð ×%Ñ% g¨t¯|©|¸VÓDˆØ�‰˜×/Ñ/ØÐ-Ñ.ó0ô 	1à�‰˜×/Ñ/°Ð6HÑ0IÓJÔKàÐ0Ñ1ˆØ ×1Ñ1°-Ó@ÐØ(Ð)HÑIˆà�‰˜×/Ñ/°Ó=Õ>r
   )	rJ   rK   rL   rM   r   rY   rc   rh   rN   rO   s   @r   rQ   rQ   N   s   ø„ ñ
ô5ò
=ò&#@öJ?r
   rQ   c                   ó\   ‡ — e Zd ZdZdZˆ fd„Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zd„ Zd„ Zˆ xZS )ÚFindMachinesViaWrapperTestszÍ
    L{findMachinesViaWrapper} recursively yields FQPN,
    L{MethodicalMachine} pairs in and under a given
    L{twisted.python.modules.PythonModule} or
    L{twisted.python.modules.PythonAttribute}.
    aÊ  
    from automat import MethodicalMachine


    class PythonClass(object):
        _classMachine = MethodicalMachine()

        class NestedClass(object):
            _nestedClassMachine = MethodicalMachine()

        ignoredAttribute = "I am ignored."

        def ignoredMethod(self):
            "I am also ignored."

    rootLevelMachine = MethodicalMachine()
    ignoredPythonObject = PythonClass()
    anotherIgnoredPythonObject = "I am ignored."
    c                 óD   •— t         t        | �  «        ddlm} || _        y )NrS   )ÚfindMachinesViaWrapper)r   rj   r   rU   rl   )r"   rl   r#   s     €r   r   z!FindMachinesViaWrapperTests.setUpÌ   s   ø€ ÜÔ)¨4Ñ6Ô8Ý6Ø&<ˆÕ#r
   c                 óÀ   — d}| j                  || j                  d«      }|d   }| j                  d|j                  «       ft	        | j                  |«      «      «       y)zÄ
        When given a L{twisted.python.modules.PythonAttribute} that refers
        directly to a L{MethodicalMachine}, L{findMachinesViaWrapper}
        yields that machine and its FQPN.
        úa        from automat import MethodicalMachine

        rootMachine = MethodicalMachine()
        úroot.pyúroot.rootMachineN)rI   r    ÚassertInrF   Úlistrl   )r"   r4   rX   ÚrootMachines       r   Útest_yieldsMachinez.FindMachinesViaWrapperTests.test_yieldsMachineÑ   s_   € ðˆð ×*Ñ*¨6°4·<±<ÀÓKˆ
Ø Ð!3Ñ4ˆØ�‰Ð)¨;×+;Ñ+;Ó+=Ð>Ü˜4×6Ñ6°{ÓCÓDõ	Fr
   c                 óÔ   — d}| j                  || j                  d«      }|d   }| j                  d|j                  «       j                  ft        | j                  |«      «      «       y)zí
        When given a L{twisted.python.modules.PythonAttribute} that refers
        to a class that contains a L{MethodicalMachine} as a class
        variable, L{findMachinesViaWrapper} yields that machine and
        its FQPN.
        úŠ        from automat import MethodicalMachine

        class PythonClass(object):
            _classMachine = MethodicalMachine()
        ú	clsmod.pyúclsmod.PythonClassú clsmod.PythonClass._classMachineN)rI   r    rq   rF   Ú_classMachinerr   rl   ©r"   r4   rX   ÚPythonClasss       r   Útest_yieldsMachineInClassz5FindMachinesViaWrapperTests.test_yieldsMachineInClassâ   sh   € ðˆð ×*Ñ*¨6°4·<±<ÀÓMˆ
Ø Ð!5Ñ6ˆØ�‰Ð9Ø"×'Ñ'Ó)×7Ñ7ð9ä˜4×6Ñ6°{ÓCÓDõ	Fr
   c                 óè   — d}| j                  || j                  d«      }|d   }| j                  d|j                  «       j                  j
                  ft        | j                  |«      «      «       y)zô
        When given a L{twisted.python.modules.PythonAttribute} that refers
        to a nested class that contains a L{MethodicalMachine} as a
        class variable, L{findMachinesViaWrapper} yields that machine
        and its FQPN.
        úµ        from automat import MethodicalMachine

        class PythonClass(object):
            class NestedClass(object):
                _classMachine = MethodicalMachine()
        únestedcls.pyúnestedcls.PythonClassú/nestedcls.PythonClass.NestedClass._classMachineN)rI   r    rq   rF   ÚNestedClassrz   rr   rl   r{   s       r   Útest_yieldsMachineInNestedClassz;FindMachinesViaWrapperTests.test_yieldsMachineInNestedClassõ   su   € ðˆð ×*Ñ*¨6Ø+/¯<©<Ø+9ó;ˆ
ð !Ð!8Ñ9ˆØ�‰ÐHØ"×'Ñ'Ó)×5Ñ5×CÑCðEä˜4×6Ñ6°{ÓCÓDõ	Fr
   c                 óÞ   — d}| j                  || j                  d«      }| j                  |«      d   j                  «       }| j	                  d|ft        | j                  |«      «      «       y)zÏ
        When given a L{twisted.python.modules.PythonModule} that refers to
        a module that contains a L{MethodicalMachine},
        L{findMachinesViaWrapper} yields that machine and its FQPN.
        rn   ro   rp   N)r>   r    rG   rF   rq   rr   rl   )r"   r4   r*   rs   s       r   Útest_yieldsMachineInModulez6FindMachinesViaWrapperTests.test_yieldsMachineInModule  sh   € ðˆð
 —‘ ¨¯©°yÓAˆØ×+Ñ+¨FÓ3Ð4FÑG×LÑLÓNˆØ�‰Ð)¨;Ð7Ü˜4×6Ñ6°vÓ>Ó?õ	Ar
   c                 óò   — d}| j                  || j                  d«      }| j                  |«      d   j                  «       }| j	                  d|j
                  ft        | j                  |«      «      «       y)zê
        When given a L{twisted.python.modules.PythonModule} that refers to
        the original module of a class containing a
        L{MethodicalMachine}, L{findMachinesViaWrapper} yields that
        machine and its FQPN.
        rv   rw   rx   ry   N)r>   r    rG   rF   rq   rz   rr   rl   ©r"   r4   r*   r|   s       r   Ú!test_yieldsMachineInClassInModulez=FindMachinesViaWrapperTests.test_yieldsMachineInClassInModule  sw   € ðˆð —‘ ¨¯©°{ÓCˆØ×+Ñ+ØóØ(ñ*ß*.©$«&ð 	à�‰Ð9Ø"×0Ñ0ð2ä˜4×6Ñ6°vÓ>Ó?õ	Ar
   c                 ó  — d}| j                  || j                  d«      }| j                  |«      d   j                  «       }| j	                  d|j
                  j                  ft        | j                  |«      «      «       y)zñ
        When given a L{twisted.python.modules.PythonModule} that refers to
        the original module of a nested class containing a
        L{MethodicalMachine}, L{findMachinesViaWrapper} yields that
        machine and its FQPN.
        r   r€   r�   r‚   N)	r>   r    rG   rF   rq   rƒ   rz   rr   rl   rˆ   s       r   Ú'test_yieldsMachineInNestedClassInModulezCFindMachinesViaWrapperTests.test_yieldsMachineInNestedClassInModule0  s   € ðˆð —‘ ¨¯©°~ÓFˆØ×+Ñ+ØóØ+ñ-ß-1©T«Vð 	ð 	�‰ÐHØ"×.Ñ.×<Ñ<ð>ä˜4×6Ñ6°vÓ>Ó?õ	Ar
   c                 óÒ   — d}d}| j                  || j                  d«       | j                  || j                  d«      }| j                  t        | j	                  |«      «      «       y)aM  
        When given a L{twisted.python.modules.PythonAttribute} that refers
        to a class imported from another module, any
        L{MethodicalMachine}s on that class are ignored.

        This behavior ensures that a machine is only discovered on a
        class when visiting the module where that class was defined.
        z‹
        from automat import MethodicalMachine

        class PythonClass(object):
            _classMachine = MethodicalMachine()
        z2
        from original import PythonClass
        r[   r\   N©r>   r    rW   rr   rl   )r"   r]   r^   ÚimportingModules       r   Útest_ignoresImportedClassz5FindMachinesViaWrapperTests.test_ignoresImportedClassF  s`   € ðˆðˆð 	�‰˜¨¯©°mÔDØŸ/™/¨/Ø*.¯,©,Ø*8ó:ˆð 	×Ñœ˜d×9Ñ9¸/ÓJÓKÕLr
   c                 óŒ  — | j                  | j                  g«      }| j                  | j                  «      j                  d«      }|j	                  «        |j                  d«      j                  «        d}| j                  ||j                  d«       |d   }t        | j                  |«      t        j                  d«      ¬«      }| j                  |d   «      }|d   j                  «       }|d	   j                  «       }t        d|fd
|j                  fgt        j                  d«      ¬«      }	| j                  |	|«       y)z`
        L{findMachinesViaWrapper} descends into packages to discover
        machines.
        Útest_packageú__init__.pyz¸
        from automat import MethodicalMachine


        class PythonClass(object):
            _classMachine = MethodicalMachine()


        rootMachine = MethodicalMachine()
        ú	module.pyr   ©Úkeyr*   ztest_package.module.rootMachineztest_package.module.PythonClassz-test_package.module.PythonClass._classMachineN)r   r    r   r/   ÚmakedirsÚtouchr>   r   Úsortedrl   ÚoperatorÚ
itemgetterrG   rF   rz   ÚassertEqual)
r"   Ú
pythonPathÚpackager4   r‘   ÚmachinesrX   rs   r|   ÚexpectedMachiness
             r   Útest_descendsIntoPackagesz5FindMachinesViaWrapperTests.test_descendsIntoPackagesa  s1  € ð
 —_‘_ d§l¡l ^Ó4ˆ
Ø—-‘- §¡Ó-×3Ñ3°NÓCˆØ×ÑÔØ�‰�mÓ$×*Ñ*Ô,ð	ˆð 	�‰˜ §¡¨kÔ:à! .Ñ1ˆÜ˜$×5Ñ5°lÓCÜ&×1Ñ1°!Ó4ô6ˆð ×*Ñ*¨<¸Ñ+AÓBˆ
Ø Ð!BÑC×HÑHÓJˆØ Ð!BÑC×HÑHÓJˆä!Ø/Øðà=Ø×'Ñ'ð)ð*ô 08×/BÑ/BÀ1Ó/Eô	GÐð 	×ÑÐ)¨8Õ4r
   c                 ó”   — d}| j                  || j                  d«      }| j                  t        | j	                  |«      «      «       y)z�
        L{findMachinesViaWrapper} ignores infinite loops.

        Note this test can't fail - it can only run forever!
        zh
        class InfiniteLoop(object):
            pass

        InfiniteLoop.loop = InfiniteLoop
        zloop.pyNr�   )r"   r4   r*   s      r   Útest_infiniteLoopz-FindMachinesViaWrapperTests.test_infiniteLoop‡  s?   € ðˆð —‘ ¨¯©°yÓAˆØ×Ñœ˜d×9Ñ9¸&ÓAÓBÕCr
   )rJ   rK   rL   rM   ÚTEST_MODULE_SOURCEr   rt   r}   r„   r†   r‰   r‹   r�   r    r¢   rN   rO   s   @r   rj   rj   °   sK   ø„ ñðÐô(=ò
Fò"Fò&Fò.Aò Aò(Aò,Mò6$5öLDr
   rj   c                   ó^   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
d	„ Zd
„ Zd„ Zd„ Zd„ Zd„ Zy)ÚWrapFQPNTestszŸ
    Tests that ensure L{wrapFQPN} loads the
    L{twisted.python.modules.PythonModule} or
    L{twisted.python.modules.PythonAttribute} for a given FQPN.
    c                 ó€   — ddl m}m} ddlm}m}m}m} || _        || _        || _        || _        || _        || _        y )Nr   )ÚPythonModuleÚPythonAttributerS   )ÚwrapFQPNÚInvalidFQPNÚNoModuleÚNoObject)r   r§   r¨   rU   r©   rª   r«   r¬   )r"   r§   r¨   r©   rª   r«   r¬   s          r   r   zWrapFQPNTests.setUpŸ  s8   € ßHßIÓIà(ˆÔØ.ˆÔØ ˆŒØ&ˆÔØ ˆŒØ ˆ�r
   c                 óÈ   — | j                  || j                  «       | j                  |j                  |j                  «       | j                  |j                  «       |«       y)zt
        Assert that a L{twisted.python.modules.PythonModule} refers to a
        particular Python module.
        N)ÚassertIsInstancer§   r›   rA   rJ   ÚassertIsrF   )r"   ÚmoduleWrapperr*   s      r   ÚassertModuleWrapperRefersToz)WrapFQPNTests.assertModuleWrapperRefersToª  sK   € ð
 	×Ñ˜m¨T×->Ñ->Ô?Ø×Ñ˜×+Ñ+¨V¯_©_Ô=Ø�‰�m×(Ñ(Ó*¨FÕ3r
   c                 ó´   — | j                  || j                  «       | j                  |j                  |«       | j	                  |j                  «       |«       y)zw
        Assert that a L{twisted.python.modules.PythonAttribute} refers to a
        particular Python object.
        N)r®   r¨   r›   rA   r¯   rF   )r"   ÚattributeWrapperÚfqpnÚobjs       r   ÚassertAttributeWrapperRefersToz,WrapFQPNTests.assertAttributeWrapperRefersTo³  sJ   € ð
 	×ÑÐ.°×0DÑ0DÔEØ×ÑÐ)×.Ñ.°Ô5Ø�‰Ð&×+Ñ+Ó-¨sÕ3r
   c                 ó†   — | j                  | j                  «      5  | j                  d«       ddd«       y# 1 sw Y   yxY w)zO
        L{wrapFQPN} raises L{InvalidFQPN} when given an empty string.
        Ú N©ÚassertRaisesrª   r©   ©r"   s    r   Útest_failsWithEmptyFQPNz%WrapFQPNTests.test_failsWithEmptyFQPN¼  s9   € ð ×Ñ˜t×/Ñ/Ó0ñ 	Ø�M‰M˜"Ô÷	÷ 	ñ 	úó	   œ7·A c                 ó”   — dD ]7  }| j                  | j                  «      5  | j                  |«       ddd«       Œ9 y# 1 sw Y   ŒDxY w)zk"
        L{wrapFQPN} raises L{InvalidFQPN} when given a badly-dotted
        FQPN.  (e.g., x..y).
        )z.failszfails.zthis..failsNr¹   ©r"   Úbads     r   Útest_failsWithBadDottingz&WrapFQPNTests.test_failsWithBadDottingÃ  sM   € ð
 7ò 	#ˆCØ×"Ñ" 4×#3Ñ#3Ó4ñ #Ø—‘˜cÔ"÷#ð #ñ	#÷#ð #úó	   ¡>¾A	c                 ó¦   — ddl }| j                  d«      }| j                  || j                  «       | j	                  |j                  «       |«       y)z�
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the single module a dotless FQPN describes.
        r   Nr:   )r:   r©   r®   r§   r¯   rF   )r"   r:   r°   s      r   Útest_singleModulezWrapFQPNTests.test_singleModuleÌ  sB   € ó
 	àŸ™ dÓ+ˆà×Ñ˜m¨T×->Ñ->Ô?Ø�‰�m×(Ñ(Ó*¨BÕ/r
   c                 ó†   — | j                  | j                  «      5  | j                  d«       ddd«       y# 1 sw Y   yxY w)z~
        L{wrapFQPN} raises L{NoModule} when given a dotless FQPN that does
        not refer to a module or package.
        zthis is not an acceptable name!N)rº   r«   r©   r»   s    r   Ú*test_failsWithMissingSingleModuleOrPackagez8WrapFQPNTests.test_failsWithMissingSingleModuleOrPackageØ  s8   € ð
 ×Ñ˜tŸ}™}Ó-ñ 	=Ø�M‰MÐ;Ô<÷	=÷ 	=ñ 	=úr½   c                 óN   — ddl }| j                  | j                  d«      |«       y)z�
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the single package a dotless FQPN describes.
        r   NÚxml)rÈ   r±   r©   ©r"   rÈ   s     r   Útest_singlePackagez WrapFQPNTests.test_singlePackageà  s    € ó
 	Ø×(Ñ(¨¯©°uÓ)=¸sÕCr
   c                 ób   — ddl }| j                  | j                  d«      |j                  «       y)z‘
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the deepest package described by dotted FQPN.
        r   Nz	xml.etree)Ú	xml.etreer±   r©   ÚetreerÉ   s     r   Útest_multiplePackagesz#WrapFQPNTests.test_multiplePackagesè  s$   € ó
 	Ø×(Ñ(¨¯©°{Ó)CÀSÇYÁYÕOr
   c                 óv   — ddl }| j                  | j                  d«      |j                  j                  «       y)z�
        L{wrapFQPN} returns a L{twisted.python.modules.PythonModule}
        referring to the deepest module described by dotted FQPN.
        r   Nzxml.etree.ElementTree)Úxml.etree.ElementTreer±   r©   rÍ   ÚElementTreerÉ   s     r   Ú test_multiplePackagesFinalModulez.WrapFQPNTests.test_multiplePackagesFinalModuleð  s/   € ó
 	%Ø×(Ñ(Ø�M‰MÐ1Ó2°C·I±I×4IÑ4Iõ	Kr
   c                 ód   — ddl }| j                  | j                  d«      d|j                  «       y)zŸ
        L{wrapFQPN} returns a L{twisted.python.modules.PythonAttribute}
        referring to the deepest object an FQPN names, traversing one module.
        r   Nzos.path)r:   r¶   r©   r   )r"   r:   s     r   Útest_singleModuleObjectz%WrapFQPNTests.test_singleModuleObjectù  s)   € ó
 	Ø×+Ñ+Ø�M‰M˜)Ó$ i°·±õ	:r
   c                 óÜ   — ddl }ddl}d|j                  j                  j                  fd|j
                  j                  ffD ]'  \  }}| j                  | j                  |«      ||«       Œ) y)z¼
        L{wrapFQPN} returns a L{twisted.python.modules.PythonAttribute}
        referring to the deepest object described by an FQPN,
        descending through several packages.
        r   Nz xml.etree.ElementTree.fromstringz!automat.MethodicalMachine.__doc__)	rÐ   ÚautomatrÍ   rÑ   Ú
fromstringÚMethodicalMachinerM   r¶   r©   )r"   rÈ   rÖ   r´   rµ   s        r   Útest_multiplePackagesObjectz)WrapFQPNTests.test_multiplePackagesObject  sq   € ó 	%Ûà=ØŸ9™9×0Ñ0×;Ñ;ð=à>Ø"×4Ñ4×<Ñ<ð>ð?ò 	0‰IˆD�#ð ×/Ñ/Ø—‘˜dÓ# T¨3õ0ñ		0r
   c                 ó”   — dD ]7  }| j                  | j                  «      5  | j                  |«       ddd«       Œ9 y# 1 sw Y   ŒDxY w)z‚
        L{wrapFQPN} raises L{NoObject} when given an FQPN that contains a
        missing attribute, module, or package.
        )zxml.etree.nope!z*xml.etree.nope!.but.the.rest.is.believableN)rº   r¬   r©   r¿   s     r   Ú4test_failsWithMultiplePackagesMissingModuleOrPackagezBWrapFQPNTests.test_failsWithMultiplePackagesMissingModuleOrPackage  sL   € ð
Bò 	#ˆCà×"Ñ" 4§=¡=Ó1ñ #Ø—‘˜cÔ"÷#ð #ñ	#÷#ð #úrÂ   N)rJ   rK   rL   rM   r   r±   r¶   r¼   rÁ   rÄ   rÆ   rÊ   rÎ   rÒ   rÔ   rÙ   rÛ   r	   r
   r   r¥   r¥   —  sK   „ ñò	!ò4ò4òò#ò
0ò=òDòPòKò:ò0ó #r
   r¥   c                   ó,   ‡ — e Zd ZdZdZˆ fd„Zd„ Zˆ xZS )ÚFindMachinesIntegrationTestszs
    Integration tests to check that L{findMachines} yields all
    machines discoverable at or below an FQPN.
    zÚ
    from automat import MethodicalMachine

    class PythonClass(object):
        _machine = MethodicalMachine()
        ignored = "i am ignored"

    rootLevel = MethodicalMachine()

    ignored = "i am ignored"
    c                 ó®  •— t         t        | �  «        ddlm} || _        | j                  | j                  «      j                  d«      }|j                  «        | j                  | j                  g«      | _
        | j                  | j                  |j                  d«       |j                  d«      }|j                  «        |j                  d«      j                  «        | j                  | j                  |j                  d«       | j!                  | j                  d   «      | _        | j!                  | j                  d   d   d   «      | _        y )NrS   )ÚfindMachinesr‘   r’   Ú
subpackager“   r*   )r   rÝ   r   rU   rß   r   r    r/   r–   r   rœ   r8   ÚSOURCEr   r—   r>   rG   ÚpackageDictrX   )r"   rß   Ú
packageDirÚsubPackageDirr#   s       €r   r   z"FindMachinesIntegrationTests.setUp0  s
  ø€ ÜÔ*¨DÑ7Ô9Ý,à(ˆÔà—]‘] 4§<¡<Ó0×6Ñ6°~ÓFˆ
Ø×ÑÔØŸ/™/¨4¯<©<¨.Ó9ˆŒØ×Ñ˜TŸ[™[¨*¯/©/¸=ÔIà"×(Ñ(¨Ó6ˆØ×ÑÔ Ø×Ñ˜MÓ*×0Ñ0Ô2à�‰˜Ÿ™ ]×%7Ñ%7¸ÔEà×0Ñ0Ø�O‰O˜NÑ+ó-ˆÔà×/Ñ/Ø�O‰O˜NÑ+¨LÑ9¸(ÑCóEˆ�r
   c                 óö  — t        | j                  d«      t        j                  d«      ¬«      }| j                  d   j                  «       }| j                  d   j                  «       }| j                  d   }|j                  «       }| j                  d   }|j                  «       }t        d|fd|j                  fd|fd	|j                  fgt        j                  d«      ¬«      }| j                  ||«       y
)z‡
        Given a top-level package FQPN, L{findMachines} discovers all
        L{MethodicalMachine} instances in and below it.
        r‘   r   r”   ztest_package.rootLevelztest_package.PythonClassz(test_package.subpackage.module.rootLevelz*test_package.subpackage.module.PythonClassz!test_package.PythonClass._machinez3test_package.subpackage.module.PythonClass._machineN)	r˜   rß   r™   rš   râ   rF   rX   Ú_machiner›   )	r"   rž   ÚtpRootLevelÚtpPythonClassÚmRLAttrÚ
mRootLevelÚmPCAttrÚmPythonClassrŸ   s	            r   Útest_discoverAllz-FindMachinesIntegrationTests.test_discoverAllF  sõ   € ô
 ˜$×+Ñ+¨NÓ;Ü&×1Ñ1°!Ó4ô6ˆð ×&Ñ&Ð'?Ñ@×EÑEÓGˆØ×(Ñ(Ð)CÑD×IÑIÓKˆà—/‘/Ð"LÑMˆØ—\‘\“^ˆ
Ø—/‘/Ð"NÑOˆØ—|‘|“~ˆä!Ø&¨Ð4Ø1°=×3IÑ3IÐJØ8¸*ÐEØCØ×#Ñ#ð%ð&ô
 ×#Ñ# AÓ&ô(Ðð 	×ÑÐ)¨8Õ4r
   )rJ   rK   rL   rM   rá   r   rí   rN   rO   s   @r   rÝ   rÝ     s   ø„ ñð

€FôEö,5r
   rÝ   )r™   r:   r'   r   r2   r   Úunittestr   r   r   r   rQ   rj   r¥   rÝ   r	   r
   r   ú<module>rï      së   ðÛ Û 	Û Û 
Û Û ß %òô9J˜8ô 9Jñx ÑÓ Ð Ð"=Ó>ô^?Ð0ó ^?ó ?ð^?ñB ÑÓ Ð Ð"=Ó>ôcDÐ"6ó cDó ?ðcDñL ÑÓ Ð Ð"=Ó>ôB#�Hó B#ó ?ðB#ñJ ÑÓ Ð Ð"=Ó>ô@5Ð#7ó @5ó ?ñ@5r
   