zmc
2023-08-08 e792e9a60d958b93aef96050644f369feb25d61b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
U
¸ý°dMÆã
@sUddlmZddlmZddlZddlZddlZddlZddl    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+erÄdd lm,Z,dd!lm-Z-dd"lm.Z.dd#lm/Z/eee d$fed%fZ0e d$e fZ1e) 2d&¡Z3d'e4d(<e ge fZ5e d$e fZ6e ge fZ7ed)e"d*Z8e e8ge fZ9Gd+d,„d,e#ƒZ:dId.d/d/d0d/d/d1d2d3œd4d5„Z;Gd6d7„d7ej-ƒZ<Gd8d9„d9e<ƒZ=Gd:d2„d2ej>e<e"ƒZ?Gd;d<„d<ej>ej-ƒZ@Gd=d>„d>e?ƒZAGd?d@„d@ƒZBGdAdB„dBƒZCGdCdD„dDƒZDGdEdF„dFe&ƒZEe( Fe<¡dGdH„ƒZGdS)Jé)Ú 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.)ÚNonAnalyzedFunctionÚAnalyzedFunctionièÚ_LambdaCacheTypeÚ_closure_per_cache_keyÚ_E)Úboundc@s6eZdZUdZdZdZded<dZdZdZ    ded<dS)Ú LambdaOptionsTNúOptional[object]Útrack_onúOptional[_LambdaCacheType]Ú lambda_cache)
Ú__name__Ú
__module__Ú __qualname__Úenable_trackingÚtrack_closure_variablesr,Ú__annotations__Úglobal_track_bound_valuesÚtrack_bound_valuesr.©r7r7úMd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\sqlalchemy/sql/lambdas.pyr*Hs
 r*TÚ_StmtLambdaTypeÚboolr+r-ÚStatementLambdaElement)Úlmbr2r3r,r5r6r.Úreturnc Cst|tjt||||||dƒ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`
 
 
    )r2r,r3r5r6r.)r;rÚ StatementRoler*)r<r2r3r,r5r6r.r7r7r8Ú lambda_stmtQs;úýr?c@seZdZUdZdZdZdejjfgZ    dZ
de d<de d    <d
Z d e d <d e d<de d<de d<de d<de d<dd„Z ed
fdddddœdd„Zdd „Zd!d"„Zed#d$„ƒZed%d&„ƒZed'd(„ƒZd)d*„Zd+d,„Zed
fd-d.d/d0d1œd2d3„Zejd4d5„ƒZd6d7„Zdd/d8d9œd:d;„Zd
S)<Ú LambdaElementaÿA 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Ú    _resolvedr7zTuple[_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Ú_AnyLambdaTypeÚfnzTuple[CodeType, ...]Ú tracker_keycCsd|jj|jjfS)Nz%s(%r))Ú    __class__r/rKÚ__code__©Úselfr7r7r8Ú__repr__ÀsþzLambdaElement.__repr__Ú _LambdaTypeú)Union[Type[LambdaOptions], LambdaOptions]úOptional[ClauseElement]©rKrHÚoptsÚapply_propagate_attrscCs\||_||_|jf|_||_|dkr2|tjkr2|}| |||¡}|dk    rX|j}|rX||_    dS©N)
rKrHrNrLrVrr>Ú_retrieve_tracker_recÚpropagate_attrsÚ_propagate_attrs)rPrKrHrVrWÚrecrZr7r7r8Ú__init__Æs
zLambdaElement.__init__c     sîˆj}|dkrt}|j}|j}|j‰t ||ˆ¡}g|_‰|jdk    rP|jj    }nd}|t
j k    rÔt   ¡‰t‡‡‡‡fdd„|jDƒƒ}t
j ˆkrÈ||}||_    z|||}    WqÒtk
rÄd}    YqÒXqÞt
j }d}    n
t
j }d}    ||_    |    dkrV|t
j k    rFtj>||}
|
|kr2t||||ƒ}    ˆ|    _|    ||
<n||
}    W5QRXnt| |¡ƒ}    ndd„t|    jˆƒDƒˆdd…<|    |_|t
j k    rê|jdk    r¢|jjˆdd…<|} | dk    rê| j}    |    jrà|    j} |    jD]}|| j| ˆƒqÊ| j} q¦|    S)Nr7csg|]}|ˆˆˆˆƒ‘qSr7r7)Ú.0Úgetter©Úanon_mapÚ
bindparamsÚclosurerVr7r8Ú
<listcomp>øsÿz7LambdaElement._retrieve_tracker_rec.<locals>.<listcomp>cSs g|]\}}|j|jdd‘qS)T©Z maintain_key)Ú _with_valueÚvalue)r^Z    orig_bindZnew_bindr7r7r8rd!sÿr)r.r'rLrKÚ __closure__Ú AnalyzedCodeÚgetrDrErFÚ
_cache_keyÚNO_CACHErraÚtupleÚclosure_trackersÚKeyErrorÚ_generation_mutexr%Úclosure_bindparamsr$Ú_invoke_user_fnÚziprIÚbindparam_trackersÚtracker_instrumented_fn) rPrKrWrVr.rLÚtrackerÚparent_closure_cache_keyrr\ÚkeyrArur7r`r8rYÜsý
 
 
 
þÿ
 
 
ÿ
ÿþ  
 
ý
z#LambdaElement._retrieve_tracker_reccCst|jj|ƒSrX)ÚgetattrrIÚ expected_expr©rPrxr7r7r8Ú __getattr__=szLambdaElement.__getattr__cCs|jjSrX)rIÚ is_sequencerOr7r7r8Ú _is_sequence@szLambdaElement._is_sequencecCs*|jrtj dd„|jDƒ¡S|jjSdS)NcSsg|]
}|j‘qSr7)Ú_select_iterable©r^Úelementr7r7r8rdHsz2LambdaElement._select_iterable.<locals>.<listcomp>)r~Ú    itertoolsÚchainÚ from_iterablerBrrOr7r7r8rDs
ÿzLambdaElement._select_iterablecCs*|jrtj dd„|jDƒ¡S|jjSdS)NcSsg|]
}|j‘qSr7)Ú _from_objectsr€r7r7r8rdRsz/LambdaElement._from_objects.<locals>.<listcomp>)r~r‚rƒr„rBr…rOr7r7r8r…Ns
ÿzLambdaElement._from_objectscCsdd„|jDƒS)NcSsi|]}|j|j“qSr7)rxrg©r^Úbr7r7r8Ú
<dictcomp>Ysz-LambdaElement._param_dict.<locals>.<dictcomp>)rDrOr7r7r8Ú _param_dictXszLambdaElement._param_dictcs`dd„|jDƒ‰ddddœ‡fdd„ ‰|jjrB‡fdd    „|Dƒ}nt|d
d ƒr\t |iˆ¡}|S) NcSsi|] }|j|“qSr7)rxr†r7r7r8rˆ\sz?LambdaElement._setup_binds_for_tracked_expr.<locals>.<dictcomp>z(Optional[visitors.ExternallyTraversible]r)rÚkwr=csDt|tjƒr@|jˆkr@ˆ|j}|jr<d|_|j|_|j|_|SdS©NT)Ú
isinstancerr rxZ    expandingZ    expand_opÚtype)rrŠÚbind)Úbindparam_lookupr7r8Úreplace^s 
 
z<LambdaElement._setup_binds_for_tracked_expr.<locals>.replacecsg|]}t |iˆ¡‘qSr7)rÚreplacement_traverse©r^Zsub_expr)rr7r8rdnsÿz?LambdaElement._setup_binds_for_tracked_expr.<locals>.<listcomp>Úis_clause_elementF)rDrIr}ryrr‘©rPÚexprr7)rrr8Ú_setup_binds_for_tracked_expr[s
þ z+LambdaElement._setup_binds_for_tracked_exprr#zOptional[_CloneCallableType]rÚNone)ÚcloneÚdeferred_copy_internalsrŠr=cKs||jfd|i|—Ž|_dS)Nr™)rB©rPr˜r™rŠr7r7r8Ú_copy_internalswsÿþýzLambdaElement._copy_internalscCs|jj}|jr| |¡}|SrX)rIrzrDr–r”r7r7r8rB„s
zLambdaElement._resolvedcCs‚|jtjkrd|tj<dS|jj|jf|j}|j}|dk    rl|jtjk    sLt‚|j}|jjf||}|j}q4|j    r~| 
|j    ¡|Sr‹) rFrkrlrKrNrMrErÚAssertionErrorrDÚextend)rPrarbrÚparentrwr7r7r8Ú_gen_cache_keys& 
þýþÿ zLambdaElement._gen_cache_keyr!)rKÚargr=cGs|ƒSrXr7©rPrKr r7r7r8rr©szLambdaElement._invoke_user_fn)r/r0r1Ú__doc__Ú__visit_name__Ú_is_lambda_elementrÚInternalTraversalÚdp_clauseelementÚ_traverse_internalsrCr4rErQr*r]rYr|Úpropertyr~rr…r‰r–rr›rZmemoized_propertyrBrŸrrr7r7r7r8r@šsD
 
ÿ  
ûa
 
    
    ý 
r@cs\eZdZdZedfdddddœ‡fdd    „ Zd
d „Zd d dœdd„Zedf‡fdd„    Z    ‡Z
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.
 
    r7rRzType[roles.SQLRole]rSzTuple[Any, ...])rKrHrVÚ lambda_argscs||_tƒ |||¡dSrX)rªÚsuperr])rPrKrHrVrª©rMr7r8r]·szDeferredLambdaElement.__init__cGs
||jŽSrX)rªr¡r7r7r8rrÁsz%DeferredLambdaElement._invoke_user_fnrr!)rªr=cGsPt|jtƒst‚|jj}||Ž}t |j|¡}| |¡}|j    D] }||ƒ}q>|SrX)
rŒrIr%rœrurÚexpectrHr–rC)rPrªZ
tracker_fnr•r™r7r7r8Ú_resolve_with_argsÄs
 
 
z(DeferredLambdaElement._resolve_with_argsNc s*tƒj|||d|r&|j|f7_dS)N)r˜r™rV)r«r›rCršr¬r7r8r›èsýz%DeferredLambdaElement._copy_internals) r/r0r1r¢r*r]rrr®rr›Ú __classcell__r7r7r¬r8r©­s û
%ÿr©c@søeZdZdZer*edfdddddœdd    „Zd
dd œd d „Zd1d
ddddddœdd„Zdd„Z    e
ddœdd„ƒZ e
dd„ƒZ e
dd„ƒZ e
dd„ƒZe
d d!„ƒZe
d"d#„ƒZe
d$d%„ƒZe
d&d'„ƒZe
d(d)„ƒZe
d*d+„ƒZe
d,d-„ƒZd.dœd/d0„ZdS)2r;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`
 
    Nr9rGrSrTrUcCsdSrXr7)rPrKrHrVrWr7r7r8r]szStatementLambdaElement.__init__ú_StmtLambdaElementType[Any])Úotherr=cCs
| |¡SrX)Ú add_criteria)rPr±r7r7r8Ú__add__szStatementLambdaElement.__add__Tr:z Optional[Any])r±r2r,r3r6r=cCs*|jt|||jj||d}t|||d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.
 
        )r2r3r5r,r6)rErV)rVÚdictr5ÚLinkedLambdaElement)rPr±r2r,r3r6rVr7r7r8r²#s*ûz#StatementLambdaElement.add_criteriacCs<trt|jjtƒst‚|jjjr.| |||¡St     |¡‚dSrX)
r rŒrIrzr!rœÚsupports_executionÚ_execute_clauseelementrÚObjectNotExecutableError©rPÚ
connectionZdistilled_paramsZexecution_optionsr7r7r8Ú_execute_on_connectionWs
ÿz-StatementLambdaElement._execute_on_connectionr©r=cCs|jSrX)Z_rec_expected_exprrOr7r7r8Ú_proxiedcszStatementLambdaElement._proxiedcCs|jjSrX)r½Ú _with_optionsrOr7r7r8r¾gsz$StatementLambdaElement._with_optionscCs|jjSrX)r½Ú_effective_plugin_targetrOr7r7r8r¿ksz/StatementLambdaElement._effective_plugin_targetcCs|jjSrX)r½Ú_execution_optionsrOr7r7r8rÀosz)StatementLambdaElement._execution_optionscCs|jjSrX)r½Ú_all_selected_columnsrOr7r7r8rÁssz,StatementLambdaElement._all_selected_columnscCs|jjSrX)r½Ú    is_selectrOr7r7r8rÂwsz StatementLambdaElement.is_selectcCs|jjSrX)r½Ú    is_updaterOr7r7r8rÃ{sz StatementLambdaElement.is_updatecCs|jjSrX)r½Ú    is_insertrOr7r7r8rÄsz StatementLambdaElement.is_insertcCs|jjSrX)r½Úis_textrOr7r7r8rŃszStatementLambdaElement.is_textcCs|jjSrX)r½Ú    is_deleterOr7r7r8rƇsz StatementLambdaElement.is_deletecCs|jjSrX)r½Úis_dmlrOr7r7r8rNjszStatementLambdaElement.is_dmlÚNullLambdaStatementcCs t| ¡ƒS)ztReturn a new :class:`.StatementLambdaElement` that will run
        all lambdas unconditionally each time.
 
        )rÈrKrOr7r7r8ÚspoilszStatementLambdaElement.spoil)TNTT)r/r0r1r¢r r*r]r³r²r»r¨r½r¾r¿rÀrÁrÂrÃrÄrÅrÆrÇrÉr7r7r7r8r;÷sFû    ú4 
 
 
 
 
 
 
 
 
 
