gߍHdZddlmZddlmZddlmZddlZddlZddl Z ddl m Z ddl m Z ddl m Z dd l m Z dd l mZdd l mZdd l mZdd l mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddlmZddlmZddlmZddlmZddl m!Z!ddl m"Z"ddl m#Z#er ddl$m%Z%dd l&m'Z'e j.ses dd!l(m)Z)dd"l(m*Z+n dd!l,m)Z)dd"l,m*Z+gd#Z-Gd$d%e"Z.Gd&d'Z/Gd(d)eZ0eee1e0fZ2 Gd*d+Z3Gd,d-e"Z4Gd.d/Z5e0Z6dPd0Z7e5jpZ8e7Gd1d2e3e/Z9ed3e94Z:ed5d64Z;e e:gdfZ<Gd7d8e"Z=Gd9d:e"e:Z>ed;d<4Z?Gd=dd?eAZBGd@dAeBZCe/ZDeAZEeBZFeCZGejf dQdBZIe dRdCZJe dSdDZJ dTdEZJe dUdFZKe dVdGZK dWdHZKe dUdIZLe dXdJZL dWdKZLe dYdLZMe dZdMZMe d[dNZM d\dOZMy)]z5Visitor/traversal interface and library functions. ) annotations)deque)EnumN)Any)Callable)cast)ClassVar)Dict)Iterable)Iterator)List)Mapping)Optional)overload)Tuple)Type) TYPE_CHECKING)TypeVar)Union)exc)util) langhelpers)HAS_CYEXTENSION)Literal)Protocol)Self)_AnnotationDict) ColumnElement)prefix_anon_map)cache_anon_map) iteratetraverse_usingtraversecloned_traversereplacement_traverse VisitableExternalTraversalInternalTraversalanon_mapceZdZddZy)_CompilerDispatchTypec yN)_selfselfvisitorkws H/opt/hc_python/lib64/python3.12/site-packages/sqlalchemy/sql/visitors.py__call__z_CompilerDispatchType.__call__Ks#N)r2r(r3rr4rreturnr__name__ __module__ __qualname__r6r0r7r5r-r-JsMr7r-cxeZdZUdZdZded<ded<ejrd dZd fd Z e d d Z d d Z xZ S)r(a,Base class for visitable objects. :class:`.Visitable` is used to implement the SQL compiler dispatch functions. Other forms of traversal such as for cache key generation are implemented separately using the :class:`.HasTraverseInternals` interface. .. versionchanged:: 2.0 The :class:`.Visitable` class was named :class:`.Traversible` in the 1.4 series; the name is changed back to :class:`.Visitable` in 2.0 which is what it was prior to 1.4. Both names remain importable in both 1.4 and 2.0 versions. r0str__visit_name__r-_original_compiler_dispatchc yr/r0)r2r3r4s r5_compiler_dispatchzVisitable._compiler_dispatchfscr7c^d|jvr|jt| y)Nr?)__dict___generate_compiler_dispatchsuper__init_subclass__)cls __class__s r5rGzVisitable.__init_subclass__hs& s|| +  + + - !#r7c0|j}d|jvr|j|_yt |t s#t jd|jdd|z}tj| dfd }|x|_|_y)NrBz__visit_name__ on class z$ must be a string at the class levelvisit_%sc| |}||fi|S#t$r}|j||fi|cYd}~Sd}~wwxYw)zLook for an attribute named "visit_" on the visitor, and call it with the same kw params. N)AttributeErrorvisit_unsupported_compilation)r2r3r4metherrgetters r5rBzAVisitable._generate_compiler_dispatch.._compiler_dispatchsQ (gD'B''" N) r?rDrBr@ isinstancer>rInvalidRequestErrorr:operator attrgetter)rH visit_namenamerBrQs @r5rEz%Visitable._generate_compiler_dispatchms'' 3<< //2.D.DC + *c*))*3<<.9%%  J&$$T* ( (&) (14 (  (    +r7c|Sr/r0)rHkeys r5__class_getitem__zVisitable.__class_getitem__s r7)r3rr4rr8r>r8None)rYrr8r)r:r;r<__doc__ __slots____annotations__typingrrBrG classmethodrErZ __classcell__)rIs@r5r(r(NsF I!66 I$ ##Jr7r(ceZdZdZdZ dZ dZ dZ dZ dZ dZ d Z d Z d Z d Z d Z dZ dZ dZ dZ dZ dZ dZ dZ dZ dZ dZ dZ dZ dZdZdZ dZ dZ! d Z" d!Z# d"Z$ d#Z% d$Z& d%Z' d&Z( d'Z) d(Z*y))*r*aDefines visitor symbols used for internal traversal. The :class:`.InternalTraversal` class is used in two ways. One is that it can serve as the superclass for an object that implements the various visit methods of the class. The other is that the symbols themselves of :class:`.InternalTraversal` are used within the ``_traverse_internals`` collection. Such as, the :class:`.Case` object defines ``_traverse_internals`` as :: class Case(ColumnElement[_T]): _traverse_internals = [ ("value", InternalTraversal.dp_clauseelement), ("whens", InternalTraversal.dp_clauseelement_tuples), ("else_", InternalTraversal.dp_clauseelement), ] Above, the :class:`.Case` class indicates its internal state as the attributes named ``value``, ``whens``, and ``else_``. They each link to an :class:`.InternalTraversal` method which indicates the type of datastructure to which each attribute refers. Using the ``_traverse_internals`` structure, objects of type :class:`.InternalTraversible` will have the following methods automatically implemented: * :meth:`.HasTraverseInternals.get_children` * :meth:`.HasTraverseInternals._copy_internals` * :meth:`.HasCacheKey._gen_cache_key` Subclasses can also implement these methods directly, particularly for the :meth:`.HasTraverseInternals._copy_internals` method, when special steps are needed. .. versionadded:: 1.4 HCHLCEFCCTSCLCTEOWCCOSSLANBOTPDDOCDMDAKPODDPSTHSJMESHUKDML_OVDML_VDML_MVPAIGISMMTHTILN)+r:r;r<r]dp_has_cache_keydp_has_cache_key_listdp_clauseelement)dp_fromclause_canonical_column_collectiondp_clauseelement_tuplesdp_clauseelement_listdp_clauseelement_tupledp_executable_optionsdp_with_context_optionsdp_fromclause_ordered_set dp_stringdp_string_list dp_anon_name dp_boolean dp_operatordp_type dp_plain_dictdp_dialect_optionsdp_string_clauseelement_dictdp_string_multi_dictdp_annotations_key dp_plain_objdp_named_ddl_elementdp_prefix_sequencedp_table_hint_listdp_setup_join_tupledp_memoized_select_entitiesdp_statement_hint_listdp_unknown_structuredp_dml_ordered_values dp_dml_valuesdp_dml_multi_valuesdp_propagate_attrs dp_ignoredp_inspectabledp_multi dp_multi_listdp_has_cache_key_tuplesdp_inspectable_listr0r7r5r*r*s%N/ 8<04- $ !"!" $KIN"LJKGM,#'    L   "&!  %+M # )IN%HM'# r7r*cpeZdZUdZdZded<dZded<ejddd  d d Z y ) HasTraverseInternalsabase for classes that have a "traverse internals" element, which defines all kinds of ways of traversing the elements of an object. Compared to :class:`.Visitable`, which relies upon an external visitor to define how the object is travered (i.e. the :class:`.SQLCompiler`), the :class:`.HasTraverseInternals` interface allows classes to define their own traversal, that is, what attributes are accessed and in what order. r0_TraverseInternalsType_traverse_internalsFbool _is_immutablezsqlalchemy.sql.traversals omit_attrsc tjj} |j}|j j }tjjfd|||dDS#t$rgcYSwxYw)aReturn immediate child :class:`.visitors.HasTraverseInternals` elements of this :class:`.visitors.HasTraverseInternals`. This is used for visit traversal. \**kw may contain flags that change the collection that is returned, for example to return a subset of items in order to cut down on larger traversals, or to return child items from a different context (such as schema-level collections instead of clause-level). c3DK|]\}}}|vr | ||fiywr/r0).0attrnameobjrOr4rs r5 z4HasTraverseInternals.get_children..s:- (##tz)co OO(s !_generated_get_children_traversal) r preloadedsql_traversalsrrM _get_childrenrun_generated_dispatch itertoolschain from_iterable)r2rr4 traversalstraverse_internalsdispatchs `` r5 get_childrenz!HasTraverseInternals.get_childrens"^^22  !%!9!9  ++BB,,- '/(*M(-    I s A11 A?>A?N)rTuple[str, ...]r4rr8zIterable[HasTraverseInternals]) r:r;r<r]r^r_rrpreload_modulerr0r7r5rrsYI//M4T45/1 , 9< ' 6 r7rceZdZddZy)_InternalTraversalDispatchTypecyr/r0)sr2r3s r5r6z'_InternalTraversalDispatchType.__call__sr7N)r2objectr3HasTraversalDispatchr8rr9r0r7r5rrsLr7rcpeZdZUdZdZiZded<d dZ d dZ d dZ d dZ y )rzcDefine infrastructure for classes that perform internal traversals .. versionadded:: 2.0 r0z2ClassVar[Dict[Union[InternalTraversal, str], str]]_dispatch_lookupc.t|}t||dS)ztGiven a method from :class:`.HasTraversalDispatch`, return the corresponding method on a subclass. N)rgetattr)r2 visit_symbolrWs r5rzHasTraversalDispatch.dispatchs  -tT4((r7c |jj|}|||S#t$r |j|j||}Y1wxYwr/)rIrDKeyErrorgenerate_dispatch)r2targetinternal_dispatchgenerate_dispatcher_name dispatchers r5rz+HasTraversalDispatch.run_generated_dispatchs_ ))223KLJ&$''  //  "35MJ  s$&A  A cD|j||}t||||Sr/)_generate_dispatchersetattr)r2 target_clsrrrs r5rz&HasTraversalDispatch.generate_dispatchs/ .. 7   4jAr7cg}|D]5\}}|j|}|t|}|j||f7ddjd|Dzdz}d|z|zdz} t t t j| i|S)Nz return [ z, c3:K|]\}}d|d|d|dyw)z (z, self.z , visitor.)Nr0)rrrVs r5rz.1s(16,* :705sz ] zdef %s(self, visitor):  )rrappendjoinrrr_exec_code_in_env) r2r method_namenamesr visit_symrOrVcode meth_texts r5rz)HasTraversalDispatch._generate_dispatcher$s#4 Hi==+D-i8  h 34 $5 16   0+=EL  *  ) ))R E  r7N)rr*r8zCallable[..., Any])rrrrrr>r8r)rz Type[object]rrrr>r8r)rrrr>r8r) r:r;r<r]r^rr_rrrrr0r7r5rrs IKMHM)((2(#& ( (&   2 #&  (  !7 FI ' r7rct}tD]S}|j}|jds!|j dd}|j }||vsJ||x||<||<Uy)Ndp_visit_)rr*rW startswithreplacevalue)lookupsymrY visit_keysym_names r5_generate_traversal_dispatchrCse F hh >>%  E84IyyH6) 38 3)-6 6F3K&* !r7ceZdZUdZej Zded<ejrd dZ dd d dZ d dZ dd d dZ y )ExternallyTraversibler0zMapping[Any, Any] _annotationscyr/r0)r2valuess r5 _annotatezExternallyTraversible._annotateZscr7rc yr/r0r2rr4s r5rz"ExternallyTraversible.get_children\s.1r7c t)zclone this elementNotImplementedError)r2r4s r5_clonezExternallyTraversible._clone`s !##r7c t)atReassign internal elements to be clones of themselves. Called during a copy-and-traverse operation on newly shallow-copied elements to create a deep copy. The given clone function should be used, which may be applying additional transformations to the element (i.e. replacement traversal, cloned traversal, annotations). rrs r5_copy_internalsz%ExternallyTraversible._copy_internalsds "##r7N)rrr8r)rrr4rr8Iterable[ExternallyTraversible])r4rr8r)rrr4rr8r\)r:r;r<r^r EMPTY_DICTrr_r`rrrrrr0r7r5rrSskI&*ooL#5 A46 2!0 2=@ 2 , 2$ 02 $, $9< $  $r7r_ET)bound_CEzColumnElement[Any]ceZdZddZy)_CloneCallableTypec yr/r0r2elementr4s r5r6z_CloneCallableType.__call__|sr7N)rr r4rr8r r9r0r7r5rr{s;r7rceZdZddZy)_TraverseTransformCallableTypec yr/r0rs r5r6z'_TraverseTransformCallableType.__call__s#r7N)rr r4rr8z Optional[_ET]r9r0r7r5rrsEr7r_ExtTr)ceZdZUdZdZiZded<ded<ddZ ddZe dd Z e dd Z dd Z dd Z e dd Z ddZy)r)zBase class for visitor objects which can traverse externally using the :func:`.visitors.traverse` function. Direct usage of the :func:`.visitors.traverse` function is usually preferred. ) _visitor_dict_nextzDict[str, Any]__traverse_options__zOptional[ExternalTraversal]rc t|jD])}t|d|jzd}|s ||fi|cSy)NrK)visitor_iteratorrr?)r2rr4vrOs r5traverse_singlez!ExternalTraversal.traverse_singles<&&A1j3+=+==tDDC2&'r7c.t||jS)zaTraverse the given expression structure, returning an iterator of all elements. )r#rr2rs r5r#zExternalTraversal.iteratessD5566r7cyr/r0r s r5r%zExternalTraversal.traverse47r7cyr/r0r s r5r%zExternalTraversal.traverse!$r7cDt||j|jS2Traverse and visit the given expression structure.)r%rrr s r5r%zExternalTraversal.traverses T668J8JKKr7cri}t|D]&}|jdst||||dd<(|S)Nr)dirrr)r2visitorsrWs r5_memoized_attr__visitor_dictz.ExternalTraversal._memoized_attr__visitor_dictsAIDx(%,T4%8ab"r7c#>K|}|r|t|dd}|ryyw)z8Iterate through this visitor and each 'chained' visitor.rN)r)r2rs r5rz"ExternalTraversal.visitor_iterators(*.G7D)AscDt|jd}||_|S)z'Chain' an additional ExternalTraversal onto this ExternalTraversal The chained visitor will receive all visit events after this one. )listrr)r2r3tails r5rzExternalTraversal.chains% D))*2.  r7N)rr(r4rr8r)rOptional[ExternallyTraversible]r8Iterator[ExternallyTraversible]r Literal[None]r8r\rrr8rrr2r8r2)r8z%Dict[str, _TraverseCallableType[Any]])r8zIterator[ExternalTraversal])r2rr3r)r8r)r:r;r<r]r^rr_rr#rr%r,propertyrrr0r7r5r)r)s+I+-.- &&' 727 (777 $($ $$L2L (L .**r7c`eZdZdZdZ ddZed dZe d dZ d dZy) CloningExternalTraversalzBase class for visitor objects which can traverse using the :func:`.visitors.cloned_traverse` function. Direct usage of the :func:`.visitors.cloned_traverse` function is usually preferred. r0cJ|Dcgc]}|j|c}Scc}w)z`Apply cloned traversal to the given list of elements, and return the new list. )r%)r2list_xs r5copy_and_processz)CloningExternalTraversal.copy_and_processs%+00%Q a %000s cyr/r0r s r5r%z!CloningExternalTraversal.traverser"r7cyr/r0r s r5r%z!CloningExternalTraversal.traverser$r7cDt||j|jSr&)r&rrr s r5r%z!CloningExternalTraversal.traverses$  **D,>,>  r7N)r<List[ExternallyTraversible]r8rBr4r6r7)r:r;r<r]r^r>rr%r0r7r5r:r:sjI101 $177 $($ $$ 2 ( r7r:c`eZdZdZdZ ddZed dZe d dZ d dZy) ReplacingExternalTraversalzBase class for visitor objects which can traverse using the :func:`.visitors.replacement_traverse` function. Direct usage of the :func:`.visitors.replacement_traverse` function is usually preferred. r0cy)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. Nr0)r2elems r5rz"ReplacingExternalTraversal.replacesr7cyr/r0r s r5r%z#ReplacingExternalTraversal.traverse r"r7cyr/r0r s r5r%z#ReplacingExternalTraversal.traverser$r7cJ dfd }t|j|S)r'crjD]'}tt|j|}|%|cSyr/)rrrDr)rr4rer2s r5rz4ReplacingExternalTraversal.traverse..replaces<**3Q7??H=H+ r7)rrr4rr8r2)r'r)r2rrs` r5r%z#ReplacingExternalTraversal.traverses9 *  - $C)B)BGLLr7N)rFrr8r2r4r6r7)r:r;r<r]r^rrr%r0r7r5rDrDsmI )  ( 77 $($ $$M2M (Mr7rDc#K|y||jdi|}|syt|g}|r@|j}|D]'}||j|jdi|)|r?yyw)aHTraverse the given expression structure, returning an iterator. Traversal is configured to be breadth-first. The central API feature used by the :func:`.visitors.iterate` function is the :meth:`_expression.ClauseElement.get_children` method of :class:`_expression.ClauseElement` objects. This method should return all the :class:`_expression.ClauseElement` objects which are associated with a particular :class:`_expression.ClauseElement` object. For example, a :class:`.Case` structure will refer to a series of :class:`_expression.ColumnElement` objects within its "whens" and "else\_" member variables. :param obj: :class:`_expression.ClauseElement` structure to be traversed :param opts: dictionary of iteration options. This dictionary is usually empty in modern usage. Nr0)rrpopleftr)roptschildrenstack t_iteratorts r5r#r#0sx0 { Is'$'H  8* E ]]_ AG LL/$/ 0 s A)A.,A.cyr/r0iteratorrr+s r5r$r$Y r7cyr/r0rTs r5r$r$a  r7cb|D])}|j|jd}|s"||+|S)aVisit the given expression structure using the given iterator of objects. :func:`.visitors.traverse_using` is usually called internally as the result of the :func:`.visitors.traverse` function. :param iterator: an iterable or sequence which will yield :class:`_expression.ClauseElement` structures; the iterator is assumed to be the product of the :func:`.visitors.iterate` function. :param obj: the :class:`_expression.ClauseElement` that was used as the target of the :func:`.iterate` function. :param visitors: dictionary of visit functions. See :func:`.traverse` for details on this dictionary. .. seealso:: :func:`.traverse` N)getr?)rUrr+rrOs r5r$r$is5:||F1148  L Jr7cyr/r0rrNr+s r5r%r%rVr7cyr/r0r\s r5r%r%rXr7c0tt||||S)aTraverse and visit the given expression structure using the default iterator. e.g.:: from sqlalchemy.sql import visitors stmt = select(some_table).where(some_table.c.foo == "bar") def visit_bindparam(bind_param): print("found bound value: %s" % bind_param.value) visitors.traverse(stmt, {}, {"bindparam": visit_bindparam}) The iteration of objects uses the :func:`.visitors.iterate` function, which does a breadth-first traversal using a stack. :param obj: :class:`_expression.ClauseElement` structure to be traversed :param opts: dictionary of iteration options. This dictionary is usually empty in modern usage. :param visitors: dictionary of visit functions. The dictionary should have strings as keys, each of which would correspond to the ``__visit_name__`` of a particular kind of SQL expression object, and callable functions as values, each of which represents a visitor function for that kind of object. )r$r#r\s r5r%r%sH '#t,c8 <.deferred_copy_internalsssD(33r7c|vr|St|vrd|vr2ttt|d|}||t|<|S|jddi|xt|<}|j ddi||j s&j|jd}|r||t|S)Nrcloner0) idrrrrrrrZr?)rFr4newelemrOrgclonedrcr+s r5rgzcloned_traverse..clone s 7?K$xv%?" !67It9LG*+2r$x(&.9T[[-Ku-K-KKr$x 7''':e:r: ))#<<(>(>EDW "T(# #r7Nrer6rFrr4rr8r)setrZ)rrNr+rergrjrcs `` @@@r5r&r&soZ02F$((9b)*G4 "4 4 $$<   )@ DH  E Jr7cyr/r0rrNrs r5r'r'3rVr7cyr/r0rns r5r'r';rar7cyr/r0rns r5r'r'CrXr7cijdgDchc] }t|c} dfd }dfd | |fd|i}d|Scc}w)a]Clone the given expression structure, allowing element replacement by a given replacement function. This function is very similar to the :func:`.visitors.cloned_traverse` function, except instead of being passed a dictionary of visitors, all elements are unconditionally passed into the given replace function. The replace function then has the option to return an entirely new object which will replace the one given. If it returns ``None``, then the object is kept in place. The difference in usage between :func:`.visitors.cloned_traverse` and :func:`.visitors.replacement_traverse` is that in the former case, an already-cloned object is passed to the visitor function, and the visitor function can then manipulate the internal state of the object. In the case of the latter, the visitor function should only return an entirely different object, or do nothing. The use case for :func:`.visitors.replacement_traverse` is that of replacing a FROM clause inside of a SQL structure with a different one, as is a common use case within the ORM. rcct|Sr/)r'rns r5rez5replacement_traverse..deferred_copy_internalsjs$Cw77r7c8t|vsd|jvr|S|}|jt||St|}|vrCd|vr|d|}|||<|S|jdi|x|<}|jddi||S)Nno_replacement_traverserrgr0)rhraddrr)rFr4riid_elemrgrjrrcs r5rgz#replacement_traverse..cloneos tH (D,=,==KdmG" BwK( T(&( B"/"Y-"5"..5F7O#*N0; 0Ab0AAF7Og+G++>%>2>g&r7Nrer6rk)rZrh)rrNrr=rergrjrcs `` @@@r5r'r'Ks8F"hhy"565r!u56G8 "8 8 ''6   )@ DH  E JO7sAr[)rr2rNMapping[str, Any]r8r3)rUr rr5r+(Mapping[str, _TraverseCallableType[Any]]r8r\)rUr rrr+rxr8r)rUr rr2r+rxr8r2)rr5rNrwr+rxr8r\)rrrNrwr+rxr8r)rr2rNrwr+rxr8r2)rr rNrwr+rxr8r )rr5rNrwr#_TraverseTransformCallableType[Any]r8r\)rr rNrwrryr8r )rrrNrwrryr8r)rr2rNrwrryr8r2)Nr] __future__r collectionsrenumrrrTr`rrrr r r r r rrrrrrrrrrr util._has_cyr util.typingrrr annotationrelementsr _py_utilr!r"r+sqlalchemy.cyextension.util__all__r-r(r*r>rrrrExtendedInternalTraversalrrrr r _TraverseCallableTyperrr MemoizedSlotsr)r:rD Traversible ClauseVisitorCloningVisitorReplacingCloningVisitorr r#r$r%r&r'r0r7r5rs #  *!"+' <4 NHNGGTPPfeC):$:;< 1 1 hMXML L ^. 7(88$0)$Be01 e/0 #-<<FXc]F 23G**GT$ 0$ N.M!9.Md ! )4 #oo&1 (&1 &1%&1R - 7    -  7     !-! (!7!% !H   7      7     $= ($= $=7$=% $=N   7     7  X (X X7X% Xv   1     1      1     D (D D1D% Dr7