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
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
U
Þ=®d]Ùã@sddlmZddlZddlZddlZddlZddlZddlm    Z    ddl
m
Z
ddl m Z ddl mZddlmZddlmZdd    lmZdd
lmZdd lmZdd lmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlmZd dlm Z d dlm!Z!d dlm"Z"d dlm#Z#d dl$m%Z%d dl$m&Z&d dl$m'Z'd dl$m(Z(d dl$m)Z)d dl*m+Z+d dl*m,Z,d d l*m-Z-d d!l*m.Z.d d"l*m/Z/d d#l*m0Z0d d$l1m2Z2d d%l1m3Z3d d&l4m5Z5d d'l4m6Z6d d(l7m8Z8d d)l9m:Z:d d*l;m<Z<d d+l;m=Z=ej>r<dd,l?m@Z@dd-l?mAZAddlBZCdWd0d1d2d3d3d4d5œd6d7„ZDdXd0d3d3d8d9œd:d;„ZEd0d<d=œd>d?„ZFejGd@e#dAZHGdBdC„dCƒZIGdDdE„dEeJƒZKGdFdG„dGƒZLdHdHdIdJœdKdL„ZMdYdNdId1dOdPœdQdR„ZNGdSdT„dTe:ƒZOejPGdUdV„dVƒƒZQdS)Zé)Ú annotationsN)Ú defaultdict)Údatetime)ÚBytesIO)Úchain)Úrandom)Ú TemporaryFile)Útime)Úunquote)Úurlsplit)Ú
urlunsplité)Ú _get_environ)Ú_make_encode_wrapper)Ú_wsgi_decoding_dance)Ú_wsgi_encoding_dance)Ú Authorization)Ú CallbackDict)ÚCombinedMultiDict)ÚEnvironHeaders)Ú FileMultiDict)ÚHeaders)Ú    MultiDict)Ú dump_cookie)Údump_options_header)Ú parse_cookie)Ú
parse_date)Úparse_options_header)ÚData)ÚEpilogue)ÚField)ÚFile)ÚMultipartEncoder)ÚPreamble)Ú
_urlencode)Ú
iri_to_uri)Úcached_property)Úget_content_type)ÚRequest)ÚResponse)ÚClosingIterator)Úget_current_url)ÚWSGIApplication)ÚWSGIEnvironmentTéÐzt.Mapping[str, t.Any]ÚboolÚintú
str | Noneztuple[t.IO[bytes], int, str])ÚdataÚ use_tempfileÚ    thresholdÚboundaryÚcharsetÚreturnc    sê|dk    rtjdtddnd}|dkr8dtƒ›tƒ›}tƒ‰d‰d‰|rfd    d
d œ‡‡‡‡fd d „ }nˆj}t| ¡ƒ}||     t
dd¡ƒt |ƒD]"\}}t |ddƒ}    |    dk    rpt |dt |ddƒƒ}
t |ddƒ} | dkrò|
rît  |
¡dpðd} |j} |  d| fg¡|
dkr*||     t|| d¡ƒn||     t||
| d¡ƒ|    dƒ} | sTq¸||     t| dd¡ƒqBq”t|tƒs„t|ƒ}||     t|tƒd¡ƒ||     t| |¡dd¡ƒq”||     tdd¡ƒˆ ¡}ˆ d¡ˆ||fS)aEncode a dict of values (either strings or file descriptors or
    :class:`FileStorage` objects.) into a multipart encoded string stored
    in a file descriptor.
 
    .. versionchanged:: 2.3
        The ``charset`` parameter is deprecated and will be removed in Werkzeug 3.0
    NúIThe 'charset' parameter is deprecated and will be removed in Werkzeug 3.0é©Ú
stacklevelúutf-8z ---------------WerkzeugFormPart_rFÚbytesr0)Úsr7cstˆrˆ |¡St|ƒ}|ˆˆkr.ˆ |¡n6t tjttdƒ¡}| ˆ ¡¡| |¡|‰d‰ˆ|7‰|SdS)Nzwb+T)ÚwriteÚlenÚtÚcastÚIOr=rÚgetvalue)r>ÚlengthZ
new_stream©Zon_diskÚstreamr4Ú total_length©úDd:\z\workplace\vscode\pyvenv\venv\Lib\site-packages\werkzeug/test.pyÚ write_binaryYs
 
z-stream_encode_multipart.<locals>.write_binaryó)r2ÚreadÚfilenameÚnameÚ content_typezapplication/octet-streamú Content-Type)rOÚheaders)rOrNrRi@T)r2Z    more_data)ÚwarningsÚwarnÚDeprecationWarningr    rrr?r"ÚencodeZ
send_eventr#Ú
_iter_dataÚgetattrÚ    mimetypesÚ
guess_typerRÚupdater r!rÚ
isinstanceÚstrrrÚtellÚseek)r2r3r4r5r6rKÚencoderÚkeyÚvalueÚreaderrNrPrRÚchunkrErIrFrJÚstream_encode_multipart8sfý  
  ÿý
 ÿÿ ÿ
reztuple[str, bytes])Úvaluesr5r6r7cCs"t|d||d\}}}|| ¡fS)zæLike `stream_encode_multipart` but returns a tuple in the form
    (``boundary``, ``data``) where data is bytes.
 
    .. versionchanged:: 2.3
        The ``charset`` parameter is deprecated and will be removed in Werkzeug 3.0
    F)r3r5r6)rerM)rfr5r6rGrErIrIrJÚencode_multiparts ÿ rgzt.Iterator[tuple[str, t.Any]])r2r7ccs^t|tƒr|jddEdHn<| ¡D]2\}}t|tƒrN|D]}||fVq<q&||fVq&dS)zÏIterate over a mapping that might have a list of values, yielding
    all key, value pairs. Almost like iter_multi_items but only allows
    lists, not tuples, of values so tuples can be used for files.
    T)ZmultiN)r\rÚitemsÚlist)r2rarbÚvrIrIrJrW®s
 