c@sNeZdZdZdZdZdejjfgZ    dd„Z
dd„Z d    d
„Z d d „Z d d„ZdS)rÈzðProvides 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.
 
    rATrBcCs||_|j|_dSrX)rBr[)rPÚ    statementr7r7r8r]ªszNullLambdaStatement.__init__cCs t|j|ƒSrX)ryrBr{r7r7r8r|®szNullLambdaStatement.__getattr__cCs||jƒ}t|ƒSrX©rBrÈ)rPr±rÊr7r7r8r³±s
zNullLambdaStatement.__add__cKs||jƒ}t|ƒSrXrË)rPr±rŠrÊr7r7r8r²¶s
z NullLambdaStatement.add_criteriacCs$|jjr| |||¡St |¡‚dSrX)rBr¶r·rr¸r¹r7r7r8r»»sÿz*NullLambdaStatement._execute_on_connectionN)r/r0r1r¢r£r¤rr¥r¦r§r]r|r³r²r»r7r7r7r8rȗs
 
ÿrÈc@s4eZdZUdZded<ddddœdd„Zd    d
„Zd S) rµzARepresent subsequent links of a :class:`.StatementLambdaElement`.r;rEr°rS)rKrErVcCs<||_||_||_|j|jf|_| |||¡|j|_dSrX)rVrKrErLrNrYr[)rPrKrErVr7r7r8r]Ës zLinkedLambdaElement.__init__cGs ||jjƒSrX)rErBr¡r7r7r8rrÙsz#LinkedLambdaElement._invoke_user_fnN)r/r0r1r¢r4r]rrr7r7r7r8rµÆs
rµc@sžeZdZUdZe ¡Zded<e     ¡Z
e dd„ƒZ dd„Z dd    „Zd
d „Zd d „Zdd„Ze dd„ƒZdd„Zdd„Zdd„Zd dd„Zd!dd„Zdd„ZdS)"ri)r3r6rtrnÚbuild_py_wrappersz1weakref.WeakKeyDictionary[CodeType, AnalyzedCode]Ú_fnsc
Ks†z|j|jWStk
r"YnX|jR|j|jkrP|j|jW5QR£St|||f|Ž|j|j<}|W5QR£SQRXdSrX)rÍrNrorpri)ÚclsrKrAZ    lambda_kwrŠZanalyzedr7r7r8rjës ÿÿzAnalyzedCode.getcCs˜t |¡rt d|¡‚|j}|jo(|j|_|j}|j}|j    }|oF| |_    g|_
g|_ g|_ |r†|rn|  |¡| |¡|r†| |¡| |||¡dS)Nz/Method %s may not be passed as a SQL expression)ÚinspectÚismethodrÚ ArgumentErrorrhr6r5r2r,r3rtrnrÌÚ_init_track_onÚ _init_globalsÚ _init_closureÚ"_setup_additional_closure_trackers)rPrKrArVrcr2r,r3r7r7r8r]þs*
ÿ
ÿ 
 
 
zAnalyzedCode.__init__cs"ˆj ‡fdd„t|ƒDƒ¡dS)Nc3s|]\}}ˆ ||¡VqdSrX)Ú_cache_key_getter_track_on)r^ÚidxÚelemrOr7r8Ú    <genexpr>&sÿz.AnalyzedCode._init_track_on.<locals>.<genexpr>)rnrÚ    enumerate)rPr,r7rOr8rÒ%sþzAnalyzedCode._init_track_oncCsl|j}|j}|j}|jjD]L}||jkr*q| |j|¡}t |¡r|     |df¡|r|     | 
|¡¡qdSrX) rÌrtr6rNÚco_namesÚ __globals__Ú_roll_down_to_literalrÚ_deep_is_literalÚappendÚ$_bound_parameter_getter_func_globals)rPrKrÌrtr6ÚnameÚ _bound_valuer7r7r8rÓ+s 
 
