L iUddlmZddlmZddlZddlZddlZddlZddl Z ddl m Z ddl m Z ddl m Z ddl mZddl mZddl mZdd l mZdd l mZdd l mZdd l mZdd l mZddl mZddlZddlmZddlmZddlmZddlmZddlmZddlmZddl m!Z!ddl m"Z"ddl m#Z#ddlm$Z$ddl%m&Z&ddlm'Z'ddlm(Z(ddlm)Z)ddl*m+Z+erdd lm,Z,dd!lm-Z-dd"lm.Z.dd#lm/Z/eee d$fed%fZ0e d$e fZ1e)jdd&Z3d'e4d(<e ge fZ5e d$e fZ6e ge fZ7ed)e"*Z8e e8ge fZ9Gd+d,e#Z: dA dBd.Z;Gd/d0ejZZ<Gd1d2e<Z=Gd3d-ej|ed?e&ZEe(je<d@ZGy)C) annotationsN)CodeType)Any)Callable)cast)List)MutableMapping)Optional)Tuple)Type) TYPE_CHECKING)TypeVar)Union) cache_key) coercions)elements)roles)schema)visitors)_clone) Executable)Options) CacheConst)ColumnOperators)exc) inspection)util)Literal) BindParameter) ClauseElement)SQLRole)_CloneCallableType.)NonAnalyzedFunctionAnalyzedFunctioni_LambdaCacheType_closure_per_cache_key_E)boundc:eZdZUdZdZdZded<dZdZdZ ded<y) LambdaOptionsTNOptional[object]track_onOptional[_LambdaCacheType] lambda_cache) __name__ __module__ __qualname__enable_trackingtrack_closure_variablesr.__annotations__global_track_bound_valuestrack_bound_valuesr0\/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sqlalchemy/sql/lambdas.pyr,r,Hs/O"!%H% $/3L,3r:r,StatementLambdaElementc Vt|tjt||||||S)ahProduce a SQL statement that is cached as a lambda. The Python code object within the lambda is scanned for both Python literals that will become bound parameters as well as closure variables that refer to Core or ORM constructs that may vary. The lambda itself will be invoked only once per particular set of constructs detected. E.g.:: from sqlalchemy import lambda_stmt stmt = lambda_stmt(lambda: table.select()) stmt += lambda s: s.where(table.c.id == 5) result = connection.execute(stmt) The object returned is an instance of :class:`_sql.StatementLambdaElement`. .. versionadded:: 1.4 :param lmb: a Python function, typically a lambda, which takes no arguments and returns a SQL expression construct :param enable_tracking: when False, all scanning of the given lambda for changes in closure variables or bound parameters is disabled. Use for a lambda that produces the identical results in all cases with no parameterization. :param track_closure_variables: when False, changes in closure variables within the lambda will not be scanned. Use for a lambda where the state of its closure variables will never change the SQL structure returned by the lambda. :param track_bound_values: when False, bound parameter tracking will be disabled for the given lambda. Use for a lambda that either does not produce any bound values, or where the initial bound values never change. :param global_track_bound_values: when False, bound parameter tracking will be disabled for the entire statement including additional links added via the :meth:`_sql.StatementLambdaElement.add_criteria` method. :param lambda_cache: a dictionary or other mapping-like object where information about the lambda's Python code as well as the tracked closure variables in the lambda itself will be stored. Defaults to a global LRU cache. This cache is independent of the "compiled_cache" used by the :class:`_engine.Connection` object. .. seealso:: :ref:`engine_lambda_caching` )r4r.r5r7r8r0)r<r StatementRoler,)lmbr4r5r.r7r8r0s r; lambda_stmtr@Qs8v "  +$;&?1%    r:c\eZdZUdZdZdZdejjfgZ dZ de d<de d <d Z d e d <d e d<de d<de d<de d<de d<dZ ed f d$dZdZdZedZedZedZdZdZed f d%d Zej6d!Zd"Zd&d#Zy )' LambdaElementaA SQL construct where the state is stored as an un-invoked lambda. The :class:`_sql.LambdaElement` is produced transparently whenever passing lambda expressions into SQL constructs, such as:: stmt = select(table).where(lambda: table.c.col == parameter) The :class:`_sql.LambdaElement` is the base of the :class:`_sql.StatementLambdaElement` which represents a full statement within a lambda. .. versionadded:: 1.4 .. seealso:: :ref:`engine_lambda_caching` lambda_elementT _resolvedr9zTuple[_CloneCallableType, ...] _transformszList[BindParameter[Any]]_resolved_bindparamsNz Optional[StatementLambdaElement] parent_lambdaz4Union[Tuple[Any, ...], Literal[CacheConst.NO_CACHE]]closure_cache_key Type[SQLRole]rolez,Union[AnalyzedFunction, NonAnalyzedFunction]_rec_AnyLambdaTypefnzTuple[CodeType, ...] tracker_keycb|jjd|jjdS)N()) __class__r1rM__code__selfs r;__repr__zLambdaElement.__repr__s& NN # # GG    r:c||_||_|jf|_||_||t j ur|}|j|||}||j}|r||_ yyyN) rMrJrSrNoptsrr>_retrieve_tracker_recpropagate_attrs_propagate_attrs)rUrMrJrYapply_propagate_attrsrecr[s r;__init__zLambdaElement.__init__s| KK> (de6I6I.I$( !((-BDI ,!11O9H%6 -r:c H|j}|t}|j}|j}|j}t j |||}gx|_}|j|jj} nd} | tjurtj} t|jD cgc] } | ||| |c} } tj| vr!| | z} | |_ |j || z} n%tj} d} ntj} d} | |_ | y| tjurLt j 5|| z}||vr$t#||||} t%|| _| ||<n||} dddnbt)|j+|} nGt-| j&|Dcgc]"\}}|j/|j0d$c}}|dd| |_| tjur|j|jj|dd|}|X|j2} | j4r1| j6}| j4D]}||j|||j}|X| Scc} w#1swYxYwcc}}w)Nr9T maintain_keyr)r0r(rNrM __closure__ AnalyzedCodegetrFrGrH _cache_keyNO_CACHEranon_maptupleclosure_trackers_generation_mutexr&listclosure_bindparamsr%_invoke_user_fnzip _with_valuevaluerKbindparam_trackerstracker_instrumented_fn)rUrMr]rYr0rNclosuretracker bindparamsparent_closure_cache_keyrhgetterrr^key orig_bindnew_bindrCrss r;rZz#LambdaElement._retrieve_tracker_recs((  1L&& WW..""    243!J    )'+'9'9'K'K $') $ $:+>+> >((*H#*":":7D(J?I""(24y@ )2&"&&{Y'>?&// #++IC!* ; 3 33!33 0% 1C,..#T+@"26j1A.,/ S)*3/ 0 0*$*>*>r*BC ,/**J,'Ix%%hnn4%HJqM J// /!!-!%!3!3!H!H 2A6:N ,$))))33,$'#9#9*--3& "0!=!=!, E0 0 0s7J 3J'JJcBt|jj|SrX)getattrrK expected_exprrUrys r; __getattr__zLambdaElement.__getattr__<styy..44r:c.|jjSrX)rK is_sequencerTs r; _is_sequencezLambdaElement._is_sequence?syy$$$r:c|jrAtjj|jDcgc]}|j c}S|jj Scc}wrX)r itertoolschain from_iterablerD_select_iterablerUelements r;rzLambdaElement._select_iterableCsR   ??009=Hg))H  >>22 2 IA$c|jrAtjj|jDcgc]}|j c}S|jj Scc}wrX)rrrrrD _from_objectsrs r;rzLambdaElement._from_objectsMsR   ??006:nnE7&&E  >>// / Frcj|jDcic]}|j|jc}Scc}wrX)rFryrq)rUbs r; _param_dictzLambdaElement._param_dictWs((,(A(AB1qwwBBBs0c>|jDcic]}|j|c} dfd }|jjr&|Dcgc]}t j |i|}}|St |ddrt j |i|}|Scc}wcc}w)Nct|tjrT|jvrF|j}|jr)d|_|j |_|j |_|SyNT) isinstancerr!ry expanding expand_optype)rkwbindbindparam_lookups r;replacez.replace]s`'8#9#9:;;"22+GKK8D(()-)0):):$+LL Kr:is_clause_elementF)r(Optional[visitors.ExternallyTraversible]rrreturnr)rFryrKrrreplacement_traverser})rUexprrrsub_exprrs @r;_setup_binds_for_tracked_exprz+LambdaElement._setup_binds_for_tracked_exprZs.2.G.GHAEE1HH = EH  5  99 !%--hGDD T. 600r7CD 1I"s B Bc 8||jfd|i||_y)Ndeferred_copy_internals)rD)rUclonerrs r;_copy_internalszLambdaElement._copy_internalsus) NN $;  r:cl|jj}|jr|j|}|SrX)rKr~rFrrUrs r;rDzLambdaElement._resolveds/yy&&  $ $55d;D r:c|jtjurd|tj<y|jj|j f|jz}|j }|V|jtjusJ|j}|jjf|z|z}|j }|V|jr|j|j|Sr) rHrfrgrMrSrRrGrrFextend)rUrhrvrparentrws r;_gen_cache_keyzLambdaElement._gen_cache_keys  ! !Z%8%8 8,0HZ(( ) GG   NN   " "# ## ++:3F3FF FF(( % ##%(@@9L ))F   $ $   d77 8r:c|SrXr9rUrMargs r;rnzLambdaElement._invoke_user_fns t r:)rM _LambdaTyperJrIrY)Union[Type[LambdaOptions], LambdaOptions]r]Optional[ClauseElement])rr$rzOptional[_CloneCallableType]rrrNone)rMrLrrrr")r1r2r3__doc____visit_name___is_lambda_elementrInternalTraversaldp_clauseelement_traverse_internalsrEr6rGrVr,r_rZrpropertyrrrrrrrrmemoized_propertyrDrrnr9r:r;rBrBsV&&N h00AAB35K/4226:M3:KK  66%% ;H9= I II8 I 7 I,^@5%%3300C:%+@D  !  ">       8r:rBcVeZdZdZedf dfd ZdZd dZedffd Z xZ S) DeferredLambdaElementa>A LambdaElement where the lambda accepts arguments and is invoked within the compile phase with special context. This lambda doesn't normally produce its real SQL expression outside of the compile phase. It is passed a fixed set of initial arguments so that it can generate a sample expression. r9c6||_t| |||yrX) lambda_argssuperr_)rUrMrJrYrrRs r;r_zDeferredLambdaElement.__init__s' T4(r:c ||jSrX)rrs r;rnz%DeferredLambdaElement._invoke_user_fns4##$$r:ct|jtsJ|jj}||}t j |j |}|j|}|jD] }||} |SrX) rrKr&rsrexpectrJrrE)rUr tracker_fnrrs r;_resolve_with_argsz(DeferredLambdaElement._resolve_with_argss$))%5666YY66 ;' 4011$70(,'7'7 1 #*40D 1 r:Nc \t|||||r|xj|fz c_yy)N)rrrY)rrrE)rUrrrrRs r;rz%DeferredLambdaElement._copy_internalss? $;   #   !8 : :  #r:)rMrLrJzType[roles.SQLRole]rYrrzTuple[Any, ...])rrrr") r1r2r3rr,r_rnrrr __classcell__)rRs@r;rrsX;H') ) )")8 ) % )%"JD ; ;r:rc(eZdZdZeredf ddZ ddZ d ddZdZ e ddZ e dZ e d Z e d Ze d Ze d Ze d Ze dZe dZe dZe dZddZy)r<a_Represent a composable SQL statement as a :class:`_sql.LambdaElement`. The :class:`_sql.StatementLambdaElement` is constructed using the :func:`_sql.lambda_stmt` function:: from sqlalchemy import lambda_stmt stmt = lambda_stmt(lambda: select(table)) Once constructed, additional criteria can be built onto the statement by adding subsequent lambdas, which accept the existing statement object as a single parameter:: stmt += lambda s: s.where(table.c.col == parameter) .. versionadded:: 1.4 .. seealso:: :ref:`engine_lambda_caching` NcyrXr9)rUrMrJrYr]s r;r_zStatementLambdaElement.__init__s r:c$|j|SrX) add_criteria)rUothers r;__add__zStatementLambdaElement.__add__s  ''r:c|jt|||jj||z}t|||S)a(Add new criteria to this :class:`_sql.StatementLambdaElement`. E.g.:: >>> def my_stmt(parameter): ... stmt = lambda_stmt( ... lambda: select(table.c.x, table.c.y), ... ) ... stmt = stmt.add_criteria(lambda: table.c.x > parameter) ... return stmt The :meth:`_sql.StatementLambdaElement.add_criteria` method is equivalent to using the Python addition operator to add a new lambda, except that additional arguments may be added including ``track_closure_values`` and ``track_on``:: >>> def my_stmt(self, foo): ... stmt = lambda_stmt( ... lambda: select(func.max(foo.x, foo.y)), ... track_closure_variables=False, ... ) ... stmt = stmt.add_criteria(lambda: self.where_criteria, track_on=[self]) ... return stmt See :func:`_sql.lambda_stmt` for a description of the parameters accepted. )r4r5r7r.r8)rGrY)rYdictr7LinkedLambdaElement)rUrr4r.r5r8rYs r;rz#StatementLambdaElement.add_criteriasDJyy4+$;&*ii&I&I1   #54HHr:ctr&t|jjtsJ|jjj r|j |||Stj|rX) r rrKr~r"supports_execution_execute_clauseelementrObjectNotExecutableErrorrU connectiondistilled_paramsexecution_optionss r;_execute_on_connectionz-StatementLambdaElement._execute_on_connectionNsc dii55}E EE 99 " " 5 544&(9 ..t4 4r:c|jSrX)_rec_expected_exprrTs r;_proxiedzStatementLambdaElement._proxiedZs&&&r:c.|jjSrX)r _with_optionsrTs r;rz$StatementLambdaElement._with_options^s}}***r:c.|jjSrX)r_effective_plugin_targetrTs r;rz/StatementLambdaElement._effective_plugin_targetbs}}555r:c.|jjSrX)r_execution_optionsrTs r;rz)StatementLambdaElement._execution_optionsfs}}///r:c.|jjSrX)r_all_selected_columnsrTs r;rz,StatementLambdaElement._all_selected_columnsjs}}222r:c.|jjSrX)r is_selectrTs r;rz StatementLambdaElement.is_selectn}}&&&r:c.|jjSrX)r is_updaterTs r;rz StatementLambdaElement.is_updaterrr:c.|jjSrX)r is_insertrTs r;rz StatementLambdaElement.is_insertvrr:c.|jjSrX)ris_textrTs r;rzStatementLambdaElement.is_textzs}}$$$r:c.|jjSrX)r is_deleterTs r;rz StatementLambdaElement.is_delete~rr:c.|jjSrX)ris_dmlrTs r;rzStatementLambdaElement.is_dmls}}###r:c4t|jS)ztReturn a new :class:`.StatementLambdaElement` that will run all lambdas unconditionally each time. )NullLambdaStatementrMrTs r;spoilzStatementLambdaElement.spoils #4779--r:)rM_StmtLambdaTyperJrIrYrr]r)r_StmtLambdaElementType[Any]rr<)TNTT) rrr4boolr.z Optional[Any]r5rr8rrr<)rr)rr)r1r2r3rr r,r_rrrrrrrrrrrrrrrrr9r:r;r<r<s0 ?L=A     <   $;  (0( (!%"&(,#' -I*-I-I -I "& -I ! -I -I^ 5''++660033''''''%%''$$.r:cheZdZdZdZdZdejjfgZ dZ dZ dZ dZ d Zy ) rzProvides the :class:`.StatementLambdaElement` API but does not cache or analyze lambdas. the lambdas are instead invoked immediately. The intended use is to isolate issues that may arise when using lambda statements. rCTrDc4||_|j|_yrX)rDr\)rU statements r;r_zNullLambdaStatement.__init__s" ) : :r:c.t|j|SrX)r}rDrs r;rzNullLambdaStatement.__getattr__st~~s++r:c<||j}t|SrXrDr)rUrrs r;rzNullLambdaStatement.__add__$..) "9--r:c <||j}t|SrXr)rUrrrs r;rz NullLambdaStatement.add_criteriarr:c~|jjr|j|||Stj|rX)rDrrrrrs r;rz*NullLambdaStatement._execute_on_connections@ >> , ,44&(9 ..t4 4r:N)r1r2r3rrrrrrrr_rrrrr9r:r;rrsK&N h00AAB;,. . 5r:rc6eZdZUdZded< ddZdZy)rzARepresent subsequent links of a :class:`.StatementLambdaElement`.r<rGc||_||_||_|j|jfz|_|j ||||j |_yrX)rYrMrGrNrSrZr\)rUrMrGrYs r;r_zLinkedLambdaElement.__init__sS  *(44 ~E ""2tT2 - > >r:c:||jjSrX)rGrDrs r;rnz#LinkedLambdaElement._invoke_user_fns$$$..//r:N)rMrrGr<rYr)r1r2r3rr6r_rnr9r:r;rrs1K)) ? ' ?. ?8 ?0r:rceZdZUdZej Zded<ejZ e dZ dZ dZdZdZd Ze d Zd Zd Zd Z ddZ ddZdZy)rd)r5r8rrrjbuild_py_wrappersz1weakref.WeakKeyDictionary[CodeType, AnalyzedCode]_fnsc ^ |j|jS#t$rYnwxYw|j5|j|jvr"|j|jcdddSt |||fi|x|j|j<}|cdddS#1swYyxYwrX)rrSKeyErrorrkrd)clsrMrC lambda_kwranalyzeds r;rezAnalyzedCode.gets 88BKK( (    " " {{chh&xx ,   0<NI0130 CHHR[[ !H   s ''1B#1(B##B,ctj|rtjd|z|j}|j xr |j |_|j}|j}|j}|xr| |_ g|_ g|_ g|_ |r7|r|j||j||r|j||j!|||y)Nz/Method %s may not be passed as a SQL expression)inspectismethodr ArgumentErrorrcr8r7r4r.r5rrrjr_init_track_on _init_globals _init_closure"_setup_additional_closure_trackers)rUrMrCrYrtr4r.r5s r;r_zAnalyzedCode.__init__s   B ##ABF ..  # # F(F(F ..=="&">">'>'Ox<$ #% !#!# ##H-   r """2& //NDIr:c`jjfdt|Dy)Nc3HK|]\}}j||ywrX)_cache_key_getter_track_on).0idxelemrUs r; z.AnalyzedCode._init_track_on..s*% T  + +C 6% s")rjr enumerate)rUr.s` r;rzAnalyzedCode._init_track_ons) $$% &x0%  r:ct|j}|j}|j}|jjD]{}||j vr|j |j |}tj|sF|j|df|s\|j|j|}yrX) rrrr8rSco_names __globals___roll_down_to_literalr_deep_is_literalappend$_bound_parameter_getter_func_globals)rUrMrrrr8name _bound_values r;rzAnalyzedCode._init_globals"s 22!44!44KK(( D2>>)55bnnT6JKL)),7!(($6%&--AA$G r:c ,|j}|j}|j}|j}|j}|j }t t|jj|D]\}\} } |j| j} tj| r8|j| |f|sO|j|j| |q|st|j|j!|| || jyrX)rrcr8r5rrrjrrorS co_freevarsr cell_contentsrr r!$_bound_parameter_getter_func_closure"_cache_key_getter_closure_variable) rUrMrrtr8r5rrrj closure_indexfvcellr$s r;rzAnalyzedCode._init_closure4s 22..!44"&">">!4400)2  '' 1*   %M:B 55d6H6HIL)),7!(("m)<=%&--AA +$++??M43E3E) r:ct||d|}|j}|jD]0}|jr|j |j ||2yrX)r&rjclosure_pywrappers_sa__has_paramr!!_cache_key_getter_tracked_literal)rUrMrCrYanalyzed_functionrj pywrappers r;rz/AnalyzedCode._setup_additional_closure_trackersWse-       00*== I++ ''::2yI r:ct|d}|rpt|tjtj t fsA |j}t|tjtj t fsA|s,tj|d}| |jS|S|S#t$rY;wxYw#t$r|cYSwxYw)N__clause_element__Fraiseerr) hasattrrrr"r SchemaItemrr4AttributeErrorrr )r rrinsps r;rz"AnalyzedCode._roll_down_to_literalms#G-AB  (00&2C2CTJ%88:G !(00&2C2CTJ!%%g>D 2244 NN&& K s#B/B>/ B;:B;> C  C cfd}|S)zReturn a getter that will extend a list of bound parameters with new entries from the ``__globals__`` collection of a particular lambda. cv|j}tj|d|j|yN_extract_bound_parameters)robject__getattribute__) current_fnrsresultwrapperr#s r;extract_parameter_valuezRAnalyzedCode._bound_parameter_getter_func_globals..extract_parameter_values;.99$?G  # #G-H I&&t,f r:r9)rUr#rDs ` r;r"z1AnalyzedCode._bound_parameter_getter_func_globalss '&r:cfd}|S)zReturn a getter that will extend a list of bound parameters with new entries from the ``__closure__`` collection of a particular lambda. c|jj}tj|d|jj|yr=)rcr'r?r@)rArsrBrCr*s r;rDzRAnalyzedCode._bound_parameter_getter_func_closure..extract_parameter_valuesN.99m   # #G-H I&&}5CCV r:r9)rUr#r*rDs ` r;r(z1AnalyzedCode._bound_parameter_getter_func_closures '&r:ct|trfd}|St|tjrfd}|Sfd}|S)zReturn a getter that will extend a cache key with new entries from the "track_on" parameter passed to a :class:`.LambdaElement`. cLtfd|jDS)Nc3BK|]}|jywrXr)rtup_elemrhrvs r;rzGAnalyzedCode._cache_key_getter_track_on..get..s& ++HjA)rir.rtrYrhrvrs ``r;rez4AnalyzedCode._cache_key_getter_track_on..gets&$(MM#$6r:cB|jj||SrX)r.rrMs r;rez4AnalyzedCode._cache_key_getter_track_on..gets}}S)88:NNr:c"|jSrX)r.rMs r;rez4AnalyzedCode._cache_key_getter_track_on..gets}}S))r:)rrirf HasCacheKey)rUrrres ` r;rz'AnalyzedCode._cache_key_getter_track_onsF dE "   j44 5 O  * r:ct|tjr fd}|St|tjrfd}|St|t j r fd}|S|}d} t|dr.d} t|dds|j}nn t|dr.| s/tj|d} | ,j| d Sj|d SjS) zReturn a getter that will extend a cache key with new entries from the ``__closure__`` collection of a particular lambda. c|j}rtj|}n8r6t|dr*t |dds|j }t|dr*|j ||S)Nr4rF)r'rr r7r}r4r)rtrYrhrvobjruse_clause_element use_inspects r;rez.getspcl00$,,S1C'!#';<&s,?G"%"8"8":C"#';<))(J??r:c6|jjSrX)r'rSrMs r;rez.getss|11:::r:c|j} tfd|DS#t$r}j |Yd}~yd}~wwxYw)Nc3BK|]}|jywrXrJ)rrrhrvs r;rzOAnalyzedCode._cache_key_getter_closure_variable..get..s&! ++HjA!rL)from_)r'rir9'_raise_for_uncacheable_closure_variable) rtrYrhrvcontentsaerMrrU variable_names `` r;rez.getsc"3<55 !$,!&@@%rAs) AA  AFr4Trr5)rU)rT)rrfrPtypes FunctionTypecollections_abcSequencer7r}r4rr r)rZ) rUrMr]rr'rTrUrerrr:s ```` `` r;r)z/AnalyzedCode._cache_key_getter_closure_variables) mZ%;%; < @t _ u'9'9 : ;Z U '?'? @ P -$G % '#78$(!w(;UC%88:G '#78%!))'EB#BBM3$C>> sG?  8 8 K r:NcPtjd|d|jd|)NzClosure variable named 'z' inside of lambda callable a does not refer to a cacheable SQL element, and also does not appear to be serving as a SQL literal bound value based on the default SQL expression returned by the function. This variable needs to remain outside the scope of a SQL-generating lambda so that a proper cache key may be generated from the lambda's state. Evaluate this variable outside of the lambda, set track_on=[] to explicitly select closure elements to track, or set track_closure_variables=False to exclude closure variables from being part of the cache key.)rInvalidRequestErrorrS)rUr]rMrYs r;rZz4AnalyzedCode._raise_for_uncacheable_closure_variables,%%bkk +  r:cr|j}|j}|j}|j||||S)aReturn a getter that will extend a cache key with new entries from the ``__closure__`` collection of a particular lambda. this getter differs from _cache_key_getter_closure_variable in that these are detected after the function is run, and PyWrapper objects have recorded that a particular literal value is in fact not being interpreted as a bound parameter. )_sa__to_evaluate_sa__closure_index _sa__namer))rUrM pytrackerrr*r]s r;r0z.AnalyzedCode._cache_key_getter_tracked_literal$sA))!44 !++ 66  }d  r:)FFrX)r1r2r3 __slots__weakrefWeakKeyDictionaryrr6 threadingRLockrk classmethodrer_rrrrrr"r(rr)rZr0r9r:r;rdrdsI "!!# ;( )$%JN $!F,2'"'&@!JZ(,& r:rdcVeZdZUdZdZded<dZded<dZded <d d Ze d d Z y)r%rN"Optional[List[BindParameter[Any]]]rm%Optional[List[_BoundParameterGetter]]rrFr"rc||_yrXrprs r;r_zNonAnalyzedFunction.__init__Bs  r:c|jSrXrprTs r;r~z!NonAnalyzedFunction.expected_exprEs yyr:)rr")rr") r1r2r3rirmr6rrrr_rr~r9r:r;r%r%8sCI=A:A@D=DK r:r%cHeZdZUdZded<ded<ded<dZd Zd Zd Zy ) r&) analyzed_coderMr.rsrrrr~rr[rmrqrmz)Union[ClauseElement, List[ClauseElement]]r~rrrrc||_||_|j|_|j||j ||yrX)rvrMrr_instrument_and_run_function_coerce_expression)rUrvrCr]rMs r;r_zAnalyzedFunction.__init__\s@+"/"B"B )).9 0EFr:c:|j}|j}gx|_}|j}|s |x|_}|j ||_y|j}|j}|r>t|jj|D cic]\} } | | j} } } ni} |jj} |D]s\} }|M||j}t|| |||jj x| | <}|sC|j#|U|j| }t|| || | <u|j%||jjD cgc]} | |  c} | x|_}|j ||_ycc} } wcc} w)N)r*r8)rvrMr.rrsrnrr5rcrorSr&r'rcopy PyWrapperr8r!_rewrite_code_obj)rUrCrvrMr.rrsr5rtr+r, new_closure new_globalsr#r*rqrs r;rxz-AnalyzedFunction._instrument_and_run_functionls** WW799"4);; EG GD (+B&667NODI&3&K&K #nnG%( (?(?$I D***  ! ..--/K'8 C#m ,#M2@@E/8&3 ..AA 0K%/*11$7NN40E(1"dE(BK%! C*&&35;;3J3JK4[&K D (+B&'667NODIcBLs F F c |j}|j}|t|tjrG|Dcgc].}t dt j|j||0c}|_ d|_ nGt dt j|j|||_ d|_ n||_ d|_ ||j|_ ytj|_ ycc}w)a,Run the tracker-generated expression through coercion rules. After the user-defined lambda has been invoked to produce a statement for re-use, run it through coercion rules to both check that it's the correct type of object and also to coerce it to its useful form. Nr")r]TF)rGrrr`rarrrrJr~rr\r[r EMPTY_DICT)rUrCr]rGrrs r;ryz#AnalyzedFunction._coerce_expressions'44 yy  $ 8 89%) &!'!((*//$2G &"$( %)#$$&++.C&"$) !%D $D  ,#8#I#ID #'??D ; &s3C-cHtt|}d}|r8|ddjd|Dddjd|Ddz }|dz }|d djd |Dzz }|d z }|Dcic] }d |z|| }}t||||d }t ||j ||j |j|} |j| _|j| _ |j| _ |j| _ | Scc}w)zaReturn a copy of f, with a new closure and new globals yes it works in pypy :P zdef make_cells(): z (z, c3&K|] }d|z ywzi%dNr9ris r;rz5AnalyzedFunction._rewrite_code_obj..6%!)6z) = (c3&K|] }d|z yw)o%dNr9rs r;rz5AnalyzedFunction._rewrite_code_obj..rrz) z def closure(): z return %s c3&K|] }d|z ywrr9rs r;rz5AnalyzedFunction._rewrite_code_obj..s1N%!)1Nrz return closure.__closure__r make_cells) rangelenjoinexecrrSr1 __defaults__r6__kwdefaults__rr2) rUf cell_valuesglobals_argrangecodervars_rtfuncs r;r}z"AnalyzedFunction._rewrite_code_objs%[)*$   6X66 6X66 D && % 1NX1N(NNN 004<=qKN*== T5% %% %'tAw JJ!**anng  !00..yy ,, >s=DN) r1r2r3rir6r_rxryr}r9r:r;r&r&Js6 I;:<<==G BPH+3Zr:r&c\eZdZdZ ddZdZdZdZdZddZ d Z d Z d Z d Z d Zy)r|aA wrapper object that is injected into the ``__globals__`` and ``__closure__`` of a Python function. When the function is instrumented with :class:`.PyWrapper` objects, it is then invoked just once in order to set up the wrappers. We look through all the :class:`.PyWrapper` objects we made to find the ones that generated a :class:`.BindParameter` object, e.g. the expression system interpreted something as a literal. Those positions in the globals/closure are then ones that we will look at, each time a new lambda comes in that refers to the same ``__code__`` object. In this way, we keep a single version of the SQL expression that this lambda produced, without calling upon the Python function that created it more than once, unless its other closure variables have changed. The expression is then transformed to have the new bound values embedded into it. Nc||_||_||_d|_d|_i|_||_||_||_y)NF) rM_name _to_evaluate_param _has_param _bind_paths_getter_closure_indexr8)rUrMr# to_evaluater*rxr8s r;r_zPyWrapper.__init__sG '  +"4r:cDtj|d}||i|}|jrutj|r`t |t jsFtj|d}tjd|d|jjd|S)NrrzCan't invoke Python callable z+() inside of lambda expression argument at a; lambda SQL constructs should not invoke functions from closure variables to produce literal values since the lambda SQL system normally extracts bound values without actually invoking the lambda or any functions within it. Call the function outside of the lambda and assign to a local variable that is used in the lambda as a closure variable, or set track_bound_values=False if the return value of this function is used in some other way other than a SQL bound value.) r?r@_sa_track_bound_valuesrr rrfrPrrc_sa_fnrS)rUrrrrqr#s r;__call__zPyWrapper.__call__#s&&t^<c R   ' '**51&& **49D))!$++"6"6 8  Lr:cNtj|d}||g|i|SN_py_wrapper_literalr?r@rUoprkwargsrs r;operatezPyWrapper.operateBs-&&t-BCE$))&))r:c Jtj|d}|||fi|Srrrs r;reverse_operatezPyWrapper.reverse_operateFs*&&t-BCE%(((r:c.tj|d}|$|j|d}|j|tj|dj D]2}tj|d}||}|j ||4y)NrTrarr)r?r@rpr!values_sa__extract_bound_parameters)rUstarting_point result_listparamr2rxrs r;r>z#PyWrapper._extract_bound_parametersJs''h7  %%n4%HE   u %00}ELLN JI,,Y BF^,G  3 3G[ I Jr:c tj|d}tj|d}|Ltj|d}tj|dd|| |jndx|_}d|_|j|dS)NrrrFT)requiredunique_compared_to_operator_compared_to_typera)r?r@rr!rrrrp)rUroperatorrrrr#s r;rzPyWrapper._py_wrapper_literalTs''h7--dNC =**49D"*"8"8&./3/?$))T # DK%#DO  4 @@r:cDtj|d}t|SNr)r?r@r)rUrs r;__bool__zPyWrapper.__bool__cs--dNC K  r:c0|jdrtj||ddS|dvrtj||S|jdr"tj|d}t||S|j |t j S)N_sa_)r4rrrrR__dict____r) startswithr?r@r}_sa__add_getterr attrgetterrUryrs r;r@zPyWrapper.__getattribute__gs >>& !**4QR9 9   **45 5 >>$ **4@D4% %''X-@-@A Ar:cDtj|d}t|Sr)r?r@iter)rUrs r;__iter__zPyWrapper.__iter__zs&&t^<Dzr:ctj|d}t|ds tdt |t rt jd|j|tjS)Nr __getitem__zUDictionary keys / list indexes inside of a cached lambda must be Python literals only) r?r@r7r9rr|rrcrr itemgetterrs r;rzPyWrapper.__getitem__~sf&&t^<t]+ / / c9 %))6 ##C)<)<==r:c,tj|d}||f}||vr||S||}tj|d}||}tj|}t j |r t |j|||} | ||<| S|S)Nrr)rx)r?r@rdrrr r|r) rUry getter_fn bind_paths bind_path_keyrxrrqrolled_down_valuerCs r; _add_getterzPyWrapper._add_getters,,T=A i( J &m, ,3&&t^<t (>>uE  % %&7 8 S%GG(/J} %NLr:)NNT)NN)r1r2r3rr_rrrr>rrr@rrrr9r:r;r|r|sL,5&>*)J A!B& >r:r|c@tj|jSrX)rr rD)r?s r;r:r:s   cmm ,,r:)TTNTTN)r?rr4rr5rr.r-r7rr8rr0r/rr<)H __future__rcollections.abcabcr`r rrrlr^rtypingrrrrr r r r r rrrjrrfrrrrrbaserrrr operatorsrrrr util.typingr r!r"r#r$r'_BoundParameterGetterLRUCacher(r6rrLrr)_StmtLambdaElementTyper,r@rBrAllowsLambdaRoler<rrrdr%r&r| _inspectsr:r9r:r;rsH#) ! %!&!'',! #s(OUDEE!c*+84==+>(>r3w #s(#2s7# T$!2$),4G4!$(!%&*#/3F FF"F F $ F  F-FFRNH**NbG;MG;TV. M:V.r,5%00(2H2H,5^000.a a H $qqh__Dm$-%-r: