~bddlZddlZddlmZddlmZmZdZdZGdde Z Gdd e Z Gd d e Z d Z d Zy)N)MethodicalMachine) PythonModule getModulectj|j}|y|}t|ts|j }t|ts|j |jk(S)z Attempt to discover if this appearance of a PythonAttribute representing a class refers to the module where that class was defined. F)inspect getmoduleload isinstanceronObjectname__name__)attr sourceModule currentModules 3/usr/lib/python3/dist-packages/automat/_discover.pyisOriginalLocationrsb $$TYY[1LM 5%..  5   !6!6 66c#xKtj|g}t}|r|j}|j }t |t r&||vr"|j||j|fntj|r@t|r5||vr1|j||j|jnct |trS||vrO|j||j|j|j|j|ryyw)a Recursively yield L{MethodicalMachine}s and their FQPNs within a L{PythonModule} or a L{twisted.python.modules.PythonAttribute} wrapper object. Note that L{PythonModule}s may refer to packages, as well. The discovery heuristic considers L{MethodicalMachine} instances that are module-level attributes or class-level attributes accessible from module scope. Machines inside nested classes will be discovered, but those returned from functions or methods will not be. @type within: L{PythonModule} or L{twisted.python.modules.PythonAttribute} @param within: Where to start the search. @return: a generator which yields FQPN, L{MethodicalMachine} pairs. N) collectionsdequesetpopr r raddr risclassr extendleftiterAttributesr iterModules)withinqueuevisitedrvalues rfindMachinesViaWrapperr"s$   vh 'EeG yy{  e. /E4H KK ))U" "ooe$);D)A7" KK    T002 3 l +W0D KK    T002 3   T--/ 0 s D4D:8D:ceZdZdZy) InvalidFQPNzH The given FQPN was not a dot-separated list of Python objects. Nr __module__ __qualname____doc__rrr$r$>rr$ceZdZdZy)NoModulezG A prefix of the FQPN was not an importable module or package. Nr%r)rrr,r,Dr*rr,ceZdZdZy)NoObjectz; A suffix of the FQPN was not an accessible object Nr%r)rrr.r.Jr*rr.cL|s tdtj|jd}d|vrtd||j  t }|r)|j  |}|j|r)|S#t $r twxYw#t $r|jYnwxYw|}|D]W tfd|jD}'#t$r&tdj|jwxYw|S)z Given an FQPN, retrieve the object via the global Python module namespace and wrap it with a L{PythonModule} or a L{twisted.python.modules.PythonAttribute}. zFQPN was empty.zMname must be a string giving a '.'-separated list of Python identifiers, not c3fK|](}|jjdddk(r|*yw)r0N)r rsplit).0child components r zwrapFQPN..ys8Lu % 1 1#q 9" = J#Ls.1z{}.{})r$rrsplitpopleftrKeyErrorr,r appendleftnextr StopIterationr.formatr )fqpn componentsmodule attributer8s @rwrapFQPNrEPsQ *++""4::c?3J Z%) ,- -""$I"9% &&(  I&F KKM   "y!!"   ! !) ,  IF  FL 0H0H0JLLI F7>>)..)DE E F F s* B4B&B#&CC"C11/D c*tt|S)a' Recursively yield L{MethodicalMachine}s and their FQPNs in and under the a Python object specified by an FQPN. The discovery heuristic considers L{MethodicalMachine} instances that are module-level attributes or class-level attributes accessible from module scope. Machines inside nested classes will be discovered, but those returned from functions or methods will not be. @type within: an FQPN @param within: Where to start the search. @return: a generator which yields FQPN, L{MethodicalMachine} pairs. )r"rE)rAs r findMachinesrGs "(4. 11r)rrautomatrtwisted.python.modulesrrrr" Exceptionr$r,r.rErGr)rrrKsK%:7"#1L) { { .b2r