ÿzAnalyzedCode._init_globalsc     Cs |j}|j}|j}|j}|j}|j}tt|jj    |ƒƒD]d\}\}    }
|
j ¡} t   | ¡r~| |    |f¡|rš| | |    |¡¡q6|r6| | ||    ||
j ¡¡q6dSrX)rÌrhr6r3rtrnrÚrsrNÚ co_freevarsrÝÚ cell_contentsrrÞrßÚ$_bound_parameter_getter_func_closureÚ"_cache_key_getter_closure_variable) rPrKrÌrcr6r3rtrnÚ closure_indexÚfvÚcellrâr7r7r8rÔ=s8 ÿ 
ÿÿ ÿÿzAnalyzedCode._init_closurecCs<t||d|ƒ}|j}|jD]}|js| | ||¡¡qdSrX)r%rnÚclosure_pywrappersZ_sa__has_paramrßÚ!_cache_key_getter_tracked_literal)rPrKrArVZanalyzed_functionrnÚ    pywrapperr7r7r8rÕ`sü
 
ÿz/AnalyzedCode._setup_additional_closure_trackerscCs”t|dƒ}|rJt|tjtjtfƒsJz | ¡}Wqtk
rFYqJYqXq|sŒt    j
|dd}|dk    rˆz
| ¡WStk
r†|YSX|S|SdS)NÚ__clause_element__F©Zraiseerr) ÚhasattrrŒrr!rZ
SchemaItemrríÚAttributeErrorrrÏ)rÎrr“Úinspr7r7r8rÝvs&
 ÿ  
 
z"AnalyzedCode._roll_down_to_literalcs‡fdd„}|S)z¢Return a getter that will extend a list of bound parameters
        with new entries from the ``__globals__`` collection of a particular
        lambda.
 
        cs&|jˆ}t |d¡|jˆ|ƒdS©NÚ_extract_bound_parameters)rÜÚobjectÚ__getattribute__©Z
current_fnruÚresultÚwrapper©rár7r8Úextract_parameter_value—s
 
 
ÿzRAnalyzedCode._bound_parameter_getter_func_globals.<locals>.extract_parameter_valuer7)rPrárúr7rùr8ràs z1AnalyzedCode._bound_parameter_getter_func_globalscs‡fdd„}|S)z¢Return a getter that will extend a list of bound parameters
        with new entries from the ``__closure__`` collection of a particular
        lambda.
 
        cs*|jˆj}t |d¡|jˆj|ƒdSrò)rhrärôrõrö©rçr7r8rú¨sÿ
 
ÿzRAnalyzedCode._bound_parameter_getter_func_closure.<locals>.extract_parameter_valuer7)rPrárçrúr7rûr8rå¡s
z1AnalyzedCode._bound_parameter_getter_func_closurecsBt|tƒr‡fdd„}n&t|tjƒr2‡fdd„}n ‡fdd„}|S)z’Return a getter that will extend a cache key with new entries
        from the "track_on" parameter passed to a :class:`.LambdaElement`.
 
        cst‡‡fdd„|jˆDƒƒS)Nc3s|]}| ˆˆ¡VqdSrX©rŸ)r^Ztup_elem©rarbr7r8rÙ½sÿzGAnalyzedCode._cache_key_getter_track_on.<locals>.get.<locals>.<genexpr>)rmr,©rcrVrarb©r×rýr8rj¼sþz4AnalyzedCode._cache_key_getter_track_on.<locals>.getcs|jˆ ||¡SrX)r,rŸrþrÿr7r8rjÄscs
|jˆSrX)r,rþrÿr7r8rjÉs)rŒrmrkÚ HasCacheKey)rPr×rØrjr7rÿr8rÖ´s 
  z'AnalyzedCode._cache_key_getter_track_onFc sÜt|tjƒr‡‡‡fdd„}nºt|tjƒr8‡fdd„}n t|tjƒrX‡‡‡‡fdd„}n€|}d}    t|dƒrˆd}    t|ddƒsˆ|     ¡}q`qˆq`|    s¸t
j |dd    }
|
d
k    r̈j ˆˆˆ|
dd Snˆj ˆˆˆ|dd Sˆ  ˆˆ¡|S) z‹Return a getter that will extend a cache key with new entries
        from the ``__closure__`` collection of a particular lambda.
 
        csJ|ˆj}ˆrt |¡}n$ˆr>t|dƒr>t|ddƒs| ¡}q| ||¡S)Nrír“F)rärrÏrïryrírŸ)rcrVrarbÚobj)r×Úuse_clause_elementÚ use_inspectr7r8rjÞs
 
 
z<AnalyzedCode._cache_key_getter_closure_variable.<locals>.getcs |ˆjjSrX)rärNrþrÿr7r8rjìsc
s\|ˆj}zt‡‡fdd„|DƒƒWStk
rV}zˆjˆˆ|dW5d}~XYnXdS)Nc3s|]}| ˆˆ¡VqdSrXrü)r^rØrýr7r8rÙõsÿzOAnalyzedCode._cache_key_getter_closure_variable.<locals>.get.<locals>.<genexpr>)Úfrom_)rärmrðÚ'_raise_for_uncacheable_closure_variable)rcrVrarbÚcontentsZae)rKr×rPÚ variable_namerýr8rjñs
þ
ÿFríTr“rîN)r)r)rŒrkrÚtypesÚ FunctionTypeÚcollections_abcÚSequencerïryrírrÏrær) rPrKrr×rärrrjrr“rñr7)rKr×rPrrrr8ræÎs@   
 
ÿÿ z/AnalyzedCode._cache_key_getter_closure_variableNcCst d||jf¡|‚dS)NaTClosure variable named '%s' inside of lambda callable %s 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=[<elements>] to explicitly select closure elements to track, or set track_closure_variables=False to exclude closure variables from being part of the cache key.)rÚInvalidRequestErrorrN)rPrrKrr7r7r8rs ôÿòz4AnalyzedCode._raise_for_uncacheable_closure_variablecCs"|j}|j}|j}| ||||¡S)a™Return 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.
 
        )Z_sa__to_evaluateZ_sa__closure_indexZ    _sa__nameræ)rPrKZ    pytrackerrØrçrr7r7r8rë.s ÿz.AnalyzedCode._cache_key_getter_tracked_literal)FF)N)r/r0r1Ú    __slots__ÚweakrefÚWeakKeyDictionaryrÍr4Ú    threadingÚRLockrpÚ classmethodrjr]rÒrÓrÔrÕrÝràrårÖrærrër7r7r7r8riÝs,
    þ
 
'#
 ù
Nÿ
ric@sVeZdZUdZdZded<dZded<dZded    <ddœd
d „Ze    dd œd d„ƒZ
dS)r$©r•Nú"Optional[List[BindParameter[Any]]]rqú%Optional[List[_BoundParameterGetter]]rtFr!r•cCs
||_dSrXrr”r7r7r8r]LszNonAnalyzedFunction.__init__r¼cCs|jSrXrrOr7r7r8rzOsz!NonAnalyzedFunction.expected_expr) r/r0r1r rqr4rtr}r]r¨rzr7r7r7r8r$Bs
  r$c@sJeZdZUdZded<ded<ded<dd    „Zd
d „Zd d „Zdd„ZdS)r%)
Ú analyzed_coderKrêrur•rtrzr}rZrqrrqz)Union[ClauseElement, List[ClauseElement]]rzrrtcCs.||_||_|j|_| |¡| ||¡dSrX)rrKrtÚ_instrument_and_run_functionÚ_coerce_expression)rPrrArWrKr7r7r8r]fs
 
zAnalyzedFunction.__init__cs|j}|j}g|_}|j}|s8||_}| |¡|_nÖ|j}|j}|rbdd„t    |j
j |ƒDƒ‰ni‰|j   ¡}    |D]f\}
} | dk    r¼|| j} t||
| | |jjdˆ|
<} |rÚ| | ¡qt|j |
} t||
| ƒ|    |
<} qt| |‡fdd„|j
j Dƒ|    ¡|_}| |¡|_dS)NcSsi|]\}}||j“qSr7)rä)r^rèrér7r7r8rˆ‡sÿzAAnalyzedFunction._instrument_and_run_function.<locals>.<dictcomp>)rçr6csg|] }ˆ|‘qSr7r7)r^rá©Z new_closurer7r8rd©szAAnalyzedFunction._instrument_and_run_function.<locals>.<listcomp>)rrKrêrÌrurrr•r3rhrsrNrãrÜÚcopyräÚ    PyWrapperr6rßÚ_rewrite_code_obj)rPrArrKrêrÌrur3rcZ new_globalsrárçrgrŽr7rr8rvsJ
 
 þ
 
ú     
ýþz-AnalyzedFunction._instrument_and_run_functioncsŠˆj}|j}|dkr`t|tjƒr>‡‡fdd„|Dƒ|_d|_qltdtj    ˆj
|ˆdƒ|_d|_n ||_d|_ˆdk    r~ˆj |_ nt j|_ dS)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.
 
        Nc    s$g|]}tdtjˆj|ˆdƒ‘qS)r!©rW)rrr­rHr’©rWrAr7r8rdÈs    øýþz7AnalyzedFunction._coerce_expression.<locals>.<listcomp>Tr!rF)rEr•rŒr