rWÚ_TAnyMultiDict)Úboundc@sÎeZdZUdZdZdZeZddlZe    ej
ƒZ [de d<de d    <d
e d <de d <d e d<deddddd
ddddddddddddddddœdd„Z edd dd!œd"d#„ƒZdd$dd%œd&d'„Ze    ddddd(œd)d*„ƒZedd+œd,d-„ƒZejddd.œd/d-„ƒZedd+œd0d1„ƒZejddd.œd2d1„ƒZedd+œd3d4„ƒZejddd.œd5d4„ƒZed6d+œd7d8„ƒZedd+œd9d:„ƒZejddd.œd;d:„ƒZdd<d=d>œd?d@„ZddAddBœdCdD„ZedAd+œdEdF„ƒZejdAdd.œdGdF„ƒZedHd+œdIdJ„ƒZejdHdd.œdKdJ„ƒZed
d+œdLdM„ƒZejd
dd.œdNdM„ƒZedd+œdOdP„ƒZejddd.œdQdP„ƒZedAd+œdRdS„ƒZejddd.œdTdS„ƒZedd+œdUdV„ƒZ edWd+œdXdY„ƒZ!dd+œdZd[„Z"dd+œd\d]„Z#dd+œd^d_„Z$dfd`dadbœdcdd„Z%dS)gÚEnvironBuilderaPThis class can be used to conveniently create a WSGI environment
    for testing purposes.  It can be used to quickly create WSGI environments
    or request objects from arbitrary data.
 
    The signature of this class is also used in some other places as of
    Werkzeug 0.5 (:func:`create_environ`, :meth:`Response.from_values`,
    :meth:`Client.open`).  Because of this most of the functionality is
    available through the constructor alone.
 
    Files and regular form data can be manipulated independently of each
    other with the :attr:`form` and :attr:`files` attributes, but are
    passed with the same argument to the constructor: `data`.
 
    `data` can be any of these values:
 
    -   a `str` or `bytes` object: The object is converted into an
        :attr:`input_stream`, the :attr:`content_length` is set and you have to
        provide a :attr:`content_type`.
    -   a `dict` or :class:`MultiDict`: The keys have to be strings. The values
        have to be either any of the following objects, or a list of any of the
        following objects:
 
        -   a :class:`file`-like object:  These are converted into
            :class:`FileStorage` objects automatically.
        -   a `tuple`:  The :meth:`~FileMultiDict.add_file` method is called
            with the key and the unpacked `tuple` items as positional
            arguments.
        -   a `str`:  The string is set as form data for the associated key.
    -   a file-like object: The object content is loaded in memory and then
        handled like a regular `str` or a `bytes`.
 
    :param path: the path of the request.  In the WSGI environment this will
                 end up as `PATH_INFO`.  If the `query_string` is not defined
                 and there is a question mark in the `path` everything after
                 it is used as query string.
    :param base_url: the base URL is a URL that is used to extract the WSGI
                     URL scheme, host (server name + server port) and the
                     script root (`SCRIPT_NAME`).
    :param query_string: an optional string or dict with URL parameters.
    :param method: the HTTP method to use, defaults to `GET`.
    :param input_stream: an optional input stream.  Do not specify this and
                         `data`.  As soon as an input stream is set you can't
                         modify :attr:`args` and :attr:`files` unless you
                         set the :attr:`input_stream` to `None` again.
    :param content_type: The content type for the request.  As of 0.5 you
                         don't have to provide this when specifying files
                         and form data via `data`.
    :param content_length: The content length for the request.  You don't
                           have to specify this when providing data via
                           `data`.
    :param errors_stream: an optional error stream that is used for
                          `wsgi.errors`.  Defaults to :data:`stderr`.
    :param multithread: controls `wsgi.multithread`.  Defaults to `False`.
    :param multiprocess: controls `wsgi.multiprocess`.  Defaults to `False`.
    :param run_once: controls `wsgi.run_once`.  Defaults to `False`.
    :param headers: an optional list or :class:`Headers` object of headers.
    :param data: a string or dict of form data or a file-object.
                 See explanation above.
    :param json: An object to be serialized and assigned to ``data``.
        Defaults the content type to ``"application/json"``.
        Serialized with the function assigned to :attr:`json_dumps`.
    :param environ_base: an optional dict of environment defaults.
    :param environ_overrides: an optional dict of environment overrides.
    :param auth: An authorization object to use for the
        ``Authorization`` header value. A ``(username, password)`` tuple
        is a shortcut for ``Basic`` authorization.
 
    .. versionchanged:: 2.3
        The ``charset`` parameter is deprecated and will be removed in Werkzeug 3.0
 
    .. versionchanged:: 2.1
        ``CONTENT_TYPE`` and ``CONTENT_LENGTH`` are not duplicated as
        header keys in the environ.
 
    .. versionchanged:: 2.0
        ``REQUEST_URI`` and ``RAW_URI`` is the full raw URI including
        the query string, not only the path.
 
    .. versionchanged:: 2.0
        The default :attr:`request_class` is ``Request`` instead of
        ``BaseRequest``.
 
    .. versionadded:: 2.0
       Added the ``auth`` parameter.
 
    .. versionadded:: 0.15
        The ``json`` param and :meth:`json_dumps` method.
 
    .. versionadded:: 0.15
        The environ has keys ``REQUEST_URI`` and ``RAW_URI`` containing
        the path before percent-decoding. This is not part of the WSGI
        PEP, but many WSGI servers include it.
 
    .. versionchanged:: 0.6
       ``path`` and ``base_url`` can now be unicode strings that are
       encoded with :func:`iri_to_uri`.
    zHTTP/1.1)r rrNzMultiDict | NoneÚ_argsr1Ú _query_stringzt.IO[bytes] | NoneÚ _input_streamÚ_formzFileMultiDict | NoneÚ_filesú/ÚGETFr]z t.Mapping[str, str] | str | Noneú
