B 4]( @sdZddlmZddlZddlmZddlmZddd d d d d dddddg ZGdddeZ ddZ Gddde e e Z Gdd d e ZGdd d eZGdd d eZdd Zdd ZddZddZddZddZd dZdS)!aOVisitor/traversal interface and library functions. SQLAlchemy schema and expression constructs rely on a Python-centric version of the classic "visitor" pattern as the primary way in which they apply functionality. The most common use of this pattern is statement compilation, where individual expression classes match up to rendering methods that produce a string result. Beyond this, the visitor system is also used to inspect expressions for various information and patterns, as well as for usage in some kinds of expression transformation. Other kinds of transformation use a non-visitor traversal system. For many examples of how the visit system is used, see the sqlalchemy.sql.util and the sqlalchemy.sql.compiler modules. For an introduction to clause adaption, see http://techspot.zzzeek.org/2008/01/23/expression-transformations/ )dequeN)exc)util VisitableType Visitable ClauseVisitorCloningVisitorReplacingCloningVisitoriterateiterate_depthfirsttraverse_usingtraversetraverse_depthfirstcloned_traversereplacement_traversecs eZdZdZfddZZS)raeMetaclass which assigns a `_compiler_dispatch` method to classes having a `__visit_name__` attribute. The _compiler_dispatch attribute becomes an instance method which looks approximately like the following:: def _compiler_dispatch (self, visitor, **kw): '''Look for an attribute named "visit_" + self.__visit_name__ on the visitor, and call it with the same kw params.''' visit_attr = 'visit_%s' % self.__visit_name__ return getattr(visitor, visit_attr)(self, **kw) Classes having no __visit_name__ attribute will remain unaffected. cs2|dkrt|drt|tt||||dS)Nr__visit_name__)hasattr_generate_dispatchsuperr__init__)clsZclsnamebasesZclsdict) __class__J/opt/alt/python37/lib64/python3.7/site-packages/sqlalchemy/sql/visitors.pyrBszVisitableType.__init__)__name__ __module__ __qualname____doc__r __classcell__rr)rrr2scsTdjkrPj}t|tr8td|fdd}n fdd}d|_|_dS)zYReturn an optimized visit dispatch function for the cls for use by the compiler. rzvisit_%scs>y |}Wn tk r,t|YnX||f|SdS)N)AttributeErrorrUnsupportedCompilationError)selfvisitorkwmeth)rgetterrr_compiler_dispatchUs  z._generate_dispatch.._compiler_dispatchcsJd|j}yt||}Wn tk r8t|YnX||f|SdS)Nzvisit_%s)rgetattrr!rr")r#r$r%Z visit_attrr&)rrrr(as  zLook for an attribute named "visit_" + self.__visit_name__ on the visitor, and call it with the same kw params. N)__dict__r isinstancestroperator attrgetterrr()rZ visit_namer(r)rr'rrIs   rc@seZdZdZdS)rzTBase class for visitable objects, applies the ``VisitableType`` metaclass. N)rrrrrrrrrpsc@sNeZdZdZiZddZddZddZej dd Z e d d Z d d Z dS)rzZBase class for visitor objects which can traverse using the traverse() function. cKs6x0|jD]&}t|d|jd}|r||f|SqWdS)Nzvisit_%s)visitor_iteratorr)r)r#objr%vr&rrrtraverse_singles zClauseVisitor.traverse_singlecCs t||jS)zatraverse the given expression structure, returning an iterator of all elements. )r __traverse_options__)r#r0rrrr szClauseVisitor.iteratecCst||j|jS)z2traverse and visit the given expression structure.)rr3 _visitor_dict)r#r0rrrrszClauseVisitor.traversecCs:i}x0t|D]$}|drt||||dd<qW|S)NZvisit_)dir startswithr))r#visitorsnamerrrr4s  zClauseVisitor._visitor_dictccs$|}x|r|Vt|dd}qWdS)z8iterate through this visitor and each 'chained' visitor._nextN)r))r#r1rrrr/szClauseVisitor.visitor_iteratorcCst|jd}||_|S)z'chain' an additional ClauseVisitor onto this ClauseVisitor. the chained visitor will receive all visit events after this one. )listr/r:)r#r$tailrrrchainszClauseVisitor.chainN)rrrrr3r2r rrZmemoized_propertyr4propertyr/r>rrrrrws c@s eZdZdZddZddZdS)r zaBase class for visitor objects which can traverse using the cloned_traverse() function. csfdd|DS)z`Apply cloned traversal to the given list of elements, and return the new list. csg|]}|qSr)r).0x)r#rr sz3CloningVisitor.copy_and_process..r)r#Zlist_r)r#rcopy_and_processszCloningVisitor.copy_and_processcCst||j|jS)z2traverse and visit the given expression structure.)rr3r4)r#r0rrrrszCloningVisitor.traverseN)rrrrrCrrrrrr sc@s eZdZdZddZddZdS)r zfBase class for visitor objects which can traverse using the replacement_traverse() function. cCsdS)areceive pre-copied elements during a cloning traversal. If the method returns a new element, the element is used instead of creating a simple copy of the element. Traversal will halt on the newly returned element if it is re-encountered. Nr)r#elemrrrreplaceszReplacingCloningVisitor.replacecsfdd}t|j|S)z2traverse and visit the given expression structure.cs*x$jD]}||}|dk r|SqWdS)N)r/rE)rDr1e)r#rrrEs  z1ReplacingCloningVisitor.traverse..replace)rr3)r#r0rEr)r#rrs z ReplacingCloningVisitor.traverseN)rrrrrErrrrrr s cCsj|jf|}|s|gSt}t|g}x:|r`|}||x|jf|D]}||qLWq(Wt|S)zwtraverse the given expression structure, returning an iterator. traversal is configured to be breadth-first. ) get_childrenrpopleftappenditer)r0optschildren traversalstacktcrrrr s   cCsj|jf|}|s|gSt|g}t}x:|r`|}||x|jf|D]}||qLWq(Wt|S)zutraverse the given expression structure, returning an iterator. traversal is configured to be depth-first. )rGrpop appendleftrIrJ)r0rKrLrNrMrOrPrrrr s   cCs,x&|D]}||jd}|r||qW|S)zSvisit the given expression structure using the given iterator of objects. N)getr)iteratorr0r8targetr&rrrr s   cCstt||||S)zXtraverse and visit the given expression structure using the default iterator. )r r )r0rKr8rrrrscCstt||||S)z[traverse and visit the given expression structure using the depth-first iterator. )r r )r0rKr8rrrrscs:it|dgfdd|dk r6|}|S)zMclone the given expression structure, allowing modifications by visitors.stop_oncsb|kr |St|krR|t|<}|jd|jd}|rR||t|SdS)N)clone)id_clone_copy_internalsrSr)rDnewelemr&)rWclonedrVr8rrrW+s  zcloned_traverse..cloneN)setrS)r0rKr8r)rWr\rVr8rr$s  csDidd|dgDfdd|dk r@|f|}|S)zgclone the given expression structure, allowing element replacement by a given replacement function.cSsh|] }t|qSr)rX)r@rArrr Asz'replacement_traverse..rVcstt|ksd|jkr|S|}|dk r<t||S|krh||<}|jfdi||SdS)NZno_replacement_traverserW)rXZ _annotationsaddrYrZ)rDr%r[)rWr\rErVrrrWCs  z#replacement_traverse..cloneN)rS)r0rKrEr)rWr\rErVrr<s  )r collectionsrr-rr__all__typerrZwith_metaclassobjectrrr r r r r rrrrrrrrs:   '7