r rzr}rrr­rHr[rZrÚ
EMPTY_DICT)rPrArWrEr•r7rr8rºs,          ÷ ýþ
z#AnalyzedFunction._coerce_expressionc    sÖttˆƒƒ}d}ˆrD|dd dd„|Dƒ¡d dd„|Dƒ¡f7}|d7}|dd d    d„|Dƒ¡7}|d
7}‡fd d „|Dƒ}t|||ƒ|d ƒ}t|ƒ|j||j|j|ƒ}|j|_|j    |_    |j
|_
|j |_ |S)zaReturn a copy of f, with a new closure and new globals
 
        yes it works in pypy :P
 
        zdef make_cells():
z    (%s) = (%s)
z, css|]}d|VqdS©zi%dNr7©r^Úir7r7r8rÙósz5AnalyzedFunction._rewrite_code_obj.<locals>.<genexpr>css|]}d|VqdS)úo%dNr7r!r7r7r8rÙôsz    def closure():
z        return %s
css|]}d|VqdSr r7r!r7r7r8rÙ÷sz    return closure.__closure__csi|]}d|ˆ|“qS)r#r7r!©Ú cell_valuesr7r8rˆùsz6AnalyzedFunction._rewrite_code_obj.<locals>.<dictcomp>Z
make_cells) ÚrangeÚlenÚjoinÚexecrrNr/Ú __defaults__r4Ú__kwdefaults__r¢r0)    rPÚfr%Úglobals_ZargrangeÚcodeZvars_rcÚfuncr7r$r8rçs2 þ 
ÿz"AnalyzedFunction._rewrite_code_objN)    r/r0r1r r4r]rrrr7r7r7r8r%Ts
 D-r%c@sleZdZdZddd„Zdd„Zdd    „Zd