int | Nonezt.IO[str] | Noner/z,Headers | t.Iterable[tuple[str, str]] | Nonez:None | (t.IO[bytes] | str | bytes | t.Mapping[str, t.Any])zt.Mapping[str, t.Any] | Nonez&Authorization | tuple[str, str] | NoneÚNone)ÚpathÚbase_urlÚ query_stringÚmethodÚ input_streamrPÚcontent_lengthÚ errors_streamÚ multithreadÚ multiprocessÚrun_oncerRr2Ú environ_baseÚenviron_overridesr6ÚmimetypeÚjsonÚauthr7cCs°t|ƒ}|dk    r$|dƒ|kr$tdƒ‚t|ƒ}|dkrF|dƒ|krF|j}|dk    r`tjdtddnd}||_t|j    ƒ|_    ||_
|dk    rœt||dkr”|ndd}||_ t |t ƒr´||_n(|dkrÄtƒ}nt |tƒsÖt|ƒ}||_||_| dkròtƒ} nt | tƒst| ƒ} | |_|dk    r||_|dkr,tj}||_|    |_|
|_| |_||_||_||_||_d|_|dk    r¢t |t ƒrt!d    |d
|d d œƒ}|j "d | #¡¡|dk    rÚ| dk    r¾t$dƒ‚| %|¡} |jdkrÚd|_| rœ|dk    ròt$dƒ‚t&| dƒr|  '¡} t | t ƒr|  (|j¡} t | t)ƒrLt*| ƒ|_|jdkrœt+| ƒ|_nPt,| ƒD]F\}}t |t t-fƒsxt&|dƒr†| .||¡n|j/ 0|¡ 1|¡qT|dk    r¬||_2dS)Nú?z6Query string is defined in the path and as an argumentr8r9r:r<©r6FÚbasicrr )ÚusernameÚpasswordrz can't provide both json and datazapplication/jsonz#can't provide input stream and datarM)3rÚ
ValueErrorr ÚqueryrSrTrUr6r%rwÚ request_urirxr\r]ryrÚargsrzrrRrPÚsysÚstderrr}r~rr€rr‚r{r|ÚclosedÚtuplerÚsetZ    to_headerÚ    TypeErrorÚ
json_dumpsÚhasattrrMrVr=rr@rWÚdictÚ_add_file_from_dataÚformZsetlistdefaultÚappendrƒ)Úselfrwrxryrzr{rPr|r}r~rr€rRr2rr‚r6rƒr„r…Zpath_srrarbrIrIrJÚ__init__9sœü ÿ
 
 
 
 
 ÿ
 
 
 
 
 
zEnvironBuilder.__init__r-út.Any)ÚenvironÚkwargsr7c Ks’tt|ƒƒ}t|dƒ| |d| d¡t|dƒ¡t|dƒ|d|d| dd    ¡| d
d    ¡|d |d |d |d|dœ }| |¡|f|ŽS)a-Turn an environ dict back into a builder. Any extra kwargs
        override the args extracted from the environ.
 
        .. versionchanged:: 2.0
            Path and query values are passed through the WSGI decoding
            dance to avoid double encoding.
 
        .. versionadded:: 0.15
        Ú    PATH_INFOúwsgi.url_schemeÚHostÚ SCRIPT_NAMEÚ QUERY_STRINGÚREQUEST_METHODú
wsgi.inputrQNúContent-Lengthú wsgi.errorsúwsgi.multithreadúwsgi.multiprocessú wsgi.run_once) rwrxryrzr{rPr|r}r~rr€rR)rrrÚ_make_base_urlÚpopr[)ÚclsržrŸrRÚoutrIrIrJÚ from_environªs( 
 
ý
 
 
ð
zEnvironBuilder.from_environzDt.IO[bytes] | tuple[t.IO[bytes], str] | tuple[t.IO[bytes], str, str])rarbr7cCs0t|tƒr|jj|f|žŽn|j ||¡dS)z=Called in the EnvironBuilder to add files from the data dict.N)r\r’ÚfilesZadd_file)r›rarbrIrIrJr˜Ës
z"EnvironBuilder._add_file_from_data)ÚschemeÚhostÚ script_rootr7cCst|||ddfƒ d¡dS)NÚrs)r Úrstrip)r²r³r´rIrIrJr¬ÖszEnvironBuilder._make_base_url©r7cCs| |j|j|j¡S)z`The base URL is used to extract the URL scheme, host name,
        port, and root path.
        )r¬Ú
url_schemer³r´©r›rIrIrJrxÚszEnvironBuilder.base_url)rbr7cCsT|dkrd}d}d}n"t|ƒ\}}}}}|s0|r8tdƒ‚| d¡|_||_||_dS)NÚhttpÚ    localhostrµz4base url must not contain a query string or fragmentrs)r r‹r¶r´r³r¸)r›rbr²Únetlocr´ÚqsÚanchorrIrIrJrxás cCs6|j d¡}|dkr2|js2|jr$dS|jr.dSdS|S)z¯The content type for the request.  Reflected from and to
        the :attr:`headers`.  Do not set if you set :attr:`files` or
        :attr:`form` for auto detection.
        rQNúmultipart/form-dataú!application/x-www-form-urlencoded)rRÚgetrprrrq©r›ÚctrIrIrJrPïs zEnvironBuilder.content_typecCs&|dkr|j dd¡n
||jd<dS©NrQ)rRr­©r›rbrIrIrJrPþscCs |j}|r| d¡d ¡SdS)zYThe mimetype (content type without charset etc.)
 
        .. versionadded:: 0.14
        ú;rN)rPÚsplitÚstriprÂrIrIrJrƒszEnvironBuilder.mimetypecCst||jƒ|_dS©N)r'r6rPrÅrIrIrJrƒszt.Mapping[str, str]cs4dddœ‡fdd„ }tˆj dd¡ƒd}t||ƒS)    zÈThe mimetype parameters as dict.  For example if the
        content type is ``text/html; charset=utf-8`` the params would be
        ``{'charset': 'utf-8'}``.
 
        .. versionadded:: 0.14
        rrv)Údr7cstˆj|ƒˆjd<dSrÄ)rrƒrR)rÊr¹rIrJÚ    on_updatesz1EnvironBuilder.mimetype_params.<locals>.on_updatez content-typerµr )rrRrÁr)r›rËrÊrIr¹rJÚmimetype_paramss    zEnvironBuilder.mimetype_paramscCs|jjdtdS)z¬The content length as integer.  Reflected from and to the
        :attr:`headers`.  Do not set if you set :attr:`files` or
        :attr:`form` for auto detection.
        r§)Útype)rRrÁr0r¹rIrIrJr|!szEnvironBuilder.content_lengthcCs*|dkr|j dd¡nt|ƒ|jd<dS)Nr§)rRr­r]rÅrIrIrJr|)sztype[_TAnyMultiDict]rk)rOÚstorager7cCs:|jdk    rtdƒ‚t||ƒ}|dkr6|ƒ}t|||ƒ|S)zÑCommon behavior for getting the :attr:`form` and
        :attr:`files` properties.
 
        :param name: Name of the internal cached attribute.
        :param storage: Storage class used for the data.
        Nzan input stream is defined)r{ÚAttributeErrorrXÚsetattr)r›rOrÎÚrvrIrIrJÚ    _get_form0s
 
 zEnvironBuilder._get_formr)rOrbr7cCsd|_t|||ƒdS)zÐCommon behavior for setting the :attr:`form` and
        :attr:`files` properties.
 
        :param name: Name of the internal cached attribute.
        :param value: Value to assign to the attribute.
        N)rprÐ)r›rOrbrIrIrJÚ    _set_formBszEnvironBuilder._set_formcCs | dt¡S)z$A :class:`MultiDict` of form values.rq)rÒrr¹rIrIrJr™LszEnvironBuilder.formcCs| d|¡dS)Nrq©rÓrÅrIrIrJr™QsrcCs | dt¡S)zrA :class:`FileMultiDict` of uploaded files. Use
        :meth:`~FileMultiDict.add_file` to add new files.
        rr)rÒrr¹rIrIrJr±UszEnvironBuilder.filescCs| d|¡dS)NrrrÔrÅrIrIrJr±\scCs|jS)zôAn optional input stream. This is mutually exclusive with
        setting :attr:`form` and :attr:`files`, setting it will clear
        those. Do not provide this if the method is not ``POST`` or
        another method that has a body.
        )rpr¹rIrIrJr{`szEnvironBuilder.input_streamcCs||_d|_d|_dSrÉ)rprqrrrÅrIrIrJr{iscCs.|jdkr(|jdk    r$t|j|jdSdS|jS)ziThe query string.  If you set this to a string
        :attr:`args` will no longer be available.
        N©Úencodingrµ)rornr$r6r¹rIrIrJryos
 
 
zEnvironBuilder.query_stringcCs||_d|_dSrÉ©rornrÅrIrIrJryzscCs*|jdk    rtdƒ‚|jdkr$tƒ|_|jS)z(The URL arguments as :class:`MultiDict`.Nza query string is defined)rorÏrnrr¹rIrIrJrŽs
 
 
zEnvironBuilder.argscCsd|_||_dSrÉr×rÅrIrIrJrŽˆscCs|j dd¡dS)z4The server name (read-only, use :attr:`host` to set)ú:r r)r³rÇr¹rIrIrJÚ server_nameszEnvironBuilder.server_namer0cCsP|j dd¡}t|ƒdkr>zt|dƒWStk
r<YnX|jdkrLdSdS)z?The server port as integer (read-only, use :attr:`host` to set)rØr r9Úhttpsi»éP)r³rÇr@r0r‹r¸)r›ÚpiecesrIrIrJÚ server_port’s 
zEnvironBuilder.server_portcCs&z | ¡Wntk
r YnXdSrÉ)ÚcloseÚ    Exceptionr¹rIrIrJÚ__del__¡s zEnvironBuilder.__del__c    Csh|jr
dSz|j ¡}Wntk
r0d}YnX|D]&}z | ¡Wq6tk
rZYq6Xq6d|_dS)z±Closes all files.  If you put real :class:`file` objects into the
        :attr:`files` dict you can call this method to automatically close
        them all in one go.
        NrIT)r‘r±rfrÏrÞrß)r›r±ÚfrIrIrJrÞ§s
 zEnvironBuilder.closecs$ˆj}ˆj}ˆj}ˆj}|dk    rP| ¡}| dd¡| ¡}| |¡||}n‚|dkrœˆjdkrhˆjnd}ttˆj    ˆj
gƒ|d\}}}|›d|›d}n6|d    krÌt ˆj    ˆjd
  d ¡}    t |    ƒ}t|    ƒ}ntƒ}i}
ˆjrè|
 ˆj¡d d d œ‡fdd„ } tˆjˆjƒ} |
 ˆj| ˆjƒ| ˆjƒtˆjˆjƒ| | ˆjtˆjƒˆjˆjˆjˆj|ˆjˆjˆj ˆj!dœ¡ˆj" #¡} |  $d¡|  $d¡|dk    r˜||
d<|dk    r®t|ƒ|
d<t%t&ƒ}|  '¡D]*\}}|d| (¡ )dd¡› *|¡q¾| +¡D]\}}d ,|¡|
|<qòˆj-r |
 ˆj-¡|
S)zÝReturn the built environ.
 
        .. versionchanged:: 0.15
            The content type and length headers are set based on
            input stream detection. Previously this only set the WSGI
            keys.
        Nrr9r¿r<r‡z ; boundary="ú"rÀrÕÚasciir])Úxr7cstt|ˆjdˆjƒS)NrÕ)rr
r6)rär¹rIrJÚ _path_encodeÞsz0EnvironBuilder.get_environ.<locals>._path_encode)r¥r£r r¤Z REQUEST_URIZRAW_URIZ SERVER_NAMEZ SERVER_PORTZ    HTTP_HOSTZSERVER_PROTOCOLz wsgi.versionr¡r¦r¨r©rªr«rQr§Ú CONTENT_TYPEÚCONTENT_LENGTHZHTTP_ú-Ú_ú, ).r{r|rƒrPr^r_r6rerr™r±r$rVr@rrr[rrrzr´rwryrÙr]rÝr³Úserver_protocolÚ wsgi_versionr¸r}r~rr€rRÚcopyÚremoverriZ to_wsgi_listÚupperÚreplaceršrhÚjoinr‚)r›r{r|rƒrPZ    start_posZend_posr6r5Z form_encodedÚresultråZraw_urirRZcombined_headersrarbrfrIr¹rJÚ get_environ¹s| 
 
ÿ 
  íÿ
 
 
 
 
 $ zEnvironBuilder.get_environztype[Request] | Noner()r®r7cCs|dkr|j}|| ¡ƒS)z¨Returns a request with the data.  If the request class is not
        specified :attr:`request_class` is used.
 
        :param cls: The request wrapper to use.
        N)Ú request_classró)r›r®rIrIrJÚ get_requestszEnvironBuilder.get_request)rsNNrtNNNNFFFNNNNNNNN)N)&Ú__name__Ú
__module__Ú __qualname__Ú__doc__rërìr(rôr„Ú staticmethodÚdumpsr•Ú__annotations__rœÚ classmethodr°r˜r¬ÚpropertyrxÚsetterrPrƒrÌr|rÒrÓr™r±r{ryrŽrÙrÝràrÞrórõrIrIrIrJrmÁsª
c
ì6q   
 
Yrmc@seZdZdZdS)ÚClientRedirectErrorzIf a redirect loop is detected when using follow_redirects=True with
    the :cls:`Client`, then this exception is raised.
    N)rör÷rørùrIrIrIrJrsrc @s eZdZdZdHdddddd    œd
d „Zed d œdd„ƒZdIdddddœdd„ZdJddddœdddddddddœdd„Zdddœdddddddœdd „Z    d!dd"œd#d$„Z
ddd%dd&œd'd(„Z dKd!dd)d*œd+d,„Z dLd-dd-d.œd/d0„Z ddd1œddddd-d2œd3d4„Zddd-d5œd6d7„Zddd-d5œd8d9„Zddd-d5œd:d;„Zddd-d5œd<d=„Zddd-d5œd>d?„Zddd-d5œd@dA„Zddd-d5œdBdC„Zddd-d5œdDdE„Zdd œdFdG„ZdS)MÚClienta±Simulate sending requests to a WSGI application without running a WSGI or HTTP
    server.
 
    :param application: The WSGI application to make requests to.
    :param response_wrapper: A :class:`.Response` class to wrap response data with.
        Defaults to :class:`.TestResponse`. If it's not a subclass of ``TestResponse``,
        one will be created.
    :param use_cookies: Persist cookies from ``Set-Cookie`` response headers to the
        ``Cookie`` header in subsequent requests. Domain and path matching is supported,
        but other cookie parameters are ignored.
    :param allow_subdomain_redirects: Allow requests to follow redirects to subdomains.
        Enable this if the application handles subdomains and redirects between them.
 
    .. versionchanged:: 2.3
        Simplify cookie implementation, support domain and path matching.
 
    .. versionchanged:: 2.1
        All data is available as properties on the returned response object. The
        response cannot be returned as a tuple.
 
    .. versionchanged:: 2.0
        ``response_wrapper`` is always a subclass of :class:``TestResponse``.
 
    .. versionchanged:: 0.5
        Added the ``use_cookies`` parameter.
    NTFr,ztype[Response] | Noner/rv)Ú applicationÚresponse_wrapperÚ use_cookiesÚallow_subdomain_redirectsr7cCsb||_|dthkrt}nt|tƒs2tdt|fiƒ}t tjd|¡|_|rRi|_    nd|_    ||_
dS)NZWrapperTestResponseÚ TestResponse) rr)rr\rÍrArBÚTyperÚ_cookiesr)r›rrrrrIrIrJrœ@s 
ýzClient.__init__zt.Iterable[Cookie] | Noner·cCs(tjdtdd|jdkrdS|j ¡S)NzuThe 'cookie_jar' attribute is a private API and will be removed in Werkzeug 3.0. Use the 'get_cookie' method instead.r9r:)rSrTrUrrfr¹rIrIrJÚ
cookie_jar[sü
zClient.cookie_jarr»rsr]z Cookie | None)raÚdomainrwr7cCs$|jdkrtdƒ‚|j |||f¡S)aDReturn a :class:`.Cookie` if it exists. Cookies are uniquely identified by
        ``(domain, path, key)``.
 
        :param key: The decoded form of the key for the cookie.
        :param domain: The domain the cookie was set for.
        :param path: The path the cookie was set for.
 
        .. versionadded:: 2.3
        Nú>Cookies are disabled. Create a client with 'use_cookies=True'.)rr”rÁ)r›rar
rwrIrIrJÚ
get_cookieis
 
ÿzClient.get_cookierµ)r
Ú origin_onlyrwr)rarbrŽr
r rwrŸr7c        Os†|jdkrtdƒ‚|r6tjdtdd|}|}|d}t |dt||f||dœ|—Ž¡}||_|j    rv|j 
|j d¡n ||j|j <dS)    a·Set a cookie to be sent in subsequent requests.
 
        This is a convenience to skip making a test request to a route that would set
        the cookie. To test the cookie, make a test request to a route that uses the
        cookie value.
 
        The client uses ``domain``, ``origin_only``, and ``path`` to determine which
        cookies to send with a request. It does not use other cookie parameters that
        browsers use, since they're not applicable in tests.
 
        :param key: The key part of the cookie.
        :param value: The value part of the cookie.
        :param domain: Send this cookie with requests that match this domain. If
            ``origin_only`` is true, it must be an exact match, otherwise it may be a
            suffix match.
        :param origin_only: Whether the domain must be an exact match to the request.
        :param path: Send this cookie with requests that match this path either exactly
            or as a prefix.
        :param kwargs: Passed to :func:`.dump_cookie`.
 
        .. versionchanged:: 2.3
            The ``origin_only`` parameter was added.
 
        .. versionchanged:: 2.3
            The ``domain`` parameter defaults to ``localhost``.
 
        .. versionchanged:: 2.3
            The first parameter ``server_name`` is deprecated and will be removed in
            Werkzeug 3.0. The first parameter is ``key``. Use the ``domain`` and
            ``origin_only`` parameters instead.
        Nr zÁThe first parameter 'server_name' is no longer used, and will be removed in Werkzeug 3.0. The positional parameters are 'key' and 'value'. Use the 'domain' and 'origin_only' parameters instead.r9r:rrs©r
rw) rr”rSrTrUÚCookieÚ_from_response_headerrr Ú_should_deleter­Ú _storage_key)    r›rarbr
r rwrŽrŸÚcookierIrIrJÚ
set_cookie|s,)
ÿûÿzClient.set_cookier)rarŽr
rwrŸr7cOs”|jdkrtdƒ‚|r2tjdtdd|}|d}|r|d dd    „|Dƒ¡}t|ƒd
krZd nd }tjd |›d|›dtdd|j |||fd¡dS)aDelete a cookie if it exists. Cookies are uniquely identified by
        ``(domain, path, key)``.
 
        :param key: The decoded form of the key for the cookie.
        :param domain: The domain the cookie was set for.
        :param path: The path the cookie was set for.
 
        .. versionchanged:: 2.3
            The ``domain`` parameter defaults to ``localhost``.
 
        .. versionchanged:: 2.3
            The first parameter ``server_name`` is deprecated and will be removed in
            Werkzeug 3.0. The first parameter is ``key``. Use the ``domain`` parameter
            instead.
 
        .. versionchanged:: 2.3
            The ``secure``, ``httponly`` and ``samesite`` parameters are deprecated and
            will be removed in Werkzeug 2.4.
        Nr z›The first parameter 'server_name' is no longer used, and will be removed in Werkzeug 2.4. The first parameter is 'key'. Use the 'domain' parameter instead.r9r:rrêcss|]}d|›dVqdS)ú'NrI)Ú.0ÚkrIrIrJÚ    <genexpr>ìsz'Client.delete_cookie.<locals>.<genexpr>r zparameters arez parameter iszThe ú z0 deprecated and will be removed in Werkzeug 2.4.)rr”rSrTrUrñr@r­)r›rar
rwrŽrŸZ kwargs_keysÚpluralrIrIrJÚ delete_cookieÀs*
ÿûüzClient.delete_cookier-)ržr7csb|jdkrdStt|ƒƒ‰ˆjp"d‰d ‡‡fdd„|j ¡Dƒ¡}|rR||d<n | dd¡dS)zÉIf cookies are enabled, set the ``Cookie`` header in the environ to the
        cookies that are applicable to the request host and path.
 
        :meta private:
 
        .. versionadded:: 2.3
        Nr»z; c3s$|]}| ˆˆj¡r| ¡VqdSrÉ)Ú_matches_requestrwÚ_to_request_header)rÚc©rÙÚurlrIrJrsþz.Client._add_cookies_to_wsgi.<locals>.<genexpr>Z HTTP_COOKIE)rr r+Úhostnamerñrfr­)r›ržrbrIrrJÚ_add_cookies_to_wsgi÷s
 
þ
zClient._add_cookies_to_wsgiz    list[str])rÙrwrRr7cCsN|jdkrdS|D]6}t |||¡}|jr<|j |jd¡q||j|j<qdS)zªIf cookies are enabled, update the stored cookies from any ``Set-Cookie``
        headers in the response.
 
        :meta private:
 
        .. versionadded:: 2.3
        N)rrrrr­r)r›rÙrwrRÚheaderrrIrIrJÚ_update_cookies_from_responses
 
z$Client._update_cookies_from_responseú&tuple[t.Iterable[bytes], str, Headers])ržÚbufferedr7cCsJ| |¡t|j||d}tt|ƒƒ}| |jp2d|j|d d¡¡|S)zVRuns the wrapped WSGI app with the given environment.
 
        :meta private:
        ©r&r»r9z
Set-Cookie)    r"Ú run_wsgi_apprr r+r$r!rwÚgetlist)r›ržr&rÑr rIrIrJr($s
  ÿzClient.run_wsgi_appr)Úresponser&r7c CsJt|jƒ\}}}}}tj|jj||d}| dd¡d d¡}    |j d¡}
|    dgkrb||_||_    n|
}    |    |
krœ|    t
|
ƒ d…|
kr”|j sœt dƒ‚nt d    ƒ‚| d
¡} |j  d
¡} | dt
| ƒ…| krÜ|t
|j ƒd…|_n ||_d|_ |jd kr<|jd krd |_|jdk    r"|j ¡d|_d|_d|_|j dd¡|j||dS)z†Perform a new request to the location given by the redirect
        response to the previous request.
 
        :meta private:
        )rwryrØr rÚ.rµNz-Following subdomain redirects is not enabled.z.Following external redirects is not supported.rs>é3é4ÚHEADrtzTransfer-Encodingr')r Úlocationrmr°ÚrequestržrÇrÙr¸r³r@rÚ RuntimeErrorr´rwÚ status_coderzr{rÞrPr|rRr­Úopen) r›r*r&r²r¼rwr½r¾ÚbuilderZ to_name_partsZfrom_name_partsÚ
path_partsZ
root_partsrIrIrJÚresolve_redirect3sBÿ 
 
 
 
zClient.resolve_redirect)r&Úfollow_redirects)rŽr&r7rŸr7c OsNd}|sXt|ƒdkrX|d}t|tƒr0| ¡}n(t|tƒrJt |¡ ¡}nt|tƒrX|}|dkr‚t||Ž}z | ¡}W5| ¡X|j|j    |d}|j
|d|iŽ}t ƒ}    g}
|s´|S|j dkr2|sÔ|  ¡| ¡|j|j f} | |    krtd|j ›d|j›d    ƒ‚|     | ¡t|
ƒ|_|
 |¡|j||d}q´t|
ƒ|_| |jj¡|S)
a|Generate an environ dict from the given arguments, make a
        request to the application using it, and return the response.
 
        :param args: Passed to :class:`EnvironBuilder` to create the
            environ for the request. If a single arg is passed, it can
            be an existing :class:`EnvironBuilder` or an environ dict.
        :param buffered: Convert the iterator returned by the app into
            a list. If the iterator has a ``close()`` method, it is
            called automatically.
        :param follow_redirects: Make additional requests to follow HTTP
            redirects until a non-redirect status is returned.
            :attr:`TestResponse.history` lists the intermediate
            responses.
 
        .. versionchanged:: 2.1
            Removed the ``as_tuple`` parameter.
 
        .. versionchanged:: 2.0
            The request input stream is closed when calling
            ``response.close()``. Input streams for redirects are
            automatically closed.
 
        .. versionchanged:: 0.5
            If a dict is provided as file in the dict for the ``data``
            parameter the content type has to be called ``content_type``
            instead of ``mimetype``. This change was made for
            consistency with :class:`werkzeug.FileWrapper`.
 
        .. versionchanged:: 0.5
            Added the ``follow_redirects`` parameter.
        Nr rr'r0>é-é.é/é1r,r-zLoop detected: A z  redirect to z was already made.)r@r\rmrõr—r°r(rÞr(ržrr“r2Z make_sequencer/rÚaddr’Úhistoryršr6Z call_on_closer{) r›r&r7rŽrŸr0Úargr4r*Z    redirectsr=Znew_redirect_entryrIrIrJr3rsH&
 
 
 
 
 
 
 
ÿ
 
 
 
z Client.open)rŽÚkwr7cOsd|d<|j||ŽS)z1Call :meth:`open` with ``method`` set to ``GET``.rtrz©r3©r›rŽr?rIrIrJrÁ×sz
Client.getcOsd|d<|j||ŽS)z2Call :meth:`open` with ``method`` set to ``POST``.ÚPOSTrzr@rArIrIrJÚpostÜsz Client.postcOsd|d<|j||ŽS)z1Call :meth:`open` with ``method`` set to ``PUT``.ÚPUTrzr@rArIrIrJÚputász
Client.putcOsd|d<|j||ŽS)z4Call :meth:`open` with ``method`` set to ``DELETE``.ÚDELETErzr@rArIrIrJÚdeleteæsz Client.deletecOsd|d<|j||ŽS)z3Call :meth:`open` with ``method`` set to ``PATCH``.ÚPATCHrzr@rArIrIrJÚpatchësz Client.patchcOsd|d<|j||ŽS)z5Call :meth:`open` with ``method`` set to ``OPTIONS``.ÚOPTIONSrzr@rArIrIrJÚoptionsðszClient.optionscOsd|d<|j||ŽS)z2Call :meth:`open` with ``method`` set to ``HEAD``.r.rzr@rArIrIrJÚheadõsz Client.headcOsd|d<|j||ŽS)z3Call :meth:`open` with ``method`` set to ``TRACE``.ÚTRACErzr@rArIrIrJÚtraceúsz Client.tracecCsdt|ƒj›d|j›dS)Nú<rú>)rÍrörr¹rIrIrJÚ__repr__ÿszClient.__repr__)NTF)r»rs)rµ)F)F)rör÷rørùrœrþr    r rrr"r$r(r6r3rÁrCrErGrIrKrLrNrQrIrIrIrJr$sJûÿýù Hû7ÿÿBüerrr-)rŽrŸr7cOs&t||Ž}z | ¡W¢S| ¡XdS)a€Create a new WSGI environ dict based on the values passed.  The first
    parameter should be the path of the request which defaults to '/'.  The
    second one can either be an absolute path (in that case the host is
    localhost:80) or a full path to the request with scheme, netloc port and
    the path to the script.
 
    This accepts the same arguments as the :class:`EnvironBuilder`
    constructor.
 
    .. versionchanged:: 0.5
       This function is now a thin wrapper over :class:`EnvironBuilder` which
       was added in 0.5.  The `headers`, `environ_base`, `environ_overrides`
       and `charset` parameters were added.
    N)rmrÞró)rŽrŸr4rIrIrJÚcreate_environs
 rRFr,r%)Úappržr&r7c
sÄt|ƒ ¡}d‰g‰d‡‡fdd„    }|||ƒ}t|ddƒ}t|ƒ}|rfz t|ƒ}W5|dk    rb|ƒXnH|D]}ˆ |¡ˆdk    rjq†qjˆr”tˆ|ƒ}|dk    r®||k    r®t||ƒ}ˆ\}}    ||t|    ƒfS)aReturn a tuple in the form (app_iter, status, headers) of the
    application output.  This works best if you pass it an application that
    returns an iterator all the time.
 
    Sometimes applications may use the `write()` callable returned
    by the `start_response` function.  This tries to resolve such edge
    cases automatically.  But if you don't get the expected output you
    should set `buffered` to `True` which enforces buffering.
 
    If passed an invalid WSGI application the behavior of this function is
    undefined.  Never pass non-conforming WSGI applications to this function.
 
    :param app: the application to execute.
    :param buffered: set to `True` to enforce buffering.
    :return: tuple in the form ``(app_iter, status, headers)``
    Ncs0|r"z|d |d¡‚W5d}X||f‰ˆjS)Nr r9)Úwith_tracebackrš)ÚstatusrRÚexc_info©Úbufferr*rIrJÚstart_response4s z$run_wsgi_app.<locals>.start_responserÞ)N)    rrírXÚiterriršrr*r)
rSržr&rYZapp_rvZ
close_funcZapp_iterÚitemrUrRrIrWrJr(s, 
 
 
 
 
r(c    s`eZdZUdZdZded<ded<dZdd    d
d dd d ddœ‡fdd„ Zed
dœdd„ƒZ    ‡Z
S)ra=:class:`~werkzeug.wrappers.Response` subclass that provides extra
    information about requests made with the test :class:`Client`.
 
    Test client requests will always return an instance of this class.
    If a custom response class is passed to the client, it is
    subclassed along with this to support test information.
 
    If the test request included large files, or if the application is
    serving a file, call :meth:`close` to close any open files and
    prevent Python showing a ``ResourceWarning``.
 
    .. versionchanged:: 2.2
        Set the ``default_mimetype`` to None to prevent a mimetype being
        assumed if missing.
 
    .. versionchanged:: 2.1
        Response instances cannot be treated as tuples.
 
    .. versionadded:: 2.0
        Test client methods always return instances of this class.
    Nr(r0ztuple[TestResponse, ...]r=FrIzt.Iterable[bytes]r]rztuple[TestResponse]rrv)r*rUrRr0r=rŸr7c s0tƒj|||f|Ž||_||_|||f|_dSrÉ)Úsuperrœr0r=Z _compat_tuple)r›r*rUrRr0r=rŸ©Ú    __class__rIrJrœ‰s    zTestResponse.__init__r·cCs |jddS)z~The response data as text. A shortcut for
        ``response.get_data(as_text=True)``.
 
        .. versionadded:: 2.1
        T)Zas_text)Úget_datar¹rIrIrJÚtext—szTestResponse.text)rI) rör÷rørùZdefault_mimetyperüZ__test__rœr&r`Ú __classcell__rIrIr]rJrbs
ú rc@sÎeZdZUdZded<ded<ded<ded<ded<d    ed
<ded <d ed <ded<ded<ded<ded<ddd dœdd„Zddœdd„Zedddddœdd„ƒZe    ddœdd „ƒZ
e    d dœd!d"„ƒZ d#S)$rzÆA cookie key, value, and parameters.
 
    The class itself is not a public API. Its attributes are documented for inspection
    with :meth:`.Client.get_cookie` only.
 
    .. versionadded:: 2.3
    r]rarbÚ decoded_keyÚ decoded_valuezdatetime | NoneÚexpiresruÚmax_ager
r/r rwz bool | NoneÚsecureÚ    http_onlyr1Ú    same_site)rÙrwr7cCsr||jks8|j op| |j¡op|dt|jƒ … d¡op||jkpp| |j¡op|t|jƒ|j d¡d… d¡S)Nr+rs)r
r Úendswithr@rwÚ
startswith)r›rÙrwrIrIrJrÓs
 
ÿû
 "õzCookie._matches_requestr·cCs|j›d|j›S)Nú=)rarbr¹rIrIrJrãszCookie._to_request_headerzte.Self)rÙrwr#r7cCsò| d¡\}}}| d¡\}}}tt|ƒ ¡ƒ\}}    i}
| d¡D]0} |  d¡\} } }| rb| ¡nd|
|  ¡ ¡<qB|| ¡| ¡||    t|
 d¡ƒd|
krªt    |
dp¦dƒnd|
 d¡p¸|d|
k|
 d¡pØ| 
d¡dpØdd    |
kd
|
k|
 d ¡d  S) NrÆrkrdzmax-agerr
rwrsrfÚhttponlyÚsamesite) rarbrbrcrdrer
r rwrfrgrh) Ú    partitionÚnextrrhrÇrÈÚlowerrrÁr0Ú
rpartition)r®rÙrwr#réZparameters_strrarbrbrcÚparamsr[rÚseprjrIrIrJræs*  ôzCookie._from_response_headerztuple[str, str, str]cCs|j|j|jfSrÉ)r
rwrbr¹rIrIrJrszCookie._storage_keycCs"|jdkp |jdk    o |j ¡dkS)Nr)rerdÚ    timestampr¹rIrIrJrs
ÿzCookie._should_deleteN) rör÷rørùrürrrýrrþrrrIrIrIrJr¡s*
r)Tr.NN)NN)F)RÚ
__future__rZ dataclassesrYrÚtypingrArSÚ collectionsrrÚiorÚ    itertoolsrrÚtempfilerr    Ú urllib.parser
r r Ú    _internalrrrrZdatastructuresrrrrrrrrºrrrrrZsansio.multipartrrr r!r"r#Úurlsr$r%Úutilsr&r'Zwrappers.requestr(Zwrappers.responser)Zwsgir*r+Ú TYPE_CHECKINGZ_typeshed.wsgir,r-Ztyping_extensionsÚterergrWÚTypeVarrkrmrßrrrRr(rZ    dataclassrrIrIrIrJÚ<module>s–                                           ûgýabÿH?