d „Zd d „Zddd„Z    dd„Z
dd„Z dd„Z dd„Z dd„ZdS)raœA 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.
 
    NTcCs:||_||_||_d|_d|_i|_||_||_||_dS)NF)    rKÚ_nameÚ _to_evaluateÚ_paramÚ
_has_paramÚ _bind_pathsÚ_getterZ_closure_indexr6)rPrKráÚ to_evaluaterçr_r6r7r7r8r]s    zPyWrapper.__init__cOs^t |d¡}|||Ž}|jrVt |¡rVt|tjƒsVt |d¡}t     d||j
j f¡‚n|SdS)Nr1r0a#Can't invoke Python callable %s() inside of lambda expression argument at %s; 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õZ_sa_track_bound_valuesrrÞrŒrkrrr Ú_sa_fnrN)rPr rŠrØrgrár7r7r8Ú__call__-s$ 
ÿþýý     
ôÿzPyWrapper.__call__cOst |d¡ƒ}||f|ž|ŽS©NÚ_py_wrapper_literal©rôrõ©rPÚopr±ÚkwargsrØr7r7r8ÚoperateLszPyWrapper.operatecKst |d¡ƒ}|||f|ŽSr9r;r<r7r7r8Úreverse_operatePszPyWrapper.reverse_operatecCsft |d¡}|dk    r,|j|dd}| |¡t |d¡ ¡D]$}t |d¡}||ƒ}| ||¡q<dS)Nr2Trer4r5)rôrõrfrßÚvaluesZ_sa__extract_bound_parameters)rPÚstarting_pointZ result_listÚparamrìr_rr7r7r8róTs 
 z#PyWrapper._extract_bound_parameterscKsht |d¡}t |d¡}|dkrZt |d¡}tj|dd||dk    rF|jndd|_}d|_|j|ddS)Nr2r1r0FT)ÚrequiredÚuniqueZ_compared_to_operatorZ_compared_to_typere)rôrõrr rr2r3rf)rPr•ÚoperatorrŠrCr6rár7r7r8r:^s   û zPyWrapper._py_wrapper_literalcCst |d¡}t|ƒS©Nr1)rôrõr:)rPr6r7r7r8Ú__bool__ms zPyWrapper.__bool__cCsd| d¡rt ||dd…¡S|dkr2t ||¡S| d¡rRt |d¡}t||ƒS| |tj¡SdS)NZ_sa_é)rír?r@r:rMÚ__dict__Ú__r1)Ú
startswithrôrõryÚ_sa__add_getterrFÚ
attrgetter©rPrxrØr7r7r8rõqs
 
 
zPyWrapper.__getattribute__cCst |d¡}t|ƒSrG)rôrõÚiter)rPrØr7r7r8Ú__iter__„s zPyWrapper.__iter__cCs@t |d¡}t|dƒstdƒ‚t|tƒr2t d¡‚| |t    j
¡S)Nr1Ú __getitem__zUDictionary keys / list indexes inside of a cached lambda must be Python literals only) rôrõrïrðrŒrrr rMrFÚ
itemgetterrOr7r7r8rRˆs 
 
ÿzPyWrapper.__getitem__c
Cszt |d¡}||f}||kr$||S||ƒ}t |d¡}||ƒ}t |¡}t |¡rrt|j|||d}    |    ||<|    S|SdS)Nr4r1)r_)rôrõrirÝrrÞrr7)
rPrxZ    getter_fnZ
bind_pathsZ bind_path_keyr_rØrgZrolled_down_valuerør7r7r8Ú _add_getter•s  
 
zPyWrapper._add_getter)NNT)NN)r/r0r1r¢r]r8r?r@rór:rHrõrQrRrTr7r7r7r8rsù
 
 
 rcCs t |j¡SrX)rrÏrB)r<r7r7r8rñ«srñ)TTNTTN)HÚ
__future__rÚcollections.abcÚabcr
rÏr‚rFrrrÚtypingrrrrrr    r
r r r rrÚrrkrrrrrÚbaserrrrÚ    operatorsrrrrZ util.typingrr r!r"r#r&Z_BoundParameterGetterZLRUCacher'r4rRrJr9r(Z_StmtLambdaElementTyper*r?r@r©ZAllowsLambdaRoler;rÈrµrir$r%rZ    _inspectsrñr7r7r7r8Ú<module>    s                                  ÿ      ùIJ
ÿ!/g5$