smlflg commited on
Commit
755dee8
·
verified ·
1 Parent(s): 90e6c59

Initial public upload from Projekte/Sidecar-Workspace (part 6)

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/AUTHORS.txt +760 -0
  2. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/INSTALLER +1 -0
  3. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/LICENSE.txt +20 -0
  4. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/METADATA +88 -0
  5. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/RECORD +1005 -0
  6. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/REQUESTED +0 -0
  7. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/WHEEL +5 -0
  8. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/entry_points.txt +4 -0
  9. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/top_level.txt +1 -0
  10. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/exceptions.py +323 -0
  11. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/fields.py +274 -0
  12. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/filepost.py +98 -0
  13. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__init__.py +0 -0
  14. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py +0 -0
  15. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +51 -0
  16. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py +155 -0
  17. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/six.py +1076 -0
  18. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/poolmanager.py +556 -0
  19. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/request.py +191 -0
  20. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/response.py +879 -0
  21. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__init__.py +49 -0
  22. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/connection.py +149 -0
  23. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/proxy.py +57 -0
  24. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/queue.py +22 -0
  25. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/request.py +137 -0
  26. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/response.py +107 -0
  27. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/retry.py +622 -0
  28. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_.py +495 -0
  29. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py +159 -0
  30. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssltransport.py +221 -0
  31. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/timeout.py +271 -0
  32. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/url.py +435 -0
  33. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/wait.py +152 -0
  34. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/vendor.txt +24 -0
  35. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__init__.py +342 -0
  36. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/labels.py +231 -0
  37. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/mklabels.py +59 -0
  38. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/tests.py +153 -0
  39. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/x_user_defined.py +325 -0
  40. Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/py.typed +4 -0
  41. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/INSTALLER +1 -0
  42. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/METADATA +152 -0
  43. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/RECORD +23 -0
  44. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/WHEEL +5 -0
  45. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/licenses/LICENSE +21 -0
  46. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/top_level.txt +1 -0
  47. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/__init__.py +30 -0
  48. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/_callers.py +169 -0
  49. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/_hooks.py +714 -0
  50. Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/_manager.py +523 -0
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/AUTHORS.txt ADDED
@@ -0,0 +1,760 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @Switch01
2
+ A_Rog
3
+ Aakanksha Agrawal
4
+ Abhinav Sagar
5
+ ABHYUDAY PRATAP SINGH
6
+ abs51295
7
+ AceGentile
8
+ Adam Chainz
9
+ Adam Tse
10
+ Adam Wentz
11
+ admin
12
+ Adrien Morison
13
+ ahayrapetyan
14
+ Ahilya
15
+ AinsworthK
16
+ Akash Srivastava
17
+ Alan Yee
18
+ Albert Tugushev
19
+ Albert-Guan
20
+ albertg
21
+ Alberto Sottile
22
+ Aleks Bunin
23
+ Ales Erjavec
24
+ Alethea Flowers
25
+ Alex Gaynor
26
+ Alex Grönholm
27
+ Alex Hedges
28
+ Alex Loosley
29
+ Alex Morega
30
+ Alex Stachowiak
31
+ Alexander Shtyrov
32
+ Alexandre Conrad
33
+ Alexey Popravka
34
+ Aleš Erjavec
35
+ Alli
36
+ Ami Fischman
37
+ Ananya Maiti
38
+ Anatoly Techtonik
39
+ Anders Kaseorg
40
+ Andre Aguiar
41
+ Andreas Lutro
42
+ Andrei Geacar
43
+ Andrew Gaul
44
+ Andrew Shymanel
45
+ Andrey Bienkowski
46
+ Andrey Bulgakov
47
+ Andrés Delfino
48
+ Andy Freeland
49
+ Andy Kluger
50
+ Ani Hayrapetyan
51
+ Aniruddha Basak
52
+ Anish Tambe
53
+ Anrs Hu
54
+ Anthony Sottile
55
+ Antoine Musso
56
+ Anton Ovchinnikov
57
+ Anton Patrushev
58
+ Antonio Alvarado Hernandez
59
+ Antony Lee
60
+ Antti Kaihola
61
+ Anubhav Patel
62
+ Anudit Nagar
63
+ Anuj Godase
64
+ AQNOUCH Mohammed
65
+ AraHaan
66
+ Arindam Choudhury
67
+ Armin Ronacher
68
+ Artem
69
+ Arun Babu Neelicattu
70
+ Ashley Manton
71
+ Ashwin Ramaswami
72
+ atse
73
+ Atsushi Odagiri
74
+ Avinash Karhana
75
+ Avner Cohen
76
+ Awit (Ah-Wit) Ghirmai
77
+ Baptiste Mispelon
78
+ Barney Gale
79
+ barneygale
80
+ Bartek Ogryczak
81
+ Bastian Venthur
82
+ Ben Bodenmiller
83
+ Ben Darnell
84
+ Ben Hoyt
85
+ Ben Mares
86
+ Ben Rosser
87
+ Bence Nagy
88
+ Benjamin Peterson
89
+ Benjamin VanEvery
90
+ Benoit Pierre
91
+ Berker Peksag
92
+ Bernard
93
+ Bernard Tyers
94
+ Bernardo B. Marques
95
+ Bernhard M. Wiedemann
96
+ Bertil Hatt
97
+ Bhavam Vidyarthi
98
+ Blazej Michalik
99
+ Bogdan Opanchuk
100
+ BorisZZZ
101
+ Brad Erickson
102
+ Bradley Ayers
103
+ Brandon L. Reiss
104
+ Brandt Bucher
105
+ Brett Randall
106
+ Brett Rosen
107
+ Brian Cristante
108
+ Brian Rosner
109
+ briantracy
110
+ BrownTruck
111
+ Bruno Oliveira
112
+ Bruno Renié
113
+ Bruno S
114
+ Bstrdsmkr
115
+ Buck Golemon
116
+ burrows
117
+ Bussonnier Matthias
118
+ bwoodsend
119
+ c22
120
+ Caleb Martinez
121
+ Calvin Smith
122
+ Carl Meyer
123
+ Carlos Liam
124
+ Carol Willing
125
+ Carter Thayer
126
+ Cass
127
+ Chandrasekhar Atina
128
+ Chih-Hsuan Yen
129
+ Chris Brinker
130
+ Chris Hunt
131
+ Chris Jerdonek
132
+ Chris Kuehl
133
+ Chris McDonough
134
+ Chris Pawley
135
+ Chris Pryer
136
+ Chris Wolfe
137
+ Christian Clauss
138
+ Christian Heimes
139
+ Christian Oudard
140
+ Christoph Reiter
141
+ Christopher Hunt
142
+ Christopher Snyder
143
+ cjc7373
144
+ Clark Boylan
145
+ Claudio Jolowicz
146
+ Clay McClure
147
+ Cody
148
+ Cody Soyland
149
+ Colin Watson
150
+ Collin Anderson
151
+ Connor Osborn
152
+ Cooper Lees
153
+ Cooper Ry Lees
154
+ Cory Benfield
155
+ Cory Wright
156
+ Craig Kerstiens
157
+ Cristian Sorinel
158
+ Cristina
159
+ Cristina Muñoz
160
+ Curtis Doty
161
+ cytolentino
162
+ Daan De Meyer
163
+ Dale
164
+ Damian
165
+ Damian Quiroga
166
+ Damian Shaw
167
+ Dan Black
168
+ Dan Savilonis
169
+ Dan Sully
170
+ Dane Hillard
171
+ daniel
172
+ Daniel Collins
173
+ Daniel Hahler
174
+ Daniel Holth
175
+ Daniel Jost
176
+ Daniel Katz
177
+ Daniel Shaulov
178
+ Daniele Esposti
179
+ Daniele Nicolodi
180
+ Daniele Procida
181
+ Daniil Konovalenko
182
+ Danny Hermes
183
+ Danny McClanahan
184
+ Darren Kavanagh
185
+ Dav Clark
186
+ Dave Abrahams
187
+ Dave Jones
188
+ David Aguilar
189
+ David Black
190
+ David Bordeynik
191
+ David Caro
192
+ David D Lowe
193
+ David Evans
194
+ David Hewitt
195
+ David Linke
196
+ David Poggi
197
+ David Pursehouse
198
+ David Runge
199
+ David Tucker
200
+ David Wales
201
+ Davidovich
202
+ ddelange
203
+ Deepak Sharma
204
+ Deepyaman Datta
205
+ Denise Yu
206
+ dependabot[bot]
207
+ derwolfe
208
+ Desetude
209
+ Devesh Kumar Singh
210
+ Diego Caraballo
211
+ Diego Ramirez
212
+ DiegoCaraballo
213
+ Dimitri Merejkowsky
214
+ Dimitri Papadopoulos
215
+ Dirk Stolle
216
+ Dmitry Gladkov
217
+ Dmitry Volodin
218
+ Domen Kožar
219
+ Dominic Davis-Foster
220
+ Donald Stufft
221
+ Dongweiming
222
+ doron zarhi
223
+ Dos Moonen
224
+ Douglas Thor
225
+ DrFeathers
226
+ Dustin Ingram
227
+ Dwayne Bailey
228
+ Ed Morley
229
+ Edgar Ramírez
230
+ Edgar Ramírez Mondragón
231
+ Ee Durbin
232
+ Efflam Lemaillet
233
+ efflamlemaillet
234
+ Eitan Adler
235
+ ekristina
236
+ elainechan
237
+ Eli Schwartz
238
+ Elisha Hollander
239
+ Ellen Marie Dash
240
+ Emil Burzo
241
+ Emil Styrke
242
+ Emmanuel Arias
243
+ Endoh Takanao
244
+ enoch
245
+ Erdinc Mutlu
246
+ Eric Cousineau
247
+ Eric Gillingham
248
+ Eric Hanchrow
249
+ Eric Hopper
250
+ Erik M. Bray
251
+ Erik Rose
252
+ Erwin Janssen
253
+ Eugene Vereshchagin
254
+ everdimension
255
+ Federico
256
+ Felipe Peter
257
+ Felix Yan
258
+ fiber-space
259
+ Filip Kokosiński
260
+ Filipe Laíns
261
+ Finn Womack
262
+ finnagin
263
+ Flavio Amurrio
264
+ Florian Briand
265
+ Florian Rathgeber
266
+ Francesco
267
+ Francesco Montesano
268
+ Frost Ming
269
+ Gabriel Curio
270
+ Gabriel de Perthuis
271
+ Garry Polley
272
+ gavin
273
+ gdanielson
274
+ Geoffrey Sneddon
275
+ George Song
276
+ Georgi Valkov
277
+ Georgy Pchelkin
278
+ ghost
279
+ Giftlin Rajaiah
280
+ gizmoguy1
281
+ gkdoc
282
+ Godefroid Chapelle
283
+ Gopinath M
284
+ GOTO Hayato
285
+ gousaiyang
286
+ gpiks
287
+ Greg Roodt
288
+ Greg Ward
289
+ Guilherme Espada
290
+ Guillaume Seguin
291
+ gutsytechster
292
+ Guy Rozendorn
293
+ Guy Tuval
294
+ gzpan123
295
+ Hanjun Kim
296
+ Hari Charan
297
+ Harsh Vardhan
298
+ harupy
299
+ Harutaka Kawamura
300
+ hauntsaninja
301
+ Henrich Hartzer
302
+ Henry Schreiner
303
+ Herbert Pfennig
304
+ Holly Stotelmyer
305
+ Honnix
306
+ Hsiaoming Yang
307
+ Hugo Lopes Tavares
308
+ Hugo van Kemenade
309
+ Hugues Bruant
310
+ Hynek Schlawack
311
+ Ian Bicking
312
+ Ian Cordasco
313
+ Ian Lee
314
+ Ian Stapleton Cordasco
315
+ Ian Wienand
316
+ Igor Kuzmitshov
317
+ Igor Sobreira
318
+ Ilan Schnell
319
+ Illia Volochii
320
+ Ilya Baryshev
321
+ Inada Naoki
322
+ Ionel Cristian Mărieș
323
+ Ionel Maries Cristian
324
+ Itamar Turner-Trauring
325
+ Ivan Pozdeev
326
+ J. Nick Koston
327
+ Jacob Kim
328
+ Jacob Walls
329
+ Jaime Sanz
330
+ jakirkham
331
+ Jakub Kuczys
332
+ Jakub Stasiak
333
+ Jakub Vysoky
334
+ Jakub Wilk
335
+ James Cleveland
336
+ James Curtin
337
+ James Firth
338
+ James Gerity
339
+ James Polley
340
+ Jan Pokorný
341
+ Jannis Leidel
342
+ Jarek Potiuk
343
+ jarondl
344
+ Jason Curtis
345
+ Jason R. Coombs
346
+ JasonMo
347
+ JasonMo1
348
+ Jay Graves
349
+ Jean Abou Samra
350
+ Jean-Christophe Fillion-Robin
351
+ Jeff Barber
352
+ Jeff Dairiki
353
+ Jeff Widman
354
+ Jelmer Vernooij
355
+ jenix21
356
+ Jeremy Stanley
357
+ Jeremy Zafran
358
+ Jesse Rittner
359
+ Jiashuo Li
360
+ Jim Fisher
361
+ Jim Garrison
362
+ Jiun Bae
363
+ Jivan Amara
364
+ Joe Bylund
365
+ Joe Michelini
366
+ John Paton
367
+ John T. Wodder II
368
+ John-Scott Atlakson
369
+ johnthagen
370
+ Jon Banafato
371
+ Jon Dufresne
372
+ Jon Parise
373
+ Jonas Nockert
374
+ Jonathan Herbert
375
+ Joonatan Partanen
376
+ Joost Molenaar
377
+ Jorge Niedbalski
378
+ Joseph Bylund
379
+ Joseph Long
380
+ Josh Bronson
381
+ Josh Hansen
382
+ Josh Schneier
383
+ Joshua
384
+ Juan Luis Cano Rodríguez
385
+ Juanjo Bazán
386
+ Judah Rand
387
+ Julian Berman
388
+ Julian Gethmann
389
+ Julien Demoor
390
+ Jussi Kukkonen
391
+ jwg4
392
+ Jyrki Pulliainen
393
+ Kai Chen
394
+ Kai Mueller
395
+ Kamal Bin Mustafa
396
+ kasium
397
+ kaustav haldar
398
+ keanemind
399
+ Keith Maxwell
400
+ Kelsey Hightower
401
+ Kenneth Belitzky
402
+ Kenneth Reitz
403
+ Kevin Burke
404
+ Kevin Carter
405
+ Kevin Frommelt
406
+ Kevin R Patterson
407
+ Kexuan Sun
408
+ Kit Randel
409
+ Klaas van Schelven
410
+ KOLANICH
411
+ kpinc
412
+ Krishna Oza
413
+ Kumar McMillan
414
+ Kurt McKee
415
+ Kyle Persohn
416
+ lakshmanaram
417
+ Laszlo Kiss-Kollar
418
+ Laurent Bristiel
419
+ Laurent LAPORTE
420
+ Laurie O
421
+ Laurie Opperman
422
+ layday
423
+ Leon Sasson
424
+ Lev Givon
425
+ Lincoln de Sousa
426
+ Lipis
427
+ lorddavidiii
428
+ Loren Carvalho
429
+ Lucas Cimon
430
+ Ludovic Gasc
431
+ Lukas Geiger
432
+ Lukas Juhrich
433
+ Luke Macken
434
+ Luo Jiebin
435
+ luojiebin
436
+ luz.paz
437
+ László Kiss Kollár
438
+ M00nL1ght
439
+ Marc Abramowitz
440
+ Marc Tamlyn
441
+ Marcus Smith
442
+ Mariatta
443
+ Mark Kohler
444
+ Mark Williams
445
+ Markus Hametner
446
+ Martey Dodoo
447
+ Martin Fischer
448
+ Martin Häcker
449
+ Martin Pavlasek
450
+ Masaki
451
+ Masklinn
452
+ Matej Stuchlik
453
+ Mathew Jennings
454
+ Mathieu Bridon
455
+ Mathieu Kniewallner
456
+ Matt Bacchi
457
+ Matt Good
458
+ Matt Maker
459
+ Matt Robenolt
460
+ matthew
461
+ Matthew Einhorn
462
+ Matthew Feickert
463
+ Matthew Gilliard
464
+ Matthew Iversen
465
+ Matthew Treinish
466
+ Matthew Trumbell
467
+ Matthew Willson
468
+ Matthias Bussonnier
469
+ mattip
470
+ Maurits van Rees
471
+ Max W Chase
472
+ Maxim Kurnikov
473
+ Maxime Rouyrre
474
+ mayeut
475
+ mbaluna
476
+ mdebi
477
+ memoselyk
478
+ meowmeowcat
479
+ Michael
480
+ Michael Aquilina
481
+ Michael E. Karpeles
482
+ Michael Klich
483
+ Michael Mintz
484
+ Michael Williamson
485
+ michaelpacer
486
+ Michał Górny
487
+ Mickaël Schoentgen
488
+ Miguel Araujo Perez
489
+ Mihir Singh
490
+ Mike
491
+ Mike Hendricks
492
+ Min RK
493
+ MinRK
494
+ Miro Hrončok
495
+ Monica Baluna
496
+ montefra
497
+ Monty Taylor
498
+ Muha Ajjan‮
499
+ Nadav Wexler
500
+ Nahuel Ambrosini
501
+ Nate Coraor
502
+ Nate Prewitt
503
+ Nathan Houghton
504
+ Nathaniel J. Smith
505
+ Nehal J Wani
506
+ Neil Botelho
507
+ Nguyễn Gia Phong
508
+ Nicholas Serra
509
+ Nick Coghlan
510
+ Nick Stenning
511
+ Nick Timkovich
512
+ Nicolas Bock
513
+ Nicole Harris
514
+ Nikhil Benesch
515
+ Nikhil Ladha
516
+ Nikita Chepanov
517
+ Nikolay Korolev
518
+ Nipunn Koorapati
519
+ Nitesh Sharma
520
+ Niyas Sait
521
+ Noah
522
+ Noah Gorny
523
+ Nowell Strite
524
+ NtaleGrey
525
+ nvdv
526
+ OBITORASU
527
+ Ofek Lev
528
+ ofrinevo
529
+ Oliver Freund
530
+ Oliver Jeeves
531
+ Oliver Mannion
532
+ Oliver Tonnhofer
533
+ Olivier Girardot
534
+ Olivier Grisel
535
+ Ollie Rutherfurd
536
+ OMOTO Kenji
537
+ Omry Yadan
538
+ onlinejudge95
539
+ Oren Held
540
+ Oscar Benjamin
541
+ Oz N Tiram
542
+ Pachwenko
543
+ Patrick Dubroy
544
+ Patrick Jenkins
545
+ Patrick Lawson
546
+ patricktokeeffe
547
+ Patrik Kopkan
548
+ Paul Ganssle
549
+ Paul Kehrer
550
+ Paul Moore
551
+ Paul Nasrat
552
+ Paul Oswald
553
+ Paul van der Linden
554
+ Paulus Schoutsen
555
+ Pavel Safronov
556
+ Pavithra Eswaramoorthy
557
+ Pawel Jasinski
558
+ Paweł Szramowski
559
+ Pekka Klärck
560
+ Peter Gessler
561
+ Peter Lisák
562
+ Peter Waller
563
+ petr-tik
564
+ Phaneendra Chiruvella
565
+ Phil Elson
566
+ Phil Freo
567
+ Phil Pennock
568
+ Phil Whelan
569
+ Philip Jägenstedt
570
+ Philip Molloy
571
+ Philippe Ombredanne
572
+ Pi Delport
573
+ Pierre-Yves Rofes
574
+ Pieter Degroote
575
+ pip
576
+ Prabakaran Kumaresshan
577
+ Prabhjyotsing Surjit Singh Sodhi
578
+ Prabhu Marappan
579
+ Pradyun Gedam
580
+ Prashant Sharma
581
+ Pratik Mallya
582
+ pre-commit-ci[bot]
583
+ Preet Thakkar
584
+ Preston Holmes
585
+ Przemek Wrzos
586
+ Pulkit Goyal
587
+ q0w
588
+ Qiangning Hong
589
+ Qiming Xu
590
+ Quentin Lee
591
+ Quentin Pradet
592
+ R. David Murray
593
+ Rafael Caricio
594
+ Ralf Schmitt
595
+ Razzi Abuissa
596
+ rdb
597
+ Reece Dunham
598
+ Remi Rampin
599
+ Rene Dudfield
600
+ Riccardo Magliocchetti
601
+ Riccardo Schirone
602
+ Richard Jones
603
+ Richard Si
604
+ Ricky Ng-Adam
605
+ Rishi
606
+ RobberPhex
607
+ Robert Collins
608
+ Robert McGibbon
609
+ Robert Pollak
610
+ Robert T. McGibbon
611
+ robin elisha robinson
612
+ Roey Berman
613
+ Rohan Jain
614
+ Roman Bogorodskiy
615
+ Roman Donchenko
616
+ Romuald Brunet
617
+ ronaudinho
618
+ Ronny Pfannschmidt
619
+ Rory McCann
620
+ Ross Brattain
621
+ Roy Wellington Ⅳ
622
+ Ruairidh MacLeod
623
+ Russell Keith-Magee
624
+ Ryan Shepherd
625
+ Ryan Wooden
626
+ ryneeverett
627
+ Sachi King
628
+ Salvatore Rinchiera
629
+ sandeepkiran-js
630
+ Sander Van Balen
631
+ Savio Jomton
632
+ schlamar
633
+ Scott Kitterman
634
+ Sean
635
+ seanj
636
+ Sebastian Jordan
637
+ Sebastian Schaetz
638
+ Segev Finer
639
+ SeongSoo Cho
640
+ Sergey Vasilyev
641
+ Seth Michael Larson
642
+ Seth Woodworth
643
+ Shahar Epstein
644
+ Shantanu
645
+ shireenrao
646
+ Shivansh-007
647
+ Shlomi Fish
648
+ Shovan Maity
649
+ Simeon Visser
650
+ Simon Cross
651
+ Simon Pichugin
652
+ sinoroc
653
+ sinscary
654
+ snook92
655
+ socketubs
656
+ Sorin Sbarnea
657
+ Srinivas Nyayapati
658
+ Stavros Korokithakis
659
+ Stefan Scherfke
660
+ Stefano Rivera
661
+ Stephan Erb
662
+ Stephen Rosen
663
+ stepshal
664
+ Steve (Gadget) Barnes
665
+ Steve Barnes
666
+ Steve Dower
667
+ Steve Kowalik
668
+ Steven Myint
669
+ Steven Silvester
670
+ stonebig
671
+ studioj
672
+ Stéphane Bidoul
673
+ Stéphane Bidoul (ACSONE)
674
+ Stéphane Klein
675
+ Sumana Harihareswara
676
+ Surbhi Sharma
677
+ Sviatoslav Sydorenko
678
+ Swat009
679
+ Sylvain
680
+ Takayuki SHIMIZUKAWA
681
+ Taneli Hukkinen
682
+ tbeswick
683
+ Thiago
684
+ Thijs Triemstra
685
+ Thomas Fenzl
686
+ Thomas Grainger
687
+ Thomas Guettler
688
+ Thomas Johansson
689
+ Thomas Kluyver
690
+ Thomas Smith
691
+ Thomas VINCENT
692
+ Tim D. Smith
693
+ Tim Gates
694
+ Tim Harder
695
+ Tim Heap
696
+ tim smith
697
+ tinruufu
698
+ Tobias Hermann
699
+ Tom Forbes
700
+ Tom Freudenheim
701
+ Tom V
702
+ Tomas Hrnciar
703
+ Tomas Orsava
704
+ Tomer Chachamu
705
+ Tommi Enenkel | AnB
706
+ Tomáš Hrnčiar
707
+ Tony Beswick
708
+ Tony Narlock
709
+ Tony Zhaocheng Tan
710
+ TonyBeswick
711
+ toonarmycaptain
712
+ Toshio Kuratomi
713
+ toxinu
714
+ Travis Swicegood
715
+ Tushar Sadhwani
716
+ Tzu-ping Chung
717
+ Valentin Haenel
718
+ Victor Stinner
719
+ victorvpaulo
720
+ Vikram - Google
721
+ Viktor Szépe
722
+ Ville Skyttä
723
+ Vinay Sajip
724
+ Vincent Philippon
725
+ Vinicyus Macedo
726
+ Vipul Kumar
727
+ Vitaly Babiy
728
+ Vladimir Fokow
729
+ Vladimir Rutsky
730
+ W. Trevor King
731
+ Wil Tan
732
+ Wilfred Hughes
733
+ William Edwards
734
+ William ML Leslie
735
+ William T Olson
736
+ William Woodruff
737
+ Wilson Mo
738
+ wim glenn
739
+ Winson Luk
740
+ Wolfgang Maier
741
+ Wu Zhenyu
742
+ XAMES3
743
+ Xavier Fernandez
744
+ xoviat
745
+ xtreak
746
+ YAMAMOTO Takashi
747
+ Yen Chi Hsuan
748
+ Yeray Diaz Diaz
749
+ Yoval P
750
+ Yu Jian
751
+ Yuan Jing Vincent Yan
752
+ Yusuke Hayashi
753
+ Zearin
754
+ Zhiping Deng
755
+ ziebam
756
+ Zvezdan Petkovic
757
+ Łukasz Langa
758
+ Роман Донченко
759
+ Семён Марьясин
760
+ ‮rekcäH nitraM‮
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2008-present The pip developers (see AUTHORS.txt file)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/METADATA ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.1
2
+ Name: pip
3
+ Version: 24.0
4
+ Summary: The PyPA recommended tool for installing Python packages.
5
+ Author-email: The pip developers <distutils-sig@python.org>
6
+ License: MIT
7
+ Project-URL: Homepage, https://pip.pypa.io/
8
+ Project-URL: Documentation, https://pip.pypa.io
9
+ Project-URL: Source, https://github.com/pypa/pip
10
+ Project-URL: Changelog, https://pip.pypa.io/en/stable/news/
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Topic :: Software Development :: Build Tools
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.7
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: Implementation :: CPython
25
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
26
+ Requires-Python: >=3.7
27
+ Description-Content-Type: text/x-rst
28
+ License-File: LICENSE.txt
29
+ License-File: AUTHORS.txt
30
+
31
+ pip - The Python Package Installer
32
+ ==================================
33
+
34
+ .. image:: https://img.shields.io/pypi/v/pip.svg
35
+ :target: https://pypi.org/project/pip/
36
+ :alt: PyPI
37
+
38
+ .. image:: https://img.shields.io/pypi/pyversions/pip
39
+ :target: https://pypi.org/project/pip
40
+ :alt: PyPI - Python Version
41
+
42
+ .. image:: https://readthedocs.org/projects/pip/badge/?version=latest
43
+ :target: https://pip.pypa.io/en/latest
44
+ :alt: Documentation
45
+
46
+ pip is the `package installer`_ for Python. You can use pip to install packages from the `Python Package Index`_ and other indexes.
47
+
48
+ Please take a look at our documentation for how to install and use pip:
49
+
50
+ * `Installation`_
51
+ * `Usage`_
52
+
53
+ We release updates regularly, with a new version every 3 months. Find more details in our documentation:
54
+
55
+ * `Release notes`_
56
+ * `Release process`_
57
+
58
+ If you find bugs, need help, or want to talk to the developers, please use our mailing lists or chat rooms:
59
+
60
+ * `Issue tracking`_
61
+ * `Discourse channel`_
62
+ * `User IRC`_
63
+
64
+ If you want to get involved head over to GitHub to get the source code, look at our development documentation and feel free to jump on the developer mailing lists and chat rooms:
65
+
66
+ * `GitHub page`_
67
+ * `Development documentation`_
68
+ * `Development IRC`_
69
+
70
+ Code of Conduct
71
+ ---------------
72
+
73
+ Everyone interacting in the pip project's codebases, issue trackers, chat
74
+ rooms, and mailing lists is expected to follow the `PSF Code of Conduct`_.
75
+
76
+ .. _package installer: https://packaging.python.org/guides/tool-recommendations/
77
+ .. _Python Package Index: https://pypi.org
78
+ .. _Installation: https://pip.pypa.io/en/stable/installation/
79
+ .. _Usage: https://pip.pypa.io/en/stable/
80
+ .. _Release notes: https://pip.pypa.io/en/stable/news.html
81
+ .. _Release process: https://pip.pypa.io/en/latest/development/release-process/
82
+ .. _GitHub page: https://github.com/pypa/pip
83
+ .. _Development documentation: https://pip.pypa.io/en/latest/development
84
+ .. _Issue tracking: https://github.com/pypa/pip/issues
85
+ .. _Discourse channel: https://discuss.python.org/c/packaging
86
+ .. _User IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa
87
+ .. _Development IRC: https://kiwiirc.com/nextclient/#ircs://irc.libera.chat:+6697/pypa-dev
88
+ .. _PSF Code of Conduct: https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/RECORD ADDED
@@ -0,0 +1,1005 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ../../../bin/pip,sha256=mgfaJsPZOeoIWapwBi1KFA3xpKgK5lsiMMr405n-HHw,281
2
+ ../../../bin/pip3,sha256=mgfaJsPZOeoIWapwBi1KFA3xpKgK5lsiMMr405n-HHw,281
3
+ ../../../bin/pip3.12,sha256=mgfaJsPZOeoIWapwBi1KFA3xpKgK5lsiMMr405n-HHw,281
4
+ pip-24.0.dist-info/AUTHORS.txt,sha256=SwXm4nkwRkmtnO1ZY-dLy7EPeoQNXMNLby5CN3GlNhY,10388
5
+ pip-24.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
6
+ pip-24.0.dist-info/LICENSE.txt,sha256=Y0MApmnUmurmWxLGxIySTFGkzfPR_whtw0VtyLyqIQQ,1093
7
+ pip-24.0.dist-info/METADATA,sha256=kNEfJ3_Vho2mee4lfJdlbd5RHIqsfQJSMUB-bOkIOeI,3581
8
+ pip-24.0.dist-info/RECORD,,
9
+ pip-24.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ pip-24.0.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
11
+ pip-24.0.dist-info/entry_points.txt,sha256=Fa_c0b-xGFaYxagIruvpJD6qqXmNTA02vAVIkmMj-9o,125
12
+ pip-24.0.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
13
+ pip/__init__.py,sha256=oAk1nFpLmUVS5Ln7NxvNoGUn5Vkn6FGQjPaNDf8Q8pk,355
14
+ pip/__main__.py,sha256=WzbhHXTbSE6gBY19mNN9m4s5o_365LOvTYSgqgbdBhE,854
15
+ pip/__pip-runner__.py,sha256=EnrfKmKMzWAdqg_JicLCOP9Y95Ux7zHh4ObvqLtQcjo,1444
16
+ pip/__pycache__/__init__.cpython-312.pyc,,
17
+ pip/__pycache__/__main__.cpython-312.pyc,,
18
+ pip/__pycache__/__pip-runner__.cpython-312.pyc,,
19
+ pip/_internal/__init__.py,sha256=iqZ5-YQsQV08tkUc7L806Reop6tguLFWf70ySF6be0Y,515
20
+ pip/_internal/__pycache__/__init__.cpython-312.pyc,,
21
+ pip/_internal/__pycache__/build_env.cpython-312.pyc,,
22
+ pip/_internal/__pycache__/cache.cpython-312.pyc,,
23
+ pip/_internal/__pycache__/configuration.cpython-312.pyc,,
24
+ pip/_internal/__pycache__/exceptions.cpython-312.pyc,,
25
+ pip/_internal/__pycache__/main.cpython-312.pyc,,
26
+ pip/_internal/__pycache__/pyproject.cpython-312.pyc,,
27
+ pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc,,
28
+ pip/_internal/__pycache__/wheel_builder.cpython-312.pyc,,
29
+ pip/_internal/build_env.py,sha256=1ESpqw0iupS_K7phZK5zshVE5Czy9BtGLFU4W6Enva8,10243
30
+ pip/_internal/cache.py,sha256=uiYD-9F0Bv1C8ZyWE85lpzDmQf7hcUkgL99GmI8I41Q,10370
31
+ pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132
32
+ pip/_internal/cli/__pycache__/__init__.cpython-312.pyc,,
33
+ pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc,,
34
+ pip/_internal/cli/__pycache__/base_command.cpython-312.pyc,,
35
+ pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc,,
36
+ pip/_internal/cli/__pycache__/command_context.cpython-312.pyc,,
37
+ pip/_internal/cli/__pycache__/main.cpython-312.pyc,,
38
+ pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc,,
39
+ pip/_internal/cli/__pycache__/parser.cpython-312.pyc,,
40
+ pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc,,
41
+ pip/_internal/cli/__pycache__/req_command.cpython-312.pyc,,
42
+ pip/_internal/cli/__pycache__/spinners.cpython-312.pyc,,
43
+ pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc,,
44
+ pip/_internal/cli/autocompletion.py,sha256=_br_5NgSxSuvPjMF0MLHzS5s6BpSkQAQHKrLK89VauM,6690
45
+ pip/_internal/cli/base_command.py,sha256=iuVWGa2oTq7gBReo0er3Z0tXJ2oqBIC6QjDHcnDhKXY,8733
46
+ pip/_internal/cli/cmdoptions.py,sha256=V8ggG6AtHpHKkH_6tRU0mhJaZTeqtrFpu75ghvMXXJk,30063
47
+ pip/_internal/cli/command_context.py,sha256=RHgIPwtObh5KhMrd3YZTkl8zbVG-6Okml7YbFX4Ehg0,774
48
+ pip/_internal/cli/main.py,sha256=Uzxt_YD1hIvB1AW5mxt6IVcht5G712AtMqdo51UMhmQ,2816
49
+ pip/_internal/cli/main_parser.py,sha256=laDpsuBDl6kyfywp9eMMA9s84jfH2TJJn-vmL0GG90w,4338
50
+ pip/_internal/cli/parser.py,sha256=KW6C3-7-4ErTNB0TfLTKwOdHcd-qefCeGnrOoE2r0RQ,10781
51
+ pip/_internal/cli/progress_bars.py,sha256=So4mPoSjXkXiSHiTzzquH3VVyVD_njXlHJSExYPXAow,1968
52
+ pip/_internal/cli/req_command.py,sha256=c7_XHABnXmD3_qlK9-r37KqdKBAcgmVKvQ2WcTrNLfc,18369
53
+ pip/_internal/cli/spinners.py,sha256=hIJ83GerdFgFCdobIA23Jggetegl_uC4Sp586nzFbPE,5118
54
+ pip/_internal/cli/status_codes.py,sha256=sEFHUaUJbqv8iArL3HAtcztWZmGOFX01hTesSytDEh0,116
55
+ pip/_internal/commands/__init__.py,sha256=5oRO9O3dM2vGuh0bFw4HOVletryrz5HHMmmPWwJrH9U,3882
56
+ pip/_internal/commands/__pycache__/__init__.cpython-312.pyc,,
57
+ pip/_internal/commands/__pycache__/cache.cpython-312.pyc,,
58
+ pip/_internal/commands/__pycache__/check.cpython-312.pyc,,
59
+ pip/_internal/commands/__pycache__/completion.cpython-312.pyc,,
60
+ pip/_internal/commands/__pycache__/configuration.cpython-312.pyc,,
61
+ pip/_internal/commands/__pycache__/debug.cpython-312.pyc,,
62
+ pip/_internal/commands/__pycache__/download.cpython-312.pyc,,
63
+ pip/_internal/commands/__pycache__/freeze.cpython-312.pyc,,
64
+ pip/_internal/commands/__pycache__/hash.cpython-312.pyc,,
65
+ pip/_internal/commands/__pycache__/help.cpython-312.pyc,,
66
+ pip/_internal/commands/__pycache__/index.cpython-312.pyc,,
67
+ pip/_internal/commands/__pycache__/inspect.cpython-312.pyc,,
68
+ pip/_internal/commands/__pycache__/install.cpython-312.pyc,,
69
+ pip/_internal/commands/__pycache__/list.cpython-312.pyc,,
70
+ pip/_internal/commands/__pycache__/search.cpython-312.pyc,,
71
+ pip/_internal/commands/__pycache__/show.cpython-312.pyc,,
72
+ pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc,,
73
+ pip/_internal/commands/__pycache__/wheel.cpython-312.pyc,,
74
+ pip/_internal/commands/cache.py,sha256=xg76_ZFEBC6zoQ3gXLRfMZJft4z2a0RwH4GEFZC6nnU,7944
75
+ pip/_internal/commands/check.py,sha256=Rb13Q28yoLh0j1gpx5SU0jlResNct21eQCRsnaO9xKA,1782
76
+ pip/_internal/commands/completion.py,sha256=HT4lD0bgsflHq2IDgYfiEdp7IGGtE7s6MgI3xn0VQEw,4287
77
+ pip/_internal/commands/configuration.py,sha256=n98enwp6y0b5G6fiRQjaZo43FlJKYve_daMhN-4BRNc,9766
78
+ pip/_internal/commands/debug.py,sha256=63972uUCeMIGOdMMVeIUGrOjTOqTVWplFC82a-hcKyA,6777
79
+ pip/_internal/commands/download.py,sha256=e4hw088zGo26WmJaMIRvCniLlLmoOjqolGyfHjsCkCQ,5335
80
+ pip/_internal/commands/freeze.py,sha256=qrIHS_-c6JPrQ92hMhAv9kkl0bHgFpRLwYJDdbcYr1o,3243
81
+ pip/_internal/commands/hash.py,sha256=EVVOuvGtoPEdFi8SNnmdqlCQrhCxV-kJsdwtdcCnXGQ,1703
82
+ pip/_internal/commands/help.py,sha256=gcc6QDkcgHMOuAn5UxaZwAStsRBrnGSn_yxjS57JIoM,1132
83
+ pip/_internal/commands/index.py,sha256=CNXQer_PeZKSJooURcCFCBEKGfwyNoUWYP_MWczAcOM,4775
84
+ pip/_internal/commands/inspect.py,sha256=2wSPt9yfr3r6g-s2S5L6PvRtaHNVyb4TuodMStJ39cw,3188
85
+ pip/_internal/commands/install.py,sha256=VxDd-BD3a27ApeE2OK34rfBXS6Zo2wtemK9-HCwPqxM,28782
86
+ pip/_internal/commands/list.py,sha256=-QbpPuGDiGN1SdThsk2ml8beBnepliefbGhMAN8tkzU,12547
87
+ pip/_internal/commands/search.py,sha256=sbBZiARRc050QquOKcCvOr2K3XLsoYebLKZGRi__iUI,5697
88
+ pip/_internal/commands/show.py,sha256=t5jia4zcYJRJZy4U_Von7zMl03hJmmcofj6oDNTnj7Y,6419
89
+ pip/_internal/commands/uninstall.py,sha256=OIqO9tqadY8kM4HwhFf1Q62fUIp7v8KDrTRo8yWMz7Y,3886
90
+ pip/_internal/commands/wheel.py,sha256=CSnX8Pmf1oPCnd7j7bn1_f58G9KHNiAblvVJ5zykN-A,6476
91
+ pip/_internal/configuration.py,sha256=XkAiBS0hpzsM-LF0Qu5hvPWO_Bs67-oQKRYFBuMbESs,14006
92
+ pip/_internal/distributions/__init__.py,sha256=Hq6kt6gXBgjNit5hTTWLAzeCNOKoB-N0pGYSqehrli8,858
93
+ pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc,,
94
+ pip/_internal/distributions/__pycache__/base.cpython-312.pyc,,
95
+ pip/_internal/distributions/__pycache__/installed.cpython-312.pyc,,
96
+ pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc,,
97
+ pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc,,
98
+ pip/_internal/distributions/base.py,sha256=oRSEvnv2ZjBnargamnv2fcJa1n6gUDKaW0g6CWSEpWs,1743
99
+ pip/_internal/distributions/installed.py,sha256=QinHFbWAQ8oE0pbD8MFZWkwlnfU1QYTccA1vnhrlYOU,842
100
+ pip/_internal/distributions/sdist.py,sha256=4K3V0VNMllHbBzCJibjwd_tylUKpmIdu2AQyhplvCQo,6709
101
+ pip/_internal/distributions/wheel.py,sha256=-ma3sOtUQj0AxXCEb6_Fhmjl3nh4k3A0HC2taAb2N-4,1277
102
+ pip/_internal/exceptions.py,sha256=TmF1iNFEneSWaemwlg6a5bpPuq2cMHK7d1-SvjsQHb0,23634
103
+ pip/_internal/index/__init__.py,sha256=vpt-JeTZefh8a-FC22ZeBSXFVbuBcXSGiILhQZJaNpQ,30
104
+ pip/_internal/index/__pycache__/__init__.cpython-312.pyc,,
105
+ pip/_internal/index/__pycache__/collector.cpython-312.pyc,,
106
+ pip/_internal/index/__pycache__/package_finder.cpython-312.pyc,,
107
+ pip/_internal/index/__pycache__/sources.cpython-312.pyc,,
108
+ pip/_internal/index/collector.py,sha256=sH0tL_cOoCk6pLLfCSGVjFM4rPEJtllF-VobvAvLSH4,16590
109
+ pip/_internal/index/package_finder.py,sha256=S_nC8gzVIMY6ikWfKoSOzRtoesUqnfNhAPl_BwSOusA,37843
110
+ pip/_internal/index/sources.py,sha256=dJegiR9f86kslaAHcv9-R5L_XBf5Rzm_FkyPteDuPxI,8688
111
+ pip/_internal/locations/__init__.py,sha256=Dh8LJWG8LRlDK4JIj9sfRF96TREzE--N_AIlx7Tqoe4,15365
112
+ pip/_internal/locations/__pycache__/__init__.cpython-312.pyc,,
113
+ pip/_internal/locations/__pycache__/_distutils.cpython-312.pyc,,
114
+ pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc,,
115
+ pip/_internal/locations/__pycache__/base.cpython-312.pyc,,
116
+ pip/_internal/locations/_distutils.py,sha256=H9ZHK_35rdDV1Qsmi4QeaBULjFT4Mbu6QuoVGkJ6QHI,6009
117
+ pip/_internal/locations/_sysconfig.py,sha256=jyNVtUfMIf0mtyY-Xp1m9yQ8iwECozSVVFmjkN9a2yw,7680
118
+ pip/_internal/locations/base.py,sha256=RQiPi1d4FVM2Bxk04dQhXZ2PqkeljEL2fZZ9SYqIQ78,2556
119
+ pip/_internal/main.py,sha256=r-UnUe8HLo5XFJz8inTcOOTiu_sxNhgHb6VwlGUllOI,340
120
+ pip/_internal/metadata/__init__.py,sha256=9pU3W3s-6HtjFuYhWcLTYVmSaziklPv7k2x8p7X1GmA,4339
121
+ pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc,,
122
+ pip/_internal/metadata/__pycache__/_json.cpython-312.pyc,,
123
+ pip/_internal/metadata/__pycache__/base.cpython-312.pyc,,
124
+ pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc,,
125
+ pip/_internal/metadata/_json.py,sha256=Rz5M5ciSNvITwaTQR6NfN8TgKgM5WfTws4D6CFknovE,2627
126
+ pip/_internal/metadata/base.py,sha256=l3Wgku4xlgr8s4p6fS-3qQ4QKOpPbWLRwi5d9omEFG4,25907
127
+ pip/_internal/metadata/importlib/__init__.py,sha256=jUUidoxnHcfITHHaAWG1G2i5fdBYklv_uJcjo2x7VYE,135
128
+ pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc,,
129
+ pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc,,
130
+ pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc,,
131
+ pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc,,
132
+ pip/_internal/metadata/importlib/_compat.py,sha256=GAe_prIfCE4iUylrnr_2dJRlkkBVRUbOidEoID7LPoE,1882
133
+ pip/_internal/metadata/importlib/_dists.py,sha256=UPl1wUujFqiwiltRJ1tMF42WRINO1sSpNNlYQ2mX0mk,8297
134
+ pip/_internal/metadata/importlib/_envs.py,sha256=XTaFIYERP2JF0QUZuPx2ETiugXbPEcZ8q8ZKeht6Lpc,7456
135
+ pip/_internal/metadata/pkg_resources.py,sha256=opjw4IBSqHvie6sXJ_cbT42meygoPEUfNURJuWZY7sk,10035
136
+ pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63
137
+ pip/_internal/models/__pycache__/__init__.cpython-312.pyc,,
138
+ pip/_internal/models/__pycache__/candidate.cpython-312.pyc,,
139
+ pip/_internal/models/__pycache__/direct_url.cpython-312.pyc,,
140
+ pip/_internal/models/__pycache__/format_control.cpython-312.pyc,,
141
+ pip/_internal/models/__pycache__/index.cpython-312.pyc,,
142
+ pip/_internal/models/__pycache__/installation_report.cpython-312.pyc,,
143
+ pip/_internal/models/__pycache__/link.cpython-312.pyc,,
144
+ pip/_internal/models/__pycache__/scheme.cpython-312.pyc,,
145
+ pip/_internal/models/__pycache__/search_scope.cpython-312.pyc,,
146
+ pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc,,
147
+ pip/_internal/models/__pycache__/target_python.cpython-312.pyc,,
148
+ pip/_internal/models/__pycache__/wheel.cpython-312.pyc,,
149
+ pip/_internal/models/candidate.py,sha256=hEPu8VdGE5qVASv6vLz-R-Rgh5-7LMbai1jgthMCd8M,931
150
+ pip/_internal/models/direct_url.py,sha256=FwouYBKcqckh7B-k2H3HVgRhhFTukFwqiS3kfvtFLSk,6889
151
+ pip/_internal/models/format_control.py,sha256=wtsQqSK9HaUiNxQEuB-C62eVimw6G4_VQFxV9-_KDBE,2486
152
+ pip/_internal/models/index.py,sha256=tYnL8oxGi4aSNWur0mG8DAP7rC6yuha_MwJO8xw0crI,1030
153
+ pip/_internal/models/installation_report.py,sha256=zRVZoaz-2vsrezj_H3hLOhMZCK9c7TbzWgC-jOalD00,2818
154
+ pip/_internal/models/link.py,sha256=XirOAGv1jgMu7vu87kuPbohGj7VHpwVrd2q3KUgVQNg,20777
155
+ pip/_internal/models/scheme.py,sha256=3EFQp_ICu_shH1-TBqhl0QAusKCPDFOlgHFeN4XowWs,738
156
+ pip/_internal/models/search_scope.py,sha256=ASVyyZxiJILw7bTIVVpJx8J293M3Hk5F33ilGn0e80c,4643
157
+ pip/_internal/models/selection_prefs.py,sha256=KZdi66gsR-_RUXUr9uejssk3rmTHrQVJWeNA2sV-VSY,1907
158
+ pip/_internal/models/target_python.py,sha256=34EkorrMuRvRp-bjqHKJ-bOO71m9xdjN2b8WWFEC2HU,4272
159
+ pip/_internal/models/wheel.py,sha256=YqazoIZyma_Q1ejFa1C7NHKQRRWlvWkdK96VRKmDBeI,3600
160
+ pip/_internal/network/__init__.py,sha256=jf6Tt5nV_7zkARBrKojIXItgejvoegVJVKUbhAa5Ioc,50
161
+ pip/_internal/network/__pycache__/__init__.cpython-312.pyc,,
162
+ pip/_internal/network/__pycache__/auth.cpython-312.pyc,,
163
+ pip/_internal/network/__pycache__/cache.cpython-312.pyc,,
164
+ pip/_internal/network/__pycache__/download.cpython-312.pyc,,
165
+ pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc,,
166
+ pip/_internal/network/__pycache__/session.cpython-312.pyc,,
167
+ pip/_internal/network/__pycache__/utils.cpython-312.pyc,,
168
+ pip/_internal/network/__pycache__/xmlrpc.cpython-312.pyc,,
169
+ pip/_internal/network/auth.py,sha256=TC-OcW2KU4W6R1hU4qPgQXvVH54adACpZz6sWq-R9NA,20541
170
+ pip/_internal/network/cache.py,sha256=48A971qCzKNFvkb57uGEk7-0xaqPS0HWj2711QNTxkU,3935
171
+ pip/_internal/network/download.py,sha256=i0Tn55CD5D7XYEFY3TxiYaCf0OaaTQ6SScNgCsSeV14,6086
172
+ pip/_internal/network/lazy_wheel.py,sha256=2PXVduYZPCPZkkQFe1J1GbfHJWeCU--FXonGyIfw9eU,7638
173
+ pip/_internal/network/session.py,sha256=9tqEDD8JiVaFdplOEXJxNo9cjRfBZ6RIa0yQQ_qBNiM,18698
174
+ pip/_internal/network/utils.py,sha256=6A5SrUJEEUHxbGtbscwU2NpCyz-3ztiDlGWHpRRhsJ8,4073
175
+ pip/_internal/network/xmlrpc.py,sha256=sAxzOacJ-N1NXGPvap9jC3zuYWSnnv3GXtgR2-E2APA,1838
176
+ pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
+ pip/_internal/operations/__pycache__/__init__.cpython-312.pyc,,
178
+ pip/_internal/operations/__pycache__/check.cpython-312.pyc,,
179
+ pip/_internal/operations/__pycache__/freeze.cpython-312.pyc,,
180
+ pip/_internal/operations/__pycache__/prepare.cpython-312.pyc,,
181
+ pip/_internal/operations/build/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
182
+ pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc,,
183
+ pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc,,
184
+ pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc,,
185
+ pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc,,
186
+ pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc,,
187
+ pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc,,
188
+ pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc,,
189
+ pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc,,
190
+ pip/_internal/operations/build/build_tracker.py,sha256=z-H5DOknZdBa3dh2Vq6VBMY5qLYIKmlj2p6CGZK5Lc8,4832
191
+ pip/_internal/operations/build/metadata.py,sha256=9S0CUD8U3QqZeXp-Zyt8HxwU90lE4QrnYDgrqZDzBnc,1422
192
+ pip/_internal/operations/build/metadata_editable.py,sha256=VLL7LvntKE8qxdhUdEJhcotFzUsOSI8NNS043xULKew,1474
193
+ pip/_internal/operations/build/metadata_legacy.py,sha256=o-eU21As175hDC7dluM1fJJ_FqokTIShyWpjKaIpHZw,2198
194
+ pip/_internal/operations/build/wheel.py,sha256=sT12FBLAxDC6wyrDorh8kvcZ1jG5qInCRWzzP-UkJiQ,1075
195
+ pip/_internal/operations/build/wheel_editable.py,sha256=yOtoH6zpAkoKYEUtr8FhzrYnkNHQaQBjWQ2HYae1MQg,1417
196
+ pip/_internal/operations/build/wheel_legacy.py,sha256=C9j6rukgQI1n_JeQLoZGuDdfUwzCXShyIdPTp6edbMQ,3064
197
+ pip/_internal/operations/check.py,sha256=fsqA88iGaqftCr2tlP3sSU202CSkoODRtW0O-JU9M4Y,6806
198
+ pip/_internal/operations/freeze.py,sha256=uqoeTAf6HOYVMR2UgAT8N85UZoGEVEoQdan_Ao6SOfk,9816
199
+ pip/_internal/operations/install/__init__.py,sha256=mX7hyD2GNBO2mFGokDQ30r_GXv7Y_PLdtxcUv144e-s,51
200
+ pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc,,
201
+ pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc,,
202
+ pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc,,
203
+ pip/_internal/operations/install/editable_legacy.py,sha256=YeR0KadWXw_ZheC1NtAG1qVIEkOgRGHc23x-YtGW7NU,1282
204
+ pip/_internal/operations/install/wheel.py,sha256=9hGb1c4bRnPIb2FG7CtUSPfPxqprmHQBtwIAlWPNTtE,27311
205
+ pip/_internal/operations/prepare.py,sha256=57Oq87HfunX3Rbqp47FdaJr9cHbAKUm_3gv7WhBAqbE,28128
206
+ pip/_internal/pyproject.py,sha256=4Xszp11xgr126yzG6BbJA0oaQ9WXuhb0jyUb-y_6lPQ,7152
207
+ pip/_internal/req/__init__.py,sha256=TELFgZOof3lhMmaICVWL9U7PlhXo9OufokbMAJ6J2GI,2738
208
+ pip/_internal/req/__pycache__/__init__.cpython-312.pyc,,
209
+ pip/_internal/req/__pycache__/constructors.cpython-312.pyc,,
210
+ pip/_internal/req/__pycache__/req_file.cpython-312.pyc,,
211
+ pip/_internal/req/__pycache__/req_install.cpython-312.pyc,,
212
+ pip/_internal/req/__pycache__/req_set.cpython-312.pyc,,
213
+ pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc,,
214
+ pip/_internal/req/constructors.py,sha256=8hlY56imEthLORRwmloyKz3YOyXymIaKsNB6P9ewvNI,19018
215
+ pip/_internal/req/req_file.py,sha256=M8ttOZL-PwAj7scPElhW3ZD2hiD9mm_6FJAGIbwAzEI,17790
216
+ pip/_internal/req/req_install.py,sha256=wtOPxkyRSM8comTks8oL1Gp2oyGqbH7JwIDRci2QiPk,35460
217
+ pip/_internal/req/req_set.py,sha256=iMYDUToSgkxFyrP_OrTtPSgw4dwjRyGRDpGooTqeA4Y,4704
218
+ pip/_internal/req/req_uninstall.py,sha256=nmvTQaRCC0iu-5Tw0djlXJhSj6WmqHRvT3qkkEdC35E,24551
219
+ pip/_internal/resolution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
220
+ pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc,,
221
+ pip/_internal/resolution/__pycache__/base.cpython-312.pyc,,
222
+ pip/_internal/resolution/base.py,sha256=qlmh325SBVfvG6Me9gc5Nsh5sdwHBwzHBq6aEXtKsLA,583
223
+ pip/_internal/resolution/legacy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
224
+ pip/_internal/resolution/legacy/__pycache__/__init__.cpython-312.pyc,,
225
+ pip/_internal/resolution/legacy/__pycache__/resolver.cpython-312.pyc,,
226
+ pip/_internal/resolution/legacy/resolver.py,sha256=Xk24jQ62GvLr4Mc7IjN_qiO88qp0BImzVmPIFz9QLOE,24025
227
+ pip/_internal/resolution/resolvelib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
228
+ pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc,,
229
+ pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc,,
230
+ pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc,,
231
+ pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc,,
232
+ pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc,,
233
+ pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc,,
234
+ pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc,,
235
+ pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc,,
236
+ pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc,,
237
+ pip/_internal/resolution/resolvelib/base.py,sha256=jg5COmHLhmBIKOR-4spdJD3jyULYa1BdsqiBu2YJnJ4,5173
238
+ pip/_internal/resolution/resolvelib/candidates.py,sha256=19Ki91Po-MSxBknGIfOGkaWkFdOznN0W_nKv7jL28L0,21052
239
+ pip/_internal/resolution/resolvelib/factory.py,sha256=vqqk-hjchdhShwWVdeW2_A-5ZblLhE_nC_v3Mhz4Svc,32292
240
+ pip/_internal/resolution/resolvelib/found_candidates.py,sha256=hvL3Hoa9VaYo-qEOZkBi2Iqw251UDxPz-uMHVaWmLpE,5705
241
+ pip/_internal/resolution/resolvelib/provider.py,sha256=4t23ivjruqM6hKBX1KpGiTt-M4HGhRcZnGLV0c01K7U,9824
242
+ pip/_internal/resolution/resolvelib/reporter.py,sha256=YFm9hQvz4DFCbjZeFTQ56hTz3Ac-mDBnHkeNRVvMHLY,3100
243
+ pip/_internal/resolution/resolvelib/requirements.py,sha256=-kJONP0WjDfdTvBAs2vUXPgAnOyNIBEAXY4b72ogtPE,5696
244
+ pip/_internal/resolution/resolvelib/resolver.py,sha256=nLJOsVMEVi2gQUVJoUFKMZAeu2f7GRMjGMvNSWyz0Bc,12592
245
+ pip/_internal/self_outdated_check.py,sha256=saxQLB8UzIFtMScquytG10TOTsYVFJQ_mkW1NY-46wE,8378
246
+ pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
247
+ pip/_internal/utils/__pycache__/__init__.cpython-312.pyc,,
248
+ pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc,,
249
+ pip/_internal/utils/__pycache__/_log.cpython-312.pyc,,
250
+ pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc,,
251
+ pip/_internal/utils/__pycache__/compat.cpython-312.pyc,,
252
+ pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc,,
253
+ pip/_internal/utils/__pycache__/datetime.cpython-312.pyc,,
254
+ pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc,,
255
+ pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc,,
256
+ pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc,,
257
+ pip/_internal/utils/__pycache__/encoding.cpython-312.pyc,,
258
+ pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc,,
259
+ pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc,,
260
+ pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc,,
261
+ pip/_internal/utils/__pycache__/glibc.cpython-312.pyc,,
262
+ pip/_internal/utils/__pycache__/hashes.cpython-312.pyc,,
263
+ pip/_internal/utils/__pycache__/logging.cpython-312.pyc,,
264
+ pip/_internal/utils/__pycache__/misc.cpython-312.pyc,,
265
+ pip/_internal/utils/__pycache__/models.cpython-312.pyc,,
266
+ pip/_internal/utils/__pycache__/packaging.cpython-312.pyc,,
267
+ pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc,,
268
+ pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc,,
269
+ pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc,,
270
+ pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc,,
271
+ pip/_internal/utils/__pycache__/urls.cpython-312.pyc,,
272
+ pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc,,
273
+ pip/_internal/utils/__pycache__/wheel.cpython-312.pyc,,
274
+ pip/_internal/utils/_jaraco_text.py,sha256=yvDGelTVugRayPaOF2k4ab0Ky4d3uOkAfuOQjASjImY,3351
275
+ pip/_internal/utils/_log.py,sha256=-jHLOE_THaZz5BFcCnoSL9EYAtJ0nXem49s9of4jvKw,1015
276
+ pip/_internal/utils/appdirs.py,sha256=swgcTKOm3daLeXTW6v5BUS2Ti2RvEnGRQYH_yDXklAo,1665
277
+ pip/_internal/utils/compat.py,sha256=ACyBfLgj3_XG-iA5omEDrXqDM0cQKzi8h8HRBInzG6Q,1884
278
+ pip/_internal/utils/compatibility_tags.py,sha256=ydin8QG8BHqYRsPY4OL6cmb44CbqXl1T0xxS97VhHkk,5377
279
+ pip/_internal/utils/datetime.py,sha256=m21Y3wAtQc-ji6Veb6k_M5g6A0ZyFI4egchTdnwh-pQ,242
280
+ pip/_internal/utils/deprecation.py,sha256=NKo8VqLioJ4nnXXGmW4KdasxF90EFHkZaHeX1fT08C8,3627
281
+ pip/_internal/utils/direct_url_helpers.py,sha256=6F1tc2rcKaCZmgfVwsE6ObIe_Pux23mUVYA-2D9wCFc,3206
282
+ pip/_internal/utils/egg_link.py,sha256=0FePZoUYKv4RGQ2t6x7w5Z427wbA_Uo3WZnAkrgsuqo,2463
283
+ pip/_internal/utils/encoding.py,sha256=qqsXDtiwMIjXMEiIVSaOjwH5YmirCaK-dIzb6-XJsL0,1169
284
+ pip/_internal/utils/entrypoints.py,sha256=YlhLTRl2oHBAuqhc-zmL7USS67TPWVHImjeAQHreZTQ,3064
285
+ pip/_internal/utils/filesystem.py,sha256=RhMIXUaNVMGjc3rhsDahWQ4MavvEQDdqXqgq-F6fpw8,5122
286
+ pip/_internal/utils/filetypes.py,sha256=i8XAQ0eFCog26Fw9yV0Yb1ygAqKYB1w9Cz9n0fj8gZU,716
287
+ pip/_internal/utils/glibc.py,sha256=Mesxxgg3BLxheLZx-dSf30b6gKpOgdVXw6W--uHSszQ,3113
288
+ pip/_internal/utils/hashes.py,sha256=MjOigC75z6qoRMkgHiHqot7eqxfwDZSrEflJMPm-bHE,5118
289
+ pip/_internal/utils/logging.py,sha256=fdtuZJ-AKkqwDTANDvGcBEpssL8el7T1jnwk1CnZl3Y,11603
290
+ pip/_internal/utils/misc.py,sha256=fNXwaeeikvnUt4CPMFIL4-IQbZDxxjj4jDpzCi4ZsOw,23623
291
+ pip/_internal/utils/models.py,sha256=5GoYU586SrxURMvDn_jBMJInitviJg4O5-iOU-6I0WY,1193
292
+ pip/_internal/utils/packaging.py,sha256=5Wm6_x7lKrlqVjPI5MBN_RurcRHwVYoQ7Ksrs84de7s,2108
293
+ pip/_internal/utils/setuptools_build.py,sha256=ouXpud-jeS8xPyTPsXJ-m34NPvK5os45otAzdSV_IJE,4435
294
+ pip/_internal/utils/subprocess.py,sha256=zzdimb75jVLE1GU4WlTZ055gczhD7n1y1xTcNc7vNZQ,9207
295
+ pip/_internal/utils/temp_dir.py,sha256=DUAw22uFruQdK43i2L2K53C-CDjRCPeAsBKJpu-rHQ4,9312
296
+ pip/_internal/utils/unpacking.py,sha256=SBb2iV1crb89MDRTEKY86R4A_UOWApTQn9VQVcMDOlE,8821
297
+ pip/_internal/utils/urls.py,sha256=AhaesUGl-9it6uvG6fsFPOr9ynFpGaTMk4t5XTX7Z_Q,1759
298
+ pip/_internal/utils/virtualenv.py,sha256=S6f7csYorRpiD6cvn3jISZYc3I8PJC43H5iMFpRAEDU,3456
299
+ pip/_internal/utils/wheel.py,sha256=i4BwUNHattzN0ixy3HBAF04tZPRh2CcxaT6t86viwkE,4499
300
+ pip/_internal/vcs/__init__.py,sha256=UAqvzpbi0VbZo3Ub6skEeZAw-ooIZR-zX_WpCbxyCoU,596
301
+ pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc,,
302
+ pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc,,
303
+ pip/_internal/vcs/__pycache__/git.cpython-312.pyc,,
304
+ pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc,,
305
+ pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc,,
306
+ pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc,,
307
+ pip/_internal/vcs/bazaar.py,sha256=j0oin0fpGRHcCFCxEcpPCQoFEvA-DMLULKdGP8Nv76o,3519
308
+ pip/_internal/vcs/git.py,sha256=CeKBGJnl6uskvvjkAUXrJVxbHJrpS_B_pyfFdjL3CRc,18121
309
+ pip/_internal/vcs/mercurial.py,sha256=oULOhzJ2Uie-06d1omkL-_Gc6meGaUkyogvqG9ZCyPs,5249
310
+ pip/_internal/vcs/subversion.py,sha256=vhZs8L-TNggXqM1bbhl-FpbxE3TrIB6Tgnx8fh3S2HE,11729
311
+ pip/_internal/vcs/versioncontrol.py,sha256=3eIjtOMYvOY5qP6BMYIYDZ375CSuec6kSEB0bOo1cSs,22787
312
+ pip/_internal/wheel_builder.py,sha256=qTTzQV8F6b1jNsFCda1TRQC8J7gK-m7iuRNgKo7Dj68,11801
313
+ pip/_vendor/__init__.py,sha256=U51NPwXdA-wXOiANIQncYjcMp6txgeOL5nHxksJeyas,4993
314
+ pip/_vendor/__pycache__/__init__.cpython-312.pyc,,
315
+ pip/_vendor/__pycache__/six.cpython-312.pyc,,
316
+ pip/_vendor/__pycache__/typing_extensions.cpython-312.pyc,,
317
+ pip/_vendor/cachecontrol/__init__.py,sha256=ctHagMhQXuvQDdm4TirZrwDOT5H8oBNAJqzdKI6sovk,676
318
+ pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc,,
319
+ pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-312.pyc,,
320
+ pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc,,
321
+ pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc,,
322
+ pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc,,
323
+ pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc,,
324
+ pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-312.pyc,,
325
+ pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc,,
326
+ pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc,,
327
+ pip/_vendor/cachecontrol/_cmd.py,sha256=iist2EpzJvDVIhMAxXq8iFnTBsiZAd6iplxfmNboNyk,1737
328
+ pip/_vendor/cachecontrol/adapter.py,sha256=_CcWvUP9048qAZjsNqViaHbdcLs9mmFNixVfpO7oebE,6392
329
+ pip/_vendor/cachecontrol/cache.py,sha256=OTQj72tUf8C1uEgczdl3Gc8vkldSzsTITKtDGKMx4z8,1952
330
+ pip/_vendor/cachecontrol/caches/__init__.py,sha256=dtrrroK5BnADR1GWjCZ19aZ0tFsMfvFBtLQQU1sp_ag,303
331
+ pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc,,
332
+ pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc,,
333
+ pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc,,
334
+ pip/_vendor/cachecontrol/caches/file_cache.py,sha256=3z8AWKD-vfKeiJqIzLmJyIYtR2yd6Tsh3u1TyLRQoIQ,5352
335
+ pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=9rmqwtYu_ljVkW6_oLqbC7EaX_a8YT_yLuna-eS0dgo,1386
336
+ pip/_vendor/cachecontrol/controller.py,sha256=keCFA3ZaNVaWTwHd6F1zqWhb4vyvNx_UvZuo5iIYMfo,18384
337
+ pip/_vendor/cachecontrol/filewrapper.py,sha256=STttGmIPBvZzt2b51dUOwoWX5crcMCpKZOisM3f5BNc,4292
338
+ pip/_vendor/cachecontrol/heuristics.py,sha256=fdFbk9W8IeLrjteIz_fK4mj2HD_Y7COXF2Uc8TgjT1c,4828
339
+ pip/_vendor/cachecontrol/serialize.py,sha256=0dHeMaDwysVAAnGVlhMOP4tDliohgNK0Jxk_zsOiWxw,7173
340
+ pip/_vendor/cachecontrol/wrapper.py,sha256=hsGc7g8QGQTT-4f8tgz3AM5qwScg6FO0BSdLSRdEvpU,1417
341
+ pip/_vendor/certifi/__init__.py,sha256=L_j-d0kYuA_MzA2_2hraF1ovf6KT6DTquRdV3paQwOk,94
342
+ pip/_vendor/certifi/__main__.py,sha256=1k3Cr95vCxxGRGDljrW3wMdpZdL3Nhf0u1n-k2qdsCY,255
343
+ pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc,,
344
+ pip/_vendor/certifi/__pycache__/__main__.cpython-312.pyc,,
345
+ pip/_vendor/certifi/__pycache__/core.cpython-312.pyc,,
346
+ pip/_vendor/certifi/cacert.pem,sha256=eU0Dn_3yd8BH4m8sfVj4Glhl2KDrcCSg-sEWT-pNJ88,281617
347
+ pip/_vendor/certifi/core.py,sha256=DNTl8b_B6C4vO3Vc9_q2uvwHpNnBQoy5onDC4McImxc,4531
348
+ pip/_vendor/chardet/__init__.py,sha256=57R-HSxj0PWmILMN0GFmUNqEMfrEVSamXyjD-W6_fbs,4797
349
+ pip/_vendor/chardet/__pycache__/__init__.cpython-312.pyc,,
350
+ pip/_vendor/chardet/__pycache__/big5freq.cpython-312.pyc,,
351
+ pip/_vendor/chardet/__pycache__/big5prober.cpython-312.pyc,,
352
+ pip/_vendor/chardet/__pycache__/chardistribution.cpython-312.pyc,,
353
+ pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-312.pyc,,
354
+ pip/_vendor/chardet/__pycache__/charsetprober.cpython-312.pyc,,
355
+ pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-312.pyc,,
356
+ pip/_vendor/chardet/__pycache__/codingstatemachinedict.cpython-312.pyc,,
357
+ pip/_vendor/chardet/__pycache__/cp949prober.cpython-312.pyc,,
358
+ pip/_vendor/chardet/__pycache__/enums.cpython-312.pyc,,
359
+ pip/_vendor/chardet/__pycache__/escprober.cpython-312.pyc,,
360
+ pip/_vendor/chardet/__pycache__/escsm.cpython-312.pyc,,
361
+ pip/_vendor/chardet/__pycache__/eucjpprober.cpython-312.pyc,,
362
+ pip/_vendor/chardet/__pycache__/euckrfreq.cpython-312.pyc,,
363
+ pip/_vendor/chardet/__pycache__/euckrprober.cpython-312.pyc,,
364
+ pip/_vendor/chardet/__pycache__/euctwfreq.cpython-312.pyc,,
365
+ pip/_vendor/chardet/__pycache__/euctwprober.cpython-312.pyc,,
366
+ pip/_vendor/chardet/__pycache__/gb2312freq.cpython-312.pyc,,
367
+ pip/_vendor/chardet/__pycache__/gb2312prober.cpython-312.pyc,,
368
+ pip/_vendor/chardet/__pycache__/hebrewprober.cpython-312.pyc,,
369
+ pip/_vendor/chardet/__pycache__/jisfreq.cpython-312.pyc,,
370
+ pip/_vendor/chardet/__pycache__/johabfreq.cpython-312.pyc,,
371
+ pip/_vendor/chardet/__pycache__/johabprober.cpython-312.pyc,,
372
+ pip/_vendor/chardet/__pycache__/jpcntx.cpython-312.pyc,,
373
+ pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-312.pyc,,
374
+ pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-312.pyc,,
375
+ pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-312.pyc,,
376
+ pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-312.pyc,,
377
+ pip/_vendor/chardet/__pycache__/langrussianmodel.cpython-312.pyc,,
378
+ pip/_vendor/chardet/__pycache__/langthaimodel.cpython-312.pyc,,
379
+ pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-312.pyc,,
380
+ pip/_vendor/chardet/__pycache__/latin1prober.cpython-312.pyc,,
381
+ pip/_vendor/chardet/__pycache__/macromanprober.cpython-312.pyc,,
382
+ pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-312.pyc,,
383
+ pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-312.pyc,,
384
+ pip/_vendor/chardet/__pycache__/mbcssm.cpython-312.pyc,,
385
+ pip/_vendor/chardet/__pycache__/resultdict.cpython-312.pyc,,
386
+ pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-312.pyc,,
387
+ pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-312.pyc,,
388
+ pip/_vendor/chardet/__pycache__/sjisprober.cpython-312.pyc,,
389
+ pip/_vendor/chardet/__pycache__/universaldetector.cpython-312.pyc,,
390
+ pip/_vendor/chardet/__pycache__/utf1632prober.cpython-312.pyc,,
391
+ pip/_vendor/chardet/__pycache__/utf8prober.cpython-312.pyc,,
392
+ pip/_vendor/chardet/__pycache__/version.cpython-312.pyc,,
393
+ pip/_vendor/chardet/big5freq.py,sha256=ltcfP-3PjlNHCoo5e4a7C4z-2DhBTXRfY6jbMbB7P30,31274
394
+ pip/_vendor/chardet/big5prober.py,sha256=lPMfwCX6v2AaPgvFh_cSWZcgLDbWiFCHLZ_p9RQ9uxE,1763
395
+ pip/_vendor/chardet/chardistribution.py,sha256=13B8XUG4oXDuLdXvfbIWwLFeR-ZU21AqTS1zcdON8bU,10032
396
+ pip/_vendor/chardet/charsetgroupprober.py,sha256=UKK3SaIZB2PCdKSIS0gnvMtLR9JJX62M-fZJu3OlWyg,3915
397
+ pip/_vendor/chardet/charsetprober.py,sha256=L3t8_wIOov8em-vZWOcbkdsrwe43N6_gqNh5pH7WPd4,5420
398
+ pip/_vendor/chardet/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
399
+ pip/_vendor/chardet/cli/__pycache__/__init__.cpython-312.pyc,,
400
+ pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-312.pyc,,
401
+ pip/_vendor/chardet/cli/chardetect.py,sha256=zibMVg5RpKb-ME9_7EYG4ZM2Sf07NHcQzZ12U-rYJho,3242
402
+ pip/_vendor/chardet/codingstatemachine.py,sha256=K7k69sw3jY5DmTXoSJQVsUtFIQKYPQVOSJJhBuGv_yE,3732
403
+ pip/_vendor/chardet/codingstatemachinedict.py,sha256=0GY3Hi2qIZvDrOOJ3AtqppM1RsYxr_66ER4EHjuMiMc,542
404
+ pip/_vendor/chardet/cp949prober.py,sha256=0jKRV7fECuWI16rNnks0ZECKA1iZYCIEaP8A1ZvjUSI,1860
405
+ pip/_vendor/chardet/enums.py,sha256=TzECiZoCKNMqgwU76cPCeKWFBqaWvAdLMev5_bCkhY8,1683
406
+ pip/_vendor/chardet/escprober.py,sha256=Kho48X65xE0scFylIdeJjM2bcbvRvv0h0WUbMWrJD3A,4006
407
+ pip/_vendor/chardet/escsm.py,sha256=AqyXpA2FQFD7k-buBty_7itGEYkhmVa8X09NLRul3QM,12176
408
+ pip/_vendor/chardet/eucjpprober.py,sha256=5KYaM9fsxkRYzw1b5k0fL-j_-ezIw-ij9r97a9MHxLY,3934
409
+ pip/_vendor/chardet/euckrfreq.py,sha256=3mHuRvXfsq_QcQysDQFb8qSudvTiol71C6Ic2w57tKM,13566
410
+ pip/_vendor/chardet/euckrprober.py,sha256=hiFT6wM174GIwRvqDsIcuOc-dDsq2uPKMKbyV8-1Xnc,1753
411
+ pip/_vendor/chardet/euctwfreq.py,sha256=2alILE1Lh5eqiFJZjzRkMQXolNJRHY5oBQd-vmZYFFM,36913
412
+ pip/_vendor/chardet/euctwprober.py,sha256=NxbpNdBtU0VFI0bKfGfDkpP7S2_8_6FlO87dVH0ogws,1753
413
+ pip/_vendor/chardet/gb2312freq.py,sha256=49OrdXzD-HXqwavkqjo8Z7gvs58hONNzDhAyMENNkvY,20735
414
+ pip/_vendor/chardet/gb2312prober.py,sha256=KPEBueaSLSvBpFeINMu0D6TgHcR90e5PaQawifzF4o0,1759
415
+ pip/_vendor/chardet/hebrewprober.py,sha256=96T_Lj_OmW-fK7JrSHojYjyG3fsGgbzkoTNleZ3kfYE,14537
416
+ pip/_vendor/chardet/jisfreq.py,sha256=mm8tfrwqhpOd3wzZKS4NJqkYBQVcDfTM2JiQ5aW932E,25796
417
+ pip/_vendor/chardet/johabfreq.py,sha256=dBpOYG34GRX6SL8k_LbS9rxZPMjLjoMlgZ03Pz5Hmqc,42498
418
+ pip/_vendor/chardet/johabprober.py,sha256=O1Qw9nVzRnun7vZp4UZM7wvJSv9W941mEU9uDMnY3DU,1752
419
+ pip/_vendor/chardet/jpcntx.py,sha256=uhHrYWkLxE_rF5OkHKInm0HUsrjgKHHVQvtt3UcvotA,27055
420
+ pip/_vendor/chardet/langbulgarianmodel.py,sha256=vmbvYFP8SZkSxoBvLkFqKiH1sjma5ihk3PTpdy71Rr4,104562
421
+ pip/_vendor/chardet/langgreekmodel.py,sha256=JfB7bupjjJH2w3X_mYnQr9cJA_7EuITC2cRW13fUjeI,98484
422
+ pip/_vendor/chardet/langhebrewmodel.py,sha256=3HXHaLQPNAGcXnJjkIJfozNZLTvTJmf4W5Awi6zRRKc,98196
423
+ pip/_vendor/chardet/langhungarianmodel.py,sha256=WxbeQIxkv8YtApiNqxQcvj-tMycsoI4Xy-fwkDHpP_Y,101363
424
+ pip/_vendor/chardet/langrussianmodel.py,sha256=s395bTZ87ESTrZCOdgXbEjZ9P1iGPwCl_8xSsac_DLY,128035
425
+ pip/_vendor/chardet/langthaimodel.py,sha256=7bJlQitRpTnVGABmbSznHnJwOHDy3InkTvtFUx13WQI,102774
426
+ pip/_vendor/chardet/langturkishmodel.py,sha256=XY0eGdTIy4eQ9Xg1LVPZacb-UBhHBR-cq0IpPVHowKc,95372
427
+ pip/_vendor/chardet/latin1prober.py,sha256=p15EEmFbmQUwbKLC7lOJVGHEZwcG45ubEZYTGu01J5g,5380
428
+ pip/_vendor/chardet/macromanprober.py,sha256=9anfzmY6TBfUPDyBDOdY07kqmTHpZ1tK0jL-p1JWcOY,6077
429
+ pip/_vendor/chardet/mbcharsetprober.py,sha256=Wr04WNI4F3X_VxEverNG-H25g7u-MDDKlNt-JGj-_uU,3715
430
+ pip/_vendor/chardet/mbcsgroupprober.py,sha256=iRpaNBjV0DNwYPu_z6TiHgRpwYahiM7ztI_4kZ4Uz9A,2131
431
+ pip/_vendor/chardet/mbcssm.py,sha256=hUtPvDYgWDaA2dWdgLsshbwRfm3Q5YRlRogdmeRUNQw,30391
432
+ pip/_vendor/chardet/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
433
+ pip/_vendor/chardet/metadata/__pycache__/__init__.cpython-312.pyc,,
434
+ pip/_vendor/chardet/metadata/__pycache__/languages.cpython-312.pyc,,
435
+ pip/_vendor/chardet/metadata/languages.py,sha256=FhvBIdZFxRQ-dTwkb_0madRKgVBCaUMQz9I5xqjE5iQ,13560
436
+ pip/_vendor/chardet/resultdict.py,sha256=ez4FRvN5KaSosJeJ2WzUyKdDdg35HDy_SSLPXKCdt5M,402
437
+ pip/_vendor/chardet/sbcharsetprober.py,sha256=-nd3F90i7GpXLjehLVHqVBE0KlWzGvQUPETLBNn4o6U,6400
438
+ pip/_vendor/chardet/sbcsgroupprober.py,sha256=gcgI0fOfgw_3YTClpbra_MNxwyEyJ3eUXraoLHYb59E,4137
439
+ pip/_vendor/chardet/sjisprober.py,sha256=aqQufMzRw46ZpFlzmYaYeT2-nzmKb-hmcrApppJ862k,4007
440
+ pip/_vendor/chardet/universaldetector.py,sha256=xYBrg4x0dd9WnT8qclfADVD9ondrUNkqPmvte1pa520,14848
441
+ pip/_vendor/chardet/utf1632prober.py,sha256=pw1epGdMj1hDGiCu1AHqqzOEfjX8MVdiW7O1BlT8-eQ,8505
442
+ pip/_vendor/chardet/utf8prober.py,sha256=8m08Ub5490H4jQ6LYXvFysGtgKoKsHUd2zH_i8_TnVw,2812
443
+ pip/_vendor/chardet/version.py,sha256=lGtJcxGM44Qz4Cbk4rbbmrKxnNr1-97U25TameLehZw,244
444
+ pip/_vendor/colorama/__init__.py,sha256=wePQA4U20tKgYARySLEC047ucNX-g8pRLpYBuiHlLb8,266
445
+ pip/_vendor/colorama/__pycache__/__init__.cpython-312.pyc,,
446
+ pip/_vendor/colorama/__pycache__/ansi.cpython-312.pyc,,
447
+ pip/_vendor/colorama/__pycache__/ansitowin32.cpython-312.pyc,,
448
+ pip/_vendor/colorama/__pycache__/initialise.cpython-312.pyc,,
449
+ pip/_vendor/colorama/__pycache__/win32.cpython-312.pyc,,
450
+ pip/_vendor/colorama/__pycache__/winterm.cpython-312.pyc,,
451
+ pip/_vendor/colorama/ansi.py,sha256=Top4EeEuaQdBWdteKMEcGOTeKeF19Q-Wo_6_Cj5kOzQ,2522
452
+ pip/_vendor/colorama/ansitowin32.py,sha256=vPNYa3OZbxjbuFyaVo0Tmhmy1FZ1lKMWCnT7odXpItk,11128
453
+ pip/_vendor/colorama/initialise.py,sha256=-hIny86ClXo39ixh5iSCfUIa2f_h_bgKRDW7gqs-KLU,3325
454
+ pip/_vendor/colorama/tests/__init__.py,sha256=MkgPAEzGQd-Rq0w0PZXSX2LadRWhUECcisJY8lSrm4Q,75
455
+ pip/_vendor/colorama/tests/__pycache__/__init__.cpython-312.pyc,,
456
+ pip/_vendor/colorama/tests/__pycache__/ansi_test.cpython-312.pyc,,
457
+ pip/_vendor/colorama/tests/__pycache__/ansitowin32_test.cpython-312.pyc,,
458
+ pip/_vendor/colorama/tests/__pycache__/initialise_test.cpython-312.pyc,,
459
+ pip/_vendor/colorama/tests/__pycache__/isatty_test.cpython-312.pyc,,
460
+ pip/_vendor/colorama/tests/__pycache__/utils.cpython-312.pyc,,
461
+ pip/_vendor/colorama/tests/__pycache__/winterm_test.cpython-312.pyc,,
462
+ pip/_vendor/colorama/tests/ansi_test.py,sha256=FeViDrUINIZcr505PAxvU4AjXz1asEiALs9GXMhwRaE,2839
463
+ pip/_vendor/colorama/tests/ansitowin32_test.py,sha256=RN7AIhMJ5EqDsYaCjVo-o4u8JzDD4ukJbmevWKS70rY,10678
464
+ pip/_vendor/colorama/tests/initialise_test.py,sha256=BbPy-XfyHwJ6zKozuQOvNvQZzsx9vdb_0bYXn7hsBTc,6741
465
+ pip/_vendor/colorama/tests/isatty_test.py,sha256=Pg26LRpv0yQDB5Ac-sxgVXG7hsA1NYvapFgApZfYzZg,1866
466
+ pip/_vendor/colorama/tests/utils.py,sha256=1IIRylG39z5-dzq09R_ngufxyPZxgldNbrxKxUGwGKE,1079
467
+ pip/_vendor/colorama/tests/winterm_test.py,sha256=qoWFPEjym5gm2RuMwpf3pOis3a5r_PJZFCzK254JL8A,3709
468
+ pip/_vendor/colorama/win32.py,sha256=YQOKwMTwtGBbsY4dL5HYTvwTeP9wIQra5MvPNddpxZs,6181
469
+ pip/_vendor/colorama/winterm.py,sha256=XCQFDHjPi6AHYNdZwy0tA02H-Jh48Jp-HvCjeLeLp3U,7134
470
+ pip/_vendor/distlib/__init__.py,sha256=hJKF7FHoqbmGckncDuEINWo_OYkDNiHODtYXSMcvjcc,625
471
+ pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc,,
472
+ pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc,,
473
+ pip/_vendor/distlib/__pycache__/database.cpython-312.pyc,,
474
+ pip/_vendor/distlib/__pycache__/index.cpython-312.pyc,,
475
+ pip/_vendor/distlib/__pycache__/locators.cpython-312.pyc,,
476
+ pip/_vendor/distlib/__pycache__/manifest.cpython-312.pyc,,
477
+ pip/_vendor/distlib/__pycache__/markers.cpython-312.pyc,,
478
+ pip/_vendor/distlib/__pycache__/metadata.cpython-312.pyc,,
479
+ pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc,,
480
+ pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc,,
481
+ pip/_vendor/distlib/__pycache__/util.cpython-312.pyc,,
482
+ pip/_vendor/distlib/__pycache__/version.cpython-312.pyc,,
483
+ pip/_vendor/distlib/__pycache__/wheel.cpython-312.pyc,,
484
+ pip/_vendor/distlib/compat.py,sha256=Un-uIBvy02w-D267OG4VEhuddqWgKj9nNkxVltAb75w,41487
485
+ pip/_vendor/distlib/database.py,sha256=0V9Qvs0Vrxa2F_-hLWitIyVyRifJ0pCxyOI-kEOBwsA,51965
486
+ pip/_vendor/distlib/index.py,sha256=lTbw268rRhj8dw1sib3VZ_0EhSGgoJO3FKJzSFMOaeA,20797
487
+ pip/_vendor/distlib/locators.py,sha256=o1r_M86_bRLafSpetmyfX8KRtFu-_Q58abvQrnOSnbA,51767
488
+ pip/_vendor/distlib/manifest.py,sha256=3qfmAmVwxRqU1o23AlfXrQGZzh6g_GGzTAP_Hb9C5zQ,14168
489
+ pip/_vendor/distlib/markers.py,sha256=n3DfOh1yvZ_8EW7atMyoYeZFXjYla0Nz0itQlojCd0A,5268
490
+ pip/_vendor/distlib/metadata.py,sha256=pB9WZ9mBfmQxc9OVIldLS5CjOoQRvKAvUwwQyKwKQtQ,39693
491
+ pip/_vendor/distlib/resources.py,sha256=LwbPksc0A1JMbi6XnuPdMBUn83X7BPuFNWqPGEKI698,10820
492
+ pip/_vendor/distlib/scripts.py,sha256=nQFXN6G7nOWNDUyxirUep-3WOlJhB7McvCs9zOnkGTI,18315
493
+ pip/_vendor/distlib/util.py,sha256=XSznxEi_i3T20UJuaVc0qXHz5ksGUCW1khYlBprN_QE,67530
494
+ pip/_vendor/distlib/version.py,sha256=9pXkduchve_aN7JG6iL9VTYV_kqNSGoc2Dwl8JuySnQ,23747
495
+ pip/_vendor/distlib/wheel.py,sha256=FVQCve8u-L0QYk5-YTZc7s4WmNQdvjRWTK08KXzZVX4,43958
496
+ pip/_vendor/distro/__init__.py,sha256=2fHjF-SfgPvjyNZ1iHh_wjqWdR_Yo5ODHwZC0jLBPhc,981
497
+ pip/_vendor/distro/__main__.py,sha256=bu9d3TifoKciZFcqRBuygV3GSuThnVD_m2IK4cz96Vs,64
498
+ pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc,,
499
+ pip/_vendor/distro/__pycache__/__main__.cpython-312.pyc,,
500
+ pip/_vendor/distro/__pycache__/distro.cpython-312.pyc,,
501
+ pip/_vendor/distro/distro.py,sha256=UZO1LjIhtFCMdlbiz39gj3raV-Amf3SBwzGzfApiMHw,49330
502
+ pip/_vendor/idna/__init__.py,sha256=KJQN1eQBr8iIK5SKrJ47lXvxG0BJ7Lm38W4zT0v_8lk,849
503
+ pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc,,
504
+ pip/_vendor/idna/__pycache__/codec.cpython-312.pyc,,
505
+ pip/_vendor/idna/__pycache__/compat.cpython-312.pyc,,
506
+ pip/_vendor/idna/__pycache__/core.cpython-312.pyc,,
507
+ pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc,,
508
+ pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc,,
509
+ pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc,,
510
+ pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc,,
511
+ pip/_vendor/idna/codec.py,sha256=6ly5odKfqrytKT9_7UrlGklHnf1DSK2r9C6cSM4sa28,3374
512
+ pip/_vendor/idna/compat.py,sha256=0_sOEUMT4CVw9doD3vyRhX80X19PwqFoUBs7gWsFME4,321
513
+ pip/_vendor/idna/core.py,sha256=kkCFNJOrE6I3WwBTXcGNuc24V_QZQ8AULE6EYe1iHlU,12813
514
+ pip/_vendor/idna/idnadata.py,sha256=9NIhTqC2piUpeIMOGZ9Bu_7eAFQ-Ic8TkP_hOzUpnDc,78344
515
+ pip/_vendor/idna/intranges.py,sha256=YBr4fRYuWH7kTKS2tXlFjM24ZF1Pdvcir-aywniInqg,1881
516
+ pip/_vendor/idna/package_data.py,sha256=C_jHJzmX8PI4xq0jpzmcTMxpb5lDsq4o5VyxQzlVrZE,21
517
+ pip/_vendor/idna/uts46data.py,sha256=zvjZU24s58_uAS850Mcd0NnD0X7_gCMAMjzWNIeUJdc,206539
518
+ pip/_vendor/msgpack/__init__.py,sha256=hyGhlnmcJkxryJBKC3X5FnEph375kQoL_mG8LZUuXgY,1132
519
+ pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc,,
520
+ pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc,,
521
+ pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc,,
522
+ pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc,,
523
+ pip/_vendor/msgpack/exceptions.py,sha256=dCTWei8dpkrMsQDcjQk74ATl9HsIBH0ybt8zOPNqMYc,1081
524
+ pip/_vendor/msgpack/ext.py,sha256=C5MK8JhVYGYFWPvxsORsqZAnvOXefYQ57m1Ym0luW5M,6079
525
+ pip/_vendor/msgpack/fallback.py,sha256=tvNBHyxxFbuVlC8GZShETClJxjLiDMOja4XwwyvNm2g,34544
526
+ pip/_vendor/packaging/__about__.py,sha256=ugASIO2w1oUyH8_COqQ2X_s0rDhjbhQC3yJocD03h2c,661
527
+ pip/_vendor/packaging/__init__.py,sha256=b9Kk5MF7KxhhLgcDmiUWukN-LatWFxPdNug0joPhHSk,497
528
+ pip/_vendor/packaging/__pycache__/__about__.cpython-312.pyc,,
529
+ pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc,,
530
+ pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc,,
531
+ pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc,,
532
+ pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc,,
533
+ pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc,,
534
+ pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc,,
535
+ pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc,,
536
+ pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc,,
537
+ pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc,,
538
+ pip/_vendor/packaging/__pycache__/version.cpython-312.pyc,,
539
+ pip/_vendor/packaging/_manylinux.py,sha256=XcbiXB-qcjv3bcohp6N98TMpOP4_j3m-iOA8ptK2GWY,11488
540
+ pip/_vendor/packaging/_musllinux.py,sha256=_KGgY_qc7vhMGpoqss25n2hiLCNKRtvz9mCrS7gkqyc,4378
541
+ pip/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
542
+ pip/_vendor/packaging/markers.py,sha256=AJBOcY8Oq0kYc570KuuPTkvuqjAlhufaE2c9sCUbm64,8487
543
+ pip/_vendor/packaging/requirements.py,sha256=NtDlPBtojpn1IUC85iMjPNsUmufjpSlwnNA-Xb4m5NA,4676
544
+ pip/_vendor/packaging/specifiers.py,sha256=LRQ0kFsHrl5qfcFNEEJrIFYsnIHQUJXY9fIsakTrrqE,30110
545
+ pip/_vendor/packaging/tags.py,sha256=lmsnGNiJ8C4D_Pf9PbM0qgbZvD9kmB9lpZBQUZa3R_Y,15699
546
+ pip/_vendor/packaging/utils.py,sha256=dJjeat3BS-TYn1RrUFVwufUMasbtzLfYRoy_HXENeFQ,4200
547
+ pip/_vendor/packaging/version.py,sha256=_fLRNrFrxYcHVfyo8vk9j8s6JM8N_xsSxVFr6RJyco8,14665
548
+ pip/_vendor/pkg_resources/__init__.py,sha256=hTAeJCNYb7dJseIDVsYK3mPQep_gphj4tQh-bspX8bg,109364
549
+ pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc,,
550
+ pip/_vendor/platformdirs/__init__.py,sha256=SkhEYVyC_HUHC6KX7n4M_6coyRMtEB38QMyOYIAX6Yk,20155
551
+ pip/_vendor/platformdirs/__main__.py,sha256=fVvSiTzr2-RM6IsjWjj4fkaOtDOgDhUWv6sA99do4CQ,1476
552
+ pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc,,
553
+ pip/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc,,
554
+ pip/_vendor/platformdirs/__pycache__/android.cpython-312.pyc,,
555
+ pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc,,
556
+ pip/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc,,
557
+ pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc,,
558
+ pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc,,
559
+ pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc,,
560
+ pip/_vendor/platformdirs/android.py,sha256=y_EEMKwYl2-bzYBDovksSn8m76on0Lda8eyJksVQE9U,7211
561
+ pip/_vendor/platformdirs/api.py,sha256=jWtX06jAJytYrkJDOqEls97mCkyHRSZkoqUlbMK5Qew,7132
562
+ pip/_vendor/platformdirs/macos.py,sha256=LueVOoVgGWDBwQb8OFwXkVKfVn33CM1Lkwf1-A86tRQ,3678
563
+ pip/_vendor/platformdirs/unix.py,sha256=22JhR8ZY0aLxSVCFnKrc6f1iz6Gv42K24Daj7aTjfSg,8809
564
+ pip/_vendor/platformdirs/version.py,sha256=mavZTQIJIXfdewEaSTn7EWrNfPZWeRofb-74xqW5f2M,160
565
+ pip/_vendor/platformdirs/windows.py,sha256=4TtbPGoWG2PRgI11uquDa7eRk8TcxvnUNuuMGZItnXc,9573
566
+ pip/_vendor/pygments/__init__.py,sha256=6AuDljQtvf89DTNUyWM7k3oUlP_lq70NU-INKKteOBY,2983
567
+ pip/_vendor/pygments/__main__.py,sha256=es8EKMvXj5yToIfQ-pf3Dv5TnIeeM6sME0LW-n4ecHo,353
568
+ pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc,,
569
+ pip/_vendor/pygments/__pycache__/__main__.cpython-312.pyc,,
570
+ pip/_vendor/pygments/__pycache__/cmdline.cpython-312.pyc,,
571
+ pip/_vendor/pygments/__pycache__/console.cpython-312.pyc,,
572
+ pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc,,
573
+ pip/_vendor/pygments/__pycache__/formatter.cpython-312.pyc,,
574
+ pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc,,
575
+ pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc,,
576
+ pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc,,
577
+ pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc,,
578
+ pip/_vendor/pygments/__pycache__/scanner.cpython-312.pyc,,
579
+ pip/_vendor/pygments/__pycache__/sphinxext.cpython-312.pyc,,
580
+ pip/_vendor/pygments/__pycache__/style.cpython-312.pyc,,
581
+ pip/_vendor/pygments/__pycache__/token.cpython-312.pyc,,
582
+ pip/_vendor/pygments/__pycache__/unistring.cpython-312.pyc,,
583
+ pip/_vendor/pygments/__pycache__/util.cpython-312.pyc,,
584
+ pip/_vendor/pygments/cmdline.py,sha256=byxYJp9gnjVeyhRlZ3UTMgo_LhkXh1afvN8wJBtAcc8,23685
585
+ pip/_vendor/pygments/console.py,sha256=2wZ5W-U6TudJD1_NLUwjclMpbomFM91lNv11_60sfGY,1697
586
+ pip/_vendor/pygments/filter.py,sha256=j5aLM9a9wSx6eH1oy473oSkJ02hGWNptBlVo4s1g_30,1938
587
+ pip/_vendor/pygments/filters/__init__.py,sha256=h_koYkUFo-FFUxjs564JHUAz7O3yJpVwI6fKN3MYzG0,40386
588
+ pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc,,
589
+ pip/_vendor/pygments/formatter.py,sha256=J9OL9hXLJKZk7moUgKwpjW9HNf4WlJFg_o_-Z_S_tTY,4178
590
+ pip/_vendor/pygments/formatters/__init__.py,sha256=_xgAcdFKr0QNYwh_i98AU9hvfP3X2wAkhElFcRRF3Uo,5424
591
+ pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-312.pyc,,
592
+ pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-312.pyc,,
593
+ pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-312.pyc,,
594
+ pip/_vendor/pygments/formatters/__pycache__/groff.cpython-312.pyc,,
595
+ pip/_vendor/pygments/formatters/__pycache__/html.cpython-312.pyc,,
596
+ pip/_vendor/pygments/formatters/__pycache__/img.cpython-312.pyc,,
597
+ pip/_vendor/pygments/formatters/__pycache__/irc.cpython-312.pyc,,
598
+ pip/_vendor/pygments/formatters/__pycache__/latex.cpython-312.pyc,,
599
+ pip/_vendor/pygments/formatters/__pycache__/other.cpython-312.pyc,,
600
+ pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc,,
601
+ pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-312.pyc,,
602
+ pip/_vendor/pygments/formatters/__pycache__/svg.cpython-312.pyc,,
603
+ pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-312.pyc,,
604
+ pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-312.pyc,,
605
+ pip/_vendor/pygments/formatters/_mapping.py,sha256=1Cw37FuQlNacnxRKmtlPX4nyLoX9_ttko5ZwscNUZZ4,4176
606
+ pip/_vendor/pygments/formatters/bbcode.py,sha256=r1b7wzWTJouADDLh-Z11iRi4iQxD0JKJ1qHl6mOYxsA,3314
607
+ pip/_vendor/pygments/formatters/groff.py,sha256=xy8Zf3tXOo6MWrXh7yPGWx3lVEkg_DhY4CxmsDb0IVo,5094
608
+ pip/_vendor/pygments/formatters/html.py,sha256=PIzAyilNqaTzSSP2slDG2VDLE3qNioWy2rgtSSoviuI,35610
609
+ pip/_vendor/pygments/formatters/img.py,sha256=XKXmg2_XONrR4mtq2jfEU8XCsoln3VSGTw-UYiEokys,21938
610
+ pip/_vendor/pygments/formatters/irc.py,sha256=Ep-m8jd3voFO6Fv57cUGFmz6JVA67IEgyiBOwv0N4a0,4981
611
+ pip/_vendor/pygments/formatters/latex.py,sha256=FGzJ-YqSTE8z_voWPdzvLY5Tq8jE_ygjGjM6dXZJ8-k,19351
612
+ pip/_vendor/pygments/formatters/other.py,sha256=gPxkk5BdAzWTCgbEHg1lpLi-1F6ZPh5A_aotgLXHnzg,5073
613
+ pip/_vendor/pygments/formatters/pangomarkup.py,sha256=6LKnQc8yh49f802bF0sPvbzck4QivMYqqoXAPaYP8uU,2212
614
+ pip/_vendor/pygments/formatters/rtf.py,sha256=aA0v_psW6KZI3N18TKDifxeL6mcF8EDXcPXDWI4vhVQ,5014
615
+ pip/_vendor/pygments/formatters/svg.py,sha256=dQONWypbzfvzGCDtdp3M_NJawScJvM2DiHbx1k-ww7g,7335
616
+ pip/_vendor/pygments/formatters/terminal.py,sha256=FG-rpjRpFmNpiGB4NzIucvxq6sQIXB3HOTo2meTKtrU,4674
617
+ pip/_vendor/pygments/formatters/terminal256.py,sha256=13SJ3D5pFdqZ9zROE6HbWnBDwHvOGE8GlsmqGhprRp4,11753
618
+ pip/_vendor/pygments/lexer.py,sha256=2BpqLlT2ExvOOi7vnjK5nB4Fp-m52ldiPaXMox5uwug,34618
619
+ pip/_vendor/pygments/lexers/__init__.py,sha256=j5KEi5O_VQ5GS59H49l-10gzUOkWKxlwGeVMlGO2MMk,12130
620
+ pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc,,
621
+ pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc,,
622
+ pip/_vendor/pygments/lexers/__pycache__/python.cpython-312.pyc,,
623
+ pip/_vendor/pygments/lexers/_mapping.py,sha256=Hts4r_ZQ8icftGM7gkBPeED5lyVSv4affFgXYE6Ap04,72281
624
+ pip/_vendor/pygments/lexers/python.py,sha256=c7jnmKFU9DLxTJW0UbwXt6Z9FJqbBlVsWA1Qr9xSA_w,53424
625
+ pip/_vendor/pygments/modeline.py,sha256=eF2vO4LpOGoPvIKKkbPfnyut8hT4UiebZPpb-BYGQdI,986
626
+ pip/_vendor/pygments/plugin.py,sha256=j1Fh310RbV2DQ9nvkmkqvlj38gdyuYKllLnGxbc8sJM,2591
627
+ pip/_vendor/pygments/regexopt.py,sha256=jg1ALogcYGU96TQS9isBl6dCrvw5y5--BP_K-uFk_8s,3072
628
+ pip/_vendor/pygments/scanner.py,sha256=b_nu5_f3HCgSdp5S_aNRBQ1MSCm4ZjDwec2OmTRickw,3092
629
+ pip/_vendor/pygments/sphinxext.py,sha256=wBFYm180qea9JKt__UzhRlNRNhczPDFDaqGD21sbuso,6882
630
+ pip/_vendor/pygments/style.py,sha256=C4qyoJrUTkq-OV3iO-8Vz3UtWYpJwSTdh5_vlGCGdNQ,6257
631
+ pip/_vendor/pygments/styles/__init__.py,sha256=he7HjQx7sC0d2kfTVLjUs0J15mtToJM6M1brwIm9--Q,3700
632
+ pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc,,
633
+ pip/_vendor/pygments/token.py,sha256=seNsmcch9OEHXYirh8Ool7w8xDhfNTbLj5rHAC-gc_o,6184
634
+ pip/_vendor/pygments/unistring.py,sha256=FaUfG14NBJEKLQoY9qj6JYeXrpYcLmKulghdxOGFaOc,63223
635
+ pip/_vendor/pygments/util.py,sha256=AEVY0qonyyEMgv4Do2dINrrqUAwUk2XYSqHM650uzek,10230
636
+ pip/_vendor/pyparsing/__init__.py,sha256=9m1JbE2JTLdBG0Mb6B0lEaZj181Wx5cuPXZpsbHEYgE,9116
637
+ pip/_vendor/pyparsing/__pycache__/__init__.cpython-312.pyc,,
638
+ pip/_vendor/pyparsing/__pycache__/actions.cpython-312.pyc,,
639
+ pip/_vendor/pyparsing/__pycache__/common.cpython-312.pyc,,
640
+ pip/_vendor/pyparsing/__pycache__/core.cpython-312.pyc,,
641
+ pip/_vendor/pyparsing/__pycache__/exceptions.cpython-312.pyc,,
642
+ pip/_vendor/pyparsing/__pycache__/helpers.cpython-312.pyc,,
643
+ pip/_vendor/pyparsing/__pycache__/results.cpython-312.pyc,,
644
+ pip/_vendor/pyparsing/__pycache__/testing.cpython-312.pyc,,
645
+ pip/_vendor/pyparsing/__pycache__/unicode.cpython-312.pyc,,
646
+ pip/_vendor/pyparsing/__pycache__/util.cpython-312.pyc,,
647
+ pip/_vendor/pyparsing/actions.py,sha256=05uaIPOznJPQ7VgRdmGCmG4sDnUPtwgv5qOYIqbL2UY,6567
648
+ pip/_vendor/pyparsing/common.py,sha256=p-3c83E5-DjlkF35G0O9-kjQRpoejP-2_z0hxZ-eol4,13387
649
+ pip/_vendor/pyparsing/core.py,sha256=yvuRlLpXSF8mgk-QhiW3OVLqD9T0rsj9tbibhRH4Yaw,224445
650
+ pip/_vendor/pyparsing/diagram/__init__.py,sha256=nxmDOoYF9NXuLaGYy01tKFjkNReWJlrGFuJNWEiTo84,24215
651
+ pip/_vendor/pyparsing/diagram/__pycache__/__init__.cpython-312.pyc,,
652
+ pip/_vendor/pyparsing/exceptions.py,sha256=6Jc6W1eDZBzyFu1J0YrcdNFVBC-RINujZmveSnB8Rxw,9523
653
+ pip/_vendor/pyparsing/helpers.py,sha256=BZJHCA8SS0pYio30KGQTc9w2qMOaK4YpZ7hcvHbnTgk,38646
654
+ pip/_vendor/pyparsing/results.py,sha256=9dyqQ-w3MjfmxWbFt8KEPU6IfXeyRdoWp2Og802rUQY,26692
655
+ pip/_vendor/pyparsing/testing.py,sha256=eJncg0p83zm1FTPvM9auNT6oavIvXaibmRFDf1qmwkY,13488
656
+ pip/_vendor/pyparsing/unicode.py,sha256=fAPdsJiARFbkPAih6NkYry0dpj4jPqelGVMlE4wWFW8,10646
657
+ pip/_vendor/pyparsing/util.py,sha256=vTMzTdwSDyV8d_dSgquUTdWgBFoA_W30nfxEJDsshRQ,8670
658
+ pip/_vendor/pyproject_hooks/__init__.py,sha256=kCehmy0UaBa9oVMD7ZIZrnswfnP3LXZ5lvnNJAL5JBM,491
659
+ pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc,,
660
+ pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-312.pyc,,
661
+ pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc,,
662
+ pip/_vendor/pyproject_hooks/_compat.py,sha256=by6evrYnqkisiM-MQcvOKs5bgDMzlOSgZqRHNqf04zE,138
663
+ pip/_vendor/pyproject_hooks/_impl.py,sha256=61GJxzQip0IInhuO69ZI5GbNQ82XEDUB_1Gg5_KtUoc,11920
664
+ pip/_vendor/pyproject_hooks/_in_process/__init__.py,sha256=9gQATptbFkelkIy0OfWFEACzqxXJMQDWCH9rBOAZVwQ,546
665
+ pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc,,
666
+ pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-312.pyc,,
667
+ pip/_vendor/pyproject_hooks/_in_process/_in_process.py,sha256=m2b34c917IW5o-Q_6TYIHlsK9lSUlNiyrITTUH_zwew,10927
668
+ pip/_vendor/requests/__init__.py,sha256=owujob4dk45Siy4EYtbCKR6wcFph7E04a_v_OuAacBA,5169
669
+ pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc,,
670
+ pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc,,
671
+ pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc,,
672
+ pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc,,
673
+ pip/_vendor/requests/__pycache__/api.cpython-312.pyc,,
674
+ pip/_vendor/requests/__pycache__/auth.cpython-312.pyc,,
675
+ pip/_vendor/requests/__pycache__/certs.cpython-312.pyc,,
676
+ pip/_vendor/requests/__pycache__/compat.cpython-312.pyc,,
677
+ pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc,,
678
+ pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc,,
679
+ pip/_vendor/requests/__pycache__/help.cpython-312.pyc,,
680
+ pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc,,
681
+ pip/_vendor/requests/__pycache__/models.cpython-312.pyc,,
682
+ pip/_vendor/requests/__pycache__/packages.cpython-312.pyc,,
683
+ pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc,,
684
+ pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc,,
685
+ pip/_vendor/requests/__pycache__/structures.cpython-312.pyc,,
686
+ pip/_vendor/requests/__pycache__/utils.cpython-312.pyc,,
687
+ pip/_vendor/requests/__version__.py,sha256=ssI3Ezt7PaxgkOW45GhtwPUclo_SO_ygtIm4A74IOfw,435
688
+ pip/_vendor/requests/_internal_utils.py,sha256=nMQymr4hs32TqVo5AbCrmcJEhvPUh7xXlluyqwslLiQ,1495
689
+ pip/_vendor/requests/adapters.py,sha256=idj6cZcId3L5xNNeJ7ieOLtw3awJk5A64xUfetHwq3M,19697
690
+ pip/_vendor/requests/api.py,sha256=q61xcXq4tmiImrvcSVLTbFyCiD2F-L_-hWKGbz4y8vg,6449
691
+ pip/_vendor/requests/auth.py,sha256=h-HLlVx9j8rKV5hfSAycP2ApOSglTz77R0tz7qCbbEE,10187
692
+ pip/_vendor/requests/certs.py,sha256=PVPooB0jP5hkZEULSCwC074532UFbR2Ptgu0I5zwmCs,575
693
+ pip/_vendor/requests/compat.py,sha256=IhK9quyX0RRuWTNcg6d2JGSAOUbM6mym2p_2XjLTwf4,1286
694
+ pip/_vendor/requests/cookies.py,sha256=kD3kNEcCj-mxbtf5fJsSaT86eGoEYpD3X0CSgpzl7BM,18560
695
+ pip/_vendor/requests/exceptions.py,sha256=FA-_kVwBZ2jhXauRctN_ewHVK25b-fj0Azyz1THQ0Kk,3823
696
+ pip/_vendor/requests/help.py,sha256=FnAAklv8MGm_qb2UilDQgS6l0cUttiCFKUjx0zn2XNA,3879
697
+ pip/_vendor/requests/hooks.py,sha256=CiuysiHA39V5UfcCBXFIx83IrDpuwfN9RcTUgv28ftQ,733
698
+ pip/_vendor/requests/models.py,sha256=dDZ-iThotky-Noq9yy97cUEJhr3wnY6mv-xR_ePg_lk,35288
699
+ pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695
700
+ pip/_vendor/requests/sessions.py,sha256=-LvTzrPtetSTrR3buxu4XhdgMrJFLB1q5D7P--L2Xhw,30373
701
+ pip/_vendor/requests/status_codes.py,sha256=FvHmT5uH-_uimtRz5hH9VCbt7VV-Nei2J9upbej6j8g,4235
702
+ pip/_vendor/requests/structures.py,sha256=-IbmhVz06S-5aPSZuUthZ6-6D9XOjRuTXHOabY041XM,2912
703
+ pip/_vendor/requests/utils.py,sha256=BvQDKkLuXCSaVfSW_1blUN0IzJSfNC8njNr8vhKj76Y,33189
704
+ pip/_vendor/resolvelib/__init__.py,sha256=h509TdEcpb5-44JonaU3ex2TM15GVBLjM9CNCPwnTTs,537
705
+ pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc,,
706
+ pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc,,
707
+ pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc,,
708
+ pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc,,
709
+ pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc,,
710
+ pip/_vendor/resolvelib/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
711
+ pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc,,
712
+ pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc,,
713
+ pip/_vendor/resolvelib/compat/collections_abc.py,sha256=uy8xUZ-NDEw916tugUXm8HgwCGiMO0f-RcdnpkfXfOs,156
714
+ pip/_vendor/resolvelib/providers.py,sha256=fuuvVrCetu5gsxPB43ERyjfO8aReS3rFQHpDgiItbs4,5871
715
+ pip/_vendor/resolvelib/reporters.py,sha256=TSbRmWzTc26w0ggsV1bxVpeWDB8QNIre6twYl7GIZBE,1601
716
+ pip/_vendor/resolvelib/resolvers.py,sha256=G8rsLZSq64g5VmIq-lB7UcIJ1gjAxIQJmTF4REZleQ0,20511
717
+ pip/_vendor/resolvelib/structs.py,sha256=0_1_XO8z_CLhegP3Vpf9VJ3zJcfLm0NOHRM-i0Ykz3o,4963
718
+ pip/_vendor/rich/__init__.py,sha256=dRxjIL-SbFVY0q3IjSMrfgBTHrm1LZDgLOygVBwiYZc,6090
719
+ pip/_vendor/rich/__main__.py,sha256=TT8sb9PTnsnKhhrGuHkLN0jdN0dtKhtPkEr9CidDbPM,8478
720
+ pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc,,
721
+ pip/_vendor/rich/__pycache__/__main__.cpython-312.pyc,,
722
+ pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc,,
723
+ pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc,,
724
+ pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc,,
725
+ pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc,,
726
+ pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc,,
727
+ pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc,,
728
+ pip/_vendor/rich/__pycache__/_inspect.cpython-312.pyc,,
729
+ pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc,,
730
+ pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc,,
731
+ pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc,,
732
+ pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc,,
733
+ pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc,,
734
+ pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc,,
735
+ pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc,,
736
+ pip/_vendor/rich/__pycache__/_stack.cpython-312.pyc,,
737
+ pip/_vendor/rich/__pycache__/_timer.cpython-312.pyc,,
738
+ pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc,,
739
+ pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc,,
740
+ pip/_vendor/rich/__pycache__/_windows_renderer.cpython-312.pyc,,
741
+ pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc,,
742
+ pip/_vendor/rich/__pycache__/abc.cpython-312.pyc,,
743
+ pip/_vendor/rich/__pycache__/align.cpython-312.pyc,,
744
+ pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc,,
745
+ pip/_vendor/rich/__pycache__/bar.cpython-312.pyc,,
746
+ pip/_vendor/rich/__pycache__/box.cpython-312.pyc,,
747
+ pip/_vendor/rich/__pycache__/cells.cpython-312.pyc,,
748
+ pip/_vendor/rich/__pycache__/color.cpython-312.pyc,,
749
+ pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc,,
750
+ pip/_vendor/rich/__pycache__/columns.cpython-312.pyc,,
751
+ pip/_vendor/rich/__pycache__/console.cpython-312.pyc,,
752
+ pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc,,
753
+ pip/_vendor/rich/__pycache__/containers.cpython-312.pyc,,
754
+ pip/_vendor/rich/__pycache__/control.cpython-312.pyc,,
755
+ pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc,,
756
+ pip/_vendor/rich/__pycache__/diagnose.cpython-312.pyc,,
757
+ pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc,,
758
+ pip/_vendor/rich/__pycache__/errors.cpython-312.pyc,,
759
+ pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc,,
760
+ pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc,,
761
+ pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc,,
762
+ pip/_vendor/rich/__pycache__/json.cpython-312.pyc,,
763
+ pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc,,
764
+ pip/_vendor/rich/__pycache__/layout.cpython-312.pyc,,
765
+ pip/_vendor/rich/__pycache__/live.cpython-312.pyc,,
766
+ pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc,,
767
+ pip/_vendor/rich/__pycache__/logging.cpython-312.pyc,,
768
+ pip/_vendor/rich/__pycache__/markup.cpython-312.pyc,,
769
+ pip/_vendor/rich/__pycache__/measure.cpython-312.pyc,,
770
+ pip/_vendor/rich/__pycache__/padding.cpython-312.pyc,,
771
+ pip/_vendor/rich/__pycache__/pager.cpython-312.pyc,,
772
+ pip/_vendor/rich/__pycache__/palette.cpython-312.pyc,,
773
+ pip/_vendor/rich/__pycache__/panel.cpython-312.pyc,,
774
+ pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc,,
775
+ pip/_vendor/rich/__pycache__/progress.cpython-312.pyc,,
776
+ pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc,,
777
+ pip/_vendor/rich/__pycache__/prompt.cpython-312.pyc,,
778
+ pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc,,
779
+ pip/_vendor/rich/__pycache__/region.cpython-312.pyc,,
780
+ pip/_vendor/rich/__pycache__/repr.cpython-312.pyc,,
781
+ pip/_vendor/rich/__pycache__/rule.cpython-312.pyc,,
782
+ pip/_vendor/rich/__pycache__/scope.cpython-312.pyc,,
783
+ pip/_vendor/rich/__pycache__/screen.cpython-312.pyc,,
784
+ pip/_vendor/rich/__pycache__/segment.cpython-312.pyc,,
785
+ pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc,,
786
+ pip/_vendor/rich/__pycache__/status.cpython-312.pyc,,
787
+ pip/_vendor/rich/__pycache__/style.cpython-312.pyc,,
788
+ pip/_vendor/rich/__pycache__/styled.cpython-312.pyc,,
789
+ pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc,,
790
+ pip/_vendor/rich/__pycache__/table.cpython-312.pyc,,
791
+ pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc,,
792
+ pip/_vendor/rich/__pycache__/text.cpython-312.pyc,,
793
+ pip/_vendor/rich/__pycache__/theme.cpython-312.pyc,,
794
+ pip/_vendor/rich/__pycache__/themes.cpython-312.pyc,,
795
+ pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc,,
796
+ pip/_vendor/rich/__pycache__/tree.cpython-312.pyc,,
797
+ pip/_vendor/rich/_cell_widths.py,sha256=2n4EiJi3X9sqIq0O16kUZ_zy6UYMd3xFfChlKfnW1Hc,10096
798
+ pip/_vendor/rich/_emoji_codes.py,sha256=hu1VL9nbVdppJrVoijVshRlcRRe_v3dju3Mmd2sKZdY,140235
799
+ pip/_vendor/rich/_emoji_replace.py,sha256=n-kcetsEUx2ZUmhQrfeMNc-teeGhpuSQ5F8VPBsyvDo,1064
800
+ pip/_vendor/rich/_export_format.py,sha256=qxgV3nKnXQu1hfbnRVswPYy-AwIg1X0LSC47cK5s8jk,2100
801
+ pip/_vendor/rich/_extension.py,sha256=Xt47QacCKwYruzjDi-gOBq724JReDj9Cm9xUi5fr-34,265
802
+ pip/_vendor/rich/_fileno.py,sha256=HWZxP5C2ajMbHryvAQZseflVfQoGzsKOHzKGsLD8ynQ,799
803
+ pip/_vendor/rich/_inspect.py,sha256=oZJGw31e64dwXSCmrDnvZbwVb1ZKhWfU8wI3VWohjJk,9695
804
+ pip/_vendor/rich/_log_render.py,sha256=1ByI0PA1ZpxZY3CGJOK54hjlq4X-Bz_boIjIqCd8Kns,3225
805
+ pip/_vendor/rich/_loop.py,sha256=hV_6CLdoPm0va22Wpw4zKqM0RYsz3TZxXj0PoS-9eDQ,1236
806
+ pip/_vendor/rich/_null_file.py,sha256=tGSXk_v-IZmbj1GAzHit8A3kYIQMiCpVsCFfsC-_KJ4,1387
807
+ pip/_vendor/rich/_palettes.py,sha256=cdev1JQKZ0JvlguV9ipHgznTdnvlIzUFDBb0It2PzjI,7063
808
+ pip/_vendor/rich/_pick.py,sha256=evDt8QN4lF5CiwrUIXlOJCntitBCOsI3ZLPEIAVRLJU,423
809
+ pip/_vendor/rich/_ratio.py,sha256=2lLSliL025Y-YMfdfGbutkQDevhcyDqc-DtUYW9mU70,5472
810
+ pip/_vendor/rich/_spinners.py,sha256=U2r1_g_1zSjsjiUdAESc2iAMc3i4ri_S8PYP6kQ5z1I,19919
811
+ pip/_vendor/rich/_stack.py,sha256=-C8OK7rxn3sIUdVwxZBBpeHhIzX0eI-VM3MemYfaXm0,351
812
+ pip/_vendor/rich/_timer.py,sha256=zelxbT6oPFZnNrwWPpc1ktUeAT-Vc4fuFcRZLQGLtMI,417
813
+ pip/_vendor/rich/_win32_console.py,sha256=P0vxI2fcndym1UU1S37XAzQzQnkyY7YqAKmxm24_gug,22820
814
+ pip/_vendor/rich/_windows.py,sha256=dvNl9TmfPzNVxiKk5WDFihErZ5796g2UC9-KGGyfXmk,1926
815
+ pip/_vendor/rich/_windows_renderer.py,sha256=t74ZL3xuDCP3nmTp9pH1L5LiI2cakJuQRQleHCJerlk,2783
816
+ pip/_vendor/rich/_wrap.py,sha256=xfV_9t0Sg6rzimmrDru8fCVmUlalYAcHLDfrJZnbbwQ,1840
817
+ pip/_vendor/rich/abc.py,sha256=ON-E-ZqSSheZ88VrKX2M3PXpFbGEUUZPMa_Af0l-4f0,890
818
+ pip/_vendor/rich/align.py,sha256=Ji-Yokfkhnfe_xMmr4ISjZB07TJXggBCOYoYa-HDAr8,10368
819
+ pip/_vendor/rich/ansi.py,sha256=iD6532QYqnBm6hADulKjrV8l8kFJ-9fEVooHJHH3hMg,6906
820
+ pip/_vendor/rich/bar.py,sha256=a7UD303BccRCrEhGjfMElpv5RFYIinaAhAuqYqhUvmw,3264
821
+ pip/_vendor/rich/box.py,sha256=FJ6nI3jD7h2XNFU138bJUt2HYmWOlRbltoCEuIAZhew,9842
822
+ pip/_vendor/rich/cells.py,sha256=627ztJs9zOL-38HJ7kXBerR-gT8KBfYC8UzEwMJDYYo,4509
823
+ pip/_vendor/rich/color.py,sha256=9Gh958U3f75WVdLTeC0U9nkGTn2n0wnojKpJ6jQEkIE,18224
824
+ pip/_vendor/rich/color_triplet.py,sha256=3lhQkdJbvWPoLDO-AnYImAWmJvV5dlgYNCVZ97ORaN4,1054
825
+ pip/_vendor/rich/columns.py,sha256=HUX0KcMm9dsKNi11fTbiM_h2iDtl8ySCaVcxlalEzq8,7131
826
+ pip/_vendor/rich/console.py,sha256=pDvkbLkvtZIMIwQx_jkZ-seyNl4zGBLviXoWXte9fwg,99218
827
+ pip/_vendor/rich/constrain.py,sha256=1VIPuC8AgtKWrcncQrjBdYqA3JVWysu6jZo1rrh7c7Q,1288
828
+ pip/_vendor/rich/containers.py,sha256=aKgm5UDHn5Nmui6IJaKdsZhbHClh_X7D-_Wg8Ehrr7s,5497
829
+ pip/_vendor/rich/control.py,sha256=DSkHTUQLorfSERAKE_oTAEUFefZnZp4bQb4q8rHbKws,6630
830
+ pip/_vendor/rich/default_styles.py,sha256=-Fe318kMVI_IwciK5POpThcO0-9DYJ67TZAN6DlmlmM,8082
831
+ pip/_vendor/rich/diagnose.py,sha256=an6uouwhKPAlvQhYpNNpGq9EJysfMIOvvCbO3oSoR24,972
832
+ pip/_vendor/rich/emoji.py,sha256=omTF9asaAnsM4yLY94eR_9dgRRSm1lHUszX20D1yYCQ,2501
833
+ pip/_vendor/rich/errors.py,sha256=5pP3Kc5d4QJ_c0KFsxrfyhjiPVe7J1zOqSFbFAzcV-Y,642
834
+ pip/_vendor/rich/file_proxy.py,sha256=Tl9THMDZ-Pk5Wm8sI1gGg_U5DhusmxD-FZ0fUbcU0W0,1683
835
+ pip/_vendor/rich/filesize.py,sha256=9fTLAPCAwHmBXdRv7KZU194jSgNrRb6Wx7RIoBgqeKY,2508
836
+ pip/_vendor/rich/highlighter.py,sha256=p3C1g4QYzezFKdR7NF9EhPbzQDvdPUhGRgSyGGEmPko,9584
837
+ pip/_vendor/rich/json.py,sha256=EYp9ucj-nDjYDkHCV6Mk1ve8nUOpuFLaW76X50Mis2M,5032
838
+ pip/_vendor/rich/jupyter.py,sha256=QyoKoE_8IdCbrtiSHp9TsTSNyTHY0FO5whE7jOTd9UE,3252
839
+ pip/_vendor/rich/layout.py,sha256=RFYL6HdCFsHf9WRpcvi3w-fpj-8O5dMZ8W96VdKNdbI,14007
840
+ pip/_vendor/rich/live.py,sha256=vZzYvu7fqwlv3Gthl2xiw1Dc_O80VlGcCV0DOHwCyDM,14273
841
+ pip/_vendor/rich/live_render.py,sha256=zElm3PrfSIvjOce28zETHMIUf9pFYSUA5o0AflgUP64,3667
842
+ pip/_vendor/rich/logging.py,sha256=uB-cB-3Q4bmXDLLpbOWkmFviw-Fde39zyMV6tKJ2WHQ,11903
843
+ pip/_vendor/rich/markup.py,sha256=xzF4uAafiEeEYDJYt_vUnJOGoTU8RrH-PH7WcWYXjCg,8198
844
+ pip/_vendor/rich/measure.py,sha256=HmrIJX8sWRTHbgh8MxEay_83VkqNW_70s8aKP5ZcYI8,5305
845
+ pip/_vendor/rich/padding.py,sha256=kTFGsdGe0os7tXLnHKpwTI90CXEvrceeZGCshmJy5zw,4970
846
+ pip/_vendor/rich/pager.py,sha256=SO_ETBFKbg3n_AgOzXm41Sv36YxXAyI3_R-KOY2_uSc,828
847
+ pip/_vendor/rich/palette.py,sha256=lInvR1ODDT2f3UZMfL1grq7dY_pDdKHw4bdUgOGaM4Y,3396
848
+ pip/_vendor/rich/panel.py,sha256=wGMe40J8KCGgQoM0LyjRErmGIkv2bsYA71RCXThD0xE,10574
849
+ pip/_vendor/rich/pretty.py,sha256=eLEYN9xVaMNuA6EJVYm4li7HdOHxCqmVKvnOqJpyFt0,35852
850
+ pip/_vendor/rich/progress.py,sha256=n4KF9vky8_5iYeXcyZPEvzyLplWlDvFLkM5JI0Bs08A,59706
851
+ pip/_vendor/rich/progress_bar.py,sha256=cEoBfkc3lLwqba4XKsUpy4vSQKDh2QQ5J2J94-ACFoo,8165
852
+ pip/_vendor/rich/prompt.py,sha256=x0mW-pIPodJM4ry6grgmmLrl8VZp99kqcmdnBe70YYA,11303
853
+ pip/_vendor/rich/protocol.py,sha256=5hHHDDNHckdk8iWH5zEbi-zuIVSF5hbU2jIo47R7lTE,1391
854
+ pip/_vendor/rich/region.py,sha256=rNT9xZrVZTYIXZC0NYn41CJQwYNbR-KecPOxTgQvB8Y,166
855
+ pip/_vendor/rich/repr.py,sha256=9Z8otOmM-tyxnyTodvXlectP60lwahjGiDTrbrxPSTg,4431
856
+ pip/_vendor/rich/rule.py,sha256=0fNaS_aERa3UMRc3T5WMpN_sumtDxfaor2y3of1ftBk,4602
857
+ pip/_vendor/rich/scope.py,sha256=TMUU8qo17thyqQCPqjDLYpg_UU1k5qVd-WwiJvnJVas,2843
858
+ pip/_vendor/rich/screen.py,sha256=YoeReESUhx74grqb0mSSb9lghhysWmFHYhsbMVQjXO8,1591
859
+ pip/_vendor/rich/segment.py,sha256=XLnJEFvcV3bjaVzMNUJiem3n8lvvI9TJ5PTu-IG2uTg,24247
860
+ pip/_vendor/rich/spinner.py,sha256=15koCmF0DQeD8-k28Lpt6X_zJQUlzEhgo_6A6uy47lc,4339
861
+ pip/_vendor/rich/status.py,sha256=gJsIXIZeSo3urOyxRUjs6VrhX5CZrA0NxIQ-dxhCnwo,4425
862
+ pip/_vendor/rich/style.py,sha256=3hiocH_4N8vwRm3-8yFWzM7tSwjjEven69XqWasSQwM,27073
863
+ pip/_vendor/rich/styled.py,sha256=eZNnzGrI4ki_54pgY3Oj0T-x3lxdXTYh4_ryDB24wBU,1258
864
+ pip/_vendor/rich/syntax.py,sha256=jgDiVCK6cpR0NmBOpZmIu-Ud4eaW7fHvjJZkDbjpcSA,35173
865
+ pip/_vendor/rich/table.py,sha256=-WzesL-VJKsaiDU3uyczpJMHy6VCaSewBYJwx8RudI8,39684
866
+ pip/_vendor/rich/terminal_theme.py,sha256=1j5-ufJfnvlAo5Qsi_ACZiXDmwMXzqgmFByObT9-yJY,3370
867
+ pip/_vendor/rich/text.py,sha256=_8JBlSau0c2z8ENOZMi1hJ7M1ZGY408E4-hXjHyyg1A,45525
868
+ pip/_vendor/rich/theme.py,sha256=belFJogzA0W0HysQabKaHOc3RWH2ko3fQAJhoN-AFdo,3777
869
+ pip/_vendor/rich/themes.py,sha256=0xgTLozfabebYtcJtDdC5QkX5IVUEaviqDUJJh4YVFk,102
870
+ pip/_vendor/rich/traceback.py,sha256=yCLVrCtyoFNENd9mkm2xeG3KmqkTwH9xpFOO7p2Bq0A,29604
871
+ pip/_vendor/rich/tree.py,sha256=BMbUYNjS9uodNPfvtY_odmU09GA5QzcMbQ5cJZhllQI,9169
872
+ pip/_vendor/six.py,sha256=TOOfQi7nFGfMrIvtdr6wX4wyHH8M7aknmuLfo2cBBrM,34549
873
+ pip/_vendor/tenacity/__init__.py,sha256=3kvAL6KClq8GFo2KFhmOzskRKSDQI-ubrlfZ8AQEEI0,20493
874
+ pip/_vendor/tenacity/__pycache__/__init__.cpython-312.pyc,,
875
+ pip/_vendor/tenacity/__pycache__/_asyncio.cpython-312.pyc,,
876
+ pip/_vendor/tenacity/__pycache__/_utils.cpython-312.pyc,,
877
+ pip/_vendor/tenacity/__pycache__/after.cpython-312.pyc,,
878
+ pip/_vendor/tenacity/__pycache__/before.cpython-312.pyc,,
879
+ pip/_vendor/tenacity/__pycache__/before_sleep.cpython-312.pyc,,
880
+ pip/_vendor/tenacity/__pycache__/nap.cpython-312.pyc,,
881
+ pip/_vendor/tenacity/__pycache__/retry.cpython-312.pyc,,
882
+ pip/_vendor/tenacity/__pycache__/stop.cpython-312.pyc,,
883
+ pip/_vendor/tenacity/__pycache__/tornadoweb.cpython-312.pyc,,
884
+ pip/_vendor/tenacity/__pycache__/wait.cpython-312.pyc,,
885
+ pip/_vendor/tenacity/_asyncio.py,sha256=Qi6wgQsGa9MQibYRy3OXqcDQswIZZ00dLOoSUGN-6o8,3551
886
+ pip/_vendor/tenacity/_utils.py,sha256=ubs6a7sxj3JDNRKWCyCU2j5r1CB7rgyONgZzYZq6D_4,2179
887
+ pip/_vendor/tenacity/after.py,sha256=S5NCISScPeIrKwIeXRwdJl3kV9Q4nqZfnNPDx6Hf__g,1682
888
+ pip/_vendor/tenacity/before.py,sha256=dIZE9gmBTffisfwNkK0F1xFwGPV41u5GK70UY4Pi5Kc,1562
889
+ pip/_vendor/tenacity/before_sleep.py,sha256=YmpgN9Y7HGlH97U24vvq_YWb5deaK4_DbiD8ZuFmy-E,2372
890
+ pip/_vendor/tenacity/nap.py,sha256=fRWvnz1aIzbIq9Ap3gAkAZgDH6oo5zxMrU6ZOVByq0I,1383
891
+ pip/_vendor/tenacity/retry.py,sha256=jrzD_mxA5mSTUEdiYB7SHpxltjhPSYZSnSRATb-ggRc,8746
892
+ pip/_vendor/tenacity/stop.py,sha256=YMJs7ZgZfND65PRLqlGB_agpfGXlemx_5Hm4PKnBqpQ,3086
893
+ pip/_vendor/tenacity/tornadoweb.py,sha256=po29_F1Mt8qZpsFjX7EVwAT0ydC_NbVia9gVi7R_wXA,2142
894
+ pip/_vendor/tenacity/wait.py,sha256=3FcBJoCDgym12_dN6xfK8C1gROY0Hn4NSI2u8xv50uE,8024
895
+ pip/_vendor/tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396
896
+ pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc,,
897
+ pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc,,
898
+ pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc,,
899
+ pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc,,
900
+ pip/_vendor/tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633
901
+ pip/_vendor/tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943
902
+ pip/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
903
+ pip/_vendor/truststore/__init__.py,sha256=qzTLSH8PvAkY1fr6QQ2vV-KwE_M83wdXugtpJaP_AbM,403
904
+ pip/_vendor/truststore/__pycache__/__init__.cpython-312.pyc,,
905
+ pip/_vendor/truststore/__pycache__/_api.cpython-312.pyc,,
906
+ pip/_vendor/truststore/__pycache__/_macos.cpython-312.pyc,,
907
+ pip/_vendor/truststore/__pycache__/_openssl.cpython-312.pyc,,
908
+ pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-312.pyc,,
909
+ pip/_vendor/truststore/__pycache__/_windows.cpython-312.pyc,,
910
+ pip/_vendor/truststore/_api.py,sha256=xjuEu_rlH4hcdJTROImEyOEqdw-F8t5vO2H2BToY0Ro,9893
911
+ pip/_vendor/truststore/_macos.py,sha256=BjvAKoAjXhdIPuxpY124HJIFswDb0pq8DjynzJOVwqc,17694
912
+ pip/_vendor/truststore/_openssl.py,sha256=LLUZ7ZGaio-i5dpKKjKCSeSufmn6T8pi9lDcFnvSyq0,2324
913
+ pip/_vendor/truststore/_ssl_constants.py,sha256=NUD4fVKdSD02ri7-db0tnO0VqLP9aHuzmStcW7tAl08,1130
914
+ pip/_vendor/truststore/_windows.py,sha256=1x_EhROeJ9QK1sMAjfnZC7awYI8UnBJYL-TjACUYI4A,17468
915
+ pip/_vendor/typing_extensions.py,sha256=EWpcpyQnVmc48E9fSyPGs-vXgHcAk9tQABQIxmMsCGk,111130
916
+ pip/_vendor/urllib3/__init__.py,sha256=iXLcYiJySn0GNbWOOZDDApgBL1JgP44EZ8i1760S8Mc,3333
917
+ pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc,,
918
+ pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc,,
919
+ pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc,,
920
+ pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc,,
921
+ pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc,,
922
+ pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc,,
923
+ pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc,,
924
+ pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc,,
925
+ pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc,,
926
+ pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc,,
927
+ pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc,,
928
+ pip/_vendor/urllib3/_collections.py,sha256=pyASJJhW7wdOpqJj9QJA8FyGRfr8E8uUUhqUvhF0728,11372
929
+ pip/_vendor/urllib3/_version.py,sha256=azoM7M7BUADl2kBhMVR6PPf2GhBDI90me1fcnzTwdcw,64
930
+ pip/_vendor/urllib3/connection.py,sha256=92k9td_y4PEiTIjNufCUa1NzMB3J3w0LEdyokYgXnW8,20300
931
+ pip/_vendor/urllib3/connectionpool.py,sha256=Be6q65SR9laoikg-h_jmc_p8OWtEmwgq_Om_Xtig-2M,40285
932
+ pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
933
+ pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc,,
934
+ pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc,,
935
+ pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-312.pyc,,
936
+ pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc,,
937
+ pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc,,
938
+ pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-312.pyc,,
939
+ pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc,,
940
+ pip/_vendor/urllib3/contrib/_appengine_environ.py,sha256=bDbyOEhW2CKLJcQqAKAyrEHN-aklsyHFKq6vF8ZFsmk,957
941
+ pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
942
+ pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc,,
943
+ pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc,,
944
+ pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc,,
945
+ pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=4Xk64qIkPBt09A5q-RIFUuDhNc9mXilVapm7WnYnzRw,17632
946
+ pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=B2JBB2_NRP02xK6DCa1Pa9IuxrPwxzDzZbixQkb7U9M,13922
947
+ pip/_vendor/urllib3/contrib/appengine.py,sha256=VR68eAVE137lxTgjBDwCna5UiBZTOKa01Aj_-5BaCz4,11036
948
+ pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=NlfkW7WMdW8ziqudopjHoW299og1BTWi0IeIibquFwk,4528
949
+ pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=hDJh4MhyY_p-oKlFcYcQaVQRDv6GMmBGuW9yjxyeejM,17081
950
+ pip/_vendor/urllib3/contrib/securetransport.py,sha256=yhZdmVjY6PI6EeFbp7qYOp6-vp1Rkv2NMuOGaEj7pmc,34448
951
+ pip/_vendor/urllib3/contrib/socks.py,sha256=aRi9eWXo9ZEb95XUxef4Z21CFlnnjbEiAo9HOseoMt4,7097
952
+ pip/_vendor/urllib3/exceptions.py,sha256=0Mnno3KHTNfXRfY7638NufOPkUb6mXOm-Lqj-4x2w8A,8217
953
+ pip/_vendor/urllib3/fields.py,sha256=kvLDCg_JmH1lLjUUEY_FLS8UhY7hBvDPuVETbY8mdrM,8579
954
+ pip/_vendor/urllib3/filepost.py,sha256=5b_qqgRHVlL7uLtdAYBzBh-GHmU5AfJVt_2N0XS3PeY,2440
955
+ pip/_vendor/urllib3/packages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
956
+ pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc,,
957
+ pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc,,
958
+ pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
959
+ pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc,,
960
+ pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc,,
961
+ pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc,,
962
+ pip/_vendor/urllib3/packages/backports/makefile.py,sha256=nbzt3i0agPVP07jqqgjhaYjMmuAi_W5E0EywZivVO8E,1417
963
+ pip/_vendor/urllib3/packages/backports/weakref_finalize.py,sha256=tRCal5OAhNSRyb0DhHp-38AtIlCsRP8BxF3NX-6rqIA,5343
964
+ pip/_vendor/urllib3/packages/six.py,sha256=b9LM0wBXv7E7SrbCjAm4wwN-hrH-iNxv18LgWNMMKPo,34665
965
+ pip/_vendor/urllib3/poolmanager.py,sha256=mJmZWy_Mb4-dHbmNCKbDqv3fZS9UF_2bVDuiECHyPaI,20943
966
+ pip/_vendor/urllib3/request.py,sha256=YTWFNr7QIwh7E1W9dde9LM77v2VWTJ5V78XuTTw7D1A,6691
967
+ pip/_vendor/urllib3/response.py,sha256=fmDJAFkG71uFTn-sVSTh2Iw0WmcXQYqkbRjihvwBjU8,30641
968
+ pip/_vendor/urllib3/util/__init__.py,sha256=JEmSmmqqLyaw8P51gUImZh8Gwg9i1zSe-DoqAitn2nc,1155
969
+ pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc,,
970
+ pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc,,
971
+ pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc,,
972
+ pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc,,
973
+ pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc,,
974
+ pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc,,
975
+ pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc,,
976
+ pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc,,
977
+ pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc,,
978
+ pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc,,
979
+ pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc,,
980
+ pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc,,
981
+ pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc,,
982
+ pip/_vendor/urllib3/util/connection.py,sha256=5Lx2B1PW29KxBn2T0xkN1CBgRBa3gGVJBKoQoRogEVk,4901
983
+ pip/_vendor/urllib3/util/proxy.py,sha256=zUvPPCJrp6dOF0N4GAVbOcl6o-4uXKSrGiTkkr5vUS4,1605
984
+ pip/_vendor/urllib3/util/queue.py,sha256=nRgX8_eX-_VkvxoX096QWoz8Ps0QHUAExILCY_7PncM,498
985
+ pip/_vendor/urllib3/util/request.py,sha256=C0OUt2tcU6LRiQJ7YYNP9GvPrSvl7ziIBekQ-5nlBZk,3997
986
+ pip/_vendor/urllib3/util/response.py,sha256=GJpg3Egi9qaJXRwBh5wv-MNuRWan5BIu40oReoxWP28,3510
987
+ pip/_vendor/urllib3/util/retry.py,sha256=6ENvOZ8PBDzh8kgixpql9lIrb2dxH-k7ZmBanJF2Ng4,22050
988
+ pip/_vendor/urllib3/util/ssl_.py,sha256=X4-AqW91aYPhPx6-xbf66yHFQKbqqfC_5Zt4WkLX1Hc,17177
989
+ pip/_vendor/urllib3/util/ssl_match_hostname.py,sha256=Ir4cZVEjmAk8gUAIHWSi7wtOO83UCYABY2xFD1Ql_WA,5758
990
+ pip/_vendor/urllib3/util/ssltransport.py,sha256=NA-u5rMTrDFDFC8QzRKUEKMG0561hOD4qBTr3Z4pv6E,6895
991
+ pip/_vendor/urllib3/util/timeout.py,sha256=cwq4dMk87mJHSBktK1miYJ-85G-3T3RmT20v7SFCpno,10168
992
+ pip/_vendor/urllib3/util/url.py,sha256=lCAE7M5myA8EDdW0sJuyyZhVB9K_j38ljWhHAnFaWoE,14296
993
+ pip/_vendor/urllib3/util/wait.py,sha256=fOX0_faozG2P7iVojQoE1mbydweNyTcm-hXEfFrTtLI,5403
994
+ pip/_vendor/vendor.txt,sha256=4NKk7fQhVsZw0U-0zmm9Q2LgGyaPXacFbnJAaS0Q6EY,493
995
+ pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579
996
+ pip/_vendor/webencodings/__pycache__/__init__.cpython-312.pyc,,
997
+ pip/_vendor/webencodings/__pycache__/labels.cpython-312.pyc,,
998
+ pip/_vendor/webencodings/__pycache__/mklabels.cpython-312.pyc,,
999
+ pip/_vendor/webencodings/__pycache__/tests.cpython-312.pyc,,
1000
+ pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-312.pyc,,
1001
+ pip/_vendor/webencodings/labels.py,sha256=4AO_KxTddqGtrL9ns7kAPjb0CcN6xsCIxbK37HY9r3E,8979
1002
+ pip/_vendor/webencodings/mklabels.py,sha256=GYIeywnpaLnP0GSic8LFWgd0UVvO_l1Nc6YoF-87R_4,1305
1003
+ pip/_vendor/webencodings/tests.py,sha256=OtGLyjhNY1fvkW1GvLJ_FV9ZoqC9Anyjr7q3kxTbzNs,6563
1004
+ pip/_vendor/webencodings/x_user_defined.py,sha256=yOqWSdmpytGfUgh_Z6JYgDNhoc-BAHyyeeT15Fr42tM,4307
1005
+ pip/py.typed,sha256=EBVvvPRTn_eIpz5e5QztSCdrMX7Qwd7VP93RSoIlZ2I,286
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/REQUESTED ADDED
File without changes
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.42.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/entry_points.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ [console_scripts]
2
+ pip = pip._internal.cli.main:main
3
+ pip3 = pip._internal.cli.main:main
4
+ pip3.12 = pip._internal.cli.main:main
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip-24.0.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/exceptions.py ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead
4
+
5
+ # Base Exceptions
6
+
7
+
8
+ class HTTPError(Exception):
9
+ """Base exception used by this module."""
10
+
11
+ pass
12
+
13
+
14
+ class HTTPWarning(Warning):
15
+ """Base warning used by this module."""
16
+
17
+ pass
18
+
19
+
20
+ class PoolError(HTTPError):
21
+ """Base exception for errors caused within a pool."""
22
+
23
+ def __init__(self, pool, message):
24
+ self.pool = pool
25
+ HTTPError.__init__(self, "%s: %s" % (pool, message))
26
+
27
+ def __reduce__(self):
28
+ # For pickling purposes.
29
+ return self.__class__, (None, None)
30
+
31
+
32
+ class RequestError(PoolError):
33
+ """Base exception for PoolErrors that have associated URLs."""
34
+
35
+ def __init__(self, pool, url, message):
36
+ self.url = url
37
+ PoolError.__init__(self, pool, message)
38
+
39
+ def __reduce__(self):
40
+ # For pickling purposes.
41
+ return self.__class__, (None, self.url, None)
42
+
43
+
44
+ class SSLError(HTTPError):
45
+ """Raised when SSL certificate fails in an HTTPS connection."""
46
+
47
+ pass
48
+
49
+
50
+ class ProxyError(HTTPError):
51
+ """Raised when the connection to a proxy fails."""
52
+
53
+ def __init__(self, message, error, *args):
54
+ super(ProxyError, self).__init__(message, error, *args)
55
+ self.original_error = error
56
+
57
+
58
+ class DecodeError(HTTPError):
59
+ """Raised when automatic decoding based on Content-Type fails."""
60
+
61
+ pass
62
+
63
+
64
+ class ProtocolError(HTTPError):
65
+ """Raised when something unexpected happens mid-request/response."""
66
+
67
+ pass
68
+
69
+
70
+ #: Renamed to ProtocolError but aliased for backwards compatibility.
71
+ ConnectionError = ProtocolError
72
+
73
+
74
+ # Leaf Exceptions
75
+
76
+
77
+ class MaxRetryError(RequestError):
78
+ """Raised when the maximum number of retries is exceeded.
79
+
80
+ :param pool: The connection pool
81
+ :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool`
82
+ :param string url: The requested Url
83
+ :param exceptions.Exception reason: The underlying error
84
+
85
+ """
86
+
87
+ def __init__(self, pool, url, reason=None):
88
+ self.reason = reason
89
+
90
+ message = "Max retries exceeded with url: %s (Caused by %r)" % (url, reason)
91
+
92
+ RequestError.__init__(self, pool, url, message)
93
+
94
+
95
+ class HostChangedError(RequestError):
96
+ """Raised when an existing pool gets a request for a foreign host."""
97
+
98
+ def __init__(self, pool, url, retries=3):
99
+ message = "Tried to open a foreign host with url: %s" % url
100
+ RequestError.__init__(self, pool, url, message)
101
+ self.retries = retries
102
+
103
+
104
+ class TimeoutStateError(HTTPError):
105
+ """Raised when passing an invalid state to a timeout"""
106
+
107
+ pass
108
+
109
+
110
+ class TimeoutError(HTTPError):
111
+ """Raised when a socket timeout error occurs.
112
+
113
+ Catching this error will catch both :exc:`ReadTimeoutErrors
114
+ <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`.
115
+ """
116
+
117
+ pass
118
+
119
+
120
+ class ReadTimeoutError(TimeoutError, RequestError):
121
+ """Raised when a socket timeout occurs while receiving data from a server"""
122
+
123
+ pass
124
+
125
+
126
+ # This timeout error does not have a URL attached and needs to inherit from the
127
+ # base HTTPError
128
+ class ConnectTimeoutError(TimeoutError):
129
+ """Raised when a socket timeout occurs while connecting to a server"""
130
+
131
+ pass
132
+
133
+
134
+ class NewConnectionError(ConnectTimeoutError, PoolError):
135
+ """Raised when we fail to establish a new connection. Usually ECONNREFUSED."""
136
+
137
+ pass
138
+
139
+
140
+ class EmptyPoolError(PoolError):
141
+ """Raised when a pool runs out of connections and no more are allowed."""
142
+
143
+ pass
144
+
145
+
146
+ class ClosedPoolError(PoolError):
147
+ """Raised when a request enters a pool after the pool has been closed."""
148
+
149
+ pass
150
+
151
+
152
+ class LocationValueError(ValueError, HTTPError):
153
+ """Raised when there is something wrong with a given URL input."""
154
+
155
+ pass
156
+
157
+
158
+ class LocationParseError(LocationValueError):
159
+ """Raised when get_host or similar fails to parse the URL input."""
160
+
161
+ def __init__(self, location):
162
+ message = "Failed to parse: %s" % location
163
+ HTTPError.__init__(self, message)
164
+
165
+ self.location = location
166
+
167
+
168
+ class URLSchemeUnknown(LocationValueError):
169
+ """Raised when a URL input has an unsupported scheme."""
170
+
171
+ def __init__(self, scheme):
172
+ message = "Not supported URL scheme %s" % scheme
173
+ super(URLSchemeUnknown, self).__init__(message)
174
+
175
+ self.scheme = scheme
176
+
177
+
178
+ class ResponseError(HTTPError):
179
+ """Used as a container for an error reason supplied in a MaxRetryError."""
180
+
181
+ GENERIC_ERROR = "too many error responses"
182
+ SPECIFIC_ERROR = "too many {status_code} error responses"
183
+
184
+
185
+ class SecurityWarning(HTTPWarning):
186
+ """Warned when performing security reducing actions"""
187
+
188
+ pass
189
+
190
+
191
+ class SubjectAltNameWarning(SecurityWarning):
192
+ """Warned when connecting to a host with a certificate missing a SAN."""
193
+
194
+ pass
195
+
196
+
197
+ class InsecureRequestWarning(SecurityWarning):
198
+ """Warned when making an unverified HTTPS request."""
199
+
200
+ pass
201
+
202
+
203
+ class SystemTimeWarning(SecurityWarning):
204
+ """Warned when system time is suspected to be wrong"""
205
+
206
+ pass
207
+
208
+
209
+ class InsecurePlatformWarning(SecurityWarning):
210
+ """Warned when certain TLS/SSL configuration is not available on a platform."""
211
+
212
+ pass
213
+
214
+
215
+ class SNIMissingWarning(HTTPWarning):
216
+ """Warned when making a HTTPS request without SNI available."""
217
+
218
+ pass
219
+
220
+
221
+ class DependencyWarning(HTTPWarning):
222
+ """
223
+ Warned when an attempt is made to import a module with missing optional
224
+ dependencies.
225
+ """
226
+
227
+ pass
228
+
229
+
230
+ class ResponseNotChunked(ProtocolError, ValueError):
231
+ """Response needs to be chunked in order to read it as chunks."""
232
+
233
+ pass
234
+
235
+
236
+ class BodyNotHttplibCompatible(HTTPError):
237
+ """
238
+ Body should be :class:`http.client.HTTPResponse` like
239
+ (have an fp attribute which returns raw chunks) for read_chunked().
240
+ """
241
+
242
+ pass
243
+
244
+
245
+ class IncompleteRead(HTTPError, httplib_IncompleteRead):
246
+ """
247
+ Response length doesn't match expected Content-Length
248
+
249
+ Subclass of :class:`http.client.IncompleteRead` to allow int value
250
+ for ``partial`` to avoid creating large objects on streamed reads.
251
+ """
252
+
253
+ def __init__(self, partial, expected):
254
+ super(IncompleteRead, self).__init__(partial, expected)
255
+
256
+ def __repr__(self):
257
+ return "IncompleteRead(%i bytes read, %i more expected)" % (
258
+ self.partial,
259
+ self.expected,
260
+ )
261
+
262
+
263
+ class InvalidChunkLength(HTTPError, httplib_IncompleteRead):
264
+ """Invalid chunk length in a chunked response."""
265
+
266
+ def __init__(self, response, length):
267
+ super(InvalidChunkLength, self).__init__(
268
+ response.tell(), response.length_remaining
269
+ )
270
+ self.response = response
271
+ self.length = length
272
+
273
+ def __repr__(self):
274
+ return "InvalidChunkLength(got length %r, %i bytes read)" % (
275
+ self.length,
276
+ self.partial,
277
+ )
278
+
279
+
280
+ class InvalidHeader(HTTPError):
281
+ """The header provided was somehow invalid."""
282
+
283
+ pass
284
+
285
+
286
+ class ProxySchemeUnknown(AssertionError, URLSchemeUnknown):
287
+ """ProxyManager does not support the supplied scheme"""
288
+
289
+ # TODO(t-8ch): Stop inheriting from AssertionError in v2.0.
290
+
291
+ def __init__(self, scheme):
292
+ # 'localhost' is here because our URL parser parses
293
+ # localhost:8080 -> scheme=localhost, remove if we fix this.
294
+ if scheme == "localhost":
295
+ scheme = None
296
+ if scheme is None:
297
+ message = "Proxy URL had no scheme, should start with http:// or https://"
298
+ else:
299
+ message = (
300
+ "Proxy URL had unsupported scheme %s, should use http:// or https://"
301
+ % scheme
302
+ )
303
+ super(ProxySchemeUnknown, self).__init__(message)
304
+
305
+
306
+ class ProxySchemeUnsupported(ValueError):
307
+ """Fetching HTTPS resources through HTTPS proxies is unsupported"""
308
+
309
+ pass
310
+
311
+
312
+ class HeaderParsingError(HTTPError):
313
+ """Raised by assert_header_parsing, but we convert it to a log.warning statement."""
314
+
315
+ def __init__(self, defects, unparsed_data):
316
+ message = "%s, unparsed data: %r" % (defects or "Unknown", unparsed_data)
317
+ super(HeaderParsingError, self).__init__(message)
318
+
319
+
320
+ class UnrewindableBodyError(HTTPError):
321
+ """urllib3 encountered an error when trying to rewind a body"""
322
+
323
+ pass
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/fields.py ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import email.utils
4
+ import mimetypes
5
+ import re
6
+
7
+ from .packages import six
8
+
9
+
10
+ def guess_content_type(filename, default="application/octet-stream"):
11
+ """
12
+ Guess the "Content-Type" of a file.
13
+
14
+ :param filename:
15
+ The filename to guess the "Content-Type" of using :mod:`mimetypes`.
16
+ :param default:
17
+ If no "Content-Type" can be guessed, default to `default`.
18
+ """
19
+ if filename:
20
+ return mimetypes.guess_type(filename)[0] or default
21
+ return default
22
+
23
+
24
+ def format_header_param_rfc2231(name, value):
25
+ """
26
+ Helper function to format and quote a single header parameter using the
27
+ strategy defined in RFC 2231.
28
+
29
+ Particularly useful for header parameters which might contain
30
+ non-ASCII values, like file names. This follows
31
+ `RFC 2388 Section 4.4 <https://tools.ietf.org/html/rfc2388#section-4.4>`_.
32
+
33
+ :param name:
34
+ The name of the parameter, a string expected to be ASCII only.
35
+ :param value:
36
+ The value of the parameter, provided as ``bytes`` or `str``.
37
+ :ret:
38
+ An RFC-2231-formatted unicode string.
39
+ """
40
+ if isinstance(value, six.binary_type):
41
+ value = value.decode("utf-8")
42
+
43
+ if not any(ch in value for ch in '"\\\r\n'):
44
+ result = u'%s="%s"' % (name, value)
45
+ try:
46
+ result.encode("ascii")
47
+ except (UnicodeEncodeError, UnicodeDecodeError):
48
+ pass
49
+ else:
50
+ return result
51
+
52
+ if six.PY2: # Python 2:
53
+ value = value.encode("utf-8")
54
+
55
+ # encode_rfc2231 accepts an encoded string and returns an ascii-encoded
56
+ # string in Python 2 but accepts and returns unicode strings in Python 3
57
+ value = email.utils.encode_rfc2231(value, "utf-8")
58
+ value = "%s*=%s" % (name, value)
59
+
60
+ if six.PY2: # Python 2:
61
+ value = value.decode("utf-8")
62
+
63
+ return value
64
+
65
+
66
+ _HTML5_REPLACEMENTS = {
67
+ u"\u0022": u"%22",
68
+ # Replace "\" with "\\".
69
+ u"\u005C": u"\u005C\u005C",
70
+ }
71
+
72
+ # All control characters from 0x00 to 0x1F *except* 0x1B.
73
+ _HTML5_REPLACEMENTS.update(
74
+ {
75
+ six.unichr(cc): u"%{:02X}".format(cc)
76
+ for cc in range(0x00, 0x1F + 1)
77
+ if cc not in (0x1B,)
78
+ }
79
+ )
80
+
81
+
82
+ def _replace_multiple(value, needles_and_replacements):
83
+ def replacer(match):
84
+ return needles_and_replacements[match.group(0)]
85
+
86
+ pattern = re.compile(
87
+ r"|".join([re.escape(needle) for needle in needles_and_replacements.keys()])
88
+ )
89
+
90
+ result = pattern.sub(replacer, value)
91
+
92
+ return result
93
+
94
+
95
+ def format_header_param_html5(name, value):
96
+ """
97
+ Helper function to format and quote a single header parameter using the
98
+ HTML5 strategy.
99
+
100
+ Particularly useful for header parameters which might contain
101
+ non-ASCII values, like file names. This follows the `HTML5 Working Draft
102
+ Section 4.10.22.7`_ and matches the behavior of curl and modern browsers.
103
+
104
+ .. _HTML5 Working Draft Section 4.10.22.7:
105
+ https://w3c.github.io/html/sec-forms.html#multipart-form-data
106
+
107
+ :param name:
108
+ The name of the parameter, a string expected to be ASCII only.
109
+ :param value:
110
+ The value of the parameter, provided as ``bytes`` or `str``.
111
+ :ret:
112
+ A unicode string, stripped of troublesome characters.
113
+ """
114
+ if isinstance(value, six.binary_type):
115
+ value = value.decode("utf-8")
116
+
117
+ value = _replace_multiple(value, _HTML5_REPLACEMENTS)
118
+
119
+ return u'%s="%s"' % (name, value)
120
+
121
+
122
+ # For backwards-compatibility.
123
+ format_header_param = format_header_param_html5
124
+
125
+
126
+ class RequestField(object):
127
+ """
128
+ A data container for request body parameters.
129
+
130
+ :param name:
131
+ The name of this request field. Must be unicode.
132
+ :param data:
133
+ The data/value body.
134
+ :param filename:
135
+ An optional filename of the request field. Must be unicode.
136
+ :param headers:
137
+ An optional dict-like object of headers to initially use for the field.
138
+ :param header_formatter:
139
+ An optional callable that is used to encode and format the headers. By
140
+ default, this is :func:`format_header_param_html5`.
141
+ """
142
+
143
+ def __init__(
144
+ self,
145
+ name,
146
+ data,
147
+ filename=None,
148
+ headers=None,
149
+ header_formatter=format_header_param_html5,
150
+ ):
151
+ self._name = name
152
+ self._filename = filename
153
+ self.data = data
154
+ self.headers = {}
155
+ if headers:
156
+ self.headers = dict(headers)
157
+ self.header_formatter = header_formatter
158
+
159
+ @classmethod
160
+ def from_tuples(cls, fieldname, value, header_formatter=format_header_param_html5):
161
+ """
162
+ A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters.
163
+
164
+ Supports constructing :class:`~urllib3.fields.RequestField` from
165
+ parameter of key/value strings AND key/filetuple. A filetuple is a
166
+ (filename, data, MIME type) tuple where the MIME type is optional.
167
+ For example::
168
+
169
+ 'foo': 'bar',
170
+ 'fakefile': ('foofile.txt', 'contents of foofile'),
171
+ 'realfile': ('barfile.txt', open('realfile').read()),
172
+ 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'),
173
+ 'nonamefile': 'contents of nonamefile field',
174
+
175
+ Field names and filenames must be unicode.
176
+ """
177
+ if isinstance(value, tuple):
178
+ if len(value) == 3:
179
+ filename, data, content_type = value
180
+ else:
181
+ filename, data = value
182
+ content_type = guess_content_type(filename)
183
+ else:
184
+ filename = None
185
+ content_type = None
186
+ data = value
187
+
188
+ request_param = cls(
189
+ fieldname, data, filename=filename, header_formatter=header_formatter
190
+ )
191
+ request_param.make_multipart(content_type=content_type)
192
+
193
+ return request_param
194
+
195
+ def _render_part(self, name, value):
196
+ """
197
+ Overridable helper function to format a single header parameter. By
198
+ default, this calls ``self.header_formatter``.
199
+
200
+ :param name:
201
+ The name of the parameter, a string expected to be ASCII only.
202
+ :param value:
203
+ The value of the parameter, provided as a unicode string.
204
+ """
205
+
206
+ return self.header_formatter(name, value)
207
+
208
+ def _render_parts(self, header_parts):
209
+ """
210
+ Helper function to format and quote a single header.
211
+
212
+ Useful for single headers that are composed of multiple items. E.g.,
213
+ 'Content-Disposition' fields.
214
+
215
+ :param header_parts:
216
+ A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format
217
+ as `k1="v1"; k2="v2"; ...`.
218
+ """
219
+ parts = []
220
+ iterable = header_parts
221
+ if isinstance(header_parts, dict):
222
+ iterable = header_parts.items()
223
+
224
+ for name, value in iterable:
225
+ if value is not None:
226
+ parts.append(self._render_part(name, value))
227
+
228
+ return u"; ".join(parts)
229
+
230
+ def render_headers(self):
231
+ """
232
+ Renders the headers for this request field.
233
+ """
234
+ lines = []
235
+
236
+ sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"]
237
+ for sort_key in sort_keys:
238
+ if self.headers.get(sort_key, False):
239
+ lines.append(u"%s: %s" % (sort_key, self.headers[sort_key]))
240
+
241
+ for header_name, header_value in self.headers.items():
242
+ if header_name not in sort_keys:
243
+ if header_value:
244
+ lines.append(u"%s: %s" % (header_name, header_value))
245
+
246
+ lines.append(u"\r\n")
247
+ return u"\r\n".join(lines)
248
+
249
+ def make_multipart(
250
+ self, content_disposition=None, content_type=None, content_location=None
251
+ ):
252
+ """
253
+ Makes this request field into a multipart request field.
254
+
255
+ This method overrides "Content-Disposition", "Content-Type" and
256
+ "Content-Location" headers to the request parameter.
257
+
258
+ :param content_type:
259
+ The 'Content-Type' of the request body.
260
+ :param content_location:
261
+ The 'Content-Location' of the request body.
262
+
263
+ """
264
+ self.headers["Content-Disposition"] = content_disposition or u"form-data"
265
+ self.headers["Content-Disposition"] += u"; ".join(
266
+ [
267
+ u"",
268
+ self._render_parts(
269
+ ((u"name", self._name), (u"filename", self._filename))
270
+ ),
271
+ ]
272
+ )
273
+ self.headers["Content-Type"] = content_type
274
+ self.headers["Content-Location"] = content_location
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/filepost.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import binascii
4
+ import codecs
5
+ import os
6
+ from io import BytesIO
7
+
8
+ from .fields import RequestField
9
+ from .packages import six
10
+ from .packages.six import b
11
+
12
+ writer = codecs.lookup("utf-8")[3]
13
+
14
+
15
+ def choose_boundary():
16
+ """
17
+ Our embarrassingly-simple replacement for mimetools.choose_boundary.
18
+ """
19
+ boundary = binascii.hexlify(os.urandom(16))
20
+ if not six.PY2:
21
+ boundary = boundary.decode("ascii")
22
+ return boundary
23
+
24
+
25
+ def iter_field_objects(fields):
26
+ """
27
+ Iterate over fields.
28
+
29
+ Supports list of (k, v) tuples and dicts, and lists of
30
+ :class:`~urllib3.fields.RequestField`.
31
+
32
+ """
33
+ if isinstance(fields, dict):
34
+ i = six.iteritems(fields)
35
+ else:
36
+ i = iter(fields)
37
+
38
+ for field in i:
39
+ if isinstance(field, RequestField):
40
+ yield field
41
+ else:
42
+ yield RequestField.from_tuples(*field)
43
+
44
+
45
+ def iter_fields(fields):
46
+ """
47
+ .. deprecated:: 1.6
48
+
49
+ Iterate over fields.
50
+
51
+ The addition of :class:`~urllib3.fields.RequestField` makes this function
52
+ obsolete. Instead, use :func:`iter_field_objects`, which returns
53
+ :class:`~urllib3.fields.RequestField` objects.
54
+
55
+ Supports list of (k, v) tuples and dicts.
56
+ """
57
+ if isinstance(fields, dict):
58
+ return ((k, v) for k, v in six.iteritems(fields))
59
+
60
+ return ((k, v) for k, v in fields)
61
+
62
+
63
+ def encode_multipart_formdata(fields, boundary=None):
64
+ """
65
+ Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
66
+
67
+ :param fields:
68
+ Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
69
+
70
+ :param boundary:
71
+ If not specified, then a random boundary will be generated using
72
+ :func:`urllib3.filepost.choose_boundary`.
73
+ """
74
+ body = BytesIO()
75
+ if boundary is None:
76
+ boundary = choose_boundary()
77
+
78
+ for field in iter_field_objects(fields):
79
+ body.write(b("--%s\r\n" % (boundary)))
80
+
81
+ writer(body).write(field.render_headers())
82
+ data = field.data
83
+
84
+ if isinstance(data, int):
85
+ data = str(data) # Backwards compatibility
86
+
87
+ if isinstance(data, six.text_type):
88
+ writer(body).write(data)
89
+ else:
90
+ body.write(data)
91
+
92
+ body.write(b"\r\n")
93
+
94
+ body.write(b("--%s--\r\n" % (boundary)))
95
+
96
+ content_type = str("multipart/form-data; boundary=%s" % boundary)
97
+
98
+ return body.getvalue(), content_type
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__init__.py ADDED
File without changes
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py ADDED
File without changes
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ backports.makefile
4
+ ~~~~~~~~~~~~~~~~~~
5
+
6
+ Backports the Python 3 ``socket.makefile`` method for use with anything that
7
+ wants to create a "fake" socket object.
8
+ """
9
+ import io
10
+ from socket import SocketIO
11
+
12
+
13
+ def backport_makefile(
14
+ self, mode="r", buffering=None, encoding=None, errors=None, newline=None
15
+ ):
16
+ """
17
+ Backport of ``socket.makefile`` from Python 3.5.
18
+ """
19
+ if not set(mode) <= {"r", "w", "b"}:
20
+ raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
21
+ writing = "w" in mode
22
+ reading = "r" in mode or not writing
23
+ assert reading or writing
24
+ binary = "b" in mode
25
+ rawmode = ""
26
+ if reading:
27
+ rawmode += "r"
28
+ if writing:
29
+ rawmode += "w"
30
+ raw = SocketIO(self, rawmode)
31
+ self._makefile_refs += 1
32
+ if buffering is None:
33
+ buffering = -1
34
+ if buffering < 0:
35
+ buffering = io.DEFAULT_BUFFER_SIZE
36
+ if buffering == 0:
37
+ if not binary:
38
+ raise ValueError("unbuffered streams must be binary")
39
+ return raw
40
+ if reading and writing:
41
+ buffer = io.BufferedRWPair(raw, raw, buffering)
42
+ elif reading:
43
+ buffer = io.BufferedReader(raw, buffering)
44
+ else:
45
+ assert writing
46
+ buffer = io.BufferedWriter(raw, buffering)
47
+ if binary:
48
+ return buffer
49
+ text = io.TextIOWrapper(buffer, encoding, errors, newline)
50
+ text.mode = mode
51
+ return text
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ backports.weakref_finalize
4
+ ~~~~~~~~~~~~~~~~~~
5
+
6
+ Backports the Python 3 ``weakref.finalize`` method.
7
+ """
8
+ from __future__ import absolute_import
9
+
10
+ import itertools
11
+ import sys
12
+ from weakref import ref
13
+
14
+ __all__ = ["weakref_finalize"]
15
+
16
+
17
+ class weakref_finalize(object):
18
+ """Class for finalization of weakrefable objects
19
+ finalize(obj, func, *args, **kwargs) returns a callable finalizer
20
+ object which will be called when obj is garbage collected. The
21
+ first time the finalizer is called it evaluates func(*arg, **kwargs)
22
+ and returns the result. After this the finalizer is dead, and
23
+ calling it just returns None.
24
+ When the program exits any remaining finalizers for which the
25
+ atexit attribute is true will be run in reverse order of creation.
26
+ By default atexit is true.
27
+ """
28
+
29
+ # Finalizer objects don't have any state of their own. They are
30
+ # just used as keys to lookup _Info objects in the registry. This
31
+ # ensures that they cannot be part of a ref-cycle.
32
+
33
+ __slots__ = ()
34
+ _registry = {}
35
+ _shutdown = False
36
+ _index_iter = itertools.count()
37
+ _dirty = False
38
+ _registered_with_atexit = False
39
+
40
+ class _Info(object):
41
+ __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index")
42
+
43
+ def __init__(self, obj, func, *args, **kwargs):
44
+ if not self._registered_with_atexit:
45
+ # We may register the exit function more than once because
46
+ # of a thread race, but that is harmless
47
+ import atexit
48
+
49
+ atexit.register(self._exitfunc)
50
+ weakref_finalize._registered_with_atexit = True
51
+ info = self._Info()
52
+ info.weakref = ref(obj, self)
53
+ info.func = func
54
+ info.args = args
55
+ info.kwargs = kwargs or None
56
+ info.atexit = True
57
+ info.index = next(self._index_iter)
58
+ self._registry[self] = info
59
+ weakref_finalize._dirty = True
60
+
61
+ def __call__(self, _=None):
62
+ """If alive then mark as dead and return func(*args, **kwargs);
63
+ otherwise return None"""
64
+ info = self._registry.pop(self, None)
65
+ if info and not self._shutdown:
66
+ return info.func(*info.args, **(info.kwargs or {}))
67
+
68
+ def detach(self):
69
+ """If alive then mark as dead and return (obj, func, args, kwargs);
70
+ otherwise return None"""
71
+ info = self._registry.get(self)
72
+ obj = info and info.weakref()
73
+ if obj is not None and self._registry.pop(self, None):
74
+ return (obj, info.func, info.args, info.kwargs or {})
75
+
76
+ def peek(self):
77
+ """If alive then return (obj, func, args, kwargs);
78
+ otherwise return None"""
79
+ info = self._registry.get(self)
80
+ obj = info and info.weakref()
81
+ if obj is not None:
82
+ return (obj, info.func, info.args, info.kwargs or {})
83
+
84
+ @property
85
+ def alive(self):
86
+ """Whether finalizer is alive"""
87
+ return self in self._registry
88
+
89
+ @property
90
+ def atexit(self):
91
+ """Whether finalizer should be called at exit"""
92
+ info = self._registry.get(self)
93
+ return bool(info) and info.atexit
94
+
95
+ @atexit.setter
96
+ def atexit(self, value):
97
+ info = self._registry.get(self)
98
+ if info:
99
+ info.atexit = bool(value)
100
+
101
+ def __repr__(self):
102
+ info = self._registry.get(self)
103
+ obj = info and info.weakref()
104
+ if obj is None:
105
+ return "<%s object at %#x; dead>" % (type(self).__name__, id(self))
106
+ else:
107
+ return "<%s object at %#x; for %r at %#x>" % (
108
+ type(self).__name__,
109
+ id(self),
110
+ type(obj).__name__,
111
+ id(obj),
112
+ )
113
+
114
+ @classmethod
115
+ def _select_for_exit(cls):
116
+ # Return live finalizers marked for exit, oldest first
117
+ L = [(f, i) for (f, i) in cls._registry.items() if i.atexit]
118
+ L.sort(key=lambda item: item[1].index)
119
+ return [f for (f, i) in L]
120
+
121
+ @classmethod
122
+ def _exitfunc(cls):
123
+ # At shutdown invoke finalizers for which atexit is true.
124
+ # This is called once all other non-daemonic threads have been
125
+ # joined.
126
+ reenable_gc = False
127
+ try:
128
+ if cls._registry:
129
+ import gc
130
+
131
+ if gc.isenabled():
132
+ reenable_gc = True
133
+ gc.disable()
134
+ pending = None
135
+ while True:
136
+ if pending is None or weakref_finalize._dirty:
137
+ pending = cls._select_for_exit()
138
+ weakref_finalize._dirty = False
139
+ if not pending:
140
+ break
141
+ f = pending.pop()
142
+ try:
143
+ # gc is disabled, so (assuming no daemonic
144
+ # threads) the following is the only line in
145
+ # this function which might trigger creation
146
+ # of a new finalizer
147
+ f()
148
+ except Exception:
149
+ sys.excepthook(*sys.exc_info())
150
+ assert f not in cls._registry
151
+ finally:
152
+ # prevent any more finalizers from executing during shutdown
153
+ weakref_finalize._shutdown = True
154
+ if reenable_gc:
155
+ gc.enable()
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/six.py ADDED
@@ -0,0 +1,1076 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2010-2020 Benjamin Peterson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ """Utilities for writing code that runs on Python 2 and 3"""
22
+
23
+ from __future__ import absolute_import
24
+
25
+ import functools
26
+ import itertools
27
+ import operator
28
+ import sys
29
+ import types
30
+
31
+ __author__ = "Benjamin Peterson <benjamin@python.org>"
32
+ __version__ = "1.16.0"
33
+
34
+
35
+ # Useful for very coarse version differentiation.
36
+ PY2 = sys.version_info[0] == 2
37
+ PY3 = sys.version_info[0] == 3
38
+ PY34 = sys.version_info[0:2] >= (3, 4)
39
+
40
+ if PY3:
41
+ string_types = (str,)
42
+ integer_types = (int,)
43
+ class_types = (type,)
44
+ text_type = str
45
+ binary_type = bytes
46
+
47
+ MAXSIZE = sys.maxsize
48
+ else:
49
+ string_types = (basestring,)
50
+ integer_types = (int, long)
51
+ class_types = (type, types.ClassType)
52
+ text_type = unicode
53
+ binary_type = str
54
+
55
+ if sys.platform.startswith("java"):
56
+ # Jython always uses 32 bits.
57
+ MAXSIZE = int((1 << 31) - 1)
58
+ else:
59
+ # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
60
+ class X(object):
61
+ def __len__(self):
62
+ return 1 << 31
63
+
64
+ try:
65
+ len(X())
66
+ except OverflowError:
67
+ # 32-bit
68
+ MAXSIZE = int((1 << 31) - 1)
69
+ else:
70
+ # 64-bit
71
+ MAXSIZE = int((1 << 63) - 1)
72
+ del X
73
+
74
+ if PY34:
75
+ from importlib.util import spec_from_loader
76
+ else:
77
+ spec_from_loader = None
78
+
79
+
80
+ def _add_doc(func, doc):
81
+ """Add documentation to a function."""
82
+ func.__doc__ = doc
83
+
84
+
85
+ def _import_module(name):
86
+ """Import module, returning the module after the last dot."""
87
+ __import__(name)
88
+ return sys.modules[name]
89
+
90
+
91
+ class _LazyDescr(object):
92
+ def __init__(self, name):
93
+ self.name = name
94
+
95
+ def __get__(self, obj, tp):
96
+ result = self._resolve()
97
+ setattr(obj, self.name, result) # Invokes __set__.
98
+ try:
99
+ # This is a bit ugly, but it avoids running this again by
100
+ # removing this descriptor.
101
+ delattr(obj.__class__, self.name)
102
+ except AttributeError:
103
+ pass
104
+ return result
105
+
106
+
107
+ class MovedModule(_LazyDescr):
108
+ def __init__(self, name, old, new=None):
109
+ super(MovedModule, self).__init__(name)
110
+ if PY3:
111
+ if new is None:
112
+ new = name
113
+ self.mod = new
114
+ else:
115
+ self.mod = old
116
+
117
+ def _resolve(self):
118
+ return _import_module(self.mod)
119
+
120
+ def __getattr__(self, attr):
121
+ _module = self._resolve()
122
+ value = getattr(_module, attr)
123
+ setattr(self, attr, value)
124
+ return value
125
+
126
+
127
+ class _LazyModule(types.ModuleType):
128
+ def __init__(self, name):
129
+ super(_LazyModule, self).__init__(name)
130
+ self.__doc__ = self.__class__.__doc__
131
+
132
+ def __dir__(self):
133
+ attrs = ["__doc__", "__name__"]
134
+ attrs += [attr.name for attr in self._moved_attributes]
135
+ return attrs
136
+
137
+ # Subclasses should override this
138
+ _moved_attributes = []
139
+
140
+
141
+ class MovedAttribute(_LazyDescr):
142
+ def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
143
+ super(MovedAttribute, self).__init__(name)
144
+ if PY3:
145
+ if new_mod is None:
146
+ new_mod = name
147
+ self.mod = new_mod
148
+ if new_attr is None:
149
+ if old_attr is None:
150
+ new_attr = name
151
+ else:
152
+ new_attr = old_attr
153
+ self.attr = new_attr
154
+ else:
155
+ self.mod = old_mod
156
+ if old_attr is None:
157
+ old_attr = name
158
+ self.attr = old_attr
159
+
160
+ def _resolve(self):
161
+ module = _import_module(self.mod)
162
+ return getattr(module, self.attr)
163
+
164
+
165
+ class _SixMetaPathImporter(object):
166
+
167
+ """
168
+ A meta path importer to import six.moves and its submodules.
169
+
170
+ This class implements a PEP302 finder and loader. It should be compatible
171
+ with Python 2.5 and all existing versions of Python3
172
+ """
173
+
174
+ def __init__(self, six_module_name):
175
+ self.name = six_module_name
176
+ self.known_modules = {}
177
+
178
+ def _add_module(self, mod, *fullnames):
179
+ for fullname in fullnames:
180
+ self.known_modules[self.name + "." + fullname] = mod
181
+
182
+ def _get_module(self, fullname):
183
+ return self.known_modules[self.name + "." + fullname]
184
+
185
+ def find_module(self, fullname, path=None):
186
+ if fullname in self.known_modules:
187
+ return self
188
+ return None
189
+
190
+ def find_spec(self, fullname, path, target=None):
191
+ if fullname in self.known_modules:
192
+ return spec_from_loader(fullname, self)
193
+ return None
194
+
195
+ def __get_module(self, fullname):
196
+ try:
197
+ return self.known_modules[fullname]
198
+ except KeyError:
199
+ raise ImportError("This loader does not know module " + fullname)
200
+
201
+ def load_module(self, fullname):
202
+ try:
203
+ # in case of a reload
204
+ return sys.modules[fullname]
205
+ except KeyError:
206
+ pass
207
+ mod = self.__get_module(fullname)
208
+ if isinstance(mod, MovedModule):
209
+ mod = mod._resolve()
210
+ else:
211
+ mod.__loader__ = self
212
+ sys.modules[fullname] = mod
213
+ return mod
214
+
215
+ def is_package(self, fullname):
216
+ """
217
+ Return true, if the named module is a package.
218
+
219
+ We need this method to get correct spec objects with
220
+ Python 3.4 (see PEP451)
221
+ """
222
+ return hasattr(self.__get_module(fullname), "__path__")
223
+
224
+ def get_code(self, fullname):
225
+ """Return None
226
+
227
+ Required, if is_package is implemented"""
228
+ self.__get_module(fullname) # eventually raises ImportError
229
+ return None
230
+
231
+ get_source = get_code # same as get_code
232
+
233
+ def create_module(self, spec):
234
+ return self.load_module(spec.name)
235
+
236
+ def exec_module(self, module):
237
+ pass
238
+
239
+
240
+ _importer = _SixMetaPathImporter(__name__)
241
+
242
+
243
+ class _MovedItems(_LazyModule):
244
+
245
+ """Lazy loading of moved objects"""
246
+
247
+ __path__ = [] # mark as package
248
+
249
+
250
+ _moved_attributes = [
251
+ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
252
+ MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
253
+ MovedAttribute(
254
+ "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"
255
+ ),
256
+ MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
257
+ MovedAttribute("intern", "__builtin__", "sys"),
258
+ MovedAttribute("map", "itertools", "builtins", "imap", "map"),
259
+ MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
260
+ MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
261
+ MovedAttribute("getoutput", "commands", "subprocess"),
262
+ MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
263
+ MovedAttribute(
264
+ "reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"
265
+ ),
266
+ MovedAttribute("reduce", "__builtin__", "functools"),
267
+ MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
268
+ MovedAttribute("StringIO", "StringIO", "io"),
269
+ MovedAttribute("UserDict", "UserDict", "collections"),
270
+ MovedAttribute("UserList", "UserList", "collections"),
271
+ MovedAttribute("UserString", "UserString", "collections"),
272
+ MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
273
+ MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
274
+ MovedAttribute(
275
+ "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"
276
+ ),
277
+ MovedModule("builtins", "__builtin__"),
278
+ MovedModule("configparser", "ConfigParser"),
279
+ MovedModule(
280
+ "collections_abc",
281
+ "collections",
282
+ "collections.abc" if sys.version_info >= (3, 3) else "collections",
283
+ ),
284
+ MovedModule("copyreg", "copy_reg"),
285
+ MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
286
+ MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
287
+ MovedModule(
288
+ "_dummy_thread",
289
+ "dummy_thread",
290
+ "_dummy_thread" if sys.version_info < (3, 9) else "_thread",
291
+ ),
292
+ MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
293
+ MovedModule("http_cookies", "Cookie", "http.cookies"),
294
+ MovedModule("html_entities", "htmlentitydefs", "html.entities"),
295
+ MovedModule("html_parser", "HTMLParser", "html.parser"),
296
+ MovedModule("http_client", "httplib", "http.client"),
297
+ MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
298
+ MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
299
+ MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
300
+ MovedModule(
301
+ "email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"
302
+ ),
303
+ MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
304
+ MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
305
+ MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
306
+ MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
307
+ MovedModule("cPickle", "cPickle", "pickle"),
308
+ MovedModule("queue", "Queue"),
309
+ MovedModule("reprlib", "repr"),
310
+ MovedModule("socketserver", "SocketServer"),
311
+ MovedModule("_thread", "thread", "_thread"),
312
+ MovedModule("tkinter", "Tkinter"),
313
+ MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
314
+ MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
315
+ MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
316
+ MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
317
+ MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
318
+ MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
319
+ MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
320
+ MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
321
+ MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"),
322
+ MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"),
323
+ MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
324
+ MovedModule("tkinter_font", "tkFont", "tkinter.font"),
325
+ MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
326
+ MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"),
327
+ MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
328
+ MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
329
+ MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
330
+ MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
331
+ MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
332
+ MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
333
+ ]
334
+ # Add windows specific modules.
335
+ if sys.platform == "win32":
336
+ _moved_attributes += [
337
+ MovedModule("winreg", "_winreg"),
338
+ ]
339
+
340
+ for attr in _moved_attributes:
341
+ setattr(_MovedItems, attr.name, attr)
342
+ if isinstance(attr, MovedModule):
343
+ _importer._add_module(attr, "moves." + attr.name)
344
+ del attr
345
+
346
+ _MovedItems._moved_attributes = _moved_attributes
347
+
348
+ moves = _MovedItems(__name__ + ".moves")
349
+ _importer._add_module(moves, "moves")
350
+
351
+
352
+ class Module_six_moves_urllib_parse(_LazyModule):
353
+
354
+ """Lazy loading of moved objects in six.moves.urllib_parse"""
355
+
356
+
357
+ _urllib_parse_moved_attributes = [
358
+ MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
359
+ MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
360
+ MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
361
+ MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
362
+ MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
363
+ MovedAttribute("urljoin", "urlparse", "urllib.parse"),
364
+ MovedAttribute("urlparse", "urlparse", "urllib.parse"),
365
+ MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
366
+ MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
367
+ MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
368
+ MovedAttribute("quote", "urllib", "urllib.parse"),
369
+ MovedAttribute("quote_plus", "urllib", "urllib.parse"),
370
+ MovedAttribute("unquote", "urllib", "urllib.parse"),
371
+ MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
372
+ MovedAttribute(
373
+ "unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"
374
+ ),
375
+ MovedAttribute("urlencode", "urllib", "urllib.parse"),
376
+ MovedAttribute("splitquery", "urllib", "urllib.parse"),
377
+ MovedAttribute("splittag", "urllib", "urllib.parse"),
378
+ MovedAttribute("splituser", "urllib", "urllib.parse"),
379
+ MovedAttribute("splitvalue", "urllib", "urllib.parse"),
380
+ MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
381
+ MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
382
+ MovedAttribute("uses_params", "urlparse", "urllib.parse"),
383
+ MovedAttribute("uses_query", "urlparse", "urllib.parse"),
384
+ MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
385
+ ]
386
+ for attr in _urllib_parse_moved_attributes:
387
+ setattr(Module_six_moves_urllib_parse, attr.name, attr)
388
+ del attr
389
+
390
+ Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
391
+
392
+ _importer._add_module(
393
+ Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
394
+ "moves.urllib_parse",
395
+ "moves.urllib.parse",
396
+ )
397
+
398
+
399
+ class Module_six_moves_urllib_error(_LazyModule):
400
+
401
+ """Lazy loading of moved objects in six.moves.urllib_error"""
402
+
403
+
404
+ _urllib_error_moved_attributes = [
405
+ MovedAttribute("URLError", "urllib2", "urllib.error"),
406
+ MovedAttribute("HTTPError", "urllib2", "urllib.error"),
407
+ MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
408
+ ]
409
+ for attr in _urllib_error_moved_attributes:
410
+ setattr(Module_six_moves_urllib_error, attr.name, attr)
411
+ del attr
412
+
413
+ Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
414
+
415
+ _importer._add_module(
416
+ Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
417
+ "moves.urllib_error",
418
+ "moves.urllib.error",
419
+ )
420
+
421
+
422
+ class Module_six_moves_urllib_request(_LazyModule):
423
+
424
+ """Lazy loading of moved objects in six.moves.urllib_request"""
425
+
426
+
427
+ _urllib_request_moved_attributes = [
428
+ MovedAttribute("urlopen", "urllib2", "urllib.request"),
429
+ MovedAttribute("install_opener", "urllib2", "urllib.request"),
430
+ MovedAttribute("build_opener", "urllib2", "urllib.request"),
431
+ MovedAttribute("pathname2url", "urllib", "urllib.request"),
432
+ MovedAttribute("url2pathname", "urllib", "urllib.request"),
433
+ MovedAttribute("getproxies", "urllib", "urllib.request"),
434
+ MovedAttribute("Request", "urllib2", "urllib.request"),
435
+ MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
436
+ MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
437
+ MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
438
+ MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
439
+ MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
440
+ MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
441
+ MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
442
+ MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
443
+ MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
444
+ MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
445
+ MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
446
+ MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
447
+ MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
448
+ MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
449
+ MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
450
+ MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
451
+ MovedAttribute("FileHandler", "urllib2", "urllib.request"),
452
+ MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
453
+ MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
454
+ MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
455
+ MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
456
+ MovedAttribute("urlretrieve", "urllib", "urllib.request"),
457
+ MovedAttribute("urlcleanup", "urllib", "urllib.request"),
458
+ MovedAttribute("URLopener", "urllib", "urllib.request"),
459
+ MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
460
+ MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
461
+ MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
462
+ MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
463
+ ]
464
+ for attr in _urllib_request_moved_attributes:
465
+ setattr(Module_six_moves_urllib_request, attr.name, attr)
466
+ del attr
467
+
468
+ Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
469
+
470
+ _importer._add_module(
471
+ Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
472
+ "moves.urllib_request",
473
+ "moves.urllib.request",
474
+ )
475
+
476
+
477
+ class Module_six_moves_urllib_response(_LazyModule):
478
+
479
+ """Lazy loading of moved objects in six.moves.urllib_response"""
480
+
481
+
482
+ _urllib_response_moved_attributes = [
483
+ MovedAttribute("addbase", "urllib", "urllib.response"),
484
+ MovedAttribute("addclosehook", "urllib", "urllib.response"),
485
+ MovedAttribute("addinfo", "urllib", "urllib.response"),
486
+ MovedAttribute("addinfourl", "urllib", "urllib.response"),
487
+ ]
488
+ for attr in _urllib_response_moved_attributes:
489
+ setattr(Module_six_moves_urllib_response, attr.name, attr)
490
+ del attr
491
+
492
+ Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
493
+
494
+ _importer._add_module(
495
+ Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
496
+ "moves.urllib_response",
497
+ "moves.urllib.response",
498
+ )
499
+
500
+
501
+ class Module_six_moves_urllib_robotparser(_LazyModule):
502
+
503
+ """Lazy loading of moved objects in six.moves.urllib_robotparser"""
504
+
505
+
506
+ _urllib_robotparser_moved_attributes = [
507
+ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
508
+ ]
509
+ for attr in _urllib_robotparser_moved_attributes:
510
+ setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
511
+ del attr
512
+
513
+ Module_six_moves_urllib_robotparser._moved_attributes = (
514
+ _urllib_robotparser_moved_attributes
515
+ )
516
+
517
+ _importer._add_module(
518
+ Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
519
+ "moves.urllib_robotparser",
520
+ "moves.urllib.robotparser",
521
+ )
522
+
523
+
524
+ class Module_six_moves_urllib(types.ModuleType):
525
+
526
+ """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
527
+
528
+ __path__ = [] # mark as package
529
+ parse = _importer._get_module("moves.urllib_parse")
530
+ error = _importer._get_module("moves.urllib_error")
531
+ request = _importer._get_module("moves.urllib_request")
532
+ response = _importer._get_module("moves.urllib_response")
533
+ robotparser = _importer._get_module("moves.urllib_robotparser")
534
+
535
+ def __dir__(self):
536
+ return ["parse", "error", "request", "response", "robotparser"]
537
+
538
+
539
+ _importer._add_module(
540
+ Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib"
541
+ )
542
+
543
+
544
+ def add_move(move):
545
+ """Add an item to six.moves."""
546
+ setattr(_MovedItems, move.name, move)
547
+
548
+
549
+ def remove_move(name):
550
+ """Remove item from six.moves."""
551
+ try:
552
+ delattr(_MovedItems, name)
553
+ except AttributeError:
554
+ try:
555
+ del moves.__dict__[name]
556
+ except KeyError:
557
+ raise AttributeError("no such move, %r" % (name,))
558
+
559
+
560
+ if PY3:
561
+ _meth_func = "__func__"
562
+ _meth_self = "__self__"
563
+
564
+ _func_closure = "__closure__"
565
+ _func_code = "__code__"
566
+ _func_defaults = "__defaults__"
567
+ _func_globals = "__globals__"
568
+ else:
569
+ _meth_func = "im_func"
570
+ _meth_self = "im_self"
571
+
572
+ _func_closure = "func_closure"
573
+ _func_code = "func_code"
574
+ _func_defaults = "func_defaults"
575
+ _func_globals = "func_globals"
576
+
577
+
578
+ try:
579
+ advance_iterator = next
580
+ except NameError:
581
+
582
+ def advance_iterator(it):
583
+ return it.next()
584
+
585
+
586
+ next = advance_iterator
587
+
588
+
589
+ try:
590
+ callable = callable
591
+ except NameError:
592
+
593
+ def callable(obj):
594
+ return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
595
+
596
+
597
+ if PY3:
598
+
599
+ def get_unbound_function(unbound):
600
+ return unbound
601
+
602
+ create_bound_method = types.MethodType
603
+
604
+ def create_unbound_method(func, cls):
605
+ return func
606
+
607
+ Iterator = object
608
+ else:
609
+
610
+ def get_unbound_function(unbound):
611
+ return unbound.im_func
612
+
613
+ def create_bound_method(func, obj):
614
+ return types.MethodType(func, obj, obj.__class__)
615
+
616
+ def create_unbound_method(func, cls):
617
+ return types.MethodType(func, None, cls)
618
+
619
+ class Iterator(object):
620
+ def next(self):
621
+ return type(self).__next__(self)
622
+
623
+ callable = callable
624
+ _add_doc(
625
+ get_unbound_function, """Get the function out of a possibly unbound function"""
626
+ )
627
+
628
+
629
+ get_method_function = operator.attrgetter(_meth_func)
630
+ get_method_self = operator.attrgetter(_meth_self)
631
+ get_function_closure = operator.attrgetter(_func_closure)
632
+ get_function_code = operator.attrgetter(_func_code)
633
+ get_function_defaults = operator.attrgetter(_func_defaults)
634
+ get_function_globals = operator.attrgetter(_func_globals)
635
+
636
+
637
+ if PY3:
638
+
639
+ def iterkeys(d, **kw):
640
+ return iter(d.keys(**kw))
641
+
642
+ def itervalues(d, **kw):
643
+ return iter(d.values(**kw))
644
+
645
+ def iteritems(d, **kw):
646
+ return iter(d.items(**kw))
647
+
648
+ def iterlists(d, **kw):
649
+ return iter(d.lists(**kw))
650
+
651
+ viewkeys = operator.methodcaller("keys")
652
+
653
+ viewvalues = operator.methodcaller("values")
654
+
655
+ viewitems = operator.methodcaller("items")
656
+ else:
657
+
658
+ def iterkeys(d, **kw):
659
+ return d.iterkeys(**kw)
660
+
661
+ def itervalues(d, **kw):
662
+ return d.itervalues(**kw)
663
+
664
+ def iteritems(d, **kw):
665
+ return d.iteritems(**kw)
666
+
667
+ def iterlists(d, **kw):
668
+ return d.iterlists(**kw)
669
+
670
+ viewkeys = operator.methodcaller("viewkeys")
671
+
672
+ viewvalues = operator.methodcaller("viewvalues")
673
+
674
+ viewitems = operator.methodcaller("viewitems")
675
+
676
+ _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
677
+ _add_doc(itervalues, "Return an iterator over the values of a dictionary.")
678
+ _add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.")
679
+ _add_doc(
680
+ iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary."
681
+ )
682
+
683
+
684
+ if PY3:
685
+
686
+ def b(s):
687
+ return s.encode("latin-1")
688
+
689
+ def u(s):
690
+ return s
691
+
692
+ unichr = chr
693
+ import struct
694
+
695
+ int2byte = struct.Struct(">B").pack
696
+ del struct
697
+ byte2int = operator.itemgetter(0)
698
+ indexbytes = operator.getitem
699
+ iterbytes = iter
700
+ import io
701
+
702
+ StringIO = io.StringIO
703
+ BytesIO = io.BytesIO
704
+ del io
705
+ _assertCountEqual = "assertCountEqual"
706
+ if sys.version_info[1] <= 1:
707
+ _assertRaisesRegex = "assertRaisesRegexp"
708
+ _assertRegex = "assertRegexpMatches"
709
+ _assertNotRegex = "assertNotRegexpMatches"
710
+ else:
711
+ _assertRaisesRegex = "assertRaisesRegex"
712
+ _assertRegex = "assertRegex"
713
+ _assertNotRegex = "assertNotRegex"
714
+ else:
715
+
716
+ def b(s):
717
+ return s
718
+
719
+ # Workaround for standalone backslash
720
+
721
+ def u(s):
722
+ return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape")
723
+
724
+ unichr = unichr
725
+ int2byte = chr
726
+
727
+ def byte2int(bs):
728
+ return ord(bs[0])
729
+
730
+ def indexbytes(buf, i):
731
+ return ord(buf[i])
732
+
733
+ iterbytes = functools.partial(itertools.imap, ord)
734
+ import StringIO
735
+
736
+ StringIO = BytesIO = StringIO.StringIO
737
+ _assertCountEqual = "assertItemsEqual"
738
+ _assertRaisesRegex = "assertRaisesRegexp"
739
+ _assertRegex = "assertRegexpMatches"
740
+ _assertNotRegex = "assertNotRegexpMatches"
741
+ _add_doc(b, """Byte literal""")
742
+ _add_doc(u, """Text literal""")
743
+
744
+
745
+ def assertCountEqual(self, *args, **kwargs):
746
+ return getattr(self, _assertCountEqual)(*args, **kwargs)
747
+
748
+
749
+ def assertRaisesRegex(self, *args, **kwargs):
750
+ return getattr(self, _assertRaisesRegex)(*args, **kwargs)
751
+
752
+
753
+ def assertRegex(self, *args, **kwargs):
754
+ return getattr(self, _assertRegex)(*args, **kwargs)
755
+
756
+
757
+ def assertNotRegex(self, *args, **kwargs):
758
+ return getattr(self, _assertNotRegex)(*args, **kwargs)
759
+
760
+
761
+ if PY3:
762
+ exec_ = getattr(moves.builtins, "exec")
763
+
764
+ def reraise(tp, value, tb=None):
765
+ try:
766
+ if value is None:
767
+ value = tp()
768
+ if value.__traceback__ is not tb:
769
+ raise value.with_traceback(tb)
770
+ raise value
771
+ finally:
772
+ value = None
773
+ tb = None
774
+
775
+ else:
776
+
777
+ def exec_(_code_, _globs_=None, _locs_=None):
778
+ """Execute code in a namespace."""
779
+ if _globs_ is None:
780
+ frame = sys._getframe(1)
781
+ _globs_ = frame.f_globals
782
+ if _locs_ is None:
783
+ _locs_ = frame.f_locals
784
+ del frame
785
+ elif _locs_ is None:
786
+ _locs_ = _globs_
787
+ exec ("""exec _code_ in _globs_, _locs_""")
788
+
789
+ exec_(
790
+ """def reraise(tp, value, tb=None):
791
+ try:
792
+ raise tp, value, tb
793
+ finally:
794
+ tb = None
795
+ """
796
+ )
797
+
798
+
799
+ if sys.version_info[:2] > (3,):
800
+ exec_(
801
+ """def raise_from(value, from_value):
802
+ try:
803
+ raise value from from_value
804
+ finally:
805
+ value = None
806
+ """
807
+ )
808
+ else:
809
+
810
+ def raise_from(value, from_value):
811
+ raise value
812
+
813
+
814
+ print_ = getattr(moves.builtins, "print", None)
815
+ if print_ is None:
816
+
817
+ def print_(*args, **kwargs):
818
+ """The new-style print function for Python 2.4 and 2.5."""
819
+ fp = kwargs.pop("file", sys.stdout)
820
+ if fp is None:
821
+ return
822
+
823
+ def write(data):
824
+ if not isinstance(data, basestring):
825
+ data = str(data)
826
+ # If the file has an encoding, encode unicode with it.
827
+ if (
828
+ isinstance(fp, file)
829
+ and isinstance(data, unicode)
830
+ and fp.encoding is not None
831
+ ):
832
+ errors = getattr(fp, "errors", None)
833
+ if errors is None:
834
+ errors = "strict"
835
+ data = data.encode(fp.encoding, errors)
836
+ fp.write(data)
837
+
838
+ want_unicode = False
839
+ sep = kwargs.pop("sep", None)
840
+ if sep is not None:
841
+ if isinstance(sep, unicode):
842
+ want_unicode = True
843
+ elif not isinstance(sep, str):
844
+ raise TypeError("sep must be None or a string")
845
+ end = kwargs.pop("end", None)
846
+ if end is not None:
847
+ if isinstance(end, unicode):
848
+ want_unicode = True
849
+ elif not isinstance(end, str):
850
+ raise TypeError("end must be None or a string")
851
+ if kwargs:
852
+ raise TypeError("invalid keyword arguments to print()")
853
+ if not want_unicode:
854
+ for arg in args:
855
+ if isinstance(arg, unicode):
856
+ want_unicode = True
857
+ break
858
+ if want_unicode:
859
+ newline = unicode("\n")
860
+ space = unicode(" ")
861
+ else:
862
+ newline = "\n"
863
+ space = " "
864
+ if sep is None:
865
+ sep = space
866
+ if end is None:
867
+ end = newline
868
+ for i, arg in enumerate(args):
869
+ if i:
870
+ write(sep)
871
+ write(arg)
872
+ write(end)
873
+
874
+
875
+ if sys.version_info[:2] < (3, 3):
876
+ _print = print_
877
+
878
+ def print_(*args, **kwargs):
879
+ fp = kwargs.get("file", sys.stdout)
880
+ flush = kwargs.pop("flush", False)
881
+ _print(*args, **kwargs)
882
+ if flush and fp is not None:
883
+ fp.flush()
884
+
885
+
886
+ _add_doc(reraise, """Reraise an exception.""")
887
+
888
+ if sys.version_info[0:2] < (3, 4):
889
+ # This does exactly the same what the :func:`py3:functools.update_wrapper`
890
+ # function does on Python versions after 3.2. It sets the ``__wrapped__``
891
+ # attribute on ``wrapper`` object and it doesn't raise an error if any of
892
+ # the attributes mentioned in ``assigned`` and ``updated`` are missing on
893
+ # ``wrapped`` object.
894
+ def _update_wrapper(
895
+ wrapper,
896
+ wrapped,
897
+ assigned=functools.WRAPPER_ASSIGNMENTS,
898
+ updated=functools.WRAPPER_UPDATES,
899
+ ):
900
+ for attr in assigned:
901
+ try:
902
+ value = getattr(wrapped, attr)
903
+ except AttributeError:
904
+ continue
905
+ else:
906
+ setattr(wrapper, attr, value)
907
+ for attr in updated:
908
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
909
+ wrapper.__wrapped__ = wrapped
910
+ return wrapper
911
+
912
+ _update_wrapper.__doc__ = functools.update_wrapper.__doc__
913
+
914
+ def wraps(
915
+ wrapped,
916
+ assigned=functools.WRAPPER_ASSIGNMENTS,
917
+ updated=functools.WRAPPER_UPDATES,
918
+ ):
919
+ return functools.partial(
920
+ _update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated
921
+ )
922
+
923
+ wraps.__doc__ = functools.wraps.__doc__
924
+
925
+ else:
926
+ wraps = functools.wraps
927
+
928
+
929
+ def with_metaclass(meta, *bases):
930
+ """Create a base class with a metaclass."""
931
+ # This requires a bit of explanation: the basic idea is to make a dummy
932
+ # metaclass for one level of class instantiation that replaces itself with
933
+ # the actual metaclass.
934
+ class metaclass(type):
935
+ def __new__(cls, name, this_bases, d):
936
+ if sys.version_info[:2] >= (3, 7):
937
+ # This version introduced PEP 560 that requires a bit
938
+ # of extra care (we mimic what is done by __build_class__).
939
+ resolved_bases = types.resolve_bases(bases)
940
+ if resolved_bases is not bases:
941
+ d["__orig_bases__"] = bases
942
+ else:
943
+ resolved_bases = bases
944
+ return meta(name, resolved_bases, d)
945
+
946
+ @classmethod
947
+ def __prepare__(cls, name, this_bases):
948
+ return meta.__prepare__(name, bases)
949
+
950
+ return type.__new__(metaclass, "temporary_class", (), {})
951
+
952
+
953
+ def add_metaclass(metaclass):
954
+ """Class decorator for creating a class with a metaclass."""
955
+
956
+ def wrapper(cls):
957
+ orig_vars = cls.__dict__.copy()
958
+ slots = orig_vars.get("__slots__")
959
+ if slots is not None:
960
+ if isinstance(slots, str):
961
+ slots = [slots]
962
+ for slots_var in slots:
963
+ orig_vars.pop(slots_var)
964
+ orig_vars.pop("__dict__", None)
965
+ orig_vars.pop("__weakref__", None)
966
+ if hasattr(cls, "__qualname__"):
967
+ orig_vars["__qualname__"] = cls.__qualname__
968
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
969
+
970
+ return wrapper
971
+
972
+
973
+ def ensure_binary(s, encoding="utf-8", errors="strict"):
974
+ """Coerce **s** to six.binary_type.
975
+
976
+ For Python 2:
977
+ - `unicode` -> encoded to `str`
978
+ - `str` -> `str`
979
+
980
+ For Python 3:
981
+ - `str` -> encoded to `bytes`
982
+ - `bytes` -> `bytes`
983
+ """
984
+ if isinstance(s, binary_type):
985
+ return s
986
+ if isinstance(s, text_type):
987
+ return s.encode(encoding, errors)
988
+ raise TypeError("not expecting type '%s'" % type(s))
989
+
990
+
991
+ def ensure_str(s, encoding="utf-8", errors="strict"):
992
+ """Coerce *s* to `str`.
993
+
994
+ For Python 2:
995
+ - `unicode` -> encoded to `str`
996
+ - `str` -> `str`
997
+
998
+ For Python 3:
999
+ - `str` -> `str`
1000
+ - `bytes` -> decoded to `str`
1001
+ """
1002
+ # Optimization: Fast return for the common case.
1003
+ if type(s) is str:
1004
+ return s
1005
+ if PY2 and isinstance(s, text_type):
1006
+ return s.encode(encoding, errors)
1007
+ elif PY3 and isinstance(s, binary_type):
1008
+ return s.decode(encoding, errors)
1009
+ elif not isinstance(s, (text_type, binary_type)):
1010
+ raise TypeError("not expecting type '%s'" % type(s))
1011
+ return s
1012
+
1013
+
1014
+ def ensure_text(s, encoding="utf-8", errors="strict"):
1015
+ """Coerce *s* to six.text_type.
1016
+
1017
+ For Python 2:
1018
+ - `unicode` -> `unicode`
1019
+ - `str` -> `unicode`
1020
+
1021
+ For Python 3:
1022
+ - `str` -> `str`
1023
+ - `bytes` -> decoded to `str`
1024
+ """
1025
+ if isinstance(s, binary_type):
1026
+ return s.decode(encoding, errors)
1027
+ elif isinstance(s, text_type):
1028
+ return s
1029
+ else:
1030
+ raise TypeError("not expecting type '%s'" % type(s))
1031
+
1032
+
1033
+ def python_2_unicode_compatible(klass):
1034
+ """
1035
+ A class decorator that defines __unicode__ and __str__ methods under Python 2.
1036
+ Under Python 3 it does nothing.
1037
+
1038
+ To support Python 2 and 3 with a single code base, define a __str__ method
1039
+ returning text and apply this decorator to the class.
1040
+ """
1041
+ if PY2:
1042
+ if "__str__" not in klass.__dict__:
1043
+ raise ValueError(
1044
+ "@python_2_unicode_compatible cannot be applied "
1045
+ "to %s because it doesn't define __str__()." % klass.__name__
1046
+ )
1047
+ klass.__unicode__ = klass.__str__
1048
+ klass.__str__ = lambda self: self.__unicode__().encode("utf-8")
1049
+ return klass
1050
+
1051
+
1052
+ # Complete the moves implementation.
1053
+ # This code is at the end of this module to speed up module loading.
1054
+ # Turn this module into a package.
1055
+ __path__ = [] # required for PEP 302 and PEP 451
1056
+ __package__ = __name__ # see PEP 366 @ReservedAssignment
1057
+ if globals().get("__spec__") is not None:
1058
+ __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
1059
+ # Remove other six meta path importers, since they cause problems. This can
1060
+ # happen if six is removed from sys.modules and then reloaded. (Setuptools does
1061
+ # this for some reason.)
1062
+ if sys.meta_path:
1063
+ for i, importer in enumerate(sys.meta_path):
1064
+ # Here's some real nastiness: Another "instance" of the six module might
1065
+ # be floating around. Therefore, we can't use isinstance() to check for
1066
+ # the six meta path importer, since the other six instance will have
1067
+ # inserted an importer with different class.
1068
+ if (
1069
+ type(importer).__name__ == "_SixMetaPathImporter"
1070
+ and importer.name == __name__
1071
+ ):
1072
+ del sys.meta_path[i]
1073
+ break
1074
+ del i, importer
1075
+ # Finally, add the importer to the meta path import hook.
1076
+ sys.meta_path.append(_importer)
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/poolmanager.py ADDED
@@ -0,0 +1,556 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import collections
4
+ import functools
5
+ import logging
6
+
7
+ from ._collections import HTTPHeaderDict, RecentlyUsedContainer
8
+ from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
9
+ from .exceptions import (
10
+ LocationValueError,
11
+ MaxRetryError,
12
+ ProxySchemeUnknown,
13
+ ProxySchemeUnsupported,
14
+ URLSchemeUnknown,
15
+ )
16
+ from .packages import six
17
+ from .packages.six.moves.urllib.parse import urljoin
18
+ from .request import RequestMethods
19
+ from .util.proxy import connection_requires_http_tunnel
20
+ from .util.retry import Retry
21
+ from .util.url import parse_url
22
+
23
+ __all__ = ["PoolManager", "ProxyManager", "proxy_from_url"]
24
+
25
+
26
+ log = logging.getLogger(__name__)
27
+
28
+ SSL_KEYWORDS = (
29
+ "key_file",
30
+ "cert_file",
31
+ "cert_reqs",
32
+ "ca_certs",
33
+ "ssl_version",
34
+ "ca_cert_dir",
35
+ "ssl_context",
36
+ "key_password",
37
+ "server_hostname",
38
+ )
39
+
40
+ # All known keyword arguments that could be provided to the pool manager, its
41
+ # pools, or the underlying connections. This is used to construct a pool key.
42
+ _key_fields = (
43
+ "key_scheme", # str
44
+ "key_host", # str
45
+ "key_port", # int
46
+ "key_timeout", # int or float or Timeout
47
+ "key_retries", # int or Retry
48
+ "key_strict", # bool
49
+ "key_block", # bool
50
+ "key_source_address", # str
51
+ "key_key_file", # str
52
+ "key_key_password", # str
53
+ "key_cert_file", # str
54
+ "key_cert_reqs", # str
55
+ "key_ca_certs", # str
56
+ "key_ssl_version", # str
57
+ "key_ca_cert_dir", # str
58
+ "key_ssl_context", # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext
59
+ "key_maxsize", # int
60
+ "key_headers", # dict
61
+ "key__proxy", # parsed proxy url
62
+ "key__proxy_headers", # dict
63
+ "key__proxy_config", # class
64
+ "key_socket_options", # list of (level (int), optname (int), value (int or str)) tuples
65
+ "key__socks_options", # dict
66
+ "key_assert_hostname", # bool or string
67
+ "key_assert_fingerprint", # str
68
+ "key_server_hostname", # str
69
+ )
70
+
71
+ #: The namedtuple class used to construct keys for the connection pool.
72
+ #: All custom key schemes should include the fields in this key at a minimum.
73
+ PoolKey = collections.namedtuple("PoolKey", _key_fields)
74
+
75
+ _proxy_config_fields = ("ssl_context", "use_forwarding_for_https")
76
+ ProxyConfig = collections.namedtuple("ProxyConfig", _proxy_config_fields)
77
+
78
+
79
+ def _default_key_normalizer(key_class, request_context):
80
+ """
81
+ Create a pool key out of a request context dictionary.
82
+
83
+ According to RFC 3986, both the scheme and host are case-insensitive.
84
+ Therefore, this function normalizes both before constructing the pool
85
+ key for an HTTPS request. If you wish to change this behaviour, provide
86
+ alternate callables to ``key_fn_by_scheme``.
87
+
88
+ :param key_class:
89
+ The class to use when constructing the key. This should be a namedtuple
90
+ with the ``scheme`` and ``host`` keys at a minimum.
91
+ :type key_class: namedtuple
92
+ :param request_context:
93
+ A dictionary-like object that contain the context for a request.
94
+ :type request_context: dict
95
+
96
+ :return: A namedtuple that can be used as a connection pool key.
97
+ :rtype: PoolKey
98
+ """
99
+ # Since we mutate the dictionary, make a copy first
100
+ context = request_context.copy()
101
+ context["scheme"] = context["scheme"].lower()
102
+ context["host"] = context["host"].lower()
103
+
104
+ # These are both dictionaries and need to be transformed into frozensets
105
+ for key in ("headers", "_proxy_headers", "_socks_options"):
106
+ if key in context and context[key] is not None:
107
+ context[key] = frozenset(context[key].items())
108
+
109
+ # The socket_options key may be a list and needs to be transformed into a
110
+ # tuple.
111
+ socket_opts = context.get("socket_options")
112
+ if socket_opts is not None:
113
+ context["socket_options"] = tuple(socket_opts)
114
+
115
+ # Map the kwargs to the names in the namedtuple - this is necessary since
116
+ # namedtuples can't have fields starting with '_'.
117
+ for key in list(context.keys()):
118
+ context["key_" + key] = context.pop(key)
119
+
120
+ # Default to ``None`` for keys missing from the context
121
+ for field in key_class._fields:
122
+ if field not in context:
123
+ context[field] = None
124
+
125
+ return key_class(**context)
126
+
127
+
128
+ #: A dictionary that maps a scheme to a callable that creates a pool key.
129
+ #: This can be used to alter the way pool keys are constructed, if desired.
130
+ #: Each PoolManager makes a copy of this dictionary so they can be configured
131
+ #: globally here, or individually on the instance.
132
+ key_fn_by_scheme = {
133
+ "http": functools.partial(_default_key_normalizer, PoolKey),
134
+ "https": functools.partial(_default_key_normalizer, PoolKey),
135
+ }
136
+
137
+ pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool}
138
+
139
+
140
+ class PoolManager(RequestMethods):
141
+ """
142
+ Allows for arbitrary requests while transparently keeping track of
143
+ necessary connection pools for you.
144
+
145
+ :param num_pools:
146
+ Number of connection pools to cache before discarding the least
147
+ recently used pool.
148
+
149
+ :param headers:
150
+ Headers to include with all requests, unless other headers are given
151
+ explicitly.
152
+
153
+ :param \\**connection_pool_kw:
154
+ Additional parameters are used to create fresh
155
+ :class:`urllib3.connectionpool.ConnectionPool` instances.
156
+
157
+ Example::
158
+
159
+ >>> manager = PoolManager(num_pools=2)
160
+ >>> r = manager.request('GET', 'http://google.com/')
161
+ >>> r = manager.request('GET', 'http://google.com/mail')
162
+ >>> r = manager.request('GET', 'http://yahoo.com/')
163
+ >>> len(manager.pools)
164
+ 2
165
+
166
+ """
167
+
168
+ proxy = None
169
+ proxy_config = None
170
+
171
+ def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
172
+ RequestMethods.__init__(self, headers)
173
+ if "retries" in connection_pool_kw:
174
+ retries = connection_pool_kw["retries"]
175
+ if not isinstance(retries, Retry):
176
+ # When Retry is initialized, raise_on_redirect is based
177
+ # on a redirect boolean value.
178
+ # But requests made via a pool manager always set
179
+ # redirect to False, and raise_on_redirect always ends
180
+ # up being False consequently.
181
+ # Here we fix the issue by setting raise_on_redirect to
182
+ # a value needed by the pool manager without considering
183
+ # the redirect boolean.
184
+ raise_on_redirect = retries is not False
185
+ retries = Retry.from_int(retries, redirect=False)
186
+ retries.raise_on_redirect = raise_on_redirect
187
+ connection_pool_kw = connection_pool_kw.copy()
188
+ connection_pool_kw["retries"] = retries
189
+ self.connection_pool_kw = connection_pool_kw
190
+ self.pools = RecentlyUsedContainer(num_pools)
191
+
192
+ # Locally set the pool classes and keys so other PoolManagers can
193
+ # override them.
194
+ self.pool_classes_by_scheme = pool_classes_by_scheme
195
+ self.key_fn_by_scheme = key_fn_by_scheme.copy()
196
+
197
+ def __enter__(self):
198
+ return self
199
+
200
+ def __exit__(self, exc_type, exc_val, exc_tb):
201
+ self.clear()
202
+ # Return False to re-raise any potential exceptions
203
+ return False
204
+
205
+ def _new_pool(self, scheme, host, port, request_context=None):
206
+ """
207
+ Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and
208
+ any additional pool keyword arguments.
209
+
210
+ If ``request_context`` is provided, it is provided as keyword arguments
211
+ to the pool class used. This method is used to actually create the
212
+ connection pools handed out by :meth:`connection_from_url` and
213
+ companion methods. It is intended to be overridden for customization.
214
+ """
215
+ pool_cls = self.pool_classes_by_scheme[scheme]
216
+ if request_context is None:
217
+ request_context = self.connection_pool_kw.copy()
218
+
219
+ # Although the context has everything necessary to create the pool,
220
+ # this function has historically only used the scheme, host, and port
221
+ # in the positional args. When an API change is acceptable these can
222
+ # be removed.
223
+ for key in ("scheme", "host", "port"):
224
+ request_context.pop(key, None)
225
+
226
+ if scheme == "http":
227
+ for kw in SSL_KEYWORDS:
228
+ request_context.pop(kw, None)
229
+
230
+ return pool_cls(host, port, **request_context)
231
+
232
+ def clear(self):
233
+ """
234
+ Empty our store of pools and direct them all to close.
235
+
236
+ This will not affect in-flight connections, but they will not be
237
+ re-used after completion.
238
+ """
239
+ self.pools.clear()
240
+
241
+ def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
242
+ """
243
+ Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
244
+
245
+ If ``port`` isn't given, it will be derived from the ``scheme`` using
246
+ ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
247
+ provided, it is merged with the instance's ``connection_pool_kw``
248
+ variable and used to create the new connection pool, if one is
249
+ needed.
250
+ """
251
+
252
+ if not host:
253
+ raise LocationValueError("No host specified.")
254
+
255
+ request_context = self._merge_pool_kwargs(pool_kwargs)
256
+ request_context["scheme"] = scheme or "http"
257
+ if not port:
258
+ port = port_by_scheme.get(request_context["scheme"].lower(), 80)
259
+ request_context["port"] = port
260
+ request_context["host"] = host
261
+
262
+ return self.connection_from_context(request_context)
263
+
264
+ def connection_from_context(self, request_context):
265
+ """
266
+ Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context.
267
+
268
+ ``request_context`` must at least contain the ``scheme`` key and its
269
+ value must be a key in ``key_fn_by_scheme`` instance variable.
270
+ """
271
+ scheme = request_context["scheme"].lower()
272
+ pool_key_constructor = self.key_fn_by_scheme.get(scheme)
273
+ if not pool_key_constructor:
274
+ raise URLSchemeUnknown(scheme)
275
+ pool_key = pool_key_constructor(request_context)
276
+
277
+ return self.connection_from_pool_key(pool_key, request_context=request_context)
278
+
279
+ def connection_from_pool_key(self, pool_key, request_context=None):
280
+ """
281
+ Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key.
282
+
283
+ ``pool_key`` should be a namedtuple that only contains immutable
284
+ objects. At a minimum it must have the ``scheme``, ``host``, and
285
+ ``port`` fields.
286
+ """
287
+ with self.pools.lock:
288
+ # If the scheme, host, or port doesn't match existing open
289
+ # connections, open a new ConnectionPool.
290
+ pool = self.pools.get(pool_key)
291
+ if pool:
292
+ return pool
293
+
294
+ # Make a fresh ConnectionPool of the desired type
295
+ scheme = request_context["scheme"]
296
+ host = request_context["host"]
297
+ port = request_context["port"]
298
+ pool = self._new_pool(scheme, host, port, request_context=request_context)
299
+ self.pools[pool_key] = pool
300
+
301
+ return pool
302
+
303
+ def connection_from_url(self, url, pool_kwargs=None):
304
+ """
305
+ Similar to :func:`urllib3.connectionpool.connection_from_url`.
306
+
307
+ If ``pool_kwargs`` is not provided and a new pool needs to be
308
+ constructed, ``self.connection_pool_kw`` is used to initialize
309
+ the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
310
+ is provided, it is used instead. Note that if a new pool does not
311
+ need to be created for the request, the provided ``pool_kwargs`` are
312
+ not used.
313
+ """
314
+ u = parse_url(url)
315
+ return self.connection_from_host(
316
+ u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs
317
+ )
318
+
319
+ def _merge_pool_kwargs(self, override):
320
+ """
321
+ Merge a dictionary of override values for self.connection_pool_kw.
322
+
323
+ This does not modify self.connection_pool_kw and returns a new dict.
324
+ Any keys in the override dictionary with a value of ``None`` are
325
+ removed from the merged dictionary.
326
+ """
327
+ base_pool_kwargs = self.connection_pool_kw.copy()
328
+ if override:
329
+ for key, value in override.items():
330
+ if value is None:
331
+ try:
332
+ del base_pool_kwargs[key]
333
+ except KeyError:
334
+ pass
335
+ else:
336
+ base_pool_kwargs[key] = value
337
+ return base_pool_kwargs
338
+
339
+ def _proxy_requires_url_absolute_form(self, parsed_url):
340
+ """
341
+ Indicates if the proxy requires the complete destination URL in the
342
+ request. Normally this is only needed when not using an HTTP CONNECT
343
+ tunnel.
344
+ """
345
+ if self.proxy is None:
346
+ return False
347
+
348
+ return not connection_requires_http_tunnel(
349
+ self.proxy, self.proxy_config, parsed_url.scheme
350
+ )
351
+
352
+ def _validate_proxy_scheme_url_selection(self, url_scheme):
353
+ """
354
+ Validates that were not attempting to do TLS in TLS connections on
355
+ Python2 or with unsupported SSL implementations.
356
+ """
357
+ if self.proxy is None or url_scheme != "https":
358
+ return
359
+
360
+ if self.proxy.scheme != "https":
361
+ return
362
+
363
+ if six.PY2 and not self.proxy_config.use_forwarding_for_https:
364
+ raise ProxySchemeUnsupported(
365
+ "Contacting HTTPS destinations through HTTPS proxies "
366
+ "'via CONNECT tunnels' is not supported in Python 2"
367
+ )
368
+
369
+ def urlopen(self, method, url, redirect=True, **kw):
370
+ """
371
+ Same as :meth:`urllib3.HTTPConnectionPool.urlopen`
372
+ with custom cross-host redirect logic and only sends the request-uri
373
+ portion of the ``url``.
374
+
375
+ The given ``url`` parameter must be absolute, such that an appropriate
376
+ :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
377
+ """
378
+ u = parse_url(url)
379
+ self._validate_proxy_scheme_url_selection(u.scheme)
380
+
381
+ conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
382
+
383
+ kw["assert_same_host"] = False
384
+ kw["redirect"] = False
385
+
386
+ if "headers" not in kw:
387
+ kw["headers"] = self.headers.copy()
388
+
389
+ if self._proxy_requires_url_absolute_form(u):
390
+ response = conn.urlopen(method, url, **kw)
391
+ else:
392
+ response = conn.urlopen(method, u.request_uri, **kw)
393
+
394
+ redirect_location = redirect and response.get_redirect_location()
395
+ if not redirect_location:
396
+ return response
397
+
398
+ # Support relative URLs for redirecting.
399
+ redirect_location = urljoin(url, redirect_location)
400
+
401
+ if response.status == 303:
402
+ # Change the method according to RFC 9110, Section 15.4.4.
403
+ method = "GET"
404
+ # And lose the body not to transfer anything sensitive.
405
+ kw["body"] = None
406
+ kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change()
407
+
408
+ retries = kw.get("retries", response.retries)
409
+ if not isinstance(retries, Retry):
410
+ retries = Retry.from_int(retries, redirect=redirect)
411
+
412
+ # Strip headers marked as unsafe to forward to the redirected location.
413
+ # Check remove_headers_on_redirect to avoid a potential network call within
414
+ # conn.is_same_host() which may use socket.gethostbyname() in the future.
415
+ if retries.remove_headers_on_redirect and not conn.is_same_host(
416
+ redirect_location
417
+ ):
418
+ headers = list(six.iterkeys(kw["headers"]))
419
+ for header in headers:
420
+ if header.lower() in retries.remove_headers_on_redirect:
421
+ kw["headers"].pop(header, None)
422
+
423
+ try:
424
+ retries = retries.increment(method, url, response=response, _pool=conn)
425
+ except MaxRetryError:
426
+ if retries.raise_on_redirect:
427
+ response.drain_conn()
428
+ raise
429
+ return response
430
+
431
+ kw["retries"] = retries
432
+ kw["redirect"] = redirect
433
+
434
+ log.info("Redirecting %s -> %s", url, redirect_location)
435
+
436
+ response.drain_conn()
437
+ return self.urlopen(method, redirect_location, **kw)
438
+
439
+
440
+ class ProxyManager(PoolManager):
441
+ """
442
+ Behaves just like :class:`PoolManager`, but sends all requests through
443
+ the defined proxy, using the CONNECT method for HTTPS URLs.
444
+
445
+ :param proxy_url:
446
+ The URL of the proxy to be used.
447
+
448
+ :param proxy_headers:
449
+ A dictionary containing headers that will be sent to the proxy. In case
450
+ of HTTP they are being sent with each request, while in the
451
+ HTTPS/CONNECT case they are sent only once. Could be used for proxy
452
+ authentication.
453
+
454
+ :param proxy_ssl_context:
455
+ The proxy SSL context is used to establish the TLS connection to the
456
+ proxy when using HTTPS proxies.
457
+
458
+ :param use_forwarding_for_https:
459
+ (Defaults to False) If set to True will forward requests to the HTTPS
460
+ proxy to be made on behalf of the client instead of creating a TLS
461
+ tunnel via the CONNECT method. **Enabling this flag means that request
462
+ and response headers and content will be visible from the HTTPS proxy**
463
+ whereas tunneling keeps request and response headers and content
464
+ private. IP address, target hostname, SNI, and port are always visible
465
+ to an HTTPS proxy even when this flag is disabled.
466
+
467
+ Example:
468
+ >>> proxy = urllib3.ProxyManager('http://localhost:3128/')
469
+ >>> r1 = proxy.request('GET', 'http://google.com/')
470
+ >>> r2 = proxy.request('GET', 'http://httpbin.org/')
471
+ >>> len(proxy.pools)
472
+ 1
473
+ >>> r3 = proxy.request('GET', 'https://httpbin.org/')
474
+ >>> r4 = proxy.request('GET', 'https://twitter.com/')
475
+ >>> len(proxy.pools)
476
+ 3
477
+
478
+ """
479
+
480
+ def __init__(
481
+ self,
482
+ proxy_url,
483
+ num_pools=10,
484
+ headers=None,
485
+ proxy_headers=None,
486
+ proxy_ssl_context=None,
487
+ use_forwarding_for_https=False,
488
+ **connection_pool_kw
489
+ ):
490
+
491
+ if isinstance(proxy_url, HTTPConnectionPool):
492
+ proxy_url = "%s://%s:%i" % (
493
+ proxy_url.scheme,
494
+ proxy_url.host,
495
+ proxy_url.port,
496
+ )
497
+ proxy = parse_url(proxy_url)
498
+
499
+ if proxy.scheme not in ("http", "https"):
500
+ raise ProxySchemeUnknown(proxy.scheme)
501
+
502
+ if not proxy.port:
503
+ port = port_by_scheme.get(proxy.scheme, 80)
504
+ proxy = proxy._replace(port=port)
505
+
506
+ self.proxy = proxy
507
+ self.proxy_headers = proxy_headers or {}
508
+ self.proxy_ssl_context = proxy_ssl_context
509
+ self.proxy_config = ProxyConfig(proxy_ssl_context, use_forwarding_for_https)
510
+
511
+ connection_pool_kw["_proxy"] = self.proxy
512
+ connection_pool_kw["_proxy_headers"] = self.proxy_headers
513
+ connection_pool_kw["_proxy_config"] = self.proxy_config
514
+
515
+ super(ProxyManager, self).__init__(num_pools, headers, **connection_pool_kw)
516
+
517
+ def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
518
+ if scheme == "https":
519
+ return super(ProxyManager, self).connection_from_host(
520
+ host, port, scheme, pool_kwargs=pool_kwargs
521
+ )
522
+
523
+ return super(ProxyManager, self).connection_from_host(
524
+ self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs
525
+ )
526
+
527
+ def _set_proxy_headers(self, url, headers=None):
528
+ """
529
+ Sets headers needed by proxies: specifically, the Accept and Host
530
+ headers. Only sets headers not provided by the user.
531
+ """
532
+ headers_ = {"Accept": "*/*"}
533
+
534
+ netloc = parse_url(url).netloc
535
+ if netloc:
536
+ headers_["Host"] = netloc
537
+
538
+ if headers:
539
+ headers_.update(headers)
540
+ return headers_
541
+
542
+ def urlopen(self, method, url, redirect=True, **kw):
543
+ "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
544
+ u = parse_url(url)
545
+ if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme):
546
+ # For connections using HTTP CONNECT, httplib sets the necessary
547
+ # headers on the CONNECT to the proxy. If we're not using CONNECT,
548
+ # we'll definitely need to set 'Host' at the very least.
549
+ headers = kw.get("headers", self.headers)
550
+ kw["headers"] = self._set_proxy_headers(url, headers)
551
+
552
+ return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw)
553
+
554
+
555
+ def proxy_from_url(url, **kw):
556
+ return ProxyManager(proxy_url=url, **kw)
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/request.py ADDED
@@ -0,0 +1,191 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import sys
4
+
5
+ from .filepost import encode_multipart_formdata
6
+ from .packages import six
7
+ from .packages.six.moves.urllib.parse import urlencode
8
+
9
+ __all__ = ["RequestMethods"]
10
+
11
+
12
+ class RequestMethods(object):
13
+ """
14
+ Convenience mixin for classes who implement a :meth:`urlopen` method, such
15
+ as :class:`urllib3.HTTPConnectionPool` and
16
+ :class:`urllib3.PoolManager`.
17
+
18
+ Provides behavior for making common types of HTTP request methods and
19
+ decides which type of request field encoding to use.
20
+
21
+ Specifically,
22
+
23
+ :meth:`.request_encode_url` is for sending requests whose fields are
24
+ encoded in the URL (such as GET, HEAD, DELETE).
25
+
26
+ :meth:`.request_encode_body` is for sending requests whose fields are
27
+ encoded in the *body* of the request using multipart or www-form-urlencoded
28
+ (such as for POST, PUT, PATCH).
29
+
30
+ :meth:`.request` is for making any kind of request, it will look up the
31
+ appropriate encoding format and use one of the above two methods to make
32
+ the request.
33
+
34
+ Initializer parameters:
35
+
36
+ :param headers:
37
+ Headers to include with all requests, unless other headers are given
38
+ explicitly.
39
+ """
40
+
41
+ _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"}
42
+
43
+ def __init__(self, headers=None):
44
+ self.headers = headers or {}
45
+
46
+ def urlopen(
47
+ self,
48
+ method,
49
+ url,
50
+ body=None,
51
+ headers=None,
52
+ encode_multipart=True,
53
+ multipart_boundary=None,
54
+ **kw
55
+ ): # Abstract
56
+ raise NotImplementedError(
57
+ "Classes extending RequestMethods must implement "
58
+ "their own ``urlopen`` method."
59
+ )
60
+
61
+ def request(self, method, url, fields=None, headers=None, **urlopen_kw):
62
+ """
63
+ Make a request using :meth:`urlopen` with the appropriate encoding of
64
+ ``fields`` based on the ``method`` used.
65
+
66
+ This is a convenience method that requires the least amount of manual
67
+ effort. It can be used in most situations, while still having the
68
+ option to drop down to more specific methods when necessary, such as
69
+ :meth:`request_encode_url`, :meth:`request_encode_body`,
70
+ or even the lowest level :meth:`urlopen`.
71
+ """
72
+ method = method.upper()
73
+
74
+ urlopen_kw["request_url"] = url
75
+
76
+ if method in self._encode_url_methods:
77
+ return self.request_encode_url(
78
+ method, url, fields=fields, headers=headers, **urlopen_kw
79
+ )
80
+ else:
81
+ return self.request_encode_body(
82
+ method, url, fields=fields, headers=headers, **urlopen_kw
83
+ )
84
+
85
+ def request_encode_url(self, method, url, fields=None, headers=None, **urlopen_kw):
86
+ """
87
+ Make a request using :meth:`urlopen` with the ``fields`` encoded in
88
+ the url. This is useful for request methods like GET, HEAD, DELETE, etc.
89
+ """
90
+ if headers is None:
91
+ headers = self.headers
92
+
93
+ extra_kw = {"headers": headers}
94
+ extra_kw.update(urlopen_kw)
95
+
96
+ if fields:
97
+ url += "?" + urlencode(fields)
98
+
99
+ return self.urlopen(method, url, **extra_kw)
100
+
101
+ def request_encode_body(
102
+ self,
103
+ method,
104
+ url,
105
+ fields=None,
106
+ headers=None,
107
+ encode_multipart=True,
108
+ multipart_boundary=None,
109
+ **urlopen_kw
110
+ ):
111
+ """
112
+ Make a request using :meth:`urlopen` with the ``fields`` encoded in
113
+ the body. This is useful for request methods like POST, PUT, PATCH, etc.
114
+
115
+ When ``encode_multipart=True`` (default), then
116
+ :func:`urllib3.encode_multipart_formdata` is used to encode
117
+ the payload with the appropriate content type. Otherwise
118
+ :func:`urllib.parse.urlencode` is used with the
119
+ 'application/x-www-form-urlencoded' content type.
120
+
121
+ Multipart encoding must be used when posting files, and it's reasonably
122
+ safe to use it in other times too. However, it may break request
123
+ signing, such as with OAuth.
124
+
125
+ Supports an optional ``fields`` parameter of key/value strings AND
126
+ key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
127
+ the MIME type is optional. For example::
128
+
129
+ fields = {
130
+ 'foo': 'bar',
131
+ 'fakefile': ('foofile.txt', 'contents of foofile'),
132
+ 'realfile': ('barfile.txt', open('realfile').read()),
133
+ 'typedfile': ('bazfile.bin', open('bazfile').read(),
134
+ 'image/jpeg'),
135
+ 'nonamefile': 'contents of nonamefile field',
136
+ }
137
+
138
+ When uploading a file, providing a filename (the first parameter of the
139
+ tuple) is optional but recommended to best mimic behavior of browsers.
140
+
141
+ Note that if ``headers`` are supplied, the 'Content-Type' header will
142
+ be overwritten because it depends on the dynamic random boundary string
143
+ which is used to compose the body of the request. The random boundary
144
+ string can be explicitly set with the ``multipart_boundary`` parameter.
145
+ """
146
+ if headers is None:
147
+ headers = self.headers
148
+
149
+ extra_kw = {"headers": {}}
150
+
151
+ if fields:
152
+ if "body" in urlopen_kw:
153
+ raise TypeError(
154
+ "request got values for both 'fields' and 'body', can only specify one."
155
+ )
156
+
157
+ if encode_multipart:
158
+ body, content_type = encode_multipart_formdata(
159
+ fields, boundary=multipart_boundary
160
+ )
161
+ else:
162
+ body, content_type = (
163
+ urlencode(fields),
164
+ "application/x-www-form-urlencoded",
165
+ )
166
+
167
+ extra_kw["body"] = body
168
+ extra_kw["headers"] = {"Content-Type": content_type}
169
+
170
+ extra_kw["headers"].update(headers)
171
+ extra_kw.update(urlopen_kw)
172
+
173
+ return self.urlopen(method, url, **extra_kw)
174
+
175
+
176
+ if not six.PY2:
177
+
178
+ class RequestModule(sys.modules[__name__].__class__):
179
+ def __call__(self, *args, **kwargs):
180
+ """
181
+ If user tries to call this module directly urllib3 v2.x style raise an error to the user
182
+ suggesting they may need urllib3 v2
183
+ """
184
+ raise TypeError(
185
+ "'module' object is not callable\n"
186
+ "urllib3.request() method is not supported in this release, "
187
+ "upgrade to urllib3 v2 to use it\n"
188
+ "see https://urllib3.readthedocs.io/en/stable/v2-migration-guide.html"
189
+ )
190
+
191
+ sys.modules[__name__].__class__ = RequestModule
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/response.py ADDED
@@ -0,0 +1,879 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import io
4
+ import logging
5
+ import sys
6
+ import warnings
7
+ import zlib
8
+ from contextlib import contextmanager
9
+ from socket import error as SocketError
10
+ from socket import timeout as SocketTimeout
11
+
12
+ brotli = None
13
+
14
+ from . import util
15
+ from ._collections import HTTPHeaderDict
16
+ from .connection import BaseSSLError, HTTPException
17
+ from .exceptions import (
18
+ BodyNotHttplibCompatible,
19
+ DecodeError,
20
+ HTTPError,
21
+ IncompleteRead,
22
+ InvalidChunkLength,
23
+ InvalidHeader,
24
+ ProtocolError,
25
+ ReadTimeoutError,
26
+ ResponseNotChunked,
27
+ SSLError,
28
+ )
29
+ from .packages import six
30
+ from .util.response import is_fp_closed, is_response_to_head
31
+
32
+ log = logging.getLogger(__name__)
33
+
34
+
35
+ class DeflateDecoder(object):
36
+ def __init__(self):
37
+ self._first_try = True
38
+ self._data = b""
39
+ self._obj = zlib.decompressobj()
40
+
41
+ def __getattr__(self, name):
42
+ return getattr(self._obj, name)
43
+
44
+ def decompress(self, data):
45
+ if not data:
46
+ return data
47
+
48
+ if not self._first_try:
49
+ return self._obj.decompress(data)
50
+
51
+ self._data += data
52
+ try:
53
+ decompressed = self._obj.decompress(data)
54
+ if decompressed:
55
+ self._first_try = False
56
+ self._data = None
57
+ return decompressed
58
+ except zlib.error:
59
+ self._first_try = False
60
+ self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
61
+ try:
62
+ return self.decompress(self._data)
63
+ finally:
64
+ self._data = None
65
+
66
+
67
+ class GzipDecoderState(object):
68
+
69
+ FIRST_MEMBER = 0
70
+ OTHER_MEMBERS = 1
71
+ SWALLOW_DATA = 2
72
+
73
+
74
+ class GzipDecoder(object):
75
+ def __init__(self):
76
+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
77
+ self._state = GzipDecoderState.FIRST_MEMBER
78
+
79
+ def __getattr__(self, name):
80
+ return getattr(self._obj, name)
81
+
82
+ def decompress(self, data):
83
+ ret = bytearray()
84
+ if self._state == GzipDecoderState.SWALLOW_DATA or not data:
85
+ return bytes(ret)
86
+ while True:
87
+ try:
88
+ ret += self._obj.decompress(data)
89
+ except zlib.error:
90
+ previous_state = self._state
91
+ # Ignore data after the first error
92
+ self._state = GzipDecoderState.SWALLOW_DATA
93
+ if previous_state == GzipDecoderState.OTHER_MEMBERS:
94
+ # Allow trailing garbage acceptable in other gzip clients
95
+ return bytes(ret)
96
+ raise
97
+ data = self._obj.unused_data
98
+ if not data:
99
+ return bytes(ret)
100
+ self._state = GzipDecoderState.OTHER_MEMBERS
101
+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
102
+
103
+
104
+ if brotli is not None:
105
+
106
+ class BrotliDecoder(object):
107
+ # Supports both 'brotlipy' and 'Brotli' packages
108
+ # since they share an import name. The top branches
109
+ # are for 'brotlipy' and bottom branches for 'Brotli'
110
+ def __init__(self):
111
+ self._obj = brotli.Decompressor()
112
+ if hasattr(self._obj, "decompress"):
113
+ self.decompress = self._obj.decompress
114
+ else:
115
+ self.decompress = self._obj.process
116
+
117
+ def flush(self):
118
+ if hasattr(self._obj, "flush"):
119
+ return self._obj.flush()
120
+ return b""
121
+
122
+
123
+ class MultiDecoder(object):
124
+ """
125
+ From RFC7231:
126
+ If one or more encodings have been applied to a representation, the
127
+ sender that applied the encodings MUST generate a Content-Encoding
128
+ header field that lists the content codings in the order in which
129
+ they were applied.
130
+ """
131
+
132
+ def __init__(self, modes):
133
+ self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")]
134
+
135
+ def flush(self):
136
+ return self._decoders[0].flush()
137
+
138
+ def decompress(self, data):
139
+ for d in reversed(self._decoders):
140
+ data = d.decompress(data)
141
+ return data
142
+
143
+
144
+ def _get_decoder(mode):
145
+ if "," in mode:
146
+ return MultiDecoder(mode)
147
+
148
+ if mode == "gzip":
149
+ return GzipDecoder()
150
+
151
+ if brotli is not None and mode == "br":
152
+ return BrotliDecoder()
153
+
154
+ return DeflateDecoder()
155
+
156
+
157
+ class HTTPResponse(io.IOBase):
158
+ """
159
+ HTTP Response container.
160
+
161
+ Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is
162
+ loaded and decoded on-demand when the ``data`` property is accessed. This
163
+ class is also compatible with the Python standard library's :mod:`io`
164
+ module, and can hence be treated as a readable object in the context of that
165
+ framework.
166
+
167
+ Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`:
168
+
169
+ :param preload_content:
170
+ If True, the response's body will be preloaded during construction.
171
+
172
+ :param decode_content:
173
+ If True, will attempt to decode the body based on the
174
+ 'content-encoding' header.
175
+
176
+ :param original_response:
177
+ When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse`
178
+ object, it's convenient to include the original for debug purposes. It's
179
+ otherwise unused.
180
+
181
+ :param retries:
182
+ The retries contains the last :class:`~urllib3.util.retry.Retry` that
183
+ was used during the request.
184
+
185
+ :param enforce_content_length:
186
+ Enforce content length checking. Body returned by server must match
187
+ value of Content-Length header, if present. Otherwise, raise error.
188
+ """
189
+
190
+ CONTENT_DECODERS = ["gzip", "deflate"]
191
+ if brotli is not None:
192
+ CONTENT_DECODERS += ["br"]
193
+ REDIRECT_STATUSES = [301, 302, 303, 307, 308]
194
+
195
+ def __init__(
196
+ self,
197
+ body="",
198
+ headers=None,
199
+ status=0,
200
+ version=0,
201
+ reason=None,
202
+ strict=0,
203
+ preload_content=True,
204
+ decode_content=True,
205
+ original_response=None,
206
+ pool=None,
207
+ connection=None,
208
+ msg=None,
209
+ retries=None,
210
+ enforce_content_length=False,
211
+ request_method=None,
212
+ request_url=None,
213
+ auto_close=True,
214
+ ):
215
+
216
+ if isinstance(headers, HTTPHeaderDict):
217
+ self.headers = headers
218
+ else:
219
+ self.headers = HTTPHeaderDict(headers)
220
+ self.status = status
221
+ self.version = version
222
+ self.reason = reason
223
+ self.strict = strict
224
+ self.decode_content = decode_content
225
+ self.retries = retries
226
+ self.enforce_content_length = enforce_content_length
227
+ self.auto_close = auto_close
228
+
229
+ self._decoder = None
230
+ self._body = None
231
+ self._fp = None
232
+ self._original_response = original_response
233
+ self._fp_bytes_read = 0
234
+ self.msg = msg
235
+ self._request_url = request_url
236
+
237
+ if body and isinstance(body, (six.string_types, bytes)):
238
+ self._body = body
239
+
240
+ self._pool = pool
241
+ self._connection = connection
242
+
243
+ if hasattr(body, "read"):
244
+ self._fp = body
245
+
246
+ # Are we using the chunked-style of transfer encoding?
247
+ self.chunked = False
248
+ self.chunk_left = None
249
+ tr_enc = self.headers.get("transfer-encoding", "").lower()
250
+ # Don't incur the penalty of creating a list and then discarding it
251
+ encodings = (enc.strip() for enc in tr_enc.split(","))
252
+ if "chunked" in encodings:
253
+ self.chunked = True
254
+
255
+ # Determine length of response
256
+ self.length_remaining = self._init_length(request_method)
257
+
258
+ # If requested, preload the body.
259
+ if preload_content and not self._body:
260
+ self._body = self.read(decode_content=decode_content)
261
+
262
+ def get_redirect_location(self):
263
+ """
264
+ Should we redirect and where to?
265
+
266
+ :returns: Truthy redirect location string if we got a redirect status
267
+ code and valid location. ``None`` if redirect status and no
268
+ location. ``False`` if not a redirect status code.
269
+ """
270
+ if self.status in self.REDIRECT_STATUSES:
271
+ return self.headers.get("location")
272
+
273
+ return False
274
+
275
+ def release_conn(self):
276
+ if not self._pool or not self._connection:
277
+ return
278
+
279
+ self._pool._put_conn(self._connection)
280
+ self._connection = None
281
+
282
+ def drain_conn(self):
283
+ """
284
+ Read and discard any remaining HTTP response data in the response connection.
285
+
286
+ Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
287
+ """
288
+ try:
289
+ self.read()
290
+ except (HTTPError, SocketError, BaseSSLError, HTTPException):
291
+ pass
292
+
293
+ @property
294
+ def data(self):
295
+ # For backwards-compat with earlier urllib3 0.4 and earlier.
296
+ if self._body:
297
+ return self._body
298
+
299
+ if self._fp:
300
+ return self.read(cache_content=True)
301
+
302
+ @property
303
+ def connection(self):
304
+ return self._connection
305
+
306
+ def isclosed(self):
307
+ return is_fp_closed(self._fp)
308
+
309
+ def tell(self):
310
+ """
311
+ Obtain the number of bytes pulled over the wire so far. May differ from
312
+ the amount of content returned by :meth:``urllib3.response.HTTPResponse.read``
313
+ if bytes are encoded on the wire (e.g, compressed).
314
+ """
315
+ return self._fp_bytes_read
316
+
317
+ def _init_length(self, request_method):
318
+ """
319
+ Set initial length value for Response content if available.
320
+ """
321
+ length = self.headers.get("content-length")
322
+
323
+ if length is not None:
324
+ if self.chunked:
325
+ # This Response will fail with an IncompleteRead if it can't be
326
+ # received as chunked. This method falls back to attempt reading
327
+ # the response before raising an exception.
328
+ log.warning(
329
+ "Received response with both Content-Length and "
330
+ "Transfer-Encoding set. This is expressly forbidden "
331
+ "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
332
+ "attempting to process response as Transfer-Encoding: "
333
+ "chunked."
334
+ )
335
+ return None
336
+
337
+ try:
338
+ # RFC 7230 section 3.3.2 specifies multiple content lengths can
339
+ # be sent in a single Content-Length header
340
+ # (e.g. Content-Length: 42, 42). This line ensures the values
341
+ # are all valid ints and that as long as the `set` length is 1,
342
+ # all values are the same. Otherwise, the header is invalid.
343
+ lengths = set([int(val) for val in length.split(",")])
344
+ if len(lengths) > 1:
345
+ raise InvalidHeader(
346
+ "Content-Length contained multiple "
347
+ "unmatching values (%s)" % length
348
+ )
349
+ length = lengths.pop()
350
+ except ValueError:
351
+ length = None
352
+ else:
353
+ if length < 0:
354
+ length = None
355
+
356
+ # Convert status to int for comparison
357
+ # In some cases, httplib returns a status of "_UNKNOWN"
358
+ try:
359
+ status = int(self.status)
360
+ except ValueError:
361
+ status = 0
362
+
363
+ # Check for responses that shouldn't include a body
364
+ if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD":
365
+ length = 0
366
+
367
+ return length
368
+
369
+ def _init_decoder(self):
370
+ """
371
+ Set-up the _decoder attribute if necessary.
372
+ """
373
+ # Note: content-encoding value should be case-insensitive, per RFC 7230
374
+ # Section 3.2
375
+ content_encoding = self.headers.get("content-encoding", "").lower()
376
+ if self._decoder is None:
377
+ if content_encoding in self.CONTENT_DECODERS:
378
+ self._decoder = _get_decoder(content_encoding)
379
+ elif "," in content_encoding:
380
+ encodings = [
381
+ e.strip()
382
+ for e in content_encoding.split(",")
383
+ if e.strip() in self.CONTENT_DECODERS
384
+ ]
385
+ if len(encodings):
386
+ self._decoder = _get_decoder(content_encoding)
387
+
388
+ DECODER_ERROR_CLASSES = (IOError, zlib.error)
389
+ if brotli is not None:
390
+ DECODER_ERROR_CLASSES += (brotli.error,)
391
+
392
+ def _decode(self, data, decode_content, flush_decoder):
393
+ """
394
+ Decode the data passed in and potentially flush the decoder.
395
+ """
396
+ if not decode_content:
397
+ return data
398
+
399
+ try:
400
+ if self._decoder:
401
+ data = self._decoder.decompress(data)
402
+ except self.DECODER_ERROR_CLASSES as e:
403
+ content_encoding = self.headers.get("content-encoding", "").lower()
404
+ raise DecodeError(
405
+ "Received response with content-encoding: %s, but "
406
+ "failed to decode it." % content_encoding,
407
+ e,
408
+ )
409
+ if flush_decoder:
410
+ data += self._flush_decoder()
411
+
412
+ return data
413
+
414
+ def _flush_decoder(self):
415
+ """
416
+ Flushes the decoder. Should only be called if the decoder is actually
417
+ being used.
418
+ """
419
+ if self._decoder:
420
+ buf = self._decoder.decompress(b"")
421
+ return buf + self._decoder.flush()
422
+
423
+ return b""
424
+
425
+ @contextmanager
426
+ def _error_catcher(self):
427
+ """
428
+ Catch low-level python exceptions, instead re-raising urllib3
429
+ variants, so that low-level exceptions are not leaked in the
430
+ high-level api.
431
+
432
+ On exit, release the connection back to the pool.
433
+ """
434
+ clean_exit = False
435
+
436
+ try:
437
+ try:
438
+ yield
439
+
440
+ except SocketTimeout:
441
+ # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
442
+ # there is yet no clean way to get at it from this context.
443
+ raise ReadTimeoutError(self._pool, None, "Read timed out.")
444
+
445
+ except BaseSSLError as e:
446
+ # FIXME: Is there a better way to differentiate between SSLErrors?
447
+ if "read operation timed out" not in str(e):
448
+ # SSL errors related to framing/MAC get wrapped and reraised here
449
+ raise SSLError(e)
450
+
451
+ raise ReadTimeoutError(self._pool, None, "Read timed out.")
452
+
453
+ except (HTTPException, SocketError) as e:
454
+ # This includes IncompleteRead.
455
+ raise ProtocolError("Connection broken: %r" % e, e)
456
+
457
+ # If no exception is thrown, we should avoid cleaning up
458
+ # unnecessarily.
459
+ clean_exit = True
460
+ finally:
461
+ # If we didn't terminate cleanly, we need to throw away our
462
+ # connection.
463
+ if not clean_exit:
464
+ # The response may not be closed but we're not going to use it
465
+ # anymore so close it now to ensure that the connection is
466
+ # released back to the pool.
467
+ if self._original_response:
468
+ self._original_response.close()
469
+
470
+ # Closing the response may not actually be sufficient to close
471
+ # everything, so if we have a hold of the connection close that
472
+ # too.
473
+ if self._connection:
474
+ self._connection.close()
475
+
476
+ # If we hold the original response but it's closed now, we should
477
+ # return the connection back to the pool.
478
+ if self._original_response and self._original_response.isclosed():
479
+ self.release_conn()
480
+
481
+ def _fp_read(self, amt):
482
+ """
483
+ Read a response with the thought that reading the number of bytes
484
+ larger than can fit in a 32-bit int at a time via SSL in some
485
+ known cases leads to an overflow error that has to be prevented
486
+ if `amt` or `self.length_remaining` indicate that a problem may
487
+ happen.
488
+
489
+ The known cases:
490
+ * 3.8 <= CPython < 3.9.7 because of a bug
491
+ https://github.com/urllib3/urllib3/issues/2513#issuecomment-1152559900.
492
+ * urllib3 injected with pyOpenSSL-backed SSL-support.
493
+ * CPython < 3.10 only when `amt` does not fit 32-bit int.
494
+ """
495
+ assert self._fp
496
+ c_int_max = 2 ** 31 - 1
497
+ if (
498
+ (
499
+ (amt and amt > c_int_max)
500
+ or (self.length_remaining and self.length_remaining > c_int_max)
501
+ )
502
+ and not util.IS_SECURETRANSPORT
503
+ and (util.IS_PYOPENSSL or sys.version_info < (3, 10))
504
+ ):
505
+ buffer = io.BytesIO()
506
+ # Besides `max_chunk_amt` being a maximum chunk size, it
507
+ # affects memory overhead of reading a response by this
508
+ # method in CPython.
509
+ # `c_int_max` equal to 2 GiB - 1 byte is the actual maximum
510
+ # chunk size that does not lead to an overflow error, but
511
+ # 256 MiB is a compromise.
512
+ max_chunk_amt = 2 ** 28
513
+ while amt is None or amt != 0:
514
+ if amt is not None:
515
+ chunk_amt = min(amt, max_chunk_amt)
516
+ amt -= chunk_amt
517
+ else:
518
+ chunk_amt = max_chunk_amt
519
+ data = self._fp.read(chunk_amt)
520
+ if not data:
521
+ break
522
+ buffer.write(data)
523
+ del data # to reduce peak memory usage by `max_chunk_amt`.
524
+ return buffer.getvalue()
525
+ else:
526
+ # StringIO doesn't like amt=None
527
+ return self._fp.read(amt) if amt is not None else self._fp.read()
528
+
529
+ def read(self, amt=None, decode_content=None, cache_content=False):
530
+ """
531
+ Similar to :meth:`http.client.HTTPResponse.read`, but with two additional
532
+ parameters: ``decode_content`` and ``cache_content``.
533
+
534
+ :param amt:
535
+ How much of the content to read. If specified, caching is skipped
536
+ because it doesn't make sense to cache partial content as the full
537
+ response.
538
+
539
+ :param decode_content:
540
+ If True, will attempt to decode the body based on the
541
+ 'content-encoding' header.
542
+
543
+ :param cache_content:
544
+ If True, will save the returned data such that the same result is
545
+ returned despite of the state of the underlying file object. This
546
+ is useful if you want the ``.data`` property to continue working
547
+ after having ``.read()`` the file object. (Overridden if ``amt`` is
548
+ set.)
549
+ """
550
+ self._init_decoder()
551
+ if decode_content is None:
552
+ decode_content = self.decode_content
553
+
554
+ if self._fp is None:
555
+ return
556
+
557
+ flush_decoder = False
558
+ fp_closed = getattr(self._fp, "closed", False)
559
+
560
+ with self._error_catcher():
561
+ data = self._fp_read(amt) if not fp_closed else b""
562
+ if amt is None:
563
+ flush_decoder = True
564
+ else:
565
+ cache_content = False
566
+ if (
567
+ amt != 0 and not data
568
+ ): # Platform-specific: Buggy versions of Python.
569
+ # Close the connection when no data is returned
570
+ #
571
+ # This is redundant to what httplib/http.client _should_
572
+ # already do. However, versions of python released before
573
+ # December 15, 2012 (http://bugs.python.org/issue16298) do
574
+ # not properly close the connection in all cases. There is
575
+ # no harm in redundantly calling close.
576
+ self._fp.close()
577
+ flush_decoder = True
578
+ if self.enforce_content_length and self.length_remaining not in (
579
+ 0,
580
+ None,
581
+ ):
582
+ # This is an edge case that httplib failed to cover due
583
+ # to concerns of backward compatibility. We're
584
+ # addressing it here to make sure IncompleteRead is
585
+ # raised during streaming, so all calls with incorrect
586
+ # Content-Length are caught.
587
+ raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
588
+
589
+ if data:
590
+ self._fp_bytes_read += len(data)
591
+ if self.length_remaining is not None:
592
+ self.length_remaining -= len(data)
593
+
594
+ data = self._decode(data, decode_content, flush_decoder)
595
+
596
+ if cache_content:
597
+ self._body = data
598
+
599
+ return data
600
+
601
+ def stream(self, amt=2 ** 16, decode_content=None):
602
+ """
603
+ A generator wrapper for the read() method. A call will block until
604
+ ``amt`` bytes have been read from the connection or until the
605
+ connection is closed.
606
+
607
+ :param amt:
608
+ How much of the content to read. The generator will return up to
609
+ much data per iteration, but may return less. This is particularly
610
+ likely when using compressed data. However, the empty string will
611
+ never be returned.
612
+
613
+ :param decode_content:
614
+ If True, will attempt to decode the body based on the
615
+ 'content-encoding' header.
616
+ """
617
+ if self.chunked and self.supports_chunked_reads():
618
+ for line in self.read_chunked(amt, decode_content=decode_content):
619
+ yield line
620
+ else:
621
+ while not is_fp_closed(self._fp):
622
+ data = self.read(amt=amt, decode_content=decode_content)
623
+
624
+ if data:
625
+ yield data
626
+
627
+ @classmethod
628
+ def from_httplib(ResponseCls, r, **response_kw):
629
+ """
630
+ Given an :class:`http.client.HTTPResponse` instance ``r``, return a
631
+ corresponding :class:`urllib3.response.HTTPResponse` object.
632
+
633
+ Remaining parameters are passed to the HTTPResponse constructor, along
634
+ with ``original_response=r``.
635
+ """
636
+ headers = r.msg
637
+
638
+ if not isinstance(headers, HTTPHeaderDict):
639
+ if six.PY2:
640
+ # Python 2.7
641
+ headers = HTTPHeaderDict.from_httplib(headers)
642
+ else:
643
+ headers = HTTPHeaderDict(headers.items())
644
+
645
+ # HTTPResponse objects in Python 3 don't have a .strict attribute
646
+ strict = getattr(r, "strict", 0)
647
+ resp = ResponseCls(
648
+ body=r,
649
+ headers=headers,
650
+ status=r.status,
651
+ version=r.version,
652
+ reason=r.reason,
653
+ strict=strict,
654
+ original_response=r,
655
+ **response_kw
656
+ )
657
+ return resp
658
+
659
+ # Backwards-compatibility methods for http.client.HTTPResponse
660
+ def getheaders(self):
661
+ warnings.warn(
662
+ "HTTPResponse.getheaders() is deprecated and will be removed "
663
+ "in urllib3 v2.1.0. Instead access HTTPResponse.headers directly.",
664
+ category=DeprecationWarning,
665
+ stacklevel=2,
666
+ )
667
+ return self.headers
668
+
669
+ def getheader(self, name, default=None):
670
+ warnings.warn(
671
+ "HTTPResponse.getheader() is deprecated and will be removed "
672
+ "in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).",
673
+ category=DeprecationWarning,
674
+ stacklevel=2,
675
+ )
676
+ return self.headers.get(name, default)
677
+
678
+ # Backwards compatibility for http.cookiejar
679
+ def info(self):
680
+ return self.headers
681
+
682
+ # Overrides from io.IOBase
683
+ def close(self):
684
+ if not self.closed:
685
+ self._fp.close()
686
+
687
+ if self._connection:
688
+ self._connection.close()
689
+
690
+ if not self.auto_close:
691
+ io.IOBase.close(self)
692
+
693
+ @property
694
+ def closed(self):
695
+ if not self.auto_close:
696
+ return io.IOBase.closed.__get__(self)
697
+ elif self._fp is None:
698
+ return True
699
+ elif hasattr(self._fp, "isclosed"):
700
+ return self._fp.isclosed()
701
+ elif hasattr(self._fp, "closed"):
702
+ return self._fp.closed
703
+ else:
704
+ return True
705
+
706
+ def fileno(self):
707
+ if self._fp is None:
708
+ raise IOError("HTTPResponse has no file to get a fileno from")
709
+ elif hasattr(self._fp, "fileno"):
710
+ return self._fp.fileno()
711
+ else:
712
+ raise IOError(
713
+ "The file-like object this HTTPResponse is wrapped "
714
+ "around has no file descriptor"
715
+ )
716
+
717
+ def flush(self):
718
+ if (
719
+ self._fp is not None
720
+ and hasattr(self._fp, "flush")
721
+ and not getattr(self._fp, "closed", False)
722
+ ):
723
+ return self._fp.flush()
724
+
725
+ def readable(self):
726
+ # This method is required for `io` module compatibility.
727
+ return True
728
+
729
+ def readinto(self, b):
730
+ # This method is required for `io` module compatibility.
731
+ temp = self.read(len(b))
732
+ if len(temp) == 0:
733
+ return 0
734
+ else:
735
+ b[: len(temp)] = temp
736
+ return len(temp)
737
+
738
+ def supports_chunked_reads(self):
739
+ """
740
+ Checks if the underlying file-like object looks like a
741
+ :class:`http.client.HTTPResponse` object. We do this by testing for
742
+ the fp attribute. If it is present we assume it returns raw chunks as
743
+ processed by read_chunked().
744
+ """
745
+ return hasattr(self._fp, "fp")
746
+
747
+ def _update_chunk_length(self):
748
+ # First, we'll figure out length of a chunk and then
749
+ # we'll try to read it from socket.
750
+ if self.chunk_left is not None:
751
+ return
752
+ line = self._fp.fp.readline()
753
+ line = line.split(b";", 1)[0]
754
+ try:
755
+ self.chunk_left = int(line, 16)
756
+ except ValueError:
757
+ # Invalid chunked protocol response, abort.
758
+ self.close()
759
+ raise InvalidChunkLength(self, line)
760
+
761
+ def _handle_chunk(self, amt):
762
+ returned_chunk = None
763
+ if amt is None:
764
+ chunk = self._fp._safe_read(self.chunk_left)
765
+ returned_chunk = chunk
766
+ self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
767
+ self.chunk_left = None
768
+ elif amt < self.chunk_left:
769
+ value = self._fp._safe_read(amt)
770
+ self.chunk_left = self.chunk_left - amt
771
+ returned_chunk = value
772
+ elif amt == self.chunk_left:
773
+ value = self._fp._safe_read(amt)
774
+ self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
775
+ self.chunk_left = None
776
+ returned_chunk = value
777
+ else: # amt > self.chunk_left
778
+ returned_chunk = self._fp._safe_read(self.chunk_left)
779
+ self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
780
+ self.chunk_left = None
781
+ return returned_chunk
782
+
783
+ def read_chunked(self, amt=None, decode_content=None):
784
+ """
785
+ Similar to :meth:`HTTPResponse.read`, but with an additional
786
+ parameter: ``decode_content``.
787
+
788
+ :param amt:
789
+ How much of the content to read. If specified, caching is skipped
790
+ because it doesn't make sense to cache partial content as the full
791
+ response.
792
+
793
+ :param decode_content:
794
+ If True, will attempt to decode the body based on the
795
+ 'content-encoding' header.
796
+ """
797
+ self._init_decoder()
798
+ # FIXME: Rewrite this method and make it a class with a better structured logic.
799
+ if not self.chunked:
800
+ raise ResponseNotChunked(
801
+ "Response is not chunked. "
802
+ "Header 'transfer-encoding: chunked' is missing."
803
+ )
804
+ if not self.supports_chunked_reads():
805
+ raise BodyNotHttplibCompatible(
806
+ "Body should be http.client.HTTPResponse like. "
807
+ "It should have have an fp attribute which returns raw chunks."
808
+ )
809
+
810
+ with self._error_catcher():
811
+ # Don't bother reading the body of a HEAD request.
812
+ if self._original_response and is_response_to_head(self._original_response):
813
+ self._original_response.close()
814
+ return
815
+
816
+ # If a response is already read and closed
817
+ # then return immediately.
818
+ if self._fp.fp is None:
819
+ return
820
+
821
+ while True:
822
+ self._update_chunk_length()
823
+ if self.chunk_left == 0:
824
+ break
825
+ chunk = self._handle_chunk(amt)
826
+ decoded = self._decode(
827
+ chunk, decode_content=decode_content, flush_decoder=False
828
+ )
829
+ if decoded:
830
+ yield decoded
831
+
832
+ if decode_content:
833
+ # On CPython and PyPy, we should never need to flush the
834
+ # decoder. However, on Jython we *might* need to, so
835
+ # lets defensively do it anyway.
836
+ decoded = self._flush_decoder()
837
+ if decoded: # Platform-specific: Jython.
838
+ yield decoded
839
+
840
+ # Chunk content ends with \r\n: discard it.
841
+ while True:
842
+ line = self._fp.fp.readline()
843
+ if not line:
844
+ # Some sites may not end with '\r\n'.
845
+ break
846
+ if line == b"\r\n":
847
+ break
848
+
849
+ # We read everything; close the "file".
850
+ if self._original_response:
851
+ self._original_response.close()
852
+
853
+ def geturl(self):
854
+ """
855
+ Returns the URL that was the source of this response.
856
+ If the request that generated this response redirected, this method
857
+ will return the final redirect location.
858
+ """
859
+ if self.retries is not None and len(self.retries.history):
860
+ return self.retries.history[-1].redirect_location
861
+ else:
862
+ return self._request_url
863
+
864
+ def __iter__(self):
865
+ buffer = []
866
+ for chunk in self.stream(decode_content=True):
867
+ if b"\n" in chunk:
868
+ chunk = chunk.split(b"\n")
869
+ yield b"".join(buffer) + chunk[0] + b"\n"
870
+ for x in chunk[1:-1]:
871
+ yield x + b"\n"
872
+ if chunk[-1]:
873
+ buffer = [chunk[-1]]
874
+ else:
875
+ buffer = []
876
+ else:
877
+ buffer.append(chunk)
878
+ if buffer:
879
+ yield b"".join(buffer)
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ # For backwards compatibility, provide imports that used to be here.
4
+ from .connection import is_connection_dropped
5
+ from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers
6
+ from .response import is_fp_closed
7
+ from .retry import Retry
8
+ from .ssl_ import (
9
+ ALPN_PROTOCOLS,
10
+ HAS_SNI,
11
+ IS_PYOPENSSL,
12
+ IS_SECURETRANSPORT,
13
+ PROTOCOL_TLS,
14
+ SSLContext,
15
+ assert_fingerprint,
16
+ resolve_cert_reqs,
17
+ resolve_ssl_version,
18
+ ssl_wrap_socket,
19
+ )
20
+ from .timeout import Timeout, current_time
21
+ from .url import Url, get_host, parse_url, split_first
22
+ from .wait import wait_for_read, wait_for_write
23
+
24
+ __all__ = (
25
+ "HAS_SNI",
26
+ "IS_PYOPENSSL",
27
+ "IS_SECURETRANSPORT",
28
+ "SSLContext",
29
+ "PROTOCOL_TLS",
30
+ "ALPN_PROTOCOLS",
31
+ "Retry",
32
+ "Timeout",
33
+ "Url",
34
+ "assert_fingerprint",
35
+ "current_time",
36
+ "is_connection_dropped",
37
+ "is_fp_closed",
38
+ "get_host",
39
+ "parse_url",
40
+ "make_headers",
41
+ "resolve_cert_reqs",
42
+ "resolve_ssl_version",
43
+ "split_first",
44
+ "ssl_wrap_socket",
45
+ "wait_for_read",
46
+ "wait_for_write",
47
+ "SKIP_HEADER",
48
+ "SKIPPABLE_HEADERS",
49
+ )
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/connection.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import socket
4
+
5
+ from ..contrib import _appengine_environ
6
+ from ..exceptions import LocationParseError
7
+ from ..packages import six
8
+ from .wait import NoWayToWaitForSocketError, wait_for_read
9
+
10
+
11
+ def is_connection_dropped(conn): # Platform-specific
12
+ """
13
+ Returns True if the connection is dropped and should be closed.
14
+
15
+ :param conn:
16
+ :class:`http.client.HTTPConnection` object.
17
+
18
+ Note: For platforms like AppEngine, this will always return ``False`` to
19
+ let the platform handle connection recycling transparently for us.
20
+ """
21
+ sock = getattr(conn, "sock", False)
22
+ if sock is False: # Platform-specific: AppEngine
23
+ return False
24
+ if sock is None: # Connection already closed (such as by httplib).
25
+ return True
26
+ try:
27
+ # Returns True if readable, which here means it's been dropped
28
+ return wait_for_read(sock, timeout=0.0)
29
+ except NoWayToWaitForSocketError: # Platform-specific: AppEngine
30
+ return False
31
+
32
+
33
+ # This function is copied from socket.py in the Python 2.7 standard
34
+ # library test suite. Added to its signature is only `socket_options`.
35
+ # One additional modification is that we avoid binding to IPv6 servers
36
+ # discovered in DNS if the system doesn't have IPv6 functionality.
37
+ def create_connection(
38
+ address,
39
+ timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
40
+ source_address=None,
41
+ socket_options=None,
42
+ ):
43
+ """Connect to *address* and return the socket object.
44
+
45
+ Convenience function. Connect to *address* (a 2-tuple ``(host,
46
+ port)``) and return the socket object. Passing the optional
47
+ *timeout* parameter will set the timeout on the socket instance
48
+ before attempting to connect. If no *timeout* is supplied, the
49
+ global default timeout setting returned by :func:`socket.getdefaulttimeout`
50
+ is used. If *source_address* is set it must be a tuple of (host, port)
51
+ for the socket to bind as a source address before making the connection.
52
+ An host of '' or port 0 tells the OS to use the default.
53
+ """
54
+
55
+ host, port = address
56
+ if host.startswith("["):
57
+ host = host.strip("[]")
58
+ err = None
59
+
60
+ # Using the value from allowed_gai_family() in the context of getaddrinfo lets
61
+ # us select whether to work with IPv4 DNS records, IPv6 records, or both.
62
+ # The original create_connection function always returns all records.
63
+ family = allowed_gai_family()
64
+
65
+ try:
66
+ host.encode("idna")
67
+ except UnicodeError:
68
+ return six.raise_from(
69
+ LocationParseError(u"'%s', label empty or too long" % host), None
70
+ )
71
+
72
+ for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
73
+ af, socktype, proto, canonname, sa = res
74
+ sock = None
75
+ try:
76
+ sock = socket.socket(af, socktype, proto)
77
+
78
+ # If provided, set socket level options before connecting.
79
+ _set_socket_options(sock, socket_options)
80
+
81
+ if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
82
+ sock.settimeout(timeout)
83
+ if source_address:
84
+ sock.bind(source_address)
85
+ sock.connect(sa)
86
+ return sock
87
+
88
+ except socket.error as e:
89
+ err = e
90
+ if sock is not None:
91
+ sock.close()
92
+ sock = None
93
+
94
+ if err is not None:
95
+ raise err
96
+
97
+ raise socket.error("getaddrinfo returns an empty list")
98
+
99
+
100
+ def _set_socket_options(sock, options):
101
+ if options is None:
102
+ return
103
+
104
+ for opt in options:
105
+ sock.setsockopt(*opt)
106
+
107
+
108
+ def allowed_gai_family():
109
+ """This function is designed to work in the context of
110
+ getaddrinfo, where family=socket.AF_UNSPEC is the default and
111
+ will perform a DNS search for both IPv6 and IPv4 records."""
112
+
113
+ family = socket.AF_INET
114
+ if HAS_IPV6:
115
+ family = socket.AF_UNSPEC
116
+ return family
117
+
118
+
119
+ def _has_ipv6(host):
120
+ """Returns True if the system can bind an IPv6 address."""
121
+ sock = None
122
+ has_ipv6 = False
123
+
124
+ # App Engine doesn't support IPV6 sockets and actually has a quota on the
125
+ # number of sockets that can be used, so just early out here instead of
126
+ # creating a socket needlessly.
127
+ # See https://github.com/urllib3/urllib3/issues/1446
128
+ if _appengine_environ.is_appengine_sandbox():
129
+ return False
130
+
131
+ if socket.has_ipv6:
132
+ # has_ipv6 returns true if cPython was compiled with IPv6 support.
133
+ # It does not tell us if the system has IPv6 support enabled. To
134
+ # determine that we must bind to an IPv6 address.
135
+ # https://github.com/urllib3/urllib3/pull/611
136
+ # https://bugs.python.org/issue658327
137
+ try:
138
+ sock = socket.socket(socket.AF_INET6)
139
+ sock.bind((host, 0))
140
+ has_ipv6 = True
141
+ except Exception:
142
+ pass
143
+
144
+ if sock:
145
+ sock.close()
146
+ return has_ipv6
147
+
148
+
149
+ HAS_IPV6 = _has_ipv6("::1")
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/proxy.py ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .ssl_ import create_urllib3_context, resolve_cert_reqs, resolve_ssl_version
2
+
3
+
4
+ def connection_requires_http_tunnel(
5
+ proxy_url=None, proxy_config=None, destination_scheme=None
6
+ ):
7
+ """
8
+ Returns True if the connection requires an HTTP CONNECT through the proxy.
9
+
10
+ :param URL proxy_url:
11
+ URL of the proxy.
12
+ :param ProxyConfig proxy_config:
13
+ Proxy configuration from poolmanager.py
14
+ :param str destination_scheme:
15
+ The scheme of the destination. (i.e https, http, etc)
16
+ """
17
+ # If we're not using a proxy, no way to use a tunnel.
18
+ if proxy_url is None:
19
+ return False
20
+
21
+ # HTTP destinations never require tunneling, we always forward.
22
+ if destination_scheme == "http":
23
+ return False
24
+
25
+ # Support for forwarding with HTTPS proxies and HTTPS destinations.
26
+ if (
27
+ proxy_url.scheme == "https"
28
+ and proxy_config
29
+ and proxy_config.use_forwarding_for_https
30
+ ):
31
+ return False
32
+
33
+ # Otherwise always use a tunnel.
34
+ return True
35
+
36
+
37
+ def create_proxy_ssl_context(
38
+ ssl_version, cert_reqs, ca_certs=None, ca_cert_dir=None, ca_cert_data=None
39
+ ):
40
+ """
41
+ Generates a default proxy ssl context if one hasn't been provided by the
42
+ user.
43
+ """
44
+ ssl_context = create_urllib3_context(
45
+ ssl_version=resolve_ssl_version(ssl_version),
46
+ cert_reqs=resolve_cert_reqs(cert_reqs),
47
+ )
48
+
49
+ if (
50
+ not ca_certs
51
+ and not ca_cert_dir
52
+ and not ca_cert_data
53
+ and hasattr(ssl_context, "load_default_certs")
54
+ ):
55
+ ssl_context.load_default_certs()
56
+
57
+ return ssl_context
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/queue.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import collections
2
+
3
+ from ..packages import six
4
+ from ..packages.six.moves import queue
5
+
6
+ if six.PY2:
7
+ # Queue is imported for side effects on MS Windows. See issue #229.
8
+ import Queue as _unused_module_Queue # noqa: F401
9
+
10
+
11
+ class LifoQueue(queue.Queue):
12
+ def _init(self, _):
13
+ self.queue = collections.deque()
14
+
15
+ def _qsize(self, len=len):
16
+ return len(self.queue)
17
+
18
+ def _put(self, item):
19
+ self.queue.append(item)
20
+
21
+ def _get(self):
22
+ return self.queue.pop()
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/request.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from base64 import b64encode
4
+
5
+ from ..exceptions import UnrewindableBodyError
6
+ from ..packages.six import b, integer_types
7
+
8
+ # Pass as a value within ``headers`` to skip
9
+ # emitting some HTTP headers that are added automatically.
10
+ # The only headers that are supported are ``Accept-Encoding``,
11
+ # ``Host``, and ``User-Agent``.
12
+ SKIP_HEADER = "@@@SKIP_HEADER@@@"
13
+ SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"])
14
+
15
+ ACCEPT_ENCODING = "gzip,deflate"
16
+
17
+ _FAILEDTELL = object()
18
+
19
+
20
+ def make_headers(
21
+ keep_alive=None,
22
+ accept_encoding=None,
23
+ user_agent=None,
24
+ basic_auth=None,
25
+ proxy_basic_auth=None,
26
+ disable_cache=None,
27
+ ):
28
+ """
29
+ Shortcuts for generating request headers.
30
+
31
+ :param keep_alive:
32
+ If ``True``, adds 'connection: keep-alive' header.
33
+
34
+ :param accept_encoding:
35
+ Can be a boolean, list, or string.
36
+ ``True`` translates to 'gzip,deflate'.
37
+ List will get joined by comma.
38
+ String will be used as provided.
39
+
40
+ :param user_agent:
41
+ String representing the user-agent you want, such as
42
+ "python-urllib3/0.6"
43
+
44
+ :param basic_auth:
45
+ Colon-separated username:password string for 'authorization: basic ...'
46
+ auth header.
47
+
48
+ :param proxy_basic_auth:
49
+ Colon-separated username:password string for 'proxy-authorization: basic ...'
50
+ auth header.
51
+
52
+ :param disable_cache:
53
+ If ``True``, adds 'cache-control: no-cache' header.
54
+
55
+ Example::
56
+
57
+ >>> make_headers(keep_alive=True, user_agent="Batman/1.0")
58
+ {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'}
59
+ >>> make_headers(accept_encoding=True)
60
+ {'accept-encoding': 'gzip,deflate'}
61
+ """
62
+ headers = {}
63
+ if accept_encoding:
64
+ if isinstance(accept_encoding, str):
65
+ pass
66
+ elif isinstance(accept_encoding, list):
67
+ accept_encoding = ",".join(accept_encoding)
68
+ else:
69
+ accept_encoding = ACCEPT_ENCODING
70
+ headers["accept-encoding"] = accept_encoding
71
+
72
+ if user_agent:
73
+ headers["user-agent"] = user_agent
74
+
75
+ if keep_alive:
76
+ headers["connection"] = "keep-alive"
77
+
78
+ if basic_auth:
79
+ headers["authorization"] = "Basic " + b64encode(b(basic_auth)).decode("utf-8")
80
+
81
+ if proxy_basic_auth:
82
+ headers["proxy-authorization"] = "Basic " + b64encode(
83
+ b(proxy_basic_auth)
84
+ ).decode("utf-8")
85
+
86
+ if disable_cache:
87
+ headers["cache-control"] = "no-cache"
88
+
89
+ return headers
90
+
91
+
92
+ def set_file_position(body, pos):
93
+ """
94
+ If a position is provided, move file to that point.
95
+ Otherwise, we'll attempt to record a position for future use.
96
+ """
97
+ if pos is not None:
98
+ rewind_body(body, pos)
99
+ elif getattr(body, "tell", None) is not None:
100
+ try:
101
+ pos = body.tell()
102
+ except (IOError, OSError):
103
+ # This differentiates from None, allowing us to catch
104
+ # a failed `tell()` later when trying to rewind the body.
105
+ pos = _FAILEDTELL
106
+
107
+ return pos
108
+
109
+
110
+ def rewind_body(body, body_pos):
111
+ """
112
+ Attempt to rewind body to a certain position.
113
+ Primarily used for request redirects and retries.
114
+
115
+ :param body:
116
+ File-like object that supports seek.
117
+
118
+ :param int pos:
119
+ Position to seek to in file.
120
+ """
121
+ body_seek = getattr(body, "seek", None)
122
+ if body_seek is not None and isinstance(body_pos, integer_types):
123
+ try:
124
+ body_seek(body_pos)
125
+ except (IOError, OSError):
126
+ raise UnrewindableBodyError(
127
+ "An error occurred when rewinding request body for redirect/retry."
128
+ )
129
+ elif body_pos is _FAILEDTELL:
130
+ raise UnrewindableBodyError(
131
+ "Unable to record file position for rewinding "
132
+ "request body during a redirect/retry."
133
+ )
134
+ else:
135
+ raise ValueError(
136
+ "body_pos must be of type integer, instead it was %s." % type(body_pos)
137
+ )
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/response.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect
4
+
5
+ from ..exceptions import HeaderParsingError
6
+ from ..packages.six.moves import http_client as httplib
7
+
8
+
9
+ def is_fp_closed(obj):
10
+ """
11
+ Checks whether a given file-like object is closed.
12
+
13
+ :param obj:
14
+ The file-like object to check.
15
+ """
16
+
17
+ try:
18
+ # Check `isclosed()` first, in case Python3 doesn't set `closed`.
19
+ # GH Issue #928
20
+ return obj.isclosed()
21
+ except AttributeError:
22
+ pass
23
+
24
+ try:
25
+ # Check via the official file-like-object way.
26
+ return obj.closed
27
+ except AttributeError:
28
+ pass
29
+
30
+ try:
31
+ # Check if the object is a container for another file-like object that
32
+ # gets released on exhaustion (e.g. HTTPResponse).
33
+ return obj.fp is None
34
+ except AttributeError:
35
+ pass
36
+
37
+ raise ValueError("Unable to determine whether fp is closed.")
38
+
39
+
40
+ def assert_header_parsing(headers):
41
+ """
42
+ Asserts whether all headers have been successfully parsed.
43
+ Extracts encountered errors from the result of parsing headers.
44
+
45
+ Only works on Python 3.
46
+
47
+ :param http.client.HTTPMessage headers: Headers to verify.
48
+
49
+ :raises urllib3.exceptions.HeaderParsingError:
50
+ If parsing errors are found.
51
+ """
52
+
53
+ # This will fail silently if we pass in the wrong kind of parameter.
54
+ # To make debugging easier add an explicit check.
55
+ if not isinstance(headers, httplib.HTTPMessage):
56
+ raise TypeError("expected httplib.Message, got {0}.".format(type(headers)))
57
+
58
+ defects = getattr(headers, "defects", None)
59
+ get_payload = getattr(headers, "get_payload", None)
60
+
61
+ unparsed_data = None
62
+ if get_payload:
63
+ # get_payload is actually email.message.Message.get_payload;
64
+ # we're only interested in the result if it's not a multipart message
65
+ if not headers.is_multipart():
66
+ payload = get_payload()
67
+
68
+ if isinstance(payload, (bytes, str)):
69
+ unparsed_data = payload
70
+ if defects:
71
+ # httplib is assuming a response body is available
72
+ # when parsing headers even when httplib only sends
73
+ # header data to parse_headers() This results in
74
+ # defects on multipart responses in particular.
75
+ # See: https://github.com/urllib3/urllib3/issues/800
76
+
77
+ # So we ignore the following defects:
78
+ # - StartBoundaryNotFoundDefect:
79
+ # The claimed start boundary was never found.
80
+ # - MultipartInvariantViolationDefect:
81
+ # A message claimed to be a multipart but no subparts were found.
82
+ defects = [
83
+ defect
84
+ for defect in defects
85
+ if not isinstance(
86
+ defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect)
87
+ )
88
+ ]
89
+
90
+ if defects or unparsed_data:
91
+ raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
92
+
93
+
94
+ def is_response_to_head(response):
95
+ """
96
+ Checks whether the request of a response has been a HEAD-request.
97
+ Handles the quirks of AppEngine.
98
+
99
+ :param http.client.HTTPResponse response:
100
+ Response to check if the originating request
101
+ used 'HEAD' as a method.
102
+ """
103
+ # FIXME: Can we do this somehow without accessing private httplib _method?
104
+ method = response._method
105
+ if isinstance(method, int): # Platform-specific: Appengine
106
+ return method == 3
107
+ return method.upper() == "HEAD"
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/retry.py ADDED
@@ -0,0 +1,622 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import email
4
+ import logging
5
+ import re
6
+ import time
7
+ import warnings
8
+ from collections import namedtuple
9
+ from itertools import takewhile
10
+
11
+ from ..exceptions import (
12
+ ConnectTimeoutError,
13
+ InvalidHeader,
14
+ MaxRetryError,
15
+ ProtocolError,
16
+ ProxyError,
17
+ ReadTimeoutError,
18
+ ResponseError,
19
+ )
20
+ from ..packages import six
21
+
22
+ log = logging.getLogger(__name__)
23
+
24
+
25
+ # Data structure for representing the metadata of requests that result in a retry.
26
+ RequestHistory = namedtuple(
27
+ "RequestHistory", ["method", "url", "error", "status", "redirect_location"]
28
+ )
29
+
30
+
31
+ # TODO: In v2 we can remove this sentinel and metaclass with deprecated options.
32
+ _Default = object()
33
+
34
+
35
+ class _RetryMeta(type):
36
+ @property
37
+ def DEFAULT_METHOD_WHITELIST(cls):
38
+ warnings.warn(
39
+ "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
40
+ "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
41
+ DeprecationWarning,
42
+ )
43
+ return cls.DEFAULT_ALLOWED_METHODS
44
+
45
+ @DEFAULT_METHOD_WHITELIST.setter
46
+ def DEFAULT_METHOD_WHITELIST(cls, value):
47
+ warnings.warn(
48
+ "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
49
+ "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
50
+ DeprecationWarning,
51
+ )
52
+ cls.DEFAULT_ALLOWED_METHODS = value
53
+
54
+ @property
55
+ def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls):
56
+ warnings.warn(
57
+ "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
58
+ "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
59
+ DeprecationWarning,
60
+ )
61
+ return cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT
62
+
63
+ @DEFAULT_REDIRECT_HEADERS_BLACKLIST.setter
64
+ def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls, value):
65
+ warnings.warn(
66
+ "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
67
+ "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
68
+ DeprecationWarning,
69
+ )
70
+ cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT = value
71
+
72
+ @property
73
+ def BACKOFF_MAX(cls):
74
+ warnings.warn(
75
+ "Using 'Retry.BACKOFF_MAX' is deprecated and "
76
+ "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead",
77
+ DeprecationWarning,
78
+ )
79
+ return cls.DEFAULT_BACKOFF_MAX
80
+
81
+ @BACKOFF_MAX.setter
82
+ def BACKOFF_MAX(cls, value):
83
+ warnings.warn(
84
+ "Using 'Retry.BACKOFF_MAX' is deprecated and "
85
+ "will be removed in v2.0. Use 'Retry.DEFAULT_BACKOFF_MAX' instead",
86
+ DeprecationWarning,
87
+ )
88
+ cls.DEFAULT_BACKOFF_MAX = value
89
+
90
+
91
+ @six.add_metaclass(_RetryMeta)
92
+ class Retry(object):
93
+ """Retry configuration.
94
+
95
+ Each retry attempt will create a new Retry object with updated values, so
96
+ they can be safely reused.
97
+
98
+ Retries can be defined as a default for a pool::
99
+
100
+ retries = Retry(connect=5, read=2, redirect=5)
101
+ http = PoolManager(retries=retries)
102
+ response = http.request('GET', 'http://example.com/')
103
+
104
+ Or per-request (which overrides the default for the pool)::
105
+
106
+ response = http.request('GET', 'http://example.com/', retries=Retry(10))
107
+
108
+ Retries can be disabled by passing ``False``::
109
+
110
+ response = http.request('GET', 'http://example.com/', retries=False)
111
+
112
+ Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless
113
+ retries are disabled, in which case the causing exception will be raised.
114
+
115
+ :param int total:
116
+ Total number of retries to allow. Takes precedence over other counts.
117
+
118
+ Set to ``None`` to remove this constraint and fall back on other
119
+ counts.
120
+
121
+ Set to ``0`` to fail on the first retry.
122
+
123
+ Set to ``False`` to disable and imply ``raise_on_redirect=False``.
124
+
125
+ :param int connect:
126
+ How many connection-related errors to retry on.
127
+
128
+ These are errors raised before the request is sent to the remote server,
129
+ which we assume has not triggered the server to process the request.
130
+
131
+ Set to ``0`` to fail on the first retry of this type.
132
+
133
+ :param int read:
134
+ How many times to retry on read errors.
135
+
136
+ These errors are raised after the request was sent to the server, so the
137
+ request may have side-effects.
138
+
139
+ Set to ``0`` to fail on the first retry of this type.
140
+
141
+ :param int redirect:
142
+ How many redirects to perform. Limit this to avoid infinite redirect
143
+ loops.
144
+
145
+ A redirect is a HTTP response with a status code 301, 302, 303, 307 or
146
+ 308.
147
+
148
+ Set to ``0`` to fail on the first retry of this type.
149
+
150
+ Set to ``False`` to disable and imply ``raise_on_redirect=False``.
151
+
152
+ :param int status:
153
+ How many times to retry on bad status codes.
154
+
155
+ These are retries made on responses, where status code matches
156
+ ``status_forcelist``.
157
+
158
+ Set to ``0`` to fail on the first retry of this type.
159
+
160
+ :param int other:
161
+ How many times to retry on other errors.
162
+
163
+ Other errors are errors that are not connect, read, redirect or status errors.
164
+ These errors might be raised after the request was sent to the server, so the
165
+ request might have side-effects.
166
+
167
+ Set to ``0`` to fail on the first retry of this type.
168
+
169
+ If ``total`` is not set, it's a good idea to set this to 0 to account
170
+ for unexpected edge cases and avoid infinite retry loops.
171
+
172
+ :param iterable allowed_methods:
173
+ Set of uppercased HTTP method verbs that we should retry on.
174
+
175
+ By default, we only retry on methods which are considered to be
176
+ idempotent (multiple requests with the same parameters end with the
177
+ same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`.
178
+
179
+ Set to a ``False`` value to retry on any verb.
180
+
181
+ .. warning::
182
+
183
+ Previously this parameter was named ``method_whitelist``, that
184
+ usage is deprecated in v1.26.0 and will be removed in v2.0.
185
+
186
+ :param iterable status_forcelist:
187
+ A set of integer HTTP status codes that we should force a retry on.
188
+ A retry is initiated if the request method is in ``allowed_methods``
189
+ and the response status code is in ``status_forcelist``.
190
+
191
+ By default, this is disabled with ``None``.
192
+
193
+ :param float backoff_factor:
194
+ A backoff factor to apply between attempts after the second try
195
+ (most errors are resolved immediately by a second try without a
196
+ delay). urllib3 will sleep for::
197
+
198
+ {backoff factor} * (2 ** ({number of total retries} - 1))
199
+
200
+ seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep
201
+ for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer
202
+ than :attr:`Retry.DEFAULT_BACKOFF_MAX`.
203
+
204
+ By default, backoff is disabled (set to 0).
205
+
206
+ :param bool raise_on_redirect: Whether, if the number of redirects is
207
+ exhausted, to raise a MaxRetryError, or to return a response with a
208
+ response code in the 3xx range.
209
+
210
+ :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
211
+ whether we should raise an exception, or return a response,
212
+ if status falls in ``status_forcelist`` range and retries have
213
+ been exhausted.
214
+
215
+ :param tuple history: The history of the request encountered during
216
+ each call to :meth:`~Retry.increment`. The list is in the order
217
+ the requests occurred. Each list item is of class :class:`RequestHistory`.
218
+
219
+ :param bool respect_retry_after_header:
220
+ Whether to respect Retry-After header on status codes defined as
221
+ :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
222
+
223
+ :param iterable remove_headers_on_redirect:
224
+ Sequence of headers to remove from the request when a response
225
+ indicating a redirect is returned before firing off the redirected
226
+ request.
227
+ """
228
+
229
+ #: Default methods to be used for ``allowed_methods``
230
+ DEFAULT_ALLOWED_METHODS = frozenset(
231
+ ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"]
232
+ )
233
+
234
+ #: Default status codes to be used for ``status_forcelist``
235
+ RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
236
+
237
+ #: Default headers to be used for ``remove_headers_on_redirect``
238
+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(
239
+ ["Cookie", "Authorization", "Proxy-Authorization"]
240
+ )
241
+
242
+ #: Maximum backoff time.
243
+ DEFAULT_BACKOFF_MAX = 120
244
+
245
+ def __init__(
246
+ self,
247
+ total=10,
248
+ connect=None,
249
+ read=None,
250
+ redirect=None,
251
+ status=None,
252
+ other=None,
253
+ allowed_methods=_Default,
254
+ status_forcelist=None,
255
+ backoff_factor=0,
256
+ raise_on_redirect=True,
257
+ raise_on_status=True,
258
+ history=None,
259
+ respect_retry_after_header=True,
260
+ remove_headers_on_redirect=_Default,
261
+ # TODO: Deprecated, remove in v2.0
262
+ method_whitelist=_Default,
263
+ ):
264
+
265
+ if method_whitelist is not _Default:
266
+ if allowed_methods is not _Default:
267
+ raise ValueError(
268
+ "Using both 'allowed_methods' and "
269
+ "'method_whitelist' together is not allowed. "
270
+ "Instead only use 'allowed_methods'"
271
+ )
272
+ warnings.warn(
273
+ "Using 'method_whitelist' with Retry is deprecated and "
274
+ "will be removed in v2.0. Use 'allowed_methods' instead",
275
+ DeprecationWarning,
276
+ stacklevel=2,
277
+ )
278
+ allowed_methods = method_whitelist
279
+ if allowed_methods is _Default:
280
+ allowed_methods = self.DEFAULT_ALLOWED_METHODS
281
+ if remove_headers_on_redirect is _Default:
282
+ remove_headers_on_redirect = self.DEFAULT_REMOVE_HEADERS_ON_REDIRECT
283
+
284
+ self.total = total
285
+ self.connect = connect
286
+ self.read = read
287
+ self.status = status
288
+ self.other = other
289
+
290
+ if redirect is False or total is False:
291
+ redirect = 0
292
+ raise_on_redirect = False
293
+
294
+ self.redirect = redirect
295
+ self.status_forcelist = status_forcelist or set()
296
+ self.allowed_methods = allowed_methods
297
+ self.backoff_factor = backoff_factor
298
+ self.raise_on_redirect = raise_on_redirect
299
+ self.raise_on_status = raise_on_status
300
+ self.history = history or tuple()
301
+ self.respect_retry_after_header = respect_retry_after_header
302
+ self.remove_headers_on_redirect = frozenset(
303
+ [h.lower() for h in remove_headers_on_redirect]
304
+ )
305
+
306
+ def new(self, **kw):
307
+ params = dict(
308
+ total=self.total,
309
+ connect=self.connect,
310
+ read=self.read,
311
+ redirect=self.redirect,
312
+ status=self.status,
313
+ other=self.other,
314
+ status_forcelist=self.status_forcelist,
315
+ backoff_factor=self.backoff_factor,
316
+ raise_on_redirect=self.raise_on_redirect,
317
+ raise_on_status=self.raise_on_status,
318
+ history=self.history,
319
+ remove_headers_on_redirect=self.remove_headers_on_redirect,
320
+ respect_retry_after_header=self.respect_retry_after_header,
321
+ )
322
+
323
+ # TODO: If already given in **kw we use what's given to us
324
+ # If not given we need to figure out what to pass. We decide
325
+ # based on whether our class has the 'method_whitelist' property
326
+ # and if so we pass the deprecated 'method_whitelist' otherwise
327
+ # we use 'allowed_methods'. Remove in v2.0
328
+ if "method_whitelist" not in kw and "allowed_methods" not in kw:
329
+ if "method_whitelist" in self.__dict__:
330
+ warnings.warn(
331
+ "Using 'method_whitelist' with Retry is deprecated and "
332
+ "will be removed in v2.0. Use 'allowed_methods' instead",
333
+ DeprecationWarning,
334
+ )
335
+ params["method_whitelist"] = self.allowed_methods
336
+ else:
337
+ params["allowed_methods"] = self.allowed_methods
338
+
339
+ params.update(kw)
340
+ return type(self)(**params)
341
+
342
+ @classmethod
343
+ def from_int(cls, retries, redirect=True, default=None):
344
+ """Backwards-compatibility for the old retries format."""
345
+ if retries is None:
346
+ retries = default if default is not None else cls.DEFAULT
347
+
348
+ if isinstance(retries, Retry):
349
+ return retries
350
+
351
+ redirect = bool(redirect) and None
352
+ new_retries = cls(retries, redirect=redirect)
353
+ log.debug("Converted retries value: %r -> %r", retries, new_retries)
354
+ return new_retries
355
+
356
+ def get_backoff_time(self):
357
+ """Formula for computing the current backoff
358
+
359
+ :rtype: float
360
+ """
361
+ # We want to consider only the last consecutive errors sequence (Ignore redirects).
362
+ consecutive_errors_len = len(
363
+ list(
364
+ takewhile(lambda x: x.redirect_location is None, reversed(self.history))
365
+ )
366
+ )
367
+ if consecutive_errors_len <= 1:
368
+ return 0
369
+
370
+ backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
371
+ return min(self.DEFAULT_BACKOFF_MAX, backoff_value)
372
+
373
+ def parse_retry_after(self, retry_after):
374
+ # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4
375
+ if re.match(r"^\s*[0-9]+\s*$", retry_after):
376
+ seconds = int(retry_after)
377
+ else:
378
+ retry_date_tuple = email.utils.parsedate_tz(retry_after)
379
+ if retry_date_tuple is None:
380
+ raise InvalidHeader("Invalid Retry-After header: %s" % retry_after)
381
+ if retry_date_tuple[9] is None: # Python 2
382
+ # Assume UTC if no timezone was specified
383
+ # On Python2.7, parsedate_tz returns None for a timezone offset
384
+ # instead of 0 if no timezone is given, where mktime_tz treats
385
+ # a None timezone offset as local time.
386
+ retry_date_tuple = retry_date_tuple[:9] + (0,) + retry_date_tuple[10:]
387
+
388
+ retry_date = email.utils.mktime_tz(retry_date_tuple)
389
+ seconds = retry_date - time.time()
390
+
391
+ if seconds < 0:
392
+ seconds = 0
393
+
394
+ return seconds
395
+
396
+ def get_retry_after(self, response):
397
+ """Get the value of Retry-After in seconds."""
398
+
399
+ retry_after = response.headers.get("Retry-After")
400
+
401
+ if retry_after is None:
402
+ return None
403
+
404
+ return self.parse_retry_after(retry_after)
405
+
406
+ def sleep_for_retry(self, response=None):
407
+ retry_after = self.get_retry_after(response)
408
+ if retry_after:
409
+ time.sleep(retry_after)
410
+ return True
411
+
412
+ return False
413
+
414
+ def _sleep_backoff(self):
415
+ backoff = self.get_backoff_time()
416
+ if backoff <= 0:
417
+ return
418
+ time.sleep(backoff)
419
+
420
+ def sleep(self, response=None):
421
+ """Sleep between retry attempts.
422
+
423
+ This method will respect a server's ``Retry-After`` response header
424
+ and sleep the duration of the time requested. If that is not present, it
425
+ will use an exponential backoff. By default, the backoff factor is 0 and
426
+ this method will return immediately.
427
+ """
428
+
429
+ if self.respect_retry_after_header and response:
430
+ slept = self.sleep_for_retry(response)
431
+ if slept:
432
+ return
433
+
434
+ self._sleep_backoff()
435
+
436
+ def _is_connection_error(self, err):
437
+ """Errors when we're fairly sure that the server did not receive the
438
+ request, so it should be safe to retry.
439
+ """
440
+ if isinstance(err, ProxyError):
441
+ err = err.original_error
442
+ return isinstance(err, ConnectTimeoutError)
443
+
444
+ def _is_read_error(self, err):
445
+ """Errors that occur after the request has been started, so we should
446
+ assume that the server began processing it.
447
+ """
448
+ return isinstance(err, (ReadTimeoutError, ProtocolError))
449
+
450
+ def _is_method_retryable(self, method):
451
+ """Checks if a given HTTP method should be retried upon, depending if
452
+ it is included in the allowed_methods
453
+ """
454
+ # TODO: For now favor if the Retry implementation sets its own method_whitelist
455
+ # property outside of our constructor to avoid breaking custom implementations.
456
+ if "method_whitelist" in self.__dict__:
457
+ warnings.warn(
458
+ "Using 'method_whitelist' with Retry is deprecated and "
459
+ "will be removed in v2.0. Use 'allowed_methods' instead",
460
+ DeprecationWarning,
461
+ )
462
+ allowed_methods = self.method_whitelist
463
+ else:
464
+ allowed_methods = self.allowed_methods
465
+
466
+ if allowed_methods and method.upper() not in allowed_methods:
467
+ return False
468
+ return True
469
+
470
+ def is_retry(self, method, status_code, has_retry_after=False):
471
+ """Is this method/status code retryable? (Based on allowlists and control
472
+ variables such as the number of total retries to allow, whether to
473
+ respect the Retry-After header, whether this header is present, and
474
+ whether the returned status code is on the list of status codes to
475
+ be retried upon on the presence of the aforementioned header)
476
+ """
477
+ if not self._is_method_retryable(method):
478
+ return False
479
+
480
+ if self.status_forcelist and status_code in self.status_forcelist:
481
+ return True
482
+
483
+ return (
484
+ self.total
485
+ and self.respect_retry_after_header
486
+ and has_retry_after
487
+ and (status_code in self.RETRY_AFTER_STATUS_CODES)
488
+ )
489
+
490
+ def is_exhausted(self):
491
+ """Are we out of retries?"""
492
+ retry_counts = (
493
+ self.total,
494
+ self.connect,
495
+ self.read,
496
+ self.redirect,
497
+ self.status,
498
+ self.other,
499
+ )
500
+ retry_counts = list(filter(None, retry_counts))
501
+ if not retry_counts:
502
+ return False
503
+
504
+ return min(retry_counts) < 0
505
+
506
+ def increment(
507
+ self,
508
+ method=None,
509
+ url=None,
510
+ response=None,
511
+ error=None,
512
+ _pool=None,
513
+ _stacktrace=None,
514
+ ):
515
+ """Return a new Retry object with incremented retry counters.
516
+
517
+ :param response: A response object, or None, if the server did not
518
+ return a response.
519
+ :type response: :class:`~urllib3.response.HTTPResponse`
520
+ :param Exception error: An error encountered during the request, or
521
+ None if the response was received successfully.
522
+
523
+ :return: A new ``Retry`` object.
524
+ """
525
+ if self.total is False and error:
526
+ # Disabled, indicate to re-raise the error.
527
+ raise six.reraise(type(error), error, _stacktrace)
528
+
529
+ total = self.total
530
+ if total is not None:
531
+ total -= 1
532
+
533
+ connect = self.connect
534
+ read = self.read
535
+ redirect = self.redirect
536
+ status_count = self.status
537
+ other = self.other
538
+ cause = "unknown"
539
+ status = None
540
+ redirect_location = None
541
+
542
+ if error and self._is_connection_error(error):
543
+ # Connect retry?
544
+ if connect is False:
545
+ raise six.reraise(type(error), error, _stacktrace)
546
+ elif connect is not None:
547
+ connect -= 1
548
+
549
+ elif error and self._is_read_error(error):
550
+ # Read retry?
551
+ if read is False or not self._is_method_retryable(method):
552
+ raise six.reraise(type(error), error, _stacktrace)
553
+ elif read is not None:
554
+ read -= 1
555
+
556
+ elif error:
557
+ # Other retry?
558
+ if other is not None:
559
+ other -= 1
560
+
561
+ elif response and response.get_redirect_location():
562
+ # Redirect retry?
563
+ if redirect is not None:
564
+ redirect -= 1
565
+ cause = "too many redirects"
566
+ redirect_location = response.get_redirect_location()
567
+ status = response.status
568
+
569
+ else:
570
+ # Incrementing because of a server error like a 500 in
571
+ # status_forcelist and the given method is in the allowed_methods
572
+ cause = ResponseError.GENERIC_ERROR
573
+ if response and response.status:
574
+ if status_count is not None:
575
+ status_count -= 1
576
+ cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status)
577
+ status = response.status
578
+
579
+ history = self.history + (
580
+ RequestHistory(method, url, error, status, redirect_location),
581
+ )
582
+
583
+ new_retry = self.new(
584
+ total=total,
585
+ connect=connect,
586
+ read=read,
587
+ redirect=redirect,
588
+ status=status_count,
589
+ other=other,
590
+ history=history,
591
+ )
592
+
593
+ if new_retry.is_exhausted():
594
+ raise MaxRetryError(_pool, url, error or ResponseError(cause))
595
+
596
+ log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
597
+
598
+ return new_retry
599
+
600
+ def __repr__(self):
601
+ return (
602
+ "{cls.__name__}(total={self.total}, connect={self.connect}, "
603
+ "read={self.read}, redirect={self.redirect}, status={self.status})"
604
+ ).format(cls=type(self), self=self)
605
+
606
+ def __getattr__(self, item):
607
+ if item == "method_whitelist":
608
+ # TODO: Remove this deprecated alias in v2.0
609
+ warnings.warn(
610
+ "Using 'method_whitelist' with Retry is deprecated and "
611
+ "will be removed in v2.0. Use 'allowed_methods' instead",
612
+ DeprecationWarning,
613
+ )
614
+ return self.allowed_methods
615
+ try:
616
+ return getattr(super(Retry, self), item)
617
+ except AttributeError:
618
+ return getattr(Retry, item)
619
+
620
+
621
+ # For backwards compatibility (equivalent to pre-v1.9):
622
+ Retry.DEFAULT = Retry(3)
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_.py ADDED
@@ -0,0 +1,495 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import hmac
4
+ import os
5
+ import sys
6
+ import warnings
7
+ from binascii import hexlify, unhexlify
8
+ from hashlib import md5, sha1, sha256
9
+
10
+ from ..exceptions import (
11
+ InsecurePlatformWarning,
12
+ ProxySchemeUnsupported,
13
+ SNIMissingWarning,
14
+ SSLError,
15
+ )
16
+ from ..packages import six
17
+ from .url import BRACELESS_IPV6_ADDRZ_RE, IPV4_RE
18
+
19
+ SSLContext = None
20
+ SSLTransport = None
21
+ HAS_SNI = False
22
+ IS_PYOPENSSL = False
23
+ IS_SECURETRANSPORT = False
24
+ ALPN_PROTOCOLS = ["http/1.1"]
25
+
26
+ # Maps the length of a digest to a possible hash function producing this digest
27
+ HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256}
28
+
29
+
30
+ def _const_compare_digest_backport(a, b):
31
+ """
32
+ Compare two digests of equal length in constant time.
33
+
34
+ The digests must be of type str/bytes.
35
+ Returns True if the digests match, and False otherwise.
36
+ """
37
+ result = abs(len(a) - len(b))
38
+ for left, right in zip(bytearray(a), bytearray(b)):
39
+ result |= left ^ right
40
+ return result == 0
41
+
42
+
43
+ _const_compare_digest = getattr(hmac, "compare_digest", _const_compare_digest_backport)
44
+
45
+ try: # Test for SSL features
46
+ import ssl
47
+ from ssl import CERT_REQUIRED, wrap_socket
48
+ except ImportError:
49
+ pass
50
+
51
+ try:
52
+ from ssl import HAS_SNI # Has SNI?
53
+ except ImportError:
54
+ pass
55
+
56
+ try:
57
+ from .ssltransport import SSLTransport
58
+ except ImportError:
59
+ pass
60
+
61
+
62
+ try: # Platform-specific: Python 3.6
63
+ from ssl import PROTOCOL_TLS
64
+
65
+ PROTOCOL_SSLv23 = PROTOCOL_TLS
66
+ except ImportError:
67
+ try:
68
+ from ssl import PROTOCOL_SSLv23 as PROTOCOL_TLS
69
+
70
+ PROTOCOL_SSLv23 = PROTOCOL_TLS
71
+ except ImportError:
72
+ PROTOCOL_SSLv23 = PROTOCOL_TLS = 2
73
+
74
+ try:
75
+ from ssl import PROTOCOL_TLS_CLIENT
76
+ except ImportError:
77
+ PROTOCOL_TLS_CLIENT = PROTOCOL_TLS
78
+
79
+
80
+ try:
81
+ from ssl import OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3
82
+ except ImportError:
83
+ OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000
84
+ OP_NO_COMPRESSION = 0x20000
85
+
86
+
87
+ try: # OP_NO_TICKET was added in Python 3.6
88
+ from ssl import OP_NO_TICKET
89
+ except ImportError:
90
+ OP_NO_TICKET = 0x4000
91
+
92
+
93
+ # A secure default.
94
+ # Sources for more information on TLS ciphers:
95
+ #
96
+ # - https://wiki.mozilla.org/Security/Server_Side_TLS
97
+ # - https://www.ssllabs.com/projects/best-practices/index.html
98
+ # - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
99
+ #
100
+ # The general intent is:
101
+ # - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE),
102
+ # - prefer ECDHE over DHE for better performance,
103
+ # - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and
104
+ # security,
105
+ # - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common,
106
+ # - disable NULL authentication, MD5 MACs, DSS, and other
107
+ # insecure ciphers for security reasons.
108
+ # - NOTE: TLS 1.3 cipher suites are managed through a different interface
109
+ # not exposed by CPython (yet!) and are enabled by default if they're available.
110
+ DEFAULT_CIPHERS = ":".join(
111
+ [
112
+ "ECDHE+AESGCM",
113
+ "ECDHE+CHACHA20",
114
+ "DHE+AESGCM",
115
+ "DHE+CHACHA20",
116
+ "ECDH+AESGCM",
117
+ "DH+AESGCM",
118
+ "ECDH+AES",
119
+ "DH+AES",
120
+ "RSA+AESGCM",
121
+ "RSA+AES",
122
+ "!aNULL",
123
+ "!eNULL",
124
+ "!MD5",
125
+ "!DSS",
126
+ ]
127
+ )
128
+
129
+ try:
130
+ from ssl import SSLContext # Modern SSL?
131
+ except ImportError:
132
+
133
+ class SSLContext(object): # Platform-specific: Python 2
134
+ def __init__(self, protocol_version):
135
+ self.protocol = protocol_version
136
+ # Use default values from a real SSLContext
137
+ self.check_hostname = False
138
+ self.verify_mode = ssl.CERT_NONE
139
+ self.ca_certs = None
140
+ self.options = 0
141
+ self.certfile = None
142
+ self.keyfile = None
143
+ self.ciphers = None
144
+
145
+ def load_cert_chain(self, certfile, keyfile):
146
+ self.certfile = certfile
147
+ self.keyfile = keyfile
148
+
149
+ def load_verify_locations(self, cafile=None, capath=None, cadata=None):
150
+ self.ca_certs = cafile
151
+
152
+ if capath is not None:
153
+ raise SSLError("CA directories not supported in older Pythons")
154
+
155
+ if cadata is not None:
156
+ raise SSLError("CA data not supported in older Pythons")
157
+
158
+ def set_ciphers(self, cipher_suite):
159
+ self.ciphers = cipher_suite
160
+
161
+ def wrap_socket(self, socket, server_hostname=None, server_side=False):
162
+ warnings.warn(
163
+ "A true SSLContext object is not available. This prevents "
164
+ "urllib3 from configuring SSL appropriately and may cause "
165
+ "certain SSL connections to fail. You can upgrade to a newer "
166
+ "version of Python to solve this. For more information, see "
167
+ "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
168
+ "#ssl-warnings",
169
+ InsecurePlatformWarning,
170
+ )
171
+ kwargs = {
172
+ "keyfile": self.keyfile,
173
+ "certfile": self.certfile,
174
+ "ca_certs": self.ca_certs,
175
+ "cert_reqs": self.verify_mode,
176
+ "ssl_version": self.protocol,
177
+ "server_side": server_side,
178
+ }
179
+ return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
180
+
181
+
182
+ def assert_fingerprint(cert, fingerprint):
183
+ """
184
+ Checks if given fingerprint matches the supplied certificate.
185
+
186
+ :param cert:
187
+ Certificate as bytes object.
188
+ :param fingerprint:
189
+ Fingerprint as string of hexdigits, can be interspersed by colons.
190
+ """
191
+
192
+ fingerprint = fingerprint.replace(":", "").lower()
193
+ digest_length = len(fingerprint)
194
+ hashfunc = HASHFUNC_MAP.get(digest_length)
195
+ if not hashfunc:
196
+ raise SSLError("Fingerprint of invalid length: {0}".format(fingerprint))
197
+
198
+ # We need encode() here for py32; works on py2 and p33.
199
+ fingerprint_bytes = unhexlify(fingerprint.encode())
200
+
201
+ cert_digest = hashfunc(cert).digest()
202
+
203
+ if not _const_compare_digest(cert_digest, fingerprint_bytes):
204
+ raise SSLError(
205
+ 'Fingerprints did not match. Expected "{0}", got "{1}".'.format(
206
+ fingerprint, hexlify(cert_digest)
207
+ )
208
+ )
209
+
210
+
211
+ def resolve_cert_reqs(candidate):
212
+ """
213
+ Resolves the argument to a numeric constant, which can be passed to
214
+ the wrap_socket function/method from the ssl module.
215
+ Defaults to :data:`ssl.CERT_REQUIRED`.
216
+ If given a string it is assumed to be the name of the constant in the
217
+ :mod:`ssl` module or its abbreviation.
218
+ (So you can specify `REQUIRED` instead of `CERT_REQUIRED`.
219
+ If it's neither `None` nor a string we assume it is already the numeric
220
+ constant which can directly be passed to wrap_socket.
221
+ """
222
+ if candidate is None:
223
+ return CERT_REQUIRED
224
+
225
+ if isinstance(candidate, str):
226
+ res = getattr(ssl, candidate, None)
227
+ if res is None:
228
+ res = getattr(ssl, "CERT_" + candidate)
229
+ return res
230
+
231
+ return candidate
232
+
233
+
234
+ def resolve_ssl_version(candidate):
235
+ """
236
+ like resolve_cert_reqs
237
+ """
238
+ if candidate is None:
239
+ return PROTOCOL_TLS
240
+
241
+ if isinstance(candidate, str):
242
+ res = getattr(ssl, candidate, None)
243
+ if res is None:
244
+ res = getattr(ssl, "PROTOCOL_" + candidate)
245
+ return res
246
+
247
+ return candidate
248
+
249
+
250
+ def create_urllib3_context(
251
+ ssl_version=None, cert_reqs=None, options=None, ciphers=None
252
+ ):
253
+ """All arguments have the same meaning as ``ssl_wrap_socket``.
254
+
255
+ By default, this function does a lot of the same work that
256
+ ``ssl.create_default_context`` does on Python 3.4+. It:
257
+
258
+ - Disables SSLv2, SSLv3, and compression
259
+ - Sets a restricted set of server ciphers
260
+
261
+ If you wish to enable SSLv3, you can do::
262
+
263
+ from pip._vendor.urllib3.util import ssl_
264
+ context = ssl_.create_urllib3_context()
265
+ context.options &= ~ssl_.OP_NO_SSLv3
266
+
267
+ You can do the same to enable compression (substituting ``COMPRESSION``
268
+ for ``SSLv3`` in the last line above).
269
+
270
+ :param ssl_version:
271
+ The desired protocol version to use. This will default to
272
+ PROTOCOL_SSLv23 which will negotiate the highest protocol that both
273
+ the server and your installation of OpenSSL support.
274
+ :param cert_reqs:
275
+ Whether to require the certificate verification. This defaults to
276
+ ``ssl.CERT_REQUIRED``.
277
+ :param options:
278
+ Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
279
+ ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
280
+ :param ciphers:
281
+ Which cipher suites to allow the server to select.
282
+ :returns:
283
+ Constructed SSLContext object with specified options
284
+ :rtype: SSLContext
285
+ """
286
+ # PROTOCOL_TLS is deprecated in Python 3.10
287
+ if not ssl_version or ssl_version == PROTOCOL_TLS:
288
+ ssl_version = PROTOCOL_TLS_CLIENT
289
+
290
+ context = SSLContext(ssl_version)
291
+
292
+ context.set_ciphers(ciphers or DEFAULT_CIPHERS)
293
+
294
+ # Setting the default here, as we may have no ssl module on import
295
+ cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
296
+
297
+ if options is None:
298
+ options = 0
299
+ # SSLv2 is easily broken and is considered harmful and dangerous
300
+ options |= OP_NO_SSLv2
301
+ # SSLv3 has several problems and is now dangerous
302
+ options |= OP_NO_SSLv3
303
+ # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
304
+ # (issue #309)
305
+ options |= OP_NO_COMPRESSION
306
+ # TLSv1.2 only. Unless set explicitly, do not request tickets.
307
+ # This may save some bandwidth on wire, and although the ticket is encrypted,
308
+ # there is a risk associated with it being on wire,
309
+ # if the server is not rotating its ticketing keys properly.
310
+ options |= OP_NO_TICKET
311
+
312
+ context.options |= options
313
+
314
+ # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
315
+ # necessary for conditional client cert authentication with TLS 1.3.
316
+ # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
317
+ # versions of Python. We only enable on Python 3.7.4+ or if certificate
318
+ # verification is enabled to work around Python issue #37428
319
+ # See: https://bugs.python.org/issue37428
320
+ if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr(
321
+ context, "post_handshake_auth", None
322
+ ) is not None:
323
+ context.post_handshake_auth = True
324
+
325
+ def disable_check_hostname():
326
+ if (
327
+ getattr(context, "check_hostname", None) is not None
328
+ ): # Platform-specific: Python 3.2
329
+ # We do our own verification, including fingerprints and alternative
330
+ # hostnames. So disable it here
331
+ context.check_hostname = False
332
+
333
+ # The order of the below lines setting verify_mode and check_hostname
334
+ # matter due to safe-guards SSLContext has to prevent an SSLContext with
335
+ # check_hostname=True, verify_mode=NONE/OPTIONAL. This is made even more
336
+ # complex because we don't know whether PROTOCOL_TLS_CLIENT will be used
337
+ # or not so we don't know the initial state of the freshly created SSLContext.
338
+ if cert_reqs == ssl.CERT_REQUIRED:
339
+ context.verify_mode = cert_reqs
340
+ disable_check_hostname()
341
+ else:
342
+ disable_check_hostname()
343
+ context.verify_mode = cert_reqs
344
+
345
+ # Enable logging of TLS session keys via defacto standard environment variable
346
+ # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values.
347
+ if hasattr(context, "keylog_filename"):
348
+ sslkeylogfile = os.environ.get("SSLKEYLOGFILE")
349
+ if sslkeylogfile:
350
+ context.keylog_filename = sslkeylogfile
351
+
352
+ return context
353
+
354
+
355
+ def ssl_wrap_socket(
356
+ sock,
357
+ keyfile=None,
358
+ certfile=None,
359
+ cert_reqs=None,
360
+ ca_certs=None,
361
+ server_hostname=None,
362
+ ssl_version=None,
363
+ ciphers=None,
364
+ ssl_context=None,
365
+ ca_cert_dir=None,
366
+ key_password=None,
367
+ ca_cert_data=None,
368
+ tls_in_tls=False,
369
+ ):
370
+ """
371
+ All arguments except for server_hostname, ssl_context, and ca_cert_dir have
372
+ the same meaning as they do when using :func:`ssl.wrap_socket`.
373
+
374
+ :param server_hostname:
375
+ When SNI is supported, the expected hostname of the certificate
376
+ :param ssl_context:
377
+ A pre-made :class:`SSLContext` object. If none is provided, one will
378
+ be created using :func:`create_urllib3_context`.
379
+ :param ciphers:
380
+ A string of ciphers we wish the client to support.
381
+ :param ca_cert_dir:
382
+ A directory containing CA certificates in multiple separate files, as
383
+ supported by OpenSSL's -CApath flag or the capath argument to
384
+ SSLContext.load_verify_locations().
385
+ :param key_password:
386
+ Optional password if the keyfile is encrypted.
387
+ :param ca_cert_data:
388
+ Optional string containing CA certificates in PEM format suitable for
389
+ passing as the cadata parameter to SSLContext.load_verify_locations()
390
+ :param tls_in_tls:
391
+ Use SSLTransport to wrap the existing socket.
392
+ """
393
+ context = ssl_context
394
+ if context is None:
395
+ # Note: This branch of code and all the variables in it are no longer
396
+ # used by urllib3 itself. We should consider deprecating and removing
397
+ # this code.
398
+ context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers)
399
+
400
+ if ca_certs or ca_cert_dir or ca_cert_data:
401
+ try:
402
+ context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data)
403
+ except (IOError, OSError) as e:
404
+ raise SSLError(e)
405
+
406
+ elif ssl_context is None and hasattr(context, "load_default_certs"):
407
+ # try to load OS default certs; works well on Windows (require Python3.4+)
408
+ context.load_default_certs()
409
+
410
+ # Attempt to detect if we get the goofy behavior of the
411
+ # keyfile being encrypted and OpenSSL asking for the
412
+ # passphrase via the terminal and instead error out.
413
+ if keyfile and key_password is None and _is_key_file_encrypted(keyfile):
414
+ raise SSLError("Client private key is encrypted, password is required")
415
+
416
+ if certfile:
417
+ if key_password is None:
418
+ context.load_cert_chain(certfile, keyfile)
419
+ else:
420
+ context.load_cert_chain(certfile, keyfile, key_password)
421
+
422
+ try:
423
+ if hasattr(context, "set_alpn_protocols"):
424
+ context.set_alpn_protocols(ALPN_PROTOCOLS)
425
+ except NotImplementedError: # Defensive: in CI, we always have set_alpn_protocols
426
+ pass
427
+
428
+ # If we detect server_hostname is an IP address then the SNI
429
+ # extension should not be used according to RFC3546 Section 3.1
430
+ use_sni_hostname = server_hostname and not is_ipaddress(server_hostname)
431
+ # SecureTransport uses server_hostname in certificate verification.
432
+ send_sni = (use_sni_hostname and HAS_SNI) or (
433
+ IS_SECURETRANSPORT and server_hostname
434
+ )
435
+ # Do not warn the user if server_hostname is an invalid SNI hostname.
436
+ if not HAS_SNI and use_sni_hostname:
437
+ warnings.warn(
438
+ "An HTTPS request has been made, but the SNI (Server Name "
439
+ "Indication) extension to TLS is not available on this platform. "
440
+ "This may cause the server to present an incorrect TLS "
441
+ "certificate, which can cause validation failures. You can upgrade to "
442
+ "a newer version of Python to solve this. For more information, see "
443
+ "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
444
+ "#ssl-warnings",
445
+ SNIMissingWarning,
446
+ )
447
+
448
+ if send_sni:
449
+ ssl_sock = _ssl_wrap_socket_impl(
450
+ sock, context, tls_in_tls, server_hostname=server_hostname
451
+ )
452
+ else:
453
+ ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
454
+ return ssl_sock
455
+
456
+
457
+ def is_ipaddress(hostname):
458
+ """Detects whether the hostname given is an IPv4 or IPv6 address.
459
+ Also detects IPv6 addresses with Zone IDs.
460
+
461
+ :param str hostname: Hostname to examine.
462
+ :return: True if the hostname is an IP address, False otherwise.
463
+ """
464
+ if not six.PY2 and isinstance(hostname, bytes):
465
+ # IDN A-label bytes are ASCII compatible.
466
+ hostname = hostname.decode("ascii")
467
+ return bool(IPV4_RE.match(hostname) or BRACELESS_IPV6_ADDRZ_RE.match(hostname))
468
+
469
+
470
+ def _is_key_file_encrypted(key_file):
471
+ """Detects if a key file is encrypted or not."""
472
+ with open(key_file, "r") as f:
473
+ for line in f:
474
+ # Look for Proc-Type: 4,ENCRYPTED
475
+ if "ENCRYPTED" in line:
476
+ return True
477
+
478
+ return False
479
+
480
+
481
+ def _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname=None):
482
+ if tls_in_tls:
483
+ if not SSLTransport:
484
+ # Import error, ssl is not available.
485
+ raise ProxySchemeUnsupported(
486
+ "TLS in TLS requires support for the 'ssl' module"
487
+ )
488
+
489
+ SSLTransport._validate_ssl_context_for_tls_in_tls(ssl_context)
490
+ return SSLTransport(sock, ssl_context, server_hostname)
491
+
492
+ if server_hostname:
493
+ return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
494
+ else:
495
+ return ssl_context.wrap_socket(sock)
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """The match_hostname() function from Python 3.3.3, essential when using SSL."""
2
+
3
+ # Note: This file is under the PSF license as the code comes from the python
4
+ # stdlib. http://docs.python.org/3/license.html
5
+
6
+ import re
7
+ import sys
8
+
9
+ # ipaddress has been backported to 2.6+ in pypi. If it is installed on the
10
+ # system, use it to handle IPAddress ServerAltnames (this was added in
11
+ # python-3.5) otherwise only do DNS matching. This allows
12
+ # util.ssl_match_hostname to continue to be used in Python 2.7.
13
+ try:
14
+ import ipaddress
15
+ except ImportError:
16
+ ipaddress = None
17
+
18
+ __version__ = "3.5.0.1"
19
+
20
+
21
+ class CertificateError(ValueError):
22
+ pass
23
+
24
+
25
+ def _dnsname_match(dn, hostname, max_wildcards=1):
26
+ """Matching according to RFC 6125, section 6.4.3
27
+
28
+ http://tools.ietf.org/html/rfc6125#section-6.4.3
29
+ """
30
+ pats = []
31
+ if not dn:
32
+ return False
33
+
34
+ # Ported from python3-syntax:
35
+ # leftmost, *remainder = dn.split(r'.')
36
+ parts = dn.split(r".")
37
+ leftmost = parts[0]
38
+ remainder = parts[1:]
39
+
40
+ wildcards = leftmost.count("*")
41
+ if wildcards > max_wildcards:
42
+ # Issue #17980: avoid denials of service by refusing more
43
+ # than one wildcard per fragment. A survey of established
44
+ # policy among SSL implementations showed it to be a
45
+ # reasonable choice.
46
+ raise CertificateError(
47
+ "too many wildcards in certificate DNS name: " + repr(dn)
48
+ )
49
+
50
+ # speed up common case w/o wildcards
51
+ if not wildcards:
52
+ return dn.lower() == hostname.lower()
53
+
54
+ # RFC 6125, section 6.4.3, subitem 1.
55
+ # The client SHOULD NOT attempt to match a presented identifier in which
56
+ # the wildcard character comprises a label other than the left-most label.
57
+ if leftmost == "*":
58
+ # When '*' is a fragment by itself, it matches a non-empty dotless
59
+ # fragment.
60
+ pats.append("[^.]+")
61
+ elif leftmost.startswith("xn--") or hostname.startswith("xn--"):
62
+ # RFC 6125, section 6.4.3, subitem 3.
63
+ # The client SHOULD NOT attempt to match a presented identifier
64
+ # where the wildcard character is embedded within an A-label or
65
+ # U-label of an internationalized domain name.
66
+ pats.append(re.escape(leftmost))
67
+ else:
68
+ # Otherwise, '*' matches any dotless string, e.g. www*
69
+ pats.append(re.escape(leftmost).replace(r"\*", "[^.]*"))
70
+
71
+ # add the remaining fragments, ignore any wildcards
72
+ for frag in remainder:
73
+ pats.append(re.escape(frag))
74
+
75
+ pat = re.compile(r"\A" + r"\.".join(pats) + r"\Z", re.IGNORECASE)
76
+ return pat.match(hostname)
77
+
78
+
79
+ def _to_unicode(obj):
80
+ if isinstance(obj, str) and sys.version_info < (3,):
81
+ # ignored flake8 # F821 to support python 2.7 function
82
+ obj = unicode(obj, encoding="ascii", errors="strict") # noqa: F821
83
+ return obj
84
+
85
+
86
+ def _ipaddress_match(ipname, host_ip):
87
+ """Exact matching of IP addresses.
88
+
89
+ RFC 6125 explicitly doesn't define an algorithm for this
90
+ (section 1.7.2 - "Out of Scope").
91
+ """
92
+ # OpenSSL may add a trailing newline to a subjectAltName's IP address
93
+ # Divergence from upstream: ipaddress can't handle byte str
94
+ ip = ipaddress.ip_address(_to_unicode(ipname).rstrip())
95
+ return ip == host_ip
96
+
97
+
98
+ def match_hostname(cert, hostname):
99
+ """Verify that *cert* (in decoded format as returned by
100
+ SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
101
+ rules are followed, but IP addresses are not accepted for *hostname*.
102
+
103
+ CertificateError is raised on failure. On success, the function
104
+ returns nothing.
105
+ """
106
+ if not cert:
107
+ raise ValueError(
108
+ "empty or no certificate, match_hostname needs a "
109
+ "SSL socket or SSL context with either "
110
+ "CERT_OPTIONAL or CERT_REQUIRED"
111
+ )
112
+ try:
113
+ # Divergence from upstream: ipaddress can't handle byte str
114
+ host_ip = ipaddress.ip_address(_to_unicode(hostname))
115
+ except (UnicodeError, ValueError):
116
+ # ValueError: Not an IP address (common case)
117
+ # UnicodeError: Divergence from upstream: Have to deal with ipaddress not taking
118
+ # byte strings. addresses should be all ascii, so we consider it not
119
+ # an ipaddress in this case
120
+ host_ip = None
121
+ except AttributeError:
122
+ # Divergence from upstream: Make ipaddress library optional
123
+ if ipaddress is None:
124
+ host_ip = None
125
+ else: # Defensive
126
+ raise
127
+ dnsnames = []
128
+ san = cert.get("subjectAltName", ())
129
+ for key, value in san:
130
+ if key == "DNS":
131
+ if host_ip is None and _dnsname_match(value, hostname):
132
+ return
133
+ dnsnames.append(value)
134
+ elif key == "IP Address":
135
+ if host_ip is not None and _ipaddress_match(value, host_ip):
136
+ return
137
+ dnsnames.append(value)
138
+ if not dnsnames:
139
+ # The subject is only checked when there is no dNSName entry
140
+ # in subjectAltName
141
+ for sub in cert.get("subject", ()):
142
+ for key, value in sub:
143
+ # XXX according to RFC 2818, the most specific Common Name
144
+ # must be used.
145
+ if key == "commonName":
146
+ if _dnsname_match(value, hostname):
147
+ return
148
+ dnsnames.append(value)
149
+ if len(dnsnames) > 1:
150
+ raise CertificateError(
151
+ "hostname %r "
152
+ "doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames)))
153
+ )
154
+ elif len(dnsnames) == 1:
155
+ raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0]))
156
+ else:
157
+ raise CertificateError(
158
+ "no appropriate commonName or subjectAltName fields were found"
159
+ )
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssltransport.py ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import socket
3
+ import ssl
4
+
5
+ from ..exceptions import ProxySchemeUnsupported
6
+ from ..packages import six
7
+
8
+ SSL_BLOCKSIZE = 16384
9
+
10
+
11
+ class SSLTransport:
12
+ """
13
+ The SSLTransport wraps an existing socket and establishes an SSL connection.
14
+
15
+ Contrary to Python's implementation of SSLSocket, it allows you to chain
16
+ multiple TLS connections together. It's particularly useful if you need to
17
+ implement TLS within TLS.
18
+
19
+ The class supports most of the socket API operations.
20
+ """
21
+
22
+ @staticmethod
23
+ def _validate_ssl_context_for_tls_in_tls(ssl_context):
24
+ """
25
+ Raises a ProxySchemeUnsupported if the provided ssl_context can't be used
26
+ for TLS in TLS.
27
+
28
+ The only requirement is that the ssl_context provides the 'wrap_bio'
29
+ methods.
30
+ """
31
+
32
+ if not hasattr(ssl_context, "wrap_bio"):
33
+ if six.PY2:
34
+ raise ProxySchemeUnsupported(
35
+ "TLS in TLS requires SSLContext.wrap_bio() which isn't "
36
+ "supported on Python 2"
37
+ )
38
+ else:
39
+ raise ProxySchemeUnsupported(
40
+ "TLS in TLS requires SSLContext.wrap_bio() which isn't "
41
+ "available on non-native SSLContext"
42
+ )
43
+
44
+ def __init__(
45
+ self, socket, ssl_context, server_hostname=None, suppress_ragged_eofs=True
46
+ ):
47
+ """
48
+ Create an SSLTransport around socket using the provided ssl_context.
49
+ """
50
+ self.incoming = ssl.MemoryBIO()
51
+ self.outgoing = ssl.MemoryBIO()
52
+
53
+ self.suppress_ragged_eofs = suppress_ragged_eofs
54
+ self.socket = socket
55
+
56
+ self.sslobj = ssl_context.wrap_bio(
57
+ self.incoming, self.outgoing, server_hostname=server_hostname
58
+ )
59
+
60
+ # Perform initial handshake.
61
+ self._ssl_io_loop(self.sslobj.do_handshake)
62
+
63
+ def __enter__(self):
64
+ return self
65
+
66
+ def __exit__(self, *_):
67
+ self.close()
68
+
69
+ def fileno(self):
70
+ return self.socket.fileno()
71
+
72
+ def read(self, len=1024, buffer=None):
73
+ return self._wrap_ssl_read(len, buffer)
74
+
75
+ def recv(self, len=1024, flags=0):
76
+ if flags != 0:
77
+ raise ValueError("non-zero flags not allowed in calls to recv")
78
+ return self._wrap_ssl_read(len)
79
+
80
+ def recv_into(self, buffer, nbytes=None, flags=0):
81
+ if flags != 0:
82
+ raise ValueError("non-zero flags not allowed in calls to recv_into")
83
+ if buffer and (nbytes is None):
84
+ nbytes = len(buffer)
85
+ elif nbytes is None:
86
+ nbytes = 1024
87
+ return self.read(nbytes, buffer)
88
+
89
+ def sendall(self, data, flags=0):
90
+ if flags != 0:
91
+ raise ValueError("non-zero flags not allowed in calls to sendall")
92
+ count = 0
93
+ with memoryview(data) as view, view.cast("B") as byte_view:
94
+ amount = len(byte_view)
95
+ while count < amount:
96
+ v = self.send(byte_view[count:])
97
+ count += v
98
+
99
+ def send(self, data, flags=0):
100
+ if flags != 0:
101
+ raise ValueError("non-zero flags not allowed in calls to send")
102
+ response = self._ssl_io_loop(self.sslobj.write, data)
103
+ return response
104
+
105
+ def makefile(
106
+ self, mode="r", buffering=None, encoding=None, errors=None, newline=None
107
+ ):
108
+ """
109
+ Python's httpclient uses makefile and buffered io when reading HTTP
110
+ messages and we need to support it.
111
+
112
+ This is unfortunately a copy and paste of socket.py makefile with small
113
+ changes to point to the socket directly.
114
+ """
115
+ if not set(mode) <= {"r", "w", "b"}:
116
+ raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
117
+
118
+ writing = "w" in mode
119
+ reading = "r" in mode or not writing
120
+ assert reading or writing
121
+ binary = "b" in mode
122
+ rawmode = ""
123
+ if reading:
124
+ rawmode += "r"
125
+ if writing:
126
+ rawmode += "w"
127
+ raw = socket.SocketIO(self, rawmode)
128
+ self.socket._io_refs += 1
129
+ if buffering is None:
130
+ buffering = -1
131
+ if buffering < 0:
132
+ buffering = io.DEFAULT_BUFFER_SIZE
133
+ if buffering == 0:
134
+ if not binary:
135
+ raise ValueError("unbuffered streams must be binary")
136
+ return raw
137
+ if reading and writing:
138
+ buffer = io.BufferedRWPair(raw, raw, buffering)
139
+ elif reading:
140
+ buffer = io.BufferedReader(raw, buffering)
141
+ else:
142
+ assert writing
143
+ buffer = io.BufferedWriter(raw, buffering)
144
+ if binary:
145
+ return buffer
146
+ text = io.TextIOWrapper(buffer, encoding, errors, newline)
147
+ text.mode = mode
148
+ return text
149
+
150
+ def unwrap(self):
151
+ self._ssl_io_loop(self.sslobj.unwrap)
152
+
153
+ def close(self):
154
+ self.socket.close()
155
+
156
+ def getpeercert(self, binary_form=False):
157
+ return self.sslobj.getpeercert(binary_form)
158
+
159
+ def version(self):
160
+ return self.sslobj.version()
161
+
162
+ def cipher(self):
163
+ return self.sslobj.cipher()
164
+
165
+ def selected_alpn_protocol(self):
166
+ return self.sslobj.selected_alpn_protocol()
167
+
168
+ def selected_npn_protocol(self):
169
+ return self.sslobj.selected_npn_protocol()
170
+
171
+ def shared_ciphers(self):
172
+ return self.sslobj.shared_ciphers()
173
+
174
+ def compression(self):
175
+ return self.sslobj.compression()
176
+
177
+ def settimeout(self, value):
178
+ self.socket.settimeout(value)
179
+
180
+ def gettimeout(self):
181
+ return self.socket.gettimeout()
182
+
183
+ def _decref_socketios(self):
184
+ self.socket._decref_socketios()
185
+
186
+ def _wrap_ssl_read(self, len, buffer=None):
187
+ try:
188
+ return self._ssl_io_loop(self.sslobj.read, len, buffer)
189
+ except ssl.SSLError as e:
190
+ if e.errno == ssl.SSL_ERROR_EOF and self.suppress_ragged_eofs:
191
+ return 0 # eof, return 0.
192
+ else:
193
+ raise
194
+
195
+ def _ssl_io_loop(self, func, *args):
196
+ """Performs an I/O loop between incoming/outgoing and the socket."""
197
+ should_loop = True
198
+ ret = None
199
+
200
+ while should_loop:
201
+ errno = None
202
+ try:
203
+ ret = func(*args)
204
+ except ssl.SSLError as e:
205
+ if e.errno not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
206
+ # WANT_READ, and WANT_WRITE are expected, others are not.
207
+ raise e
208
+ errno = e.errno
209
+
210
+ buf = self.outgoing.read()
211
+ self.socket.sendall(buf)
212
+
213
+ if errno is None:
214
+ should_loop = False
215
+ elif errno == ssl.SSL_ERROR_WANT_READ:
216
+ buf = self.socket.recv(SSL_BLOCKSIZE)
217
+ if buf:
218
+ self.incoming.write(buf)
219
+ else:
220
+ self.incoming.write_eof()
221
+ return ret
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/timeout.py ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import time
4
+
5
+ # The default socket timeout, used by httplib to indicate that no timeout was; specified by the user
6
+ from socket import _GLOBAL_DEFAULT_TIMEOUT, getdefaulttimeout
7
+
8
+ from ..exceptions import TimeoutStateError
9
+
10
+ # A sentinel value to indicate that no timeout was specified by the user in
11
+ # urllib3
12
+ _Default = object()
13
+
14
+
15
+ # Use time.monotonic if available.
16
+ current_time = getattr(time, "monotonic", time.time)
17
+
18
+
19
+ class Timeout(object):
20
+ """Timeout configuration.
21
+
22
+ Timeouts can be defined as a default for a pool:
23
+
24
+ .. code-block:: python
25
+
26
+ timeout = Timeout(connect=2.0, read=7.0)
27
+ http = PoolManager(timeout=timeout)
28
+ response = http.request('GET', 'http://example.com/')
29
+
30
+ Or per-request (which overrides the default for the pool):
31
+
32
+ .. code-block:: python
33
+
34
+ response = http.request('GET', 'http://example.com/', timeout=Timeout(10))
35
+
36
+ Timeouts can be disabled by setting all the parameters to ``None``:
37
+
38
+ .. code-block:: python
39
+
40
+ no_timeout = Timeout(connect=None, read=None)
41
+ response = http.request('GET', 'http://example.com/, timeout=no_timeout)
42
+
43
+
44
+ :param total:
45
+ This combines the connect and read timeouts into one; the read timeout
46
+ will be set to the time leftover from the connect attempt. In the
47
+ event that both a connect timeout and a total are specified, or a read
48
+ timeout and a total are specified, the shorter timeout will be applied.
49
+
50
+ Defaults to None.
51
+
52
+ :type total: int, float, or None
53
+
54
+ :param connect:
55
+ The maximum amount of time (in seconds) to wait for a connection
56
+ attempt to a server to succeed. Omitting the parameter will default the
57
+ connect timeout to the system default, probably `the global default
58
+ timeout in socket.py
59
+ <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
60
+ None will set an infinite timeout for connection attempts.
61
+
62
+ :type connect: int, float, or None
63
+
64
+ :param read:
65
+ The maximum amount of time (in seconds) to wait between consecutive
66
+ read operations for a response from the server. Omitting the parameter
67
+ will default the read timeout to the system default, probably `the
68
+ global default timeout in socket.py
69
+ <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
70
+ None will set an infinite timeout.
71
+
72
+ :type read: int, float, or None
73
+
74
+ .. note::
75
+
76
+ Many factors can affect the total amount of time for urllib3 to return
77
+ an HTTP response.
78
+
79
+ For example, Python's DNS resolver does not obey the timeout specified
80
+ on the socket. Other factors that can affect total request time include
81
+ high CPU load, high swap, the program running at a low priority level,
82
+ or other behaviors.
83
+
84
+ In addition, the read and total timeouts only measure the time between
85
+ read operations on the socket connecting the client and the server,
86
+ not the total amount of time for the request to return a complete
87
+ response. For most requests, the timeout is raised because the server
88
+ has not sent the first byte in the specified time. This is not always
89
+ the case; if a server streams one byte every fifteen seconds, a timeout
90
+ of 20 seconds will not trigger, even though the request will take
91
+ several minutes to complete.
92
+
93
+ If your goal is to cut off any request after a set amount of wall clock
94
+ time, consider having a second "watcher" thread to cut off a slow
95
+ request.
96
+ """
97
+
98
+ #: A sentinel object representing the default timeout value
99
+ DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT
100
+
101
+ def __init__(self, total=None, connect=_Default, read=_Default):
102
+ self._connect = self._validate_timeout(connect, "connect")
103
+ self._read = self._validate_timeout(read, "read")
104
+ self.total = self._validate_timeout(total, "total")
105
+ self._start_connect = None
106
+
107
+ def __repr__(self):
108
+ return "%s(connect=%r, read=%r, total=%r)" % (
109
+ type(self).__name__,
110
+ self._connect,
111
+ self._read,
112
+ self.total,
113
+ )
114
+
115
+ # __str__ provided for backwards compatibility
116
+ __str__ = __repr__
117
+
118
+ @classmethod
119
+ def resolve_default_timeout(cls, timeout):
120
+ return getdefaulttimeout() if timeout is cls.DEFAULT_TIMEOUT else timeout
121
+
122
+ @classmethod
123
+ def _validate_timeout(cls, value, name):
124
+ """Check that a timeout attribute is valid.
125
+
126
+ :param value: The timeout value to validate
127
+ :param name: The name of the timeout attribute to validate. This is
128
+ used to specify in error messages.
129
+ :return: The validated and casted version of the given value.
130
+ :raises ValueError: If it is a numeric value less than or equal to
131
+ zero, or the type is not an integer, float, or None.
132
+ """
133
+ if value is _Default:
134
+ return cls.DEFAULT_TIMEOUT
135
+
136
+ if value is None or value is cls.DEFAULT_TIMEOUT:
137
+ return value
138
+
139
+ if isinstance(value, bool):
140
+ raise ValueError(
141
+ "Timeout cannot be a boolean value. It must "
142
+ "be an int, float or None."
143
+ )
144
+ try:
145
+ float(value)
146
+ except (TypeError, ValueError):
147
+ raise ValueError(
148
+ "Timeout value %s was %s, but it must be an "
149
+ "int, float or None." % (name, value)
150
+ )
151
+
152
+ try:
153
+ if value <= 0:
154
+ raise ValueError(
155
+ "Attempted to set %s timeout to %s, but the "
156
+ "timeout cannot be set to a value less "
157
+ "than or equal to 0." % (name, value)
158
+ )
159
+ except TypeError:
160
+ # Python 3
161
+ raise ValueError(
162
+ "Timeout value %s was %s, but it must be an "
163
+ "int, float or None." % (name, value)
164
+ )
165
+
166
+ return value
167
+
168
+ @classmethod
169
+ def from_float(cls, timeout):
170
+ """Create a new Timeout from a legacy timeout value.
171
+
172
+ The timeout value used by httplib.py sets the same timeout on the
173
+ connect(), and recv() socket requests. This creates a :class:`Timeout`
174
+ object that sets the individual timeouts to the ``timeout`` value
175
+ passed to this function.
176
+
177
+ :param timeout: The legacy timeout value.
178
+ :type timeout: integer, float, sentinel default object, or None
179
+ :return: Timeout object
180
+ :rtype: :class:`Timeout`
181
+ """
182
+ return Timeout(read=timeout, connect=timeout)
183
+
184
+ def clone(self):
185
+ """Create a copy of the timeout object
186
+
187
+ Timeout properties are stored per-pool but each request needs a fresh
188
+ Timeout object to ensure each one has its own start/stop configured.
189
+
190
+ :return: a copy of the timeout object
191
+ :rtype: :class:`Timeout`
192
+ """
193
+ # We can't use copy.deepcopy because that will also create a new object
194
+ # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to
195
+ # detect the user default.
196
+ return Timeout(connect=self._connect, read=self._read, total=self.total)
197
+
198
+ def start_connect(self):
199
+ """Start the timeout clock, used during a connect() attempt
200
+
201
+ :raises urllib3.exceptions.TimeoutStateError: if you attempt
202
+ to start a timer that has been started already.
203
+ """
204
+ if self._start_connect is not None:
205
+ raise TimeoutStateError("Timeout timer has already been started.")
206
+ self._start_connect = current_time()
207
+ return self._start_connect
208
+
209
+ def get_connect_duration(self):
210
+ """Gets the time elapsed since the call to :meth:`start_connect`.
211
+
212
+ :return: Elapsed time in seconds.
213
+ :rtype: float
214
+ :raises urllib3.exceptions.TimeoutStateError: if you attempt
215
+ to get duration for a timer that hasn't been started.
216
+ """
217
+ if self._start_connect is None:
218
+ raise TimeoutStateError(
219
+ "Can't get connect duration for timer that has not started."
220
+ )
221
+ return current_time() - self._start_connect
222
+
223
+ @property
224
+ def connect_timeout(self):
225
+ """Get the value to use when setting a connection timeout.
226
+
227
+ This will be a positive float or integer, the value None
228
+ (never timeout), or the default system timeout.
229
+
230
+ :return: Connect timeout.
231
+ :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
232
+ """
233
+ if self.total is None:
234
+ return self._connect
235
+
236
+ if self._connect is None or self._connect is self.DEFAULT_TIMEOUT:
237
+ return self.total
238
+
239
+ return min(self._connect, self.total)
240
+
241
+ @property
242
+ def read_timeout(self):
243
+ """Get the value for the read timeout.
244
+
245
+ This assumes some time has elapsed in the connection timeout and
246
+ computes the read timeout appropriately.
247
+
248
+ If self.total is set, the read timeout is dependent on the amount of
249
+ time taken by the connect timeout. If the connection time has not been
250
+ established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be
251
+ raised.
252
+
253
+ :return: Value to use for the read timeout.
254
+ :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
255
+ :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect`
256
+ has not yet been called on this object.
257
+ """
258
+ if (
259
+ self.total is not None
260
+ and self.total is not self.DEFAULT_TIMEOUT
261
+ and self._read is not None
262
+ and self._read is not self.DEFAULT_TIMEOUT
263
+ ):
264
+ # In case the connect timeout has not yet been established.
265
+ if self._start_connect is None:
266
+ return self._read
267
+ return max(0, min(self.total - self.get_connect_duration(), self._read))
268
+ elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT:
269
+ return max(0, self.total - self.get_connect_duration())
270
+ else:
271
+ return self._read
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/url.py ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import re
4
+ from collections import namedtuple
5
+
6
+ from ..exceptions import LocationParseError
7
+ from ..packages import six
8
+
9
+ url_attrs = ["scheme", "auth", "host", "port", "path", "query", "fragment"]
10
+
11
+ # We only want to normalize urls with an HTTP(S) scheme.
12
+ # urllib3 infers URLs without a scheme (None) to be http.
13
+ NORMALIZABLE_SCHEMES = ("http", "https", None)
14
+
15
+ # Almost all of these patterns were derived from the
16
+ # 'rfc3986' module: https://github.com/python-hyper/rfc3986
17
+ PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}")
18
+ SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)")
19
+ URI_RE = re.compile(
20
+ r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?"
21
+ r"(?://([^\\/?#]*))?"
22
+ r"([^?#]*)"
23
+ r"(?:\?([^#]*))?"
24
+ r"(?:#(.*))?$",
25
+ re.UNICODE | re.DOTALL,
26
+ )
27
+
28
+ IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}"
29
+ HEX_PAT = "[0-9A-Fa-f]{1,4}"
30
+ LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=HEX_PAT, ipv4=IPV4_PAT)
31
+ _subs = {"hex": HEX_PAT, "ls32": LS32_PAT}
32
+ _variations = [
33
+ # 6( h16 ":" ) ls32
34
+ "(?:%(hex)s:){6}%(ls32)s",
35
+ # "::" 5( h16 ":" ) ls32
36
+ "::(?:%(hex)s:){5}%(ls32)s",
37
+ # [ h16 ] "::" 4( h16 ":" ) ls32
38
+ "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s",
39
+ # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
40
+ "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s",
41
+ # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
42
+ "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s",
43
+ # [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
44
+ "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s",
45
+ # [ *4( h16 ":" ) h16 ] "::" ls32
46
+ "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s",
47
+ # [ *5( h16 ":" ) h16 ] "::" h16
48
+ "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s",
49
+ # [ *6( h16 ":" ) h16 ] "::"
50
+ "(?:(?:%(hex)s:){0,6}%(hex)s)?::",
51
+ ]
52
+
53
+ UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._\-~"
54
+ IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")"
55
+ ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+"
56
+ IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]"
57
+ REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*"
58
+ TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$")
59
+
60
+ IPV4_RE = re.compile("^" + IPV4_PAT + "$")
61
+ IPV6_RE = re.compile("^" + IPV6_PAT + "$")
62
+ IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT + "$")
63
+ BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT[2:-2] + "$")
64
+ ZONE_ID_RE = re.compile("(" + ZONE_ID_PAT + r")\]$")
65
+
66
+ _HOST_PORT_PAT = ("^(%s|%s|%s)(?::0*?(|0|[1-9][0-9]{0,4}))?$") % (
67
+ REG_NAME_PAT,
68
+ IPV4_PAT,
69
+ IPV6_ADDRZ_PAT,
70
+ )
71
+ _HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL)
72
+
73
+ UNRESERVED_CHARS = set(
74
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~"
75
+ )
76
+ SUB_DELIM_CHARS = set("!$&'()*+,;=")
77
+ USERINFO_CHARS = UNRESERVED_CHARS | SUB_DELIM_CHARS | {":"}
78
+ PATH_CHARS = USERINFO_CHARS | {"@", "/"}
79
+ QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {"?"}
80
+
81
+
82
+ class Url(namedtuple("Url", url_attrs)):
83
+ """
84
+ Data structure for representing an HTTP URL. Used as a return value for
85
+ :func:`parse_url`. Both the scheme and host are normalized as they are
86
+ both case-insensitive according to RFC 3986.
87
+ """
88
+
89
+ __slots__ = ()
90
+
91
+ def __new__(
92
+ cls,
93
+ scheme=None,
94
+ auth=None,
95
+ host=None,
96
+ port=None,
97
+ path=None,
98
+ query=None,
99
+ fragment=None,
100
+ ):
101
+ if path and not path.startswith("/"):
102
+ path = "/" + path
103
+ if scheme is not None:
104
+ scheme = scheme.lower()
105
+ return super(Url, cls).__new__(
106
+ cls, scheme, auth, host, port, path, query, fragment
107
+ )
108
+
109
+ @property
110
+ def hostname(self):
111
+ """For backwards-compatibility with urlparse. We're nice like that."""
112
+ return self.host
113
+
114
+ @property
115
+ def request_uri(self):
116
+ """Absolute path including the query string."""
117
+ uri = self.path or "/"
118
+
119
+ if self.query is not None:
120
+ uri += "?" + self.query
121
+
122
+ return uri
123
+
124
+ @property
125
+ def netloc(self):
126
+ """Network location including host and port"""
127
+ if self.port:
128
+ return "%s:%d" % (self.host, self.port)
129
+ return self.host
130
+
131
+ @property
132
+ def url(self):
133
+ """
134
+ Convert self into a url
135
+
136
+ This function should more or less round-trip with :func:`.parse_url`. The
137
+ returned url may not be exactly the same as the url inputted to
138
+ :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls
139
+ with a blank port will have : removed).
140
+
141
+ Example: ::
142
+
143
+ >>> U = parse_url('http://google.com/mail/')
144
+ >>> U.url
145
+ 'http://google.com/mail/'
146
+ >>> Url('http', 'username:password', 'host.com', 80,
147
+ ... '/path', 'query', 'fragment').url
148
+ 'http://username:password@host.com:80/path?query#fragment'
149
+ """
150
+ scheme, auth, host, port, path, query, fragment = self
151
+ url = u""
152
+
153
+ # We use "is not None" we want things to happen with empty strings (or 0 port)
154
+ if scheme is not None:
155
+ url += scheme + u"://"
156
+ if auth is not None:
157
+ url += auth + u"@"
158
+ if host is not None:
159
+ url += host
160
+ if port is not None:
161
+ url += u":" + str(port)
162
+ if path is not None:
163
+ url += path
164
+ if query is not None:
165
+ url += u"?" + query
166
+ if fragment is not None:
167
+ url += u"#" + fragment
168
+
169
+ return url
170
+
171
+ def __str__(self):
172
+ return self.url
173
+
174
+
175
+ def split_first(s, delims):
176
+ """
177
+ .. deprecated:: 1.25
178
+
179
+ Given a string and an iterable of delimiters, split on the first found
180
+ delimiter. Return two split parts and the matched delimiter.
181
+
182
+ If not found, then the first part is the full input string.
183
+
184
+ Example::
185
+
186
+ >>> split_first('foo/bar?baz', '?/=')
187
+ ('foo', 'bar?baz', '/')
188
+ >>> split_first('foo/bar?baz', '123')
189
+ ('foo/bar?baz', '', None)
190
+
191
+ Scales linearly with number of delims. Not ideal for large number of delims.
192
+ """
193
+ min_idx = None
194
+ min_delim = None
195
+ for d in delims:
196
+ idx = s.find(d)
197
+ if idx < 0:
198
+ continue
199
+
200
+ if min_idx is None or idx < min_idx:
201
+ min_idx = idx
202
+ min_delim = d
203
+
204
+ if min_idx is None or min_idx < 0:
205
+ return s, "", None
206
+
207
+ return s[:min_idx], s[min_idx + 1 :], min_delim
208
+
209
+
210
+ def _encode_invalid_chars(component, allowed_chars, encoding="utf-8"):
211
+ """Percent-encodes a URI component without reapplying
212
+ onto an already percent-encoded component.
213
+ """
214
+ if component is None:
215
+ return component
216
+
217
+ component = six.ensure_text(component)
218
+
219
+ # Normalize existing percent-encoded bytes.
220
+ # Try to see if the component we're encoding is already percent-encoded
221
+ # so we can skip all '%' characters but still encode all others.
222
+ component, percent_encodings = PERCENT_RE.subn(
223
+ lambda match: match.group(0).upper(), component
224
+ )
225
+
226
+ uri_bytes = component.encode("utf-8", "surrogatepass")
227
+ is_percent_encoded = percent_encodings == uri_bytes.count(b"%")
228
+ encoded_component = bytearray()
229
+
230
+ for i in range(0, len(uri_bytes)):
231
+ # Will return a single character bytestring on both Python 2 & 3
232
+ byte = uri_bytes[i : i + 1]
233
+ byte_ord = ord(byte)
234
+ if (is_percent_encoded and byte == b"%") or (
235
+ byte_ord < 128 and byte.decode() in allowed_chars
236
+ ):
237
+ encoded_component += byte
238
+ continue
239
+ encoded_component.extend(b"%" + (hex(byte_ord)[2:].encode().zfill(2).upper()))
240
+
241
+ return encoded_component.decode(encoding)
242
+
243
+
244
+ def _remove_path_dot_segments(path):
245
+ # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
246
+ segments = path.split("/") # Turn the path into a list of segments
247
+ output = [] # Initialize the variable to use to store output
248
+
249
+ for segment in segments:
250
+ # '.' is the current directory, so ignore it, it is superfluous
251
+ if segment == ".":
252
+ continue
253
+ # Anything other than '..', should be appended to the output
254
+ elif segment != "..":
255
+ output.append(segment)
256
+ # In this case segment == '..', if we can, we should pop the last
257
+ # element
258
+ elif output:
259
+ output.pop()
260
+
261
+ # If the path starts with '/' and the output is empty or the first string
262
+ # is non-empty
263
+ if path.startswith("/") and (not output or output[0]):
264
+ output.insert(0, "")
265
+
266
+ # If the path starts with '/.' or '/..' ensure we add one more empty
267
+ # string to add a trailing '/'
268
+ if path.endswith(("/.", "/..")):
269
+ output.append("")
270
+
271
+ return "/".join(output)
272
+
273
+
274
+ def _normalize_host(host, scheme):
275
+ if host:
276
+ if isinstance(host, six.binary_type):
277
+ host = six.ensure_str(host)
278
+
279
+ if scheme in NORMALIZABLE_SCHEMES:
280
+ is_ipv6 = IPV6_ADDRZ_RE.match(host)
281
+ if is_ipv6:
282
+ # IPv6 hosts of the form 'a::b%zone' are encoded in a URL as
283
+ # such per RFC 6874: 'a::b%25zone'. Unquote the ZoneID
284
+ # separator as necessary to return a valid RFC 4007 scoped IP.
285
+ match = ZONE_ID_RE.search(host)
286
+ if match:
287
+ start, end = match.span(1)
288
+ zone_id = host[start:end]
289
+
290
+ if zone_id.startswith("%25") and zone_id != "%25":
291
+ zone_id = zone_id[3:]
292
+ else:
293
+ zone_id = zone_id[1:]
294
+ zone_id = "%" + _encode_invalid_chars(zone_id, UNRESERVED_CHARS)
295
+ return host[:start].lower() + zone_id + host[end:]
296
+ else:
297
+ return host.lower()
298
+ elif not IPV4_RE.match(host):
299
+ return six.ensure_str(
300
+ b".".join([_idna_encode(label) for label in host.split(".")])
301
+ )
302
+ return host
303
+
304
+
305
+ def _idna_encode(name):
306
+ if name and any(ord(x) >= 128 for x in name):
307
+ try:
308
+ from pip._vendor import idna
309
+ except ImportError:
310
+ six.raise_from(
311
+ LocationParseError("Unable to parse URL without the 'idna' module"),
312
+ None,
313
+ )
314
+ try:
315
+ return idna.encode(name.lower(), strict=True, std3_rules=True)
316
+ except idna.IDNAError:
317
+ six.raise_from(
318
+ LocationParseError(u"Name '%s' is not a valid IDNA label" % name), None
319
+ )
320
+ return name.lower().encode("ascii")
321
+
322
+
323
+ def _encode_target(target):
324
+ """Percent-encodes a request target so that there are no invalid characters"""
325
+ path, query = TARGET_RE.match(target).groups()
326
+ target = _encode_invalid_chars(path, PATH_CHARS)
327
+ query = _encode_invalid_chars(query, QUERY_CHARS)
328
+ if query is not None:
329
+ target += "?" + query
330
+ return target
331
+
332
+
333
+ def parse_url(url):
334
+ """
335
+ Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
336
+ performed to parse incomplete urls. Fields not provided will be None.
337
+ This parser is RFC 3986 and RFC 6874 compliant.
338
+
339
+ The parser logic and helper functions are based heavily on
340
+ work done in the ``rfc3986`` module.
341
+
342
+ :param str url: URL to parse into a :class:`.Url` namedtuple.
343
+
344
+ Partly backwards-compatible with :mod:`urlparse`.
345
+
346
+ Example::
347
+
348
+ >>> parse_url('http://google.com/mail/')
349
+ Url(scheme='http', host='google.com', port=None, path='/mail/', ...)
350
+ >>> parse_url('google.com:80')
351
+ Url(scheme=None, host='google.com', port=80, path=None, ...)
352
+ >>> parse_url('/foo?bar')
353
+ Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
354
+ """
355
+ if not url:
356
+ # Empty
357
+ return Url()
358
+
359
+ source_url = url
360
+ if not SCHEME_RE.search(url):
361
+ url = "//" + url
362
+
363
+ try:
364
+ scheme, authority, path, query, fragment = URI_RE.match(url).groups()
365
+ normalize_uri = scheme is None or scheme.lower() in NORMALIZABLE_SCHEMES
366
+
367
+ if scheme:
368
+ scheme = scheme.lower()
369
+
370
+ if authority:
371
+ auth, _, host_port = authority.rpartition("@")
372
+ auth = auth or None
373
+ host, port = _HOST_PORT_RE.match(host_port).groups()
374
+ if auth and normalize_uri:
375
+ auth = _encode_invalid_chars(auth, USERINFO_CHARS)
376
+ if port == "":
377
+ port = None
378
+ else:
379
+ auth, host, port = None, None, None
380
+
381
+ if port is not None:
382
+ port = int(port)
383
+ if not (0 <= port <= 65535):
384
+ raise LocationParseError(url)
385
+
386
+ host = _normalize_host(host, scheme)
387
+
388
+ if normalize_uri and path:
389
+ path = _remove_path_dot_segments(path)
390
+ path = _encode_invalid_chars(path, PATH_CHARS)
391
+ if normalize_uri and query:
392
+ query = _encode_invalid_chars(query, QUERY_CHARS)
393
+ if normalize_uri and fragment:
394
+ fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS)
395
+
396
+ except (ValueError, AttributeError):
397
+ return six.raise_from(LocationParseError(source_url), None)
398
+
399
+ # For the sake of backwards compatibility we put empty
400
+ # string values for path if there are any defined values
401
+ # beyond the path in the URL.
402
+ # TODO: Remove this when we break backwards compatibility.
403
+ if not path:
404
+ if query is not None or fragment is not None:
405
+ path = ""
406
+ else:
407
+ path = None
408
+
409
+ # Ensure that each part of the URL is a `str` for
410
+ # backwards compatibility.
411
+ if isinstance(url, six.text_type):
412
+ ensure_func = six.ensure_text
413
+ else:
414
+ ensure_func = six.ensure_str
415
+
416
+ def ensure_type(x):
417
+ return x if x is None else ensure_func(x)
418
+
419
+ return Url(
420
+ scheme=ensure_type(scheme),
421
+ auth=ensure_type(auth),
422
+ host=ensure_type(host),
423
+ port=port,
424
+ path=ensure_type(path),
425
+ query=ensure_type(query),
426
+ fragment=ensure_type(fragment),
427
+ )
428
+
429
+
430
+ def get_host(url):
431
+ """
432
+ Deprecated. Use :func:`parse_url` instead.
433
+ """
434
+ p = parse_url(url)
435
+ return p.scheme or "http", p.hostname, p.port
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/wait.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import errno
2
+ import select
3
+ import sys
4
+ from functools import partial
5
+
6
+ try:
7
+ from time import monotonic
8
+ except ImportError:
9
+ from time import time as monotonic
10
+
11
+ __all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"]
12
+
13
+
14
+ class NoWayToWaitForSocketError(Exception):
15
+ pass
16
+
17
+
18
+ # How should we wait on sockets?
19
+ #
20
+ # There are two types of APIs you can use for waiting on sockets: the fancy
21
+ # modern stateful APIs like epoll/kqueue, and the older stateless APIs like
22
+ # select/poll. The stateful APIs are more efficient when you have a lots of
23
+ # sockets to keep track of, because you can set them up once and then use them
24
+ # lots of times. But we only ever want to wait on a single socket at a time
25
+ # and don't want to keep track of state, so the stateless APIs are actually
26
+ # more efficient. So we want to use select() or poll().
27
+ #
28
+ # Now, how do we choose between select() and poll()? On traditional Unixes,
29
+ # select() has a strange calling convention that makes it slow, or fail
30
+ # altogether, for high-numbered file descriptors. The point of poll() is to fix
31
+ # that, so on Unixes, we prefer poll().
32
+ #
33
+ # On Windows, there is no poll() (or at least Python doesn't provide a wrapper
34
+ # for it), but that's OK, because on Windows, select() doesn't have this
35
+ # strange calling convention; plain select() works fine.
36
+ #
37
+ # So: on Windows we use select(), and everywhere else we use poll(). We also
38
+ # fall back to select() in case poll() is somehow broken or missing.
39
+
40
+ if sys.version_info >= (3, 5):
41
+ # Modern Python, that retries syscalls by default
42
+ def _retry_on_intr(fn, timeout):
43
+ return fn(timeout)
44
+
45
+ else:
46
+ # Old and broken Pythons.
47
+ def _retry_on_intr(fn, timeout):
48
+ if timeout is None:
49
+ deadline = float("inf")
50
+ else:
51
+ deadline = monotonic() + timeout
52
+
53
+ while True:
54
+ try:
55
+ return fn(timeout)
56
+ # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7
57
+ except (OSError, select.error) as e:
58
+ # 'e.args[0]' incantation works for both OSError and select.error
59
+ if e.args[0] != errno.EINTR:
60
+ raise
61
+ else:
62
+ timeout = deadline - monotonic()
63
+ if timeout < 0:
64
+ timeout = 0
65
+ if timeout == float("inf"):
66
+ timeout = None
67
+ continue
68
+
69
+
70
+ def select_wait_for_socket(sock, read=False, write=False, timeout=None):
71
+ if not read and not write:
72
+ raise RuntimeError("must specify at least one of read=True, write=True")
73
+ rcheck = []
74
+ wcheck = []
75
+ if read:
76
+ rcheck.append(sock)
77
+ if write:
78
+ wcheck.append(sock)
79
+ # When doing a non-blocking connect, most systems signal success by
80
+ # marking the socket writable. Windows, though, signals success by marked
81
+ # it as "exceptional". We paper over the difference by checking the write
82
+ # sockets for both conditions. (The stdlib selectors module does the same
83
+ # thing.)
84
+ fn = partial(select.select, rcheck, wcheck, wcheck)
85
+ rready, wready, xready = _retry_on_intr(fn, timeout)
86
+ return bool(rready or wready or xready)
87
+
88
+
89
+ def poll_wait_for_socket(sock, read=False, write=False, timeout=None):
90
+ if not read and not write:
91
+ raise RuntimeError("must specify at least one of read=True, write=True")
92
+ mask = 0
93
+ if read:
94
+ mask |= select.POLLIN
95
+ if write:
96
+ mask |= select.POLLOUT
97
+ poll_obj = select.poll()
98
+ poll_obj.register(sock, mask)
99
+
100
+ # For some reason, poll() takes timeout in milliseconds
101
+ def do_poll(t):
102
+ if t is not None:
103
+ t *= 1000
104
+ return poll_obj.poll(t)
105
+
106
+ return bool(_retry_on_intr(do_poll, timeout))
107
+
108
+
109
+ def null_wait_for_socket(*args, **kwargs):
110
+ raise NoWayToWaitForSocketError("no select-equivalent available")
111
+
112
+
113
+ def _have_working_poll():
114
+ # Apparently some systems have a select.poll that fails as soon as you try
115
+ # to use it, either due to strange configuration or broken monkeypatching
116
+ # from libraries like eventlet/greenlet.
117
+ try:
118
+ poll_obj = select.poll()
119
+ _retry_on_intr(poll_obj.poll, 0)
120
+ except (AttributeError, OSError):
121
+ return False
122
+ else:
123
+ return True
124
+
125
+
126
+ def wait_for_socket(*args, **kwargs):
127
+ # We delay choosing which implementation to use until the first time we're
128
+ # called. We could do it at import time, but then we might make the wrong
129
+ # decision if someone goes wild with monkeypatching select.poll after
130
+ # we're imported.
131
+ global wait_for_socket
132
+ if _have_working_poll():
133
+ wait_for_socket = poll_wait_for_socket
134
+ elif hasattr(select, "select"):
135
+ wait_for_socket = select_wait_for_socket
136
+ else: # Platform-specific: Appengine.
137
+ wait_for_socket = null_wait_for_socket
138
+ return wait_for_socket(*args, **kwargs)
139
+
140
+
141
+ def wait_for_read(sock, timeout=None):
142
+ """Waits for reading to be available on a given socket.
143
+ Returns True if the socket is readable, or False if the timeout expired.
144
+ """
145
+ return wait_for_socket(sock, read=True, timeout=timeout)
146
+
147
+
148
+ def wait_for_write(sock, timeout=None):
149
+ """Waits for writing to be available on a given socket.
150
+ Returns True if the socket is readable, or False if the timeout expired.
151
+ """
152
+ return wait_for_socket(sock, write=True, timeout=timeout)
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/vendor.txt ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CacheControl==0.13.1 # Make sure to update the license in pyproject.toml for this.
2
+ colorama==0.4.6
3
+ distlib==0.3.8
4
+ distro==1.8.0
5
+ msgpack==1.0.5
6
+ packaging==21.3
7
+ platformdirs==3.8.1
8
+ pyparsing==3.1.0
9
+ pyproject-hooks==1.0.0
10
+ requests==2.31.0
11
+ certifi==2023.7.22
12
+ chardet==5.1.0
13
+ idna==3.4
14
+ urllib3==1.26.17
15
+ rich==13.4.2
16
+ pygments==2.15.1
17
+ typing_extensions==4.7.1
18
+ resolvelib==1.0.1
19
+ setuptools==68.0.0
20
+ six==1.16.0
21
+ tenacity==8.2.2
22
+ tomli==2.0.1
23
+ truststore==0.8.0
24
+ webencodings==0.5.1
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/__init__.py ADDED
@@ -0,0 +1,342 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf-8
2
+ """
3
+
4
+ webencodings
5
+ ~~~~~~~~~~~~
6
+
7
+ This is a Python implementation of the `WHATWG Encoding standard
8
+ <http://encoding.spec.whatwg.org/>`. See README for details.
9
+
10
+ :copyright: Copyright 2012 by Simon Sapin
11
+ :license: BSD, see LICENSE for details.
12
+
13
+ """
14
+
15
+ from __future__ import unicode_literals
16
+
17
+ import codecs
18
+
19
+ from .labels import LABELS
20
+
21
+
22
+ VERSION = '0.5.1'
23
+
24
+
25
+ # Some names in Encoding are not valid Python aliases. Remap these.
26
+ PYTHON_NAMES = {
27
+ 'iso-8859-8-i': 'iso-8859-8',
28
+ 'x-mac-cyrillic': 'mac-cyrillic',
29
+ 'macintosh': 'mac-roman',
30
+ 'windows-874': 'cp874'}
31
+
32
+ CACHE = {}
33
+
34
+
35
+ def ascii_lower(string):
36
+ r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z.
37
+
38
+ :param string: An Unicode string.
39
+ :returns: A new Unicode string.
40
+
41
+ This is used for `ASCII case-insensitive
42
+ <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_
43
+ matching of encoding labels.
44
+ The same matching is also used, among other things,
45
+ for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_.
46
+
47
+ This is different from the :meth:`~py:str.lower` method of Unicode strings
48
+ which also affect non-ASCII characters,
49
+ sometimes mapping them into the ASCII range:
50
+
51
+ >>> keyword = u'Bac\N{KELVIN SIGN}ground'
52
+ >>> assert keyword.lower() == u'background'
53
+ >>> assert ascii_lower(keyword) != keyword.lower()
54
+ >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground'
55
+
56
+ """
57
+ # This turns out to be faster than unicode.translate()
58
+ return string.encode('utf8').lower().decode('utf8')
59
+
60
+
61
+ def lookup(label):
62
+ """
63
+ Look for an encoding by its label.
64
+ This is the spec’s `get an encoding
65
+ <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm.
66
+ Supported labels are listed there.
67
+
68
+ :param label: A string.
69
+ :returns:
70
+ An :class:`Encoding` object, or :obj:`None` for an unknown label.
71
+
72
+ """
73
+ # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020.
74
+ label = ascii_lower(label.strip('\t\n\f\r '))
75
+ name = LABELS.get(label)
76
+ if name is None:
77
+ return None
78
+ encoding = CACHE.get(name)
79
+ if encoding is None:
80
+ if name == 'x-user-defined':
81
+ from .x_user_defined import codec_info
82
+ else:
83
+ python_name = PYTHON_NAMES.get(name, name)
84
+ # Any python_name value that gets to here should be valid.
85
+ codec_info = codecs.lookup(python_name)
86
+ encoding = Encoding(name, codec_info)
87
+ CACHE[name] = encoding
88
+ return encoding
89
+
90
+
91
+ def _get_encoding(encoding_or_label):
92
+ """
93
+ Accept either an encoding object or label.
94
+
95
+ :param encoding: An :class:`Encoding` object or a label string.
96
+ :returns: An :class:`Encoding` object.
97
+ :raises: :exc:`~exceptions.LookupError` for an unknown label.
98
+
99
+ """
100
+ if hasattr(encoding_or_label, 'codec_info'):
101
+ return encoding_or_label
102
+
103
+ encoding = lookup(encoding_or_label)
104
+ if encoding is None:
105
+ raise LookupError('Unknown encoding label: %r' % encoding_or_label)
106
+ return encoding
107
+
108
+
109
+ class Encoding(object):
110
+ """Reresents a character encoding such as UTF-8,
111
+ that can be used for decoding or encoding.
112
+
113
+ .. attribute:: name
114
+
115
+ Canonical name of the encoding
116
+
117
+ .. attribute:: codec_info
118
+
119
+ The actual implementation of the encoding,
120
+ a stdlib :class:`~codecs.CodecInfo` object.
121
+ See :func:`codecs.register`.
122
+
123
+ """
124
+ def __init__(self, name, codec_info):
125
+ self.name = name
126
+ self.codec_info = codec_info
127
+
128
+ def __repr__(self):
129
+ return '<Encoding %s>' % self.name
130
+
131
+
132
+ #: The UTF-8 encoding. Should be used for new content and formats.
133
+ UTF8 = lookup('utf-8')
134
+
135
+ _UTF16LE = lookup('utf-16le')
136
+ _UTF16BE = lookup('utf-16be')
137
+
138
+
139
+ def decode(input, fallback_encoding, errors='replace'):
140
+ """
141
+ Decode a single string.
142
+
143
+ :param input: A byte string
144
+ :param fallback_encoding:
145
+ An :class:`Encoding` object or a label string.
146
+ The encoding to use if :obj:`input` does note have a BOM.
147
+ :param errors: Type of error handling. See :func:`codecs.register`.
148
+ :raises: :exc:`~exceptions.LookupError` for an unknown encoding label.
149
+ :return:
150
+ A ``(output, encoding)`` tuple of an Unicode string
151
+ and an :obj:`Encoding`.
152
+
153
+ """
154
+ # Fail early if `encoding` is an invalid label.
155
+ fallback_encoding = _get_encoding(fallback_encoding)
156
+ bom_encoding, input = _detect_bom(input)
157
+ encoding = bom_encoding or fallback_encoding
158
+ return encoding.codec_info.decode(input, errors)[0], encoding
159
+
160
+
161
+ def _detect_bom(input):
162
+ """Return (bom_encoding, input), with any BOM removed from the input."""
163
+ if input.startswith(b'\xFF\xFE'):
164
+ return _UTF16LE, input[2:]
165
+ if input.startswith(b'\xFE\xFF'):
166
+ return _UTF16BE, input[2:]
167
+ if input.startswith(b'\xEF\xBB\xBF'):
168
+ return UTF8, input[3:]
169
+ return None, input
170
+
171
+
172
+ def encode(input, encoding=UTF8, errors='strict'):
173
+ """
174
+ Encode a single string.
175
+
176
+ :param input: An Unicode string.
177
+ :param encoding: An :class:`Encoding` object or a label string.
178
+ :param errors: Type of error handling. See :func:`codecs.register`.
179
+ :raises: :exc:`~exceptions.LookupError` for an unknown encoding label.
180
+ :return: A byte string.
181
+
182
+ """
183
+ return _get_encoding(encoding).codec_info.encode(input, errors)[0]
184
+
185
+
186
+ def iter_decode(input, fallback_encoding, errors='replace'):
187
+ """
188
+ "Pull"-based decoder.
189
+
190
+ :param input:
191
+ An iterable of byte strings.
192
+
193
+ The input is first consumed just enough to determine the encoding
194
+ based on the precense of a BOM,
195
+ then consumed on demand when the return value is.
196
+ :param fallback_encoding:
197
+ An :class:`Encoding` object or a label string.
198
+ The encoding to use if :obj:`input` does note have a BOM.
199
+ :param errors: Type of error handling. See :func:`codecs.register`.
200
+ :raises: :exc:`~exceptions.LookupError` for an unknown encoding label.
201
+ :returns:
202
+ An ``(output, encoding)`` tuple.
203
+ :obj:`output` is an iterable of Unicode strings,
204
+ :obj:`encoding` is the :obj:`Encoding` that is being used.
205
+
206
+ """
207
+
208
+ decoder = IncrementalDecoder(fallback_encoding, errors)
209
+ generator = _iter_decode_generator(input, decoder)
210
+ encoding = next(generator)
211
+ return generator, encoding
212
+
213
+
214
+ def _iter_decode_generator(input, decoder):
215
+ """Return a generator that first yields the :obj:`Encoding`,
216
+ then yields output chukns as Unicode strings.
217
+
218
+ """
219
+ decode = decoder.decode
220
+ input = iter(input)
221
+ for chunck in input:
222
+ output = decode(chunck)
223
+ if output:
224
+ assert decoder.encoding is not None
225
+ yield decoder.encoding
226
+ yield output
227
+ break
228
+ else:
229
+ # Input exhausted without determining the encoding
230
+ output = decode(b'', final=True)
231
+ assert decoder.encoding is not None
232
+ yield decoder.encoding
233
+ if output:
234
+ yield output
235
+ return
236
+
237
+ for chunck in input:
238
+ output = decode(chunck)
239
+ if output:
240
+ yield output
241
+ output = decode(b'', final=True)
242
+ if output:
243
+ yield output
244
+
245
+
246
+ def iter_encode(input, encoding=UTF8, errors='strict'):
247
+ """
248
+ “Pull”-based encoder.
249
+
250
+ :param input: An iterable of Unicode strings.
251
+ :param encoding: An :class:`Encoding` object or a label string.
252
+ :param errors: Type of error handling. See :func:`codecs.register`.
253
+ :raises: :exc:`~exceptions.LookupError` for an unknown encoding label.
254
+ :returns: An iterable of byte strings.
255
+
256
+ """
257
+ # Fail early if `encoding` is an invalid label.
258
+ encode = IncrementalEncoder(encoding, errors).encode
259
+ return _iter_encode_generator(input, encode)
260
+
261
+
262
+ def _iter_encode_generator(input, encode):
263
+ for chunck in input:
264
+ output = encode(chunck)
265
+ if output:
266
+ yield output
267
+ output = encode('', final=True)
268
+ if output:
269
+ yield output
270
+
271
+
272
+ class IncrementalDecoder(object):
273
+ """
274
+ “Push”-based decoder.
275
+
276
+ :param fallback_encoding:
277
+ An :class:`Encoding` object or a label string.
278
+ The encoding to use if :obj:`input` does note have a BOM.
279
+ :param errors: Type of error handling. See :func:`codecs.register`.
280
+ :raises: :exc:`~exceptions.LookupError` for an unknown encoding label.
281
+
282
+ """
283
+ def __init__(self, fallback_encoding, errors='replace'):
284
+ # Fail early if `encoding` is an invalid label.
285
+ self._fallback_encoding = _get_encoding(fallback_encoding)
286
+ self._errors = errors
287
+ self._buffer = b''
288
+ self._decoder = None
289
+ #: The actual :class:`Encoding` that is being used,
290
+ #: or :obj:`None` if that is not determined yet.
291
+ #: (Ie. if there is not enough input yet to determine
292
+ #: if there is a BOM.)
293
+ self.encoding = None # Not known yet.
294
+
295
+ def decode(self, input, final=False):
296
+ """Decode one chunk of the input.
297
+
298
+ :param input: A byte string.
299
+ :param final:
300
+ Indicate that no more input is available.
301
+ Must be :obj:`True` if this is the last call.
302
+ :returns: An Unicode string.
303
+
304
+ """
305
+ decoder = self._decoder
306
+ if decoder is not None:
307
+ return decoder(input, final)
308
+
309
+ input = self._buffer + input
310
+ encoding, input = _detect_bom(input)
311
+ if encoding is None:
312
+ if len(input) < 3 and not final: # Not enough data yet.
313
+ self._buffer = input
314
+ return ''
315
+ else: # No BOM
316
+ encoding = self._fallback_encoding
317
+ decoder = encoding.codec_info.incrementaldecoder(self._errors).decode
318
+ self._decoder = decoder
319
+ self.encoding = encoding
320
+ return decoder(input, final)
321
+
322
+
323
+ class IncrementalEncoder(object):
324
+ """
325
+ “Push”-based encoder.
326
+
327
+ :param encoding: An :class:`Encoding` object or a label string.
328
+ :param errors: Type of error handling. See :func:`codecs.register`.
329
+ :raises: :exc:`~exceptions.LookupError` for an unknown encoding label.
330
+
331
+ .. method:: encode(input, final=False)
332
+
333
+ :param input: An Unicode string.
334
+ :param final:
335
+ Indicate that no more input is available.
336
+ Must be :obj:`True` if this is the last call.
337
+ :returns: A byte string.
338
+
339
+ """
340
+ def __init__(self, encoding=UTF8, errors='strict'):
341
+ encoding = _get_encoding(encoding)
342
+ self.encode = encoding.codec_info.incrementalencoder(errors).encode
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/labels.py ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+
3
+ webencodings.labels
4
+ ~~~~~~~~~~~~~~~~~~~
5
+
6
+ Map encoding labels to their name.
7
+
8
+ :copyright: Copyright 2012 by Simon Sapin
9
+ :license: BSD, see LICENSE for details.
10
+
11
+ """
12
+
13
+ # XXX Do not edit!
14
+ # This file is automatically generated by mklabels.py
15
+
16
+ LABELS = {
17
+ 'unicode-1-1-utf-8': 'utf-8',
18
+ 'utf-8': 'utf-8',
19
+ 'utf8': 'utf-8',
20
+ '866': 'ibm866',
21
+ 'cp866': 'ibm866',
22
+ 'csibm866': 'ibm866',
23
+ 'ibm866': 'ibm866',
24
+ 'csisolatin2': 'iso-8859-2',
25
+ 'iso-8859-2': 'iso-8859-2',
26
+ 'iso-ir-101': 'iso-8859-2',
27
+ 'iso8859-2': 'iso-8859-2',
28
+ 'iso88592': 'iso-8859-2',
29
+ 'iso_8859-2': 'iso-8859-2',
30
+ 'iso_8859-2:1987': 'iso-8859-2',
31
+ 'l2': 'iso-8859-2',
32
+ 'latin2': 'iso-8859-2',
33
+ 'csisolatin3': 'iso-8859-3',
34
+ 'iso-8859-3': 'iso-8859-3',
35
+ 'iso-ir-109': 'iso-8859-3',
36
+ 'iso8859-3': 'iso-8859-3',
37
+ 'iso88593': 'iso-8859-3',
38
+ 'iso_8859-3': 'iso-8859-3',
39
+ 'iso_8859-3:1988': 'iso-8859-3',
40
+ 'l3': 'iso-8859-3',
41
+ 'latin3': 'iso-8859-3',
42
+ 'csisolatin4': 'iso-8859-4',
43
+ 'iso-8859-4': 'iso-8859-4',
44
+ 'iso-ir-110': 'iso-8859-4',
45
+ 'iso8859-4': 'iso-8859-4',
46
+ 'iso88594': 'iso-8859-4',
47
+ 'iso_8859-4': 'iso-8859-4',
48
+ 'iso_8859-4:1988': 'iso-8859-4',
49
+ 'l4': 'iso-8859-4',
50
+ 'latin4': 'iso-8859-4',
51
+ 'csisolatincyrillic': 'iso-8859-5',
52
+ 'cyrillic': 'iso-8859-5',
53
+ 'iso-8859-5': 'iso-8859-5',
54
+ 'iso-ir-144': 'iso-8859-5',
55
+ 'iso8859-5': 'iso-8859-5',
56
+ 'iso88595': 'iso-8859-5',
57
+ 'iso_8859-5': 'iso-8859-5',
58
+ 'iso_8859-5:1988': 'iso-8859-5',
59
+ 'arabic': 'iso-8859-6',
60
+ 'asmo-708': 'iso-8859-6',
61
+ 'csiso88596e': 'iso-8859-6',
62
+ 'csiso88596i': 'iso-8859-6',
63
+ 'csisolatinarabic': 'iso-8859-6',
64
+ 'ecma-114': 'iso-8859-6',
65
+ 'iso-8859-6': 'iso-8859-6',
66
+ 'iso-8859-6-e': 'iso-8859-6',
67
+ 'iso-8859-6-i': 'iso-8859-6',
68
+ 'iso-ir-127': 'iso-8859-6',
69
+ 'iso8859-6': 'iso-8859-6',
70
+ 'iso88596': 'iso-8859-6',
71
+ 'iso_8859-6': 'iso-8859-6',
72
+ 'iso_8859-6:1987': 'iso-8859-6',
73
+ 'csisolatingreek': 'iso-8859-7',
74
+ 'ecma-118': 'iso-8859-7',
75
+ 'elot_928': 'iso-8859-7',
76
+ 'greek': 'iso-8859-7',
77
+ 'greek8': 'iso-8859-7',
78
+ 'iso-8859-7': 'iso-8859-7',
79
+ 'iso-ir-126': 'iso-8859-7',
80
+ 'iso8859-7': 'iso-8859-7',
81
+ 'iso88597': 'iso-8859-7',
82
+ 'iso_8859-7': 'iso-8859-7',
83
+ 'iso_8859-7:1987': 'iso-8859-7',
84
+ 'sun_eu_greek': 'iso-8859-7',
85
+ 'csiso88598e': 'iso-8859-8',
86
+ 'csisolatinhebrew': 'iso-8859-8',
87
+ 'hebrew': 'iso-8859-8',
88
+ 'iso-8859-8': 'iso-8859-8',
89
+ 'iso-8859-8-e': 'iso-8859-8',
90
+ 'iso-ir-138': 'iso-8859-8',
91
+ 'iso8859-8': 'iso-8859-8',
92
+ 'iso88598': 'iso-8859-8',
93
+ 'iso_8859-8': 'iso-8859-8',
94
+ 'iso_8859-8:1988': 'iso-8859-8',
95
+ 'visual': 'iso-8859-8',
96
+ 'csiso88598i': 'iso-8859-8-i',
97
+ 'iso-8859-8-i': 'iso-8859-8-i',
98
+ 'logical': 'iso-8859-8-i',
99
+ 'csisolatin6': 'iso-8859-10',
100
+ 'iso-8859-10': 'iso-8859-10',
101
+ 'iso-ir-157': 'iso-8859-10',
102
+ 'iso8859-10': 'iso-8859-10',
103
+ 'iso885910': 'iso-8859-10',
104
+ 'l6': 'iso-8859-10',
105
+ 'latin6': 'iso-8859-10',
106
+ 'iso-8859-13': 'iso-8859-13',
107
+ 'iso8859-13': 'iso-8859-13',
108
+ 'iso885913': 'iso-8859-13',
109
+ 'iso-8859-14': 'iso-8859-14',
110
+ 'iso8859-14': 'iso-8859-14',
111
+ 'iso885914': 'iso-8859-14',
112
+ 'csisolatin9': 'iso-8859-15',
113
+ 'iso-8859-15': 'iso-8859-15',
114
+ 'iso8859-15': 'iso-8859-15',
115
+ 'iso885915': 'iso-8859-15',
116
+ 'iso_8859-15': 'iso-8859-15',
117
+ 'l9': 'iso-8859-15',
118
+ 'iso-8859-16': 'iso-8859-16',
119
+ 'cskoi8r': 'koi8-r',
120
+ 'koi': 'koi8-r',
121
+ 'koi8': 'koi8-r',
122
+ 'koi8-r': 'koi8-r',
123
+ 'koi8_r': 'koi8-r',
124
+ 'koi8-u': 'koi8-u',
125
+ 'csmacintosh': 'macintosh',
126
+ 'mac': 'macintosh',
127
+ 'macintosh': 'macintosh',
128
+ 'x-mac-roman': 'macintosh',
129
+ 'dos-874': 'windows-874',
130
+ 'iso-8859-11': 'windows-874',
131
+ 'iso8859-11': 'windows-874',
132
+ 'iso885911': 'windows-874',
133
+ 'tis-620': 'windows-874',
134
+ 'windows-874': 'windows-874',
135
+ 'cp1250': 'windows-1250',
136
+ 'windows-1250': 'windows-1250',
137
+ 'x-cp1250': 'windows-1250',
138
+ 'cp1251': 'windows-1251',
139
+ 'windows-1251': 'windows-1251',
140
+ 'x-cp1251': 'windows-1251',
141
+ 'ansi_x3.4-1968': 'windows-1252',
142
+ 'ascii': 'windows-1252',
143
+ 'cp1252': 'windows-1252',
144
+ 'cp819': 'windows-1252',
145
+ 'csisolatin1': 'windows-1252',
146
+ 'ibm819': 'windows-1252',
147
+ 'iso-8859-1': 'windows-1252',
148
+ 'iso-ir-100': 'windows-1252',
149
+ 'iso8859-1': 'windows-1252',
150
+ 'iso88591': 'windows-1252',
151
+ 'iso_8859-1': 'windows-1252',
152
+ 'iso_8859-1:1987': 'windows-1252',
153
+ 'l1': 'windows-1252',
154
+ 'latin1': 'windows-1252',
155
+ 'us-ascii': 'windows-1252',
156
+ 'windows-1252': 'windows-1252',
157
+ 'x-cp1252': 'windows-1252',
158
+ 'cp1253': 'windows-1253',
159
+ 'windows-1253': 'windows-1253',
160
+ 'x-cp1253': 'windows-1253',
161
+ 'cp1254': 'windows-1254',
162
+ 'csisolatin5': 'windows-1254',
163
+ 'iso-8859-9': 'windows-1254',
164
+ 'iso-ir-148': 'windows-1254',
165
+ 'iso8859-9': 'windows-1254',
166
+ 'iso88599': 'windows-1254',
167
+ 'iso_8859-9': 'windows-1254',
168
+ 'iso_8859-9:1989': 'windows-1254',
169
+ 'l5': 'windows-1254',
170
+ 'latin5': 'windows-1254',
171
+ 'windows-1254': 'windows-1254',
172
+ 'x-cp1254': 'windows-1254',
173
+ 'cp1255': 'windows-1255',
174
+ 'windows-1255': 'windows-1255',
175
+ 'x-cp1255': 'windows-1255',
176
+ 'cp1256': 'windows-1256',
177
+ 'windows-1256': 'windows-1256',
178
+ 'x-cp1256': 'windows-1256',
179
+ 'cp1257': 'windows-1257',
180
+ 'windows-1257': 'windows-1257',
181
+ 'x-cp1257': 'windows-1257',
182
+ 'cp1258': 'windows-1258',
183
+ 'windows-1258': 'windows-1258',
184
+ 'x-cp1258': 'windows-1258',
185
+ 'x-mac-cyrillic': 'x-mac-cyrillic',
186
+ 'x-mac-ukrainian': 'x-mac-cyrillic',
187
+ 'chinese': 'gbk',
188
+ 'csgb2312': 'gbk',
189
+ 'csiso58gb231280': 'gbk',
190
+ 'gb2312': 'gbk',
191
+ 'gb_2312': 'gbk',
192
+ 'gb_2312-80': 'gbk',
193
+ 'gbk': 'gbk',
194
+ 'iso-ir-58': 'gbk',
195
+ 'x-gbk': 'gbk',
196
+ 'gb18030': 'gb18030',
197
+ 'hz-gb-2312': 'hz-gb-2312',
198
+ 'big5': 'big5',
199
+ 'big5-hkscs': 'big5',
200
+ 'cn-big5': 'big5',
201
+ 'csbig5': 'big5',
202
+ 'x-x-big5': 'big5',
203
+ 'cseucpkdfmtjapanese': 'euc-jp',
204
+ 'euc-jp': 'euc-jp',
205
+ 'x-euc-jp': 'euc-jp',
206
+ 'csiso2022jp': 'iso-2022-jp',
207
+ 'iso-2022-jp': 'iso-2022-jp',
208
+ 'csshiftjis': 'shift_jis',
209
+ 'ms_kanji': 'shift_jis',
210
+ 'shift-jis': 'shift_jis',
211
+ 'shift_jis': 'shift_jis',
212
+ 'sjis': 'shift_jis',
213
+ 'windows-31j': 'shift_jis',
214
+ 'x-sjis': 'shift_jis',
215
+ 'cseuckr': 'euc-kr',
216
+ 'csksc56011987': 'euc-kr',
217
+ 'euc-kr': 'euc-kr',
218
+ 'iso-ir-149': 'euc-kr',
219
+ 'korean': 'euc-kr',
220
+ 'ks_c_5601-1987': 'euc-kr',
221
+ 'ks_c_5601-1989': 'euc-kr',
222
+ 'ksc5601': 'euc-kr',
223
+ 'ksc_5601': 'euc-kr',
224
+ 'windows-949': 'euc-kr',
225
+ 'csiso2022kr': 'iso-2022-kr',
226
+ 'iso-2022-kr': 'iso-2022-kr',
227
+ 'utf-16be': 'utf-16be',
228
+ 'utf-16': 'utf-16le',
229
+ 'utf-16le': 'utf-16le',
230
+ 'x-user-defined': 'x-user-defined',
231
+ }
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/mklabels.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+
3
+ webencodings.mklabels
4
+ ~~~~~~~~~~~~~~~~~~~~~
5
+
6
+ Regenarate the webencodings.labels module.
7
+
8
+ :copyright: Copyright 2012 by Simon Sapin
9
+ :license: BSD, see LICENSE for details.
10
+
11
+ """
12
+
13
+ import json
14
+ try:
15
+ from urllib import urlopen
16
+ except ImportError:
17
+ from urllib.request import urlopen
18
+
19
+
20
+ def assert_lower(string):
21
+ assert string == string.lower()
22
+ return string
23
+
24
+
25
+ def generate(url):
26
+ parts = ['''\
27
+ """
28
+
29
+ webencodings.labels
30
+ ~~~~~~~~~~~~~~~~~~~
31
+
32
+ Map encoding labels to their name.
33
+
34
+ :copyright: Copyright 2012 by Simon Sapin
35
+ :license: BSD, see LICENSE for details.
36
+
37
+ """
38
+
39
+ # XXX Do not edit!
40
+ # This file is automatically generated by mklabels.py
41
+
42
+ LABELS = {
43
+ ''']
44
+ labels = [
45
+ (repr(assert_lower(label)).lstrip('u'),
46
+ repr(encoding['name']).lstrip('u'))
47
+ for category in json.loads(urlopen(url).read().decode('ascii'))
48
+ for encoding in category['encodings']
49
+ for label in encoding['labels']]
50
+ max_len = max(len(label) for label, name in labels)
51
+ parts.extend(
52
+ ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name)
53
+ for label, name in labels)
54
+ parts.append('}')
55
+ return ''.join(parts)
56
+
57
+
58
+ if __name__ == '__main__':
59
+ print(generate('http://encoding.spec.whatwg.org/encodings.json'))
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/tests.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf-8
2
+ """
3
+
4
+ webencodings.tests
5
+ ~~~~~~~~~~~~~~~~~~
6
+
7
+ A basic test suite for Encoding.
8
+
9
+ :copyright: Copyright 2012 by Simon Sapin
10
+ :license: BSD, see LICENSE for details.
11
+
12
+ """
13
+
14
+ from __future__ import unicode_literals
15
+
16
+ from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode,
17
+ IncrementalDecoder, IncrementalEncoder, UTF8)
18
+
19
+
20
+ def assert_raises(exception, function, *args, **kwargs):
21
+ try:
22
+ function(*args, **kwargs)
23
+ except exception:
24
+ return
25
+ else: # pragma: no cover
26
+ raise AssertionError('Did not raise %s.' % exception)
27
+
28
+
29
+ def test_labels():
30
+ assert lookup('utf-8').name == 'utf-8'
31
+ assert lookup('Utf-8').name == 'utf-8'
32
+ assert lookup('UTF-8').name == 'utf-8'
33
+ assert lookup('utf8').name == 'utf-8'
34
+ assert lookup('utf8').name == 'utf-8'
35
+ assert lookup('utf8 ').name == 'utf-8'
36
+ assert lookup(' \r\nutf8\t').name == 'utf-8'
37
+ assert lookup('u8') is None # Python label.
38
+ assert lookup('utf-8 ') is None # Non-ASCII white space.
39
+
40
+ assert lookup('US-ASCII').name == 'windows-1252'
41
+ assert lookup('iso-8859-1').name == 'windows-1252'
42
+ assert lookup('latin1').name == 'windows-1252'
43
+ assert lookup('LATIN1').name == 'windows-1252'
44
+ assert lookup('latin-1') is None
45
+ assert lookup('LATİN1') is None # ASCII-only case insensitivity.
46
+
47
+
48
+ def test_all_labels():
49
+ for label in LABELS:
50
+ assert decode(b'', label) == ('', lookup(label))
51
+ assert encode('', label) == b''
52
+ for repeat in [0, 1, 12]:
53
+ output, _ = iter_decode([b''] * repeat, label)
54
+ assert list(output) == []
55
+ assert list(iter_encode([''] * repeat, label)) == []
56
+ decoder = IncrementalDecoder(label)
57
+ assert decoder.decode(b'') == ''
58
+ assert decoder.decode(b'', final=True) == ''
59
+ encoder = IncrementalEncoder(label)
60
+ assert encoder.encode('') == b''
61
+ assert encoder.encode('', final=True) == b''
62
+ # All encoding names are valid labels too:
63
+ for name in set(LABELS.values()):
64
+ assert lookup(name).name == name
65
+
66
+
67
+ def test_invalid_label():
68
+ assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid')
69
+ assert_raises(LookupError, encode, 'é', 'invalid')
70
+ assert_raises(LookupError, iter_decode, [], 'invalid')
71
+ assert_raises(LookupError, iter_encode, [], 'invalid')
72
+ assert_raises(LookupError, IncrementalDecoder, 'invalid')
73
+ assert_raises(LookupError, IncrementalEncoder, 'invalid')
74
+
75
+
76
+ def test_decode():
77
+ assert decode(b'\x80', 'latin1') == ('€', lookup('latin1'))
78
+ assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1'))
79
+ assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8'))
80
+ assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8'))
81
+ assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii'))
82
+ assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM
83
+
84
+ assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM
85
+ assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM
86
+ assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be'))
87
+ assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le'))
88
+
89
+ assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be'))
90
+ assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le'))
91
+ assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le'))
92
+
93
+ assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be'))
94
+ assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le'))
95
+ assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le'))
96
+
97
+
98
+ def test_encode():
99
+ assert encode('é', 'latin1') == b'\xe9'
100
+ assert encode('é', 'utf8') == b'\xc3\xa9'
101
+ assert encode('é', 'utf8') == b'\xc3\xa9'
102
+ assert encode('é', 'utf-16') == b'\xe9\x00'
103
+ assert encode('é', 'utf-16le') == b'\xe9\x00'
104
+ assert encode('é', 'utf-16be') == b'\x00\xe9'
105
+
106
+
107
+ def test_iter_decode():
108
+ def iter_decode_to_string(input, fallback_encoding):
109
+ output, _encoding = iter_decode(input, fallback_encoding)
110
+ return ''.join(output)
111
+ assert iter_decode_to_string([], 'latin1') == ''
112
+ assert iter_decode_to_string([b''], 'latin1') == ''
113
+ assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é'
114
+ assert iter_decode_to_string([b'hello'], 'latin1') == 'hello'
115
+ assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello'
116
+ assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello'
117
+ assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é'
118
+ assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é'
119
+ assert iter_decode_to_string([
120
+ b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é'
121
+ assert iter_decode_to_string([
122
+ b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD'
123
+ assert iter_decode_to_string([
124
+ b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é'
125
+ assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == ''
126
+ assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»'
127
+ assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é'
128
+ assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é'
129
+ assert iter_decode_to_string([
130
+ b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é'
131
+ assert iter_decode_to_string([
132
+ b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo'
133
+
134
+
135
+ def test_iter_encode():
136
+ assert b''.join(iter_encode([], 'latin1')) == b''
137
+ assert b''.join(iter_encode([''], 'latin1')) == b''
138
+ assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9'
139
+ assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9'
140
+ assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00'
141
+ assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00'
142
+ assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9'
143
+ assert b''.join(iter_encode([
144
+ '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo'
145
+
146
+
147
+ def test_x_user_defined():
148
+ encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca'
149
+ decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca'
150
+ encoded = b'aa'
151
+ decoded = 'aa'
152
+ assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined'))
153
+ assert encode(decoded, 'x-user-defined') == encoded
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/_vendor/webencodings/x_user_defined.py ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # coding: utf-8
2
+ """
3
+
4
+ webencodings.x_user_defined
5
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
6
+
7
+ An implementation of the x-user-defined encoding.
8
+
9
+ :copyright: Copyright 2012 by Simon Sapin
10
+ :license: BSD, see LICENSE for details.
11
+
12
+ """
13
+
14
+ from __future__ import unicode_literals
15
+
16
+ import codecs
17
+
18
+
19
+ ### Codec APIs
20
+
21
+ class Codec(codecs.Codec):
22
+
23
+ def encode(self, input, errors='strict'):
24
+ return codecs.charmap_encode(input, errors, encoding_table)
25
+
26
+ def decode(self, input, errors='strict'):
27
+ return codecs.charmap_decode(input, errors, decoding_table)
28
+
29
+
30
+ class IncrementalEncoder(codecs.IncrementalEncoder):
31
+ def encode(self, input, final=False):
32
+ return codecs.charmap_encode(input, self.errors, encoding_table)[0]
33
+
34
+
35
+ class IncrementalDecoder(codecs.IncrementalDecoder):
36
+ def decode(self, input, final=False):
37
+ return codecs.charmap_decode(input, self.errors, decoding_table)[0]
38
+
39
+
40
+ class StreamWriter(Codec, codecs.StreamWriter):
41
+ pass
42
+
43
+
44
+ class StreamReader(Codec, codecs.StreamReader):
45
+ pass
46
+
47
+
48
+ ### encodings module API
49
+
50
+ codec_info = codecs.CodecInfo(
51
+ name='x-user-defined',
52
+ encode=Codec().encode,
53
+ decode=Codec().decode,
54
+ incrementalencoder=IncrementalEncoder,
55
+ incrementaldecoder=IncrementalDecoder,
56
+ streamreader=StreamReader,
57
+ streamwriter=StreamWriter,
58
+ )
59
+
60
+
61
+ ### Decoding Table
62
+
63
+ # Python 3:
64
+ # for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700))
65
+ decoding_table = (
66
+ '\x00'
67
+ '\x01'
68
+ '\x02'
69
+ '\x03'
70
+ '\x04'
71
+ '\x05'
72
+ '\x06'
73
+ '\x07'
74
+ '\x08'
75
+ '\t'
76
+ '\n'
77
+ '\x0b'
78
+ '\x0c'
79
+ '\r'
80
+ '\x0e'
81
+ '\x0f'
82
+ '\x10'
83
+ '\x11'
84
+ '\x12'
85
+ '\x13'
86
+ '\x14'
87
+ '\x15'
88
+ '\x16'
89
+ '\x17'
90
+ '\x18'
91
+ '\x19'
92
+ '\x1a'
93
+ '\x1b'
94
+ '\x1c'
95
+ '\x1d'
96
+ '\x1e'
97
+ '\x1f'
98
+ ' '
99
+ '!'
100
+ '"'
101
+ '#'
102
+ '$'
103
+ '%'
104
+ '&'
105
+ "'"
106
+ '('
107
+ ')'
108
+ '*'
109
+ '+'
110
+ ','
111
+ '-'
112
+ '.'
113
+ '/'
114
+ '0'
115
+ '1'
116
+ '2'
117
+ '3'
118
+ '4'
119
+ '5'
120
+ '6'
121
+ '7'
122
+ '8'
123
+ '9'
124
+ ':'
125
+ ';'
126
+ '<'
127
+ '='
128
+ '>'
129
+ '?'
130
+ '@'
131
+ 'A'
132
+ 'B'
133
+ 'C'
134
+ 'D'
135
+ 'E'
136
+ 'F'
137
+ 'G'
138
+ 'H'
139
+ 'I'
140
+ 'J'
141
+ 'K'
142
+ 'L'
143
+ 'M'
144
+ 'N'
145
+ 'O'
146
+ 'P'
147
+ 'Q'
148
+ 'R'
149
+ 'S'
150
+ 'T'
151
+ 'U'
152
+ 'V'
153
+ 'W'
154
+ 'X'
155
+ 'Y'
156
+ 'Z'
157
+ '['
158
+ '\\'
159
+ ']'
160
+ '^'
161
+ '_'
162
+ '`'
163
+ 'a'
164
+ 'b'
165
+ 'c'
166
+ 'd'
167
+ 'e'
168
+ 'f'
169
+ 'g'
170
+ 'h'
171
+ 'i'
172
+ 'j'
173
+ 'k'
174
+ 'l'
175
+ 'm'
176
+ 'n'
177
+ 'o'
178
+ 'p'
179
+ 'q'
180
+ 'r'
181
+ 's'
182
+ 't'
183
+ 'u'
184
+ 'v'
185
+ 'w'
186
+ 'x'
187
+ 'y'
188
+ 'z'
189
+ '{'
190
+ '|'
191
+ '}'
192
+ '~'
193
+ '\x7f'
194
+ '\uf780'
195
+ '\uf781'
196
+ '\uf782'
197
+ '\uf783'
198
+ '\uf784'
199
+ '\uf785'
200
+ '\uf786'
201
+ '\uf787'
202
+ '\uf788'
203
+ '\uf789'
204
+ '\uf78a'
205
+ '\uf78b'
206
+ '\uf78c'
207
+ '\uf78d'
208
+ '\uf78e'
209
+ '\uf78f'
210
+ '\uf790'
211
+ '\uf791'
212
+ '\uf792'
213
+ '\uf793'
214
+ '\uf794'
215
+ '\uf795'
216
+ '\uf796'
217
+ '\uf797'
218
+ '\uf798'
219
+ '\uf799'
220
+ '\uf79a'
221
+ '\uf79b'
222
+ '\uf79c'
223
+ '\uf79d'
224
+ '\uf79e'
225
+ '\uf79f'
226
+ '\uf7a0'
227
+ '\uf7a1'
228
+ '\uf7a2'
229
+ '\uf7a3'
230
+ '\uf7a4'
231
+ '\uf7a5'
232
+ '\uf7a6'
233
+ '\uf7a7'
234
+ '\uf7a8'
235
+ '\uf7a9'
236
+ '\uf7aa'
237
+ '\uf7ab'
238
+ '\uf7ac'
239
+ '\uf7ad'
240
+ '\uf7ae'
241
+ '\uf7af'
242
+ '\uf7b0'
243
+ '\uf7b1'
244
+ '\uf7b2'
245
+ '\uf7b3'
246
+ '\uf7b4'
247
+ '\uf7b5'
248
+ '\uf7b6'
249
+ '\uf7b7'
250
+ '\uf7b8'
251
+ '\uf7b9'
252
+ '\uf7ba'
253
+ '\uf7bb'
254
+ '\uf7bc'
255
+ '\uf7bd'
256
+ '\uf7be'
257
+ '\uf7bf'
258
+ '\uf7c0'
259
+ '\uf7c1'
260
+ '\uf7c2'
261
+ '\uf7c3'
262
+ '\uf7c4'
263
+ '\uf7c5'
264
+ '\uf7c6'
265
+ '\uf7c7'
266
+ '\uf7c8'
267
+ '\uf7c9'
268
+ '\uf7ca'
269
+ '\uf7cb'
270
+ '\uf7cc'
271
+ '\uf7cd'
272
+ '\uf7ce'
273
+ '\uf7cf'
274
+ '\uf7d0'
275
+ '\uf7d1'
276
+ '\uf7d2'
277
+ '\uf7d3'
278
+ '\uf7d4'
279
+ '\uf7d5'
280
+ '\uf7d6'
281
+ '\uf7d7'
282
+ '\uf7d8'
283
+ '\uf7d9'
284
+ '\uf7da'
285
+ '\uf7db'
286
+ '\uf7dc'
287
+ '\uf7dd'
288
+ '\uf7de'
289
+ '\uf7df'
290
+ '\uf7e0'
291
+ '\uf7e1'
292
+ '\uf7e2'
293
+ '\uf7e3'
294
+ '\uf7e4'
295
+ '\uf7e5'
296
+ '\uf7e6'
297
+ '\uf7e7'
298
+ '\uf7e8'
299
+ '\uf7e9'
300
+ '\uf7ea'
301
+ '\uf7eb'
302
+ '\uf7ec'
303
+ '\uf7ed'
304
+ '\uf7ee'
305
+ '\uf7ef'
306
+ '\uf7f0'
307
+ '\uf7f1'
308
+ '\uf7f2'
309
+ '\uf7f3'
310
+ '\uf7f4'
311
+ '\uf7f5'
312
+ '\uf7f6'
313
+ '\uf7f7'
314
+ '\uf7f8'
315
+ '\uf7f9'
316
+ '\uf7fa'
317
+ '\uf7fb'
318
+ '\uf7fc'
319
+ '\uf7fd'
320
+ '\uf7fe'
321
+ '\uf7ff'
322
+ )
323
+
324
+ ### Encoding table
325
+ encoding_table = codecs.charmap_build(decoding_table)
Sidecar-Courser/.venv/lib/python3.12/site-packages/pip/py.typed ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ pip is a command line program. While it is implemented in Python, and so is
2
+ available for import, you must not use pip's internal APIs in this way. Typing
3
+ information is provided as a convenience only and is not a guarantee. Expect
4
+ unannounced changes to the API and types in releases.
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/INSTALLER ADDED
@@ -0,0 +1 @@
 
 
1
+ pip
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/METADATA ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Metadata-Version: 2.4
2
+ Name: pluggy
3
+ Version: 1.6.0
4
+ Summary: plugin and hook calling mechanisms for python
5
+ Author-email: Holger Krekel <holger@merlinux.eu>
6
+ License: MIT
7
+ Classifier: Development Status :: 6 - Mature
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: POSIX
11
+ Classifier: Operating System :: Microsoft :: Windows
12
+ Classifier: Operating System :: MacOS :: MacOS X
13
+ Classifier: Topic :: Software Development :: Testing
14
+ Classifier: Topic :: Software Development :: Libraries
15
+ Classifier: Topic :: Utilities
16
+ Classifier: Programming Language :: Python :: Implementation :: CPython
17
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Requires-Python: >=3.9
26
+ Description-Content-Type: text/x-rst
27
+ License-File: LICENSE
28
+ Provides-Extra: dev
29
+ Requires-Dist: pre-commit; extra == "dev"
30
+ Requires-Dist: tox; extra == "dev"
31
+ Provides-Extra: testing
32
+ Requires-Dist: pytest; extra == "testing"
33
+ Requires-Dist: pytest-benchmark; extra == "testing"
34
+ Requires-Dist: coverage; extra == "testing"
35
+ Dynamic: license-file
36
+
37
+ ====================================================
38
+ pluggy - A minimalist production ready plugin system
39
+ ====================================================
40
+
41
+ |pypi| |conda-forge| |versions| |github-actions| |gitter| |black| |codecov|
42
+
43
+ This is the core framework used by the `pytest`_, `tox`_, and `devpi`_ projects.
44
+
45
+ Please `read the docs`_ to learn more!
46
+
47
+ A definitive example
48
+ ====================
49
+ .. code-block:: python
50
+
51
+ import pluggy
52
+
53
+ hookspec = pluggy.HookspecMarker("myproject")
54
+ hookimpl = pluggy.HookimplMarker("myproject")
55
+
56
+
57
+ class MySpec:
58
+ """A hook specification namespace."""
59
+
60
+ @hookspec
61
+ def myhook(self, arg1, arg2):
62
+ """My special little hook that you can customize."""
63
+
64
+
65
+ class Plugin_1:
66
+ """A hook implementation namespace."""
67
+
68
+ @hookimpl
69
+ def myhook(self, arg1, arg2):
70
+ print("inside Plugin_1.myhook()")
71
+ return arg1 + arg2
72
+
73
+
74
+ class Plugin_2:
75
+ """A 2nd hook implementation namespace."""
76
+
77
+ @hookimpl
78
+ def myhook(self, arg1, arg2):
79
+ print("inside Plugin_2.myhook()")
80
+ return arg1 - arg2
81
+
82
+
83
+ # create a manager and add the spec
84
+ pm = pluggy.PluginManager("myproject")
85
+ pm.add_hookspecs(MySpec)
86
+
87
+ # register plugins
88
+ pm.register(Plugin_1())
89
+ pm.register(Plugin_2())
90
+
91
+ # call our ``myhook`` hook
92
+ results = pm.hook.myhook(arg1=1, arg2=2)
93
+ print(results)
94
+
95
+
96
+ Running this directly gets us::
97
+
98
+ $ python docs/examples/toy-example.py
99
+ inside Plugin_2.myhook()
100
+ inside Plugin_1.myhook()
101
+ [-1, 3]
102
+
103
+
104
+ .. badges
105
+
106
+ .. |pypi| image:: https://img.shields.io/pypi/v/pluggy.svg
107
+ :target: https://pypi.org/pypi/pluggy
108
+
109
+ .. |versions| image:: https://img.shields.io/pypi/pyversions/pluggy.svg
110
+ :target: https://pypi.org/pypi/pluggy
111
+
112
+ .. |github-actions| image:: https://github.com/pytest-dev/pluggy/workflows/main/badge.svg
113
+ :target: https://github.com/pytest-dev/pluggy/actions
114
+
115
+ .. |conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pluggy.svg
116
+ :target: https://anaconda.org/conda-forge/pytest
117
+
118
+ .. |gitter| image:: https://badges.gitter.im/pytest-dev/pluggy.svg
119
+ :alt: Join the chat at https://gitter.im/pytest-dev/pluggy
120
+ :target: https://gitter.im/pytest-dev/pluggy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
121
+
122
+ .. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
123
+ :target: https://github.com/ambv/black
124
+
125
+ .. |codecov| image:: https://codecov.io/gh/pytest-dev/pluggy/branch/master/graph/badge.svg
126
+ :target: https://codecov.io/gh/pytest-dev/pluggy
127
+ :alt: Code coverage Status
128
+
129
+ .. links
130
+ .. _pytest:
131
+ http://pytest.org
132
+ .. _tox:
133
+ https://tox.readthedocs.org
134
+ .. _devpi:
135
+ http://doc.devpi.net
136
+ .. _read the docs:
137
+ https://pluggy.readthedocs.io/en/latest/
138
+
139
+
140
+ Support pluggy
141
+ --------------
142
+
143
+ `Open Collective`_ is an online funding platform for open and transparent communities.
144
+ It provides tools to raise money and share your finances in full transparency.
145
+
146
+ It is the platform of choice for individuals and companies that want to make one-time or
147
+ monthly donations directly to the project.
148
+
149
+ ``pluggy`` is part of the ``pytest-dev`` project, see more details in the `pytest collective`_.
150
+
151
+ .. _Open Collective: https://opencollective.com
152
+ .. _pytest collective: https://opencollective.com/pytest
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/RECORD ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ pluggy-1.6.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
2
+ pluggy-1.6.0.dist-info/METADATA,sha256=dDjDXuJaCV63QW-EtGHC10Qlxec0rVTDkSRTxlJE4Bw,4811
3
+ pluggy-1.6.0.dist-info/RECORD,,
4
+ pluggy-1.6.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
5
+ pluggy-1.6.0.dist-info/licenses/LICENSE,sha256=1rZebCE6XQtXeRHTTW5ZSbn1nXbCOMUHGi8_wWz7JgY,1110
6
+ pluggy-1.6.0.dist-info/top_level.txt,sha256=xKSCRhai-v9MckvMuWqNz16c1tbsmOggoMSwTgcpYHE,7
7
+ pluggy/__init__.py,sha256=D6dp1gmEDjtDp8hAwQc-qrgaulnL4iltrqkLDd-g9tg,811
8
+ pluggy/__pycache__/__init__.cpython-312.pyc,,
9
+ pluggy/__pycache__/_callers.cpython-312.pyc,,
10
+ pluggy/__pycache__/_hooks.cpython-312.pyc,,
11
+ pluggy/__pycache__/_manager.cpython-312.pyc,,
12
+ pluggy/__pycache__/_result.cpython-312.pyc,,
13
+ pluggy/__pycache__/_tracing.cpython-312.pyc,,
14
+ pluggy/__pycache__/_version.cpython-312.pyc,,
15
+ pluggy/__pycache__/_warnings.cpython-312.pyc,,
16
+ pluggy/_callers.py,sha256=gEZllGaSYVssZ2UmpNfmYC0bdVgh2jYbAFeYKvuRMjY,5991
17
+ pluggy/_hooks.py,sha256=E6f3nYcI6dbEuO0Gmy61ozgGU_59_e69kC08a06EBuo,25218
18
+ pluggy/_manager.py,sha256=K4Ip_pkEjvT2oOIfQPp8CwAWoXVnENgQRcy9tlGii0o,20219
19
+ pluggy/_result.py,sha256=3Xfy7DrjXbYb7puRquyY2VbidIWNq6Pp7QnuElMdj8Q,3098
20
+ pluggy/_tracing.py,sha256=nXd2BCmDgf8jJxV-HO3PqxR-WV53eWnF8B4AF1nJGgo,2073
21
+ pluggy/_version.py,sha256=5FGJNp9Lkk9uOxeCjXpoCGBF79Ar6LGPOR7-atBqb_4,511
22
+ pluggy/_warnings.py,sha256=td0AvZBpfamriCC3OqsLwxMh-SzAMjfjmc58T5vP3lw,828
23
+ pluggy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/WHEEL ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.7.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/licenses/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 holger krekel (rather uses bitbucket/hpk42)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy-1.6.0.dist-info/top_level.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ pluggy
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/__init__.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __all__ = [
2
+ "__version__",
3
+ "PluginManager",
4
+ "PluginValidationError",
5
+ "HookCaller",
6
+ "HookCallError",
7
+ "HookspecOpts",
8
+ "HookimplOpts",
9
+ "HookImpl",
10
+ "HookRelay",
11
+ "HookspecMarker",
12
+ "HookimplMarker",
13
+ "Result",
14
+ "PluggyWarning",
15
+ "PluggyTeardownRaisedWarning",
16
+ ]
17
+ from ._hooks import HookCaller
18
+ from ._hooks import HookImpl
19
+ from ._hooks import HookimplMarker
20
+ from ._hooks import HookimplOpts
21
+ from ._hooks import HookRelay
22
+ from ._hooks import HookspecMarker
23
+ from ._hooks import HookspecOpts
24
+ from ._manager import PluginManager
25
+ from ._manager import PluginValidationError
26
+ from ._result import HookCallError
27
+ from ._result import Result
28
+ from ._version import version as __version__
29
+ from ._warnings import PluggyTeardownRaisedWarning
30
+ from ._warnings import PluggyWarning
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/_callers.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Call loop machinery
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from collections.abc import Generator
8
+ from collections.abc import Mapping
9
+ from collections.abc import Sequence
10
+ from typing import cast
11
+ from typing import NoReturn
12
+ import warnings
13
+
14
+ from ._hooks import HookImpl
15
+ from ._result import HookCallError
16
+ from ._result import Result
17
+ from ._warnings import PluggyTeardownRaisedWarning
18
+
19
+
20
+ # Need to distinguish between old- and new-style hook wrappers.
21
+ # Wrapping with a tuple is the fastest type-safe way I found to do it.
22
+ Teardown = Generator[None, object, object]
23
+
24
+
25
+ def run_old_style_hookwrapper(
26
+ hook_impl: HookImpl, hook_name: str, args: Sequence[object]
27
+ ) -> Teardown:
28
+ """
29
+ backward compatibility wrapper to run a old style hookwrapper as a wrapper
30
+ """
31
+
32
+ teardown: Teardown = cast(Teardown, hook_impl.function(*args))
33
+ try:
34
+ next(teardown)
35
+ except StopIteration:
36
+ _raise_wrapfail(teardown, "did not yield")
37
+ try:
38
+ res = yield
39
+ result = Result(res, None)
40
+ except BaseException as exc:
41
+ result = Result(None, exc)
42
+ try:
43
+ teardown.send(result)
44
+ except StopIteration:
45
+ pass
46
+ except BaseException as e:
47
+ _warn_teardown_exception(hook_name, hook_impl, e)
48
+ raise
49
+ else:
50
+ _raise_wrapfail(teardown, "has second yield")
51
+ finally:
52
+ teardown.close()
53
+ return result.get_result()
54
+
55
+
56
+ def _raise_wrapfail(
57
+ wrap_controller: Generator[None, object, object],
58
+ msg: str,
59
+ ) -> NoReturn:
60
+ co = wrap_controller.gi_code # type: ignore[attr-defined]
61
+ raise RuntimeError(
62
+ f"wrap_controller at {co.co_name!r} {co.co_filename}:{co.co_firstlineno} {msg}"
63
+ )
64
+
65
+
66
+ def _warn_teardown_exception(
67
+ hook_name: str, hook_impl: HookImpl, e: BaseException
68
+ ) -> None:
69
+ msg = "A plugin raised an exception during an old-style hookwrapper teardown.\n"
70
+ msg += f"Plugin: {hook_impl.plugin_name}, Hook: {hook_name}\n"
71
+ msg += f"{type(e).__name__}: {e}\n"
72
+ msg += "For more information see https://pluggy.readthedocs.io/en/stable/api_reference.html#pluggy.PluggyTeardownRaisedWarning" # noqa: E501
73
+ warnings.warn(PluggyTeardownRaisedWarning(msg), stacklevel=6)
74
+
75
+
76
+ def _multicall(
77
+ hook_name: str,
78
+ hook_impls: Sequence[HookImpl],
79
+ caller_kwargs: Mapping[str, object],
80
+ firstresult: bool,
81
+ ) -> object | list[object]:
82
+ """Execute a call into multiple python functions/methods and return the
83
+ result(s).
84
+
85
+ ``caller_kwargs`` comes from HookCaller.__call__().
86
+ """
87
+ __tracebackhide__ = True
88
+ results: list[object] = []
89
+ exception = None
90
+ try: # run impl and wrapper setup functions in a loop
91
+ teardowns: list[Teardown] = []
92
+ try:
93
+ for hook_impl in reversed(hook_impls):
94
+ try:
95
+ args = [caller_kwargs[argname] for argname in hook_impl.argnames]
96
+ except KeyError as e:
97
+ # coverage bug - this is tested
98
+ for argname in hook_impl.argnames: # pragma: no cover
99
+ if argname not in caller_kwargs:
100
+ raise HookCallError(
101
+ f"hook call must provide argument {argname!r}"
102
+ ) from e
103
+
104
+ if hook_impl.hookwrapper:
105
+ function_gen = run_old_style_hookwrapper(hook_impl, hook_name, args)
106
+
107
+ next(function_gen) # first yield
108
+ teardowns.append(function_gen)
109
+
110
+ elif hook_impl.wrapper:
111
+ try:
112
+ # If this cast is not valid, a type error is raised below,
113
+ # which is the desired response.
114
+ res = hook_impl.function(*args)
115
+ function_gen = cast(Generator[None, object, object], res)
116
+ next(function_gen) # first yield
117
+ teardowns.append(function_gen)
118
+ except StopIteration:
119
+ _raise_wrapfail(function_gen, "did not yield")
120
+ else:
121
+ res = hook_impl.function(*args)
122
+ if res is not None:
123
+ results.append(res)
124
+ if firstresult: # halt further impl calls
125
+ break
126
+ except BaseException as exc:
127
+ exception = exc
128
+ finally:
129
+ if firstresult: # first result hooks return a single value
130
+ result = results[0] if results else None
131
+ else:
132
+ result = results
133
+
134
+ # run all wrapper post-yield blocks
135
+ for teardown in reversed(teardowns):
136
+ try:
137
+ if exception is not None:
138
+ try:
139
+ teardown.throw(exception)
140
+ except RuntimeError as re:
141
+ # StopIteration from generator causes RuntimeError
142
+ # even for coroutine usage - see #544
143
+ if (
144
+ isinstance(exception, StopIteration)
145
+ and re.__cause__ is exception
146
+ ):
147
+ teardown.close()
148
+ continue
149
+ else:
150
+ raise
151
+ else:
152
+ teardown.send(result)
153
+ # Following is unreachable for a well behaved hook wrapper.
154
+ # Try to force finalizers otherwise postponed till GC action.
155
+ # Note: close() may raise if generator handles GeneratorExit.
156
+ teardown.close()
157
+ except StopIteration as si:
158
+ result = si.value
159
+ exception = None
160
+ continue
161
+ except BaseException as e:
162
+ exception = e
163
+ continue
164
+ _raise_wrapfail(teardown, "has second yield")
165
+
166
+ if exception is not None:
167
+ raise exception
168
+ else:
169
+ return result
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/_hooks.py ADDED
@@ -0,0 +1,714 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Internal hook annotation, representation and calling machinery.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from collections.abc import Generator
8
+ from collections.abc import Mapping
9
+ from collections.abc import Sequence
10
+ from collections.abc import Set
11
+ import inspect
12
+ import sys
13
+ from types import ModuleType
14
+ from typing import Any
15
+ from typing import Callable
16
+ from typing import Final
17
+ from typing import final
18
+ from typing import Optional
19
+ from typing import overload
20
+ from typing import TYPE_CHECKING
21
+ from typing import TypedDict
22
+ from typing import TypeVar
23
+ from typing import Union
24
+ import warnings
25
+
26
+ from ._result import Result
27
+
28
+
29
+ _T = TypeVar("_T")
30
+ _F = TypeVar("_F", bound=Callable[..., object])
31
+ _Namespace = Union[ModuleType, type]
32
+ _Plugin = object
33
+ _HookExec = Callable[
34
+ [str, Sequence["HookImpl"], Mapping[str, object], bool],
35
+ Union[object, list[object]],
36
+ ]
37
+ _HookImplFunction = Callable[..., Union[_T, Generator[None, Result[_T], None]]]
38
+
39
+
40
+ class HookspecOpts(TypedDict):
41
+ """Options for a hook specification."""
42
+
43
+ #: Whether the hook is :ref:`first result only <firstresult>`.
44
+ firstresult: bool
45
+ #: Whether the hook is :ref:`historic <historic>`.
46
+ historic: bool
47
+ #: Whether the hook :ref:`warns when implemented <warn_on_impl>`.
48
+ warn_on_impl: Warning | None
49
+ #: Whether the hook warns when :ref:`certain arguments are requested
50
+ #: <warn_on_impl>`.
51
+ #:
52
+ #: .. versionadded:: 1.5
53
+ warn_on_impl_args: Mapping[str, Warning] | None
54
+
55
+
56
+ class HookimplOpts(TypedDict):
57
+ """Options for a hook implementation."""
58
+
59
+ #: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`.
60
+ wrapper: bool
61
+ #: Whether the hook implementation is an :ref:`old-style wrapper
62
+ #: <old_style_hookwrappers>`.
63
+ hookwrapper: bool
64
+ #: Whether validation against a hook specification is :ref:`optional
65
+ #: <optionalhook>`.
66
+ optionalhook: bool
67
+ #: Whether to try to order this hook implementation :ref:`first
68
+ #: <callorder>`.
69
+ tryfirst: bool
70
+ #: Whether to try to order this hook implementation :ref:`last
71
+ #: <callorder>`.
72
+ trylast: bool
73
+ #: The name of the hook specification to match, see :ref:`specname`.
74
+ specname: str | None
75
+
76
+
77
+ @final
78
+ class HookspecMarker:
79
+ """Decorator for marking functions as hook specifications.
80
+
81
+ Instantiate it with a project_name to get a decorator.
82
+ Calling :meth:`PluginManager.add_hookspecs` later will discover all marked
83
+ functions if the :class:`PluginManager` uses the same project name.
84
+ """
85
+
86
+ __slots__ = ("project_name",)
87
+
88
+ def __init__(self, project_name: str) -> None:
89
+ self.project_name: Final = project_name
90
+
91
+ @overload
92
+ def __call__(
93
+ self,
94
+ function: _F,
95
+ firstresult: bool = False,
96
+ historic: bool = False,
97
+ warn_on_impl: Warning | None = None,
98
+ warn_on_impl_args: Mapping[str, Warning] | None = None,
99
+ ) -> _F: ...
100
+
101
+ @overload # noqa: F811
102
+ def __call__( # noqa: F811
103
+ self,
104
+ function: None = ...,
105
+ firstresult: bool = ...,
106
+ historic: bool = ...,
107
+ warn_on_impl: Warning | None = ...,
108
+ warn_on_impl_args: Mapping[str, Warning] | None = ...,
109
+ ) -> Callable[[_F], _F]: ...
110
+
111
+ def __call__( # noqa: F811
112
+ self,
113
+ function: _F | None = None,
114
+ firstresult: bool = False,
115
+ historic: bool = False,
116
+ warn_on_impl: Warning | None = None,
117
+ warn_on_impl_args: Mapping[str, Warning] | None = None,
118
+ ) -> _F | Callable[[_F], _F]:
119
+ """If passed a function, directly sets attributes on the function
120
+ which will make it discoverable to :meth:`PluginManager.add_hookspecs`.
121
+
122
+ If passed no function, returns a decorator which can be applied to a
123
+ function later using the attributes supplied.
124
+
125
+ :param firstresult:
126
+ If ``True``, the 1:N hook call (N being the number of registered
127
+ hook implementation functions) will stop at I<=N when the I'th
128
+ function returns a non-``None`` result. See :ref:`firstresult`.
129
+
130
+ :param historic:
131
+ If ``True``, every call to the hook will be memorized and replayed
132
+ on plugins registered after the call was made. See :ref:`historic`.
133
+
134
+ :param warn_on_impl:
135
+ If given, every implementation of this hook will trigger the given
136
+ warning. See :ref:`warn_on_impl`.
137
+
138
+ :param warn_on_impl_args:
139
+ If given, every implementation of this hook which requests one of
140
+ the arguments in the dict will trigger the corresponding warning.
141
+ See :ref:`warn_on_impl`.
142
+
143
+ .. versionadded:: 1.5
144
+ """
145
+
146
+ def setattr_hookspec_opts(func: _F) -> _F:
147
+ if historic and firstresult:
148
+ raise ValueError("cannot have a historic firstresult hook")
149
+ opts: HookspecOpts = {
150
+ "firstresult": firstresult,
151
+ "historic": historic,
152
+ "warn_on_impl": warn_on_impl,
153
+ "warn_on_impl_args": warn_on_impl_args,
154
+ }
155
+ setattr(func, self.project_name + "_spec", opts)
156
+ return func
157
+
158
+ if function is not None:
159
+ return setattr_hookspec_opts(function)
160
+ else:
161
+ return setattr_hookspec_opts
162
+
163
+
164
+ @final
165
+ class HookimplMarker:
166
+ """Decorator for marking functions as hook implementations.
167
+
168
+ Instantiate it with a ``project_name`` to get a decorator.
169
+ Calling :meth:`PluginManager.register` later will discover all marked
170
+ functions if the :class:`PluginManager` uses the same project name.
171
+ """
172
+
173
+ __slots__ = ("project_name",)
174
+
175
+ def __init__(self, project_name: str) -> None:
176
+ self.project_name: Final = project_name
177
+
178
+ @overload
179
+ def __call__(
180
+ self,
181
+ function: _F,
182
+ hookwrapper: bool = ...,
183
+ optionalhook: bool = ...,
184
+ tryfirst: bool = ...,
185
+ trylast: bool = ...,
186
+ specname: str | None = ...,
187
+ wrapper: bool = ...,
188
+ ) -> _F: ...
189
+
190
+ @overload # noqa: F811
191
+ def __call__( # noqa: F811
192
+ self,
193
+ function: None = ...,
194
+ hookwrapper: bool = ...,
195
+ optionalhook: bool = ...,
196
+ tryfirst: bool = ...,
197
+ trylast: bool = ...,
198
+ specname: str | None = ...,
199
+ wrapper: bool = ...,
200
+ ) -> Callable[[_F], _F]: ...
201
+
202
+ def __call__( # noqa: F811
203
+ self,
204
+ function: _F | None = None,
205
+ hookwrapper: bool = False,
206
+ optionalhook: bool = False,
207
+ tryfirst: bool = False,
208
+ trylast: bool = False,
209
+ specname: str | None = None,
210
+ wrapper: bool = False,
211
+ ) -> _F | Callable[[_F], _F]:
212
+ """If passed a function, directly sets attributes on the function
213
+ which will make it discoverable to :meth:`PluginManager.register`.
214
+
215
+ If passed no function, returns a decorator which can be applied to a
216
+ function later using the attributes supplied.
217
+
218
+ :param optionalhook:
219
+ If ``True``, a missing matching hook specification will not result
220
+ in an error (by default it is an error if no matching spec is
221
+ found). See :ref:`optionalhook`.
222
+
223
+ :param tryfirst:
224
+ If ``True``, this hook implementation will run as early as possible
225
+ in the chain of N hook implementations for a specification. See
226
+ :ref:`callorder`.
227
+
228
+ :param trylast:
229
+ If ``True``, this hook implementation will run as late as possible
230
+ in the chain of N hook implementations for a specification. See
231
+ :ref:`callorder`.
232
+
233
+ :param wrapper:
234
+ If ``True`` ("new-style hook wrapper"), the hook implementation
235
+ needs to execute exactly one ``yield``. The code before the
236
+ ``yield`` is run early before any non-hook-wrapper function is run.
237
+ The code after the ``yield`` is run after all non-hook-wrapper
238
+ functions have run. The ``yield`` receives the result value of the
239
+ inner calls, or raises the exception of inner calls (including
240
+ earlier hook wrapper calls). The return value of the function
241
+ becomes the return value of the hook, and a raised exception becomes
242
+ the exception of the hook. See :ref:`hookwrapper`.
243
+
244
+ :param hookwrapper:
245
+ If ``True`` ("old-style hook wrapper"), the hook implementation
246
+ needs to execute exactly one ``yield``. The code before the
247
+ ``yield`` is run early before any non-hook-wrapper function is run.
248
+ The code after the ``yield`` is run after all non-hook-wrapper
249
+ function have run The ``yield`` receives a :class:`Result` object
250
+ representing the exception or result outcome of the inner calls
251
+ (including earlier hook wrapper calls). This option is mutually
252
+ exclusive with ``wrapper``. See :ref:`old_style_hookwrapper`.
253
+
254
+ :param specname:
255
+ If provided, the given name will be used instead of the function
256
+ name when matching this hook implementation to a hook specification
257
+ during registration. See :ref:`specname`.
258
+
259
+ .. versionadded:: 1.2.0
260
+ The ``wrapper`` parameter.
261
+ """
262
+
263
+ def setattr_hookimpl_opts(func: _F) -> _F:
264
+ opts: HookimplOpts = {
265
+ "wrapper": wrapper,
266
+ "hookwrapper": hookwrapper,
267
+ "optionalhook": optionalhook,
268
+ "tryfirst": tryfirst,
269
+ "trylast": trylast,
270
+ "specname": specname,
271
+ }
272
+ setattr(func, self.project_name + "_impl", opts)
273
+ return func
274
+
275
+ if function is None:
276
+ return setattr_hookimpl_opts
277
+ else:
278
+ return setattr_hookimpl_opts(function)
279
+
280
+
281
+ def normalize_hookimpl_opts(opts: HookimplOpts) -> None:
282
+ opts.setdefault("tryfirst", False)
283
+ opts.setdefault("trylast", False)
284
+ opts.setdefault("wrapper", False)
285
+ opts.setdefault("hookwrapper", False)
286
+ opts.setdefault("optionalhook", False)
287
+ opts.setdefault("specname", None)
288
+
289
+
290
+ _PYPY = hasattr(sys, "pypy_version_info")
291
+
292
+
293
+ def varnames(func: object) -> tuple[tuple[str, ...], tuple[str, ...]]:
294
+ """Return tuple of positional and keywrord argument names for a function,
295
+ method, class or callable.
296
+
297
+ In case of a class, its ``__init__`` method is considered.
298
+ For methods the ``self`` parameter is not included.
299
+ """
300
+ if inspect.isclass(func):
301
+ try:
302
+ func = func.__init__
303
+ except AttributeError: # pragma: no cover - pypy special case
304
+ return (), ()
305
+ elif not inspect.isroutine(func): # callable object?
306
+ try:
307
+ func = getattr(func, "__call__", func)
308
+ except Exception: # pragma: no cover - pypy special case
309
+ return (), ()
310
+
311
+ try:
312
+ # func MUST be a function or method here or we won't parse any args.
313
+ sig = inspect.signature(
314
+ func.__func__ if inspect.ismethod(func) else func # type:ignore[arg-type]
315
+ )
316
+ except TypeError: # pragma: no cover
317
+ return (), ()
318
+
319
+ _valid_param_kinds = (
320
+ inspect.Parameter.POSITIONAL_ONLY,
321
+ inspect.Parameter.POSITIONAL_OR_KEYWORD,
322
+ )
323
+ _valid_params = {
324
+ name: param
325
+ for name, param in sig.parameters.items()
326
+ if param.kind in _valid_param_kinds
327
+ }
328
+ args = tuple(_valid_params)
329
+ defaults = (
330
+ tuple(
331
+ param.default
332
+ for param in _valid_params.values()
333
+ if param.default is not param.empty
334
+ )
335
+ or None
336
+ )
337
+
338
+ if defaults:
339
+ index = -len(defaults)
340
+ args, kwargs = args[:index], tuple(args[index:])
341
+ else:
342
+ kwargs = ()
343
+
344
+ # strip any implicit instance arg
345
+ # pypy3 uses "obj" instead of "self" for default dunder methods
346
+ if not _PYPY:
347
+ implicit_names: tuple[str, ...] = ("self",)
348
+ else: # pragma: no cover
349
+ implicit_names = ("self", "obj")
350
+ if args:
351
+ qualname: str = getattr(func, "__qualname__", "")
352
+ if inspect.ismethod(func) or ("." in qualname and args[0] in implicit_names):
353
+ args = args[1:]
354
+
355
+ return args, kwargs
356
+
357
+
358
+ @final
359
+ class HookRelay:
360
+ """Hook holder object for performing 1:N hook calls where N is the number
361
+ of registered plugins."""
362
+
363
+ __slots__ = ("__dict__",)
364
+
365
+ def __init__(self) -> None:
366
+ """:meta private:"""
367
+
368
+ if TYPE_CHECKING:
369
+
370
+ def __getattr__(self, name: str) -> HookCaller: ...
371
+
372
+
373
+ # Historical name (pluggy<=1.2), kept for backward compatibility.
374
+ _HookRelay = HookRelay
375
+
376
+
377
+ _CallHistory = list[tuple[Mapping[str, object], Optional[Callable[[Any], None]]]]
378
+
379
+
380
+ class HookCaller:
381
+ """A caller of all registered implementations of a hook specification."""
382
+
383
+ __slots__ = (
384
+ "name",
385
+ "spec",
386
+ "_hookexec",
387
+ "_hookimpls",
388
+ "_call_history",
389
+ )
390
+
391
+ def __init__(
392
+ self,
393
+ name: str,
394
+ hook_execute: _HookExec,
395
+ specmodule_or_class: _Namespace | None = None,
396
+ spec_opts: HookspecOpts | None = None,
397
+ ) -> None:
398
+ """:meta private:"""
399
+ #: Name of the hook getting called.
400
+ self.name: Final = name
401
+ self._hookexec: Final = hook_execute
402
+ # The hookimpls list. The caller iterates it *in reverse*. Format:
403
+ # 1. trylast nonwrappers
404
+ # 2. nonwrappers
405
+ # 3. tryfirst nonwrappers
406
+ # 4. trylast wrappers
407
+ # 5. wrappers
408
+ # 6. tryfirst wrappers
409
+ self._hookimpls: Final[list[HookImpl]] = []
410
+ self._call_history: _CallHistory | None = None
411
+ # TODO: Document, or make private.
412
+ self.spec: HookSpec | None = None
413
+ if specmodule_or_class is not None:
414
+ assert spec_opts is not None
415
+ self.set_specification(specmodule_or_class, spec_opts)
416
+
417
+ # TODO: Document, or make private.
418
+ def has_spec(self) -> bool:
419
+ return self.spec is not None
420
+
421
+ # TODO: Document, or make private.
422
+ def set_specification(
423
+ self,
424
+ specmodule_or_class: _Namespace,
425
+ spec_opts: HookspecOpts,
426
+ ) -> None:
427
+ if self.spec is not None:
428
+ raise ValueError(
429
+ f"Hook {self.spec.name!r} is already registered "
430
+ f"within namespace {self.spec.namespace}"
431
+ )
432
+ self.spec = HookSpec(specmodule_or_class, self.name, spec_opts)
433
+ if spec_opts.get("historic"):
434
+ self._call_history = []
435
+
436
+ def is_historic(self) -> bool:
437
+ """Whether this caller is :ref:`historic <historic>`."""
438
+ return self._call_history is not None
439
+
440
+ def _remove_plugin(self, plugin: _Plugin) -> None:
441
+ for i, method in enumerate(self._hookimpls):
442
+ if method.plugin == plugin:
443
+ del self._hookimpls[i]
444
+ return
445
+ raise ValueError(f"plugin {plugin!r} not found")
446
+
447
+ def get_hookimpls(self) -> list[HookImpl]:
448
+ """Get all registered hook implementations for this hook."""
449
+ return self._hookimpls.copy()
450
+
451
+ def _add_hookimpl(self, hookimpl: HookImpl) -> None:
452
+ """Add an implementation to the callback chain."""
453
+ for i, method in enumerate(self._hookimpls):
454
+ if method.hookwrapper or method.wrapper:
455
+ splitpoint = i
456
+ break
457
+ else:
458
+ splitpoint = len(self._hookimpls)
459
+ if hookimpl.hookwrapper or hookimpl.wrapper:
460
+ start, end = splitpoint, len(self._hookimpls)
461
+ else:
462
+ start, end = 0, splitpoint
463
+
464
+ if hookimpl.trylast:
465
+ self._hookimpls.insert(start, hookimpl)
466
+ elif hookimpl.tryfirst:
467
+ self._hookimpls.insert(end, hookimpl)
468
+ else:
469
+ # find last non-tryfirst method
470
+ i = end - 1
471
+ while i >= start and self._hookimpls[i].tryfirst:
472
+ i -= 1
473
+ self._hookimpls.insert(i + 1, hookimpl)
474
+
475
+ def __repr__(self) -> str:
476
+ return f"<HookCaller {self.name!r}>"
477
+
478
+ def _verify_all_args_are_provided(self, kwargs: Mapping[str, object]) -> None:
479
+ # This is written to avoid expensive operations when not needed.
480
+ if self.spec:
481
+ for argname in self.spec.argnames:
482
+ if argname not in kwargs:
483
+ notincall = ", ".join(
484
+ repr(argname)
485
+ for argname in self.spec.argnames
486
+ # Avoid self.spec.argnames - kwargs.keys()
487
+ # it doesn't preserve order.
488
+ if argname not in kwargs.keys()
489
+ )
490
+ warnings.warn(
491
+ f"Argument(s) {notincall} which are declared in the hookspec "
492
+ "cannot be found in this hook call",
493
+ stacklevel=2,
494
+ )
495
+ break
496
+
497
+ def __call__(self, **kwargs: object) -> Any:
498
+ """Call the hook.
499
+
500
+ Only accepts keyword arguments, which should match the hook
501
+ specification.
502
+
503
+ Returns the result(s) of calling all registered plugins, see
504
+ :ref:`calling`.
505
+ """
506
+ assert not self.is_historic(), (
507
+ "Cannot directly call a historic hook - use call_historic instead."
508
+ )
509
+ self._verify_all_args_are_provided(kwargs)
510
+ firstresult = self.spec.opts.get("firstresult", False) if self.spec else False
511
+ # Copy because plugins may register other plugins during iteration (#438).
512
+ return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
513
+
514
+ def call_historic(
515
+ self,
516
+ result_callback: Callable[[Any], None] | None = None,
517
+ kwargs: Mapping[str, object] | None = None,
518
+ ) -> None:
519
+ """Call the hook with given ``kwargs`` for all registered plugins and
520
+ for all plugins which will be registered afterwards, see
521
+ :ref:`historic`.
522
+
523
+ :param result_callback:
524
+ If provided, will be called for each non-``None`` result obtained
525
+ from a hook implementation.
526
+ """
527
+ assert self._call_history is not None
528
+ kwargs = kwargs or {}
529
+ self._verify_all_args_are_provided(kwargs)
530
+ self._call_history.append((kwargs, result_callback))
531
+ # Historizing hooks don't return results.
532
+ # Remember firstresult isn't compatible with historic.
533
+ # Copy because plugins may register other plugins during iteration (#438).
534
+ res = self._hookexec(self.name, self._hookimpls.copy(), kwargs, False)
535
+ if result_callback is None:
536
+ return
537
+ if isinstance(res, list):
538
+ for x in res:
539
+ result_callback(x)
540
+
541
+ def call_extra(
542
+ self, methods: Sequence[Callable[..., object]], kwargs: Mapping[str, object]
543
+ ) -> Any:
544
+ """Call the hook with some additional temporarily participating
545
+ methods using the specified ``kwargs`` as call parameters, see
546
+ :ref:`call_extra`."""
547
+ assert not self.is_historic(), (
548
+ "Cannot directly call a historic hook - use call_historic instead."
549
+ )
550
+ self._verify_all_args_are_provided(kwargs)
551
+ opts: HookimplOpts = {
552
+ "wrapper": False,
553
+ "hookwrapper": False,
554
+ "optionalhook": False,
555
+ "trylast": False,
556
+ "tryfirst": False,
557
+ "specname": None,
558
+ }
559
+ hookimpls = self._hookimpls.copy()
560
+ for method in methods:
561
+ hookimpl = HookImpl(None, "<temp>", method, opts)
562
+ # Find last non-tryfirst nonwrapper method.
563
+ i = len(hookimpls) - 1
564
+ while i >= 0 and (
565
+ # Skip wrappers.
566
+ (hookimpls[i].hookwrapper or hookimpls[i].wrapper)
567
+ # Skip tryfirst nonwrappers.
568
+ or hookimpls[i].tryfirst
569
+ ):
570
+ i -= 1
571
+ hookimpls.insert(i + 1, hookimpl)
572
+ firstresult = self.spec.opts.get("firstresult", False) if self.spec else False
573
+ return self._hookexec(self.name, hookimpls, kwargs, firstresult)
574
+
575
+ def _maybe_apply_history(self, method: HookImpl) -> None:
576
+ """Apply call history to a new hookimpl if it is marked as historic."""
577
+ if self.is_historic():
578
+ assert self._call_history is not None
579
+ for kwargs, result_callback in self._call_history:
580
+ res = self._hookexec(self.name, [method], kwargs, False)
581
+ if res and result_callback is not None:
582
+ # XXX: remember firstresult isn't compat with historic
583
+ assert isinstance(res, list)
584
+ result_callback(res[0])
585
+
586
+
587
+ # Historical name (pluggy<=1.2), kept for backward compatibility.
588
+ _HookCaller = HookCaller
589
+
590
+
591
+ class _SubsetHookCaller(HookCaller):
592
+ """A proxy to another HookCaller which manages calls to all registered
593
+ plugins except the ones from remove_plugins."""
594
+
595
+ # This class is unusual: in inhertits from `HookCaller` so all of
596
+ # the *code* runs in the class, but it delegates all underlying *data*
597
+ # to the original HookCaller.
598
+ # `subset_hook_caller` used to be implemented by creating a full-fledged
599
+ # HookCaller, copying all hookimpls from the original. This had problems
600
+ # with memory leaks (#346) and historic calls (#347), which make a proxy
601
+ # approach better.
602
+ # An alternative implementation is to use a `_getattr__`/`__getattribute__`
603
+ # proxy, however that adds more overhead and is more tricky to implement.
604
+
605
+ __slots__ = (
606
+ "_orig",
607
+ "_remove_plugins",
608
+ )
609
+
610
+ def __init__(self, orig: HookCaller, remove_plugins: Set[_Plugin]) -> None:
611
+ self._orig = orig
612
+ self._remove_plugins = remove_plugins
613
+ self.name = orig.name # type: ignore[misc]
614
+ self._hookexec = orig._hookexec # type: ignore[misc]
615
+
616
+ @property # type: ignore[misc]
617
+ def _hookimpls(self) -> list[HookImpl]:
618
+ return [
619
+ impl
620
+ for impl in self._orig._hookimpls
621
+ if impl.plugin not in self._remove_plugins
622
+ ]
623
+
624
+ @property
625
+ def spec(self) -> HookSpec | None: # type: ignore[override]
626
+ return self._orig.spec
627
+
628
+ @property
629
+ def _call_history(self) -> _CallHistory | None: # type: ignore[override]
630
+ return self._orig._call_history
631
+
632
+ def __repr__(self) -> str:
633
+ return f"<_SubsetHookCaller {self.name!r}>"
634
+
635
+
636
+ @final
637
+ class HookImpl:
638
+ """A hook implementation in a :class:`HookCaller`."""
639
+
640
+ __slots__ = (
641
+ "function",
642
+ "argnames",
643
+ "kwargnames",
644
+ "plugin",
645
+ "opts",
646
+ "plugin_name",
647
+ "wrapper",
648
+ "hookwrapper",
649
+ "optionalhook",
650
+ "tryfirst",
651
+ "trylast",
652
+ )
653
+
654
+ def __init__(
655
+ self,
656
+ plugin: _Plugin,
657
+ plugin_name: str,
658
+ function: _HookImplFunction[object],
659
+ hook_impl_opts: HookimplOpts,
660
+ ) -> None:
661
+ """:meta private:"""
662
+ #: The hook implementation function.
663
+ self.function: Final = function
664
+ argnames, kwargnames = varnames(self.function)
665
+ #: The positional parameter names of ``function```.
666
+ self.argnames: Final = argnames
667
+ #: The keyword parameter names of ``function```.
668
+ self.kwargnames: Final = kwargnames
669
+ #: The plugin which defined this hook implementation.
670
+ self.plugin: Final = plugin
671
+ #: The :class:`HookimplOpts` used to configure this hook implementation.
672
+ self.opts: Final = hook_impl_opts
673
+ #: The name of the plugin which defined this hook implementation.
674
+ self.plugin_name: Final = plugin_name
675
+ #: Whether the hook implementation is a :ref:`wrapper <hookwrapper>`.
676
+ self.wrapper: Final = hook_impl_opts["wrapper"]
677
+ #: Whether the hook implementation is an :ref:`old-style wrapper
678
+ #: <old_style_hookwrappers>`.
679
+ self.hookwrapper: Final = hook_impl_opts["hookwrapper"]
680
+ #: Whether validation against a hook specification is :ref:`optional
681
+ #: <optionalhook>`.
682
+ self.optionalhook: Final = hook_impl_opts["optionalhook"]
683
+ #: Whether to try to order this hook implementation :ref:`first
684
+ #: <callorder>`.
685
+ self.tryfirst: Final = hook_impl_opts["tryfirst"]
686
+ #: Whether to try to order this hook implementation :ref:`last
687
+ #: <callorder>`.
688
+ self.trylast: Final = hook_impl_opts["trylast"]
689
+
690
+ def __repr__(self) -> str:
691
+ return f"<HookImpl plugin_name={self.plugin_name!r}, plugin={self.plugin!r}>"
692
+
693
+
694
+ @final
695
+ class HookSpec:
696
+ __slots__ = (
697
+ "namespace",
698
+ "function",
699
+ "name",
700
+ "argnames",
701
+ "kwargnames",
702
+ "opts",
703
+ "warn_on_impl",
704
+ "warn_on_impl_args",
705
+ )
706
+
707
+ def __init__(self, namespace: _Namespace, name: str, opts: HookspecOpts) -> None:
708
+ self.namespace = namespace
709
+ self.function: Callable[..., object] = getattr(namespace, name)
710
+ self.name = name
711
+ self.argnames, self.kwargnames = varnames(self.function)
712
+ self.opts = opts
713
+ self.warn_on_impl = opts.get("warn_on_impl")
714
+ self.warn_on_impl_args = opts.get("warn_on_impl_args")
Sidecar-Courser/.venv/lib/python3.12/site-packages/pluggy/_manager.py ADDED
@@ -0,0 +1,523 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Iterable
4
+ from collections.abc import Mapping
5
+ from collections.abc import Sequence
6
+ import inspect
7
+ import types
8
+ from typing import Any
9
+ from typing import Callable
10
+ from typing import cast
11
+ from typing import Final
12
+ from typing import TYPE_CHECKING
13
+ import warnings
14
+
15
+ from . import _tracing
16
+ from ._callers import _multicall
17
+ from ._hooks import _HookImplFunction
18
+ from ._hooks import _Namespace
19
+ from ._hooks import _Plugin
20
+ from ._hooks import _SubsetHookCaller
21
+ from ._hooks import HookCaller
22
+ from ._hooks import HookImpl
23
+ from ._hooks import HookimplOpts
24
+ from ._hooks import HookRelay
25
+ from ._hooks import HookspecOpts
26
+ from ._hooks import normalize_hookimpl_opts
27
+ from ._result import Result
28
+
29
+
30
+ if TYPE_CHECKING:
31
+ # importtlib.metadata import is slow, defer it.
32
+ import importlib.metadata
33
+
34
+
35
+ _BeforeTrace = Callable[[str, Sequence[HookImpl], Mapping[str, Any]], None]
36
+ _AfterTrace = Callable[[Result[Any], str, Sequence[HookImpl], Mapping[str, Any]], None]
37
+
38
+
39
+ def _warn_for_function(warning: Warning, function: Callable[..., object]) -> None:
40
+ func = cast(types.FunctionType, function)
41
+ warnings.warn_explicit(
42
+ warning,
43
+ type(warning),
44
+ lineno=func.__code__.co_firstlineno,
45
+ filename=func.__code__.co_filename,
46
+ )
47
+
48
+
49
+ class PluginValidationError(Exception):
50
+ """Plugin failed validation.
51
+
52
+ :param plugin: The plugin which failed validation.
53
+ :param message: Error message.
54
+ """
55
+
56
+ def __init__(self, plugin: _Plugin, message: str) -> None:
57
+ super().__init__(message)
58
+ #: The plugin which failed validation.
59
+ self.plugin = plugin
60
+
61
+
62
+ class DistFacade:
63
+ """Emulate a pkg_resources Distribution"""
64
+
65
+ def __init__(self, dist: importlib.metadata.Distribution) -> None:
66
+ self._dist = dist
67
+
68
+ @property
69
+ def project_name(self) -> str:
70
+ name: str = self.metadata["name"]
71
+ return name
72
+
73
+ def __getattr__(self, attr: str, default: Any | None = None) -> Any:
74
+ return getattr(self._dist, attr, default)
75
+
76
+ def __dir__(self) -> list[str]:
77
+ return sorted(dir(self._dist) + ["_dist", "project_name"])
78
+
79
+
80
+ class PluginManager:
81
+ """Core class which manages registration of plugin objects and 1:N hook
82
+ calling.
83
+
84
+ You can register new hooks by calling :meth:`add_hookspecs(module_or_class)
85
+ <PluginManager.add_hookspecs>`.
86
+
87
+ You can register plugin objects (which contain hook implementations) by
88
+ calling :meth:`register(plugin) <PluginManager.register>`.
89
+
90
+ For debugging purposes you can call :meth:`PluginManager.enable_tracing`
91
+ which will subsequently send debug information to the trace helper.
92
+
93
+ :param project_name:
94
+ The short project name. Prefer snake case. Make sure it's unique!
95
+ """
96
+
97
+ def __init__(self, project_name: str) -> None:
98
+ #: The project name.
99
+ self.project_name: Final = project_name
100
+ self._name2plugin: Final[dict[str, _Plugin]] = {}
101
+ self._plugin_distinfo: Final[list[tuple[_Plugin, DistFacade]]] = []
102
+ #: The "hook relay", used to call a hook on all registered plugins.
103
+ #: See :ref:`calling`.
104
+ self.hook: Final = HookRelay()
105
+ #: The tracing entry point. See :ref:`tracing`.
106
+ self.trace: Final[_tracing.TagTracerSub] = _tracing.TagTracer().get(
107
+ "pluginmanage"
108
+ )
109
+ self._inner_hookexec = _multicall
110
+
111
+ def _hookexec(
112
+ self,
113
+ hook_name: str,
114
+ methods: Sequence[HookImpl],
115
+ kwargs: Mapping[str, object],
116
+ firstresult: bool,
117
+ ) -> object | list[object]:
118
+ # called from all hookcaller instances.
119
+ # enable_tracing will set its own wrapping function at self._inner_hookexec
120
+ return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
121
+
122
+ def register(self, plugin: _Plugin, name: str | None = None) -> str | None:
123
+ """Register a plugin and return its name.
124
+
125
+ :param name:
126
+ The name under which to register the plugin. If not specified, a
127
+ name is generated using :func:`get_canonical_name`.
128
+
129
+ :returns:
130
+ The plugin name. If the name is blocked from registering, returns
131
+ ``None``.
132
+
133
+ If the plugin is already registered, raises a :exc:`ValueError`.
134
+ """
135
+ plugin_name = name or self.get_canonical_name(plugin)
136
+
137
+ if plugin_name in self._name2plugin:
138
+ if self._name2plugin.get(plugin_name, -1) is None:
139
+ return None # blocked plugin, return None to indicate no registration
140
+ raise ValueError(
141
+ "Plugin name already registered: "
142
+ f"{plugin_name}={plugin}\n{self._name2plugin}"
143
+ )
144
+
145
+ if plugin in self._name2plugin.values():
146
+ raise ValueError(
147
+ "Plugin already registered under a different name: "
148
+ f"{plugin_name}={plugin}\n{self._name2plugin}"
149
+ )
150
+
151
+ # XXX if an error happens we should make sure no state has been
152
+ # changed at point of return
153
+ self._name2plugin[plugin_name] = plugin
154
+
155
+ # register matching hook implementations of the plugin
156
+ for name in dir(plugin):
157
+ hookimpl_opts = self.parse_hookimpl_opts(plugin, name)
158
+ if hookimpl_opts is not None:
159
+ normalize_hookimpl_opts(hookimpl_opts)
160
+ method: _HookImplFunction[object] = getattr(plugin, name)
161
+ hookimpl = HookImpl(plugin, plugin_name, method, hookimpl_opts)
162
+ name = hookimpl_opts.get("specname") or name
163
+ hook: HookCaller | None = getattr(self.hook, name, None)
164
+ if hook is None:
165
+ hook = HookCaller(name, self._hookexec)
166
+ setattr(self.hook, name, hook)
167
+ elif hook.has_spec():
168
+ self._verify_hook(hook, hookimpl)
169
+ hook._maybe_apply_history(hookimpl)
170
+ hook._add_hookimpl(hookimpl)
171
+ return plugin_name
172
+
173
+ def parse_hookimpl_opts(self, plugin: _Plugin, name: str) -> HookimplOpts | None:
174
+ """Try to obtain a hook implementation from an item with the given name
175
+ in the given plugin which is being searched for hook impls.
176
+
177
+ :returns:
178
+ The parsed hookimpl options, or None to skip the given item.
179
+
180
+ This method can be overridden by ``PluginManager`` subclasses to
181
+ customize how hook implementation are picked up. By default, returns the
182
+ options for items decorated with :class:`HookimplMarker`.
183
+ """
184
+ method: object = getattr(plugin, name)
185
+ if not inspect.isroutine(method):
186
+ return None
187
+ try:
188
+ res: HookimplOpts | None = getattr(
189
+ method, self.project_name + "_impl", None
190
+ )
191
+ except Exception: # pragma: no cover
192
+ res = {} # type: ignore[assignment] #pragma: no cover
193
+ if res is not None and not isinstance(res, dict):
194
+ # false positive
195
+ res = None # type:ignore[unreachable] #pragma: no cover
196
+ return res
197
+
198
+ def unregister(
199
+ self, plugin: _Plugin | None = None, name: str | None = None
200
+ ) -> Any | None:
201
+ """Unregister a plugin and all of its hook implementations.
202
+
203
+ The plugin can be specified either by the plugin object or the plugin
204
+ name. If both are specified, they must agree.
205
+
206
+ Returns the unregistered plugin, or ``None`` if not found.
207
+ """
208
+ if name is None:
209
+ assert plugin is not None, "one of name or plugin needs to be specified"
210
+ name = self.get_name(plugin)
211
+ assert name is not None, "plugin is not registered"
212
+
213
+ if plugin is None:
214
+ plugin = self.get_plugin(name)
215
+ if plugin is None:
216
+ return None
217
+
218
+ hookcallers = self.get_hookcallers(plugin)
219
+ if hookcallers:
220
+ for hookcaller in hookcallers:
221
+ hookcaller._remove_plugin(plugin)
222
+
223
+ # if self._name2plugin[name] == None registration was blocked: ignore
224
+ if self._name2plugin.get(name):
225
+ assert name is not None
226
+ del self._name2plugin[name]
227
+
228
+ return plugin
229
+
230
+ def set_blocked(self, name: str) -> None:
231
+ """Block registrations of the given name, unregister if already registered."""
232
+ self.unregister(name=name)
233
+ self._name2plugin[name] = None
234
+
235
+ def is_blocked(self, name: str) -> bool:
236
+ """Return whether the given plugin name is blocked."""
237
+ return name in self._name2plugin and self._name2plugin[name] is None
238
+
239
+ def unblock(self, name: str) -> bool:
240
+ """Unblocks a name.
241
+
242
+ Returns whether the name was actually blocked.
243
+ """
244
+ if self._name2plugin.get(name, -1) is None:
245
+ del self._name2plugin[name]
246
+ return True
247
+ return False
248
+
249
+ def add_hookspecs(self, module_or_class: _Namespace) -> None:
250
+ """Add new hook specifications defined in the given ``module_or_class``.
251
+
252
+ Functions are recognized as hook specifications if they have been
253
+ decorated with a matching :class:`HookspecMarker`.
254
+ """
255
+ names = []
256
+ for name in dir(module_or_class):
257
+ spec_opts = self.parse_hookspec_opts(module_or_class, name)
258
+ if spec_opts is not None:
259
+ hc: HookCaller | None = getattr(self.hook, name, None)
260
+ if hc is None:
261
+ hc = HookCaller(name, self._hookexec, module_or_class, spec_opts)
262
+ setattr(self.hook, name, hc)
263
+ else:
264
+ # Plugins registered this hook without knowing the spec.
265
+ hc.set_specification(module_or_class, spec_opts)
266
+ for hookfunction in hc.get_hookimpls():
267
+ self._verify_hook(hc, hookfunction)
268
+ names.append(name)
269
+
270
+ if not names:
271
+ raise ValueError(
272
+ f"did not find any {self.project_name!r} hooks in {module_or_class!r}"
273
+ )
274
+
275
+ def parse_hookspec_opts(
276
+ self, module_or_class: _Namespace, name: str
277
+ ) -> HookspecOpts | None:
278
+ """Try to obtain a hook specification from an item with the given name
279
+ in the given module or class which is being searched for hook specs.
280
+
281
+ :returns:
282
+ The parsed hookspec options for defining a hook, or None to skip the
283
+ given item.
284
+
285
+ This method can be overridden by ``PluginManager`` subclasses to
286
+ customize how hook specifications are picked up. By default, returns the
287
+ options for items decorated with :class:`HookspecMarker`.
288
+ """
289
+ method = getattr(module_or_class, name)
290
+ opts: HookspecOpts | None = getattr(method, self.project_name + "_spec", None)
291
+ return opts
292
+
293
+ def get_plugins(self) -> set[Any]:
294
+ """Return a set of all registered plugin objects."""
295
+ return {x for x in self._name2plugin.values() if x is not None}
296
+
297
+ def is_registered(self, plugin: _Plugin) -> bool:
298
+ """Return whether the plugin is already registered."""
299
+ return any(plugin == val for val in self._name2plugin.values())
300
+
301
+ def get_canonical_name(self, plugin: _Plugin) -> str:
302
+ """Return a canonical name for a plugin object.
303
+
304
+ Note that a plugin may be registered under a different name
305
+ specified by the caller of :meth:`register(plugin, name) <register>`.
306
+ To obtain the name of a registered plugin use :meth:`get_name(plugin)
307
+ <get_name>` instead.
308
+ """
309
+ name: str | None = getattr(plugin, "__name__", None)
310
+ return name or str(id(plugin))
311
+
312
+ def get_plugin(self, name: str) -> Any | None:
313
+ """Return the plugin registered under the given name, if any."""
314
+ return self._name2plugin.get(name)
315
+
316
+ def has_plugin(self, name: str) -> bool:
317
+ """Return whether a plugin with the given name is registered."""
318
+ return self.get_plugin(name) is not None
319
+
320
+ def get_name(self, plugin: _Plugin) -> str | None:
321
+ """Return the name the plugin is registered under, or ``None`` if
322
+ is isn't."""
323
+ for name, val in self._name2plugin.items():
324
+ if plugin == val:
325
+ return name
326
+ return None
327
+
328
+ def _verify_hook(self, hook: HookCaller, hookimpl: HookImpl) -> None:
329
+ if hook.is_historic() and (hookimpl.hookwrapper or hookimpl.wrapper):
330
+ raise PluginValidationError(
331
+ hookimpl.plugin,
332
+ f"Plugin {hookimpl.plugin_name!r}\nhook {hook.name!r}\n"
333
+ "historic incompatible with yield/wrapper/hookwrapper",
334
+ )
335
+
336
+ assert hook.spec is not None
337
+ if hook.spec.warn_on_impl:
338
+ _warn_for_function(hook.spec.warn_on_impl, hookimpl.function)
339
+
340
+ # positional arg checking
341
+ notinspec = set(hookimpl.argnames) - set(hook.spec.argnames)
342
+ if notinspec:
343
+ raise PluginValidationError(
344
+ hookimpl.plugin,
345
+ f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"
346
+ f"hookimpl definition: {_formatdef(hookimpl.function)}\n"
347
+ f"Argument(s) {notinspec} are declared in the hookimpl but "
348
+ "can not be found in the hookspec",
349
+ )
350
+
351
+ if hook.spec.warn_on_impl_args:
352
+ for hookimpl_argname in hookimpl.argnames:
353
+ argname_warning = hook.spec.warn_on_impl_args.get(hookimpl_argname)
354
+ if argname_warning is not None:
355
+ _warn_for_function(argname_warning, hookimpl.function)
356
+
357
+ if (
358
+ hookimpl.wrapper or hookimpl.hookwrapper
359
+ ) and not inspect.isgeneratorfunction(hookimpl.function):
360
+ raise PluginValidationError(
361
+ hookimpl.plugin,
362
+ f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"
363
+ f"hookimpl definition: {_formatdef(hookimpl.function)}\n"
364
+ "Declared as wrapper=True or hookwrapper=True "
365
+ "but function is not a generator function",
366
+ )
367
+
368
+ if hookimpl.wrapper and hookimpl.hookwrapper:
369
+ raise PluginValidationError(
370
+ hookimpl.plugin,
371
+ f"Plugin {hookimpl.plugin_name!r} for hook {hook.name!r}\n"
372
+ f"hookimpl definition: {_formatdef(hookimpl.function)}\n"
373
+ "The wrapper=True and hookwrapper=True options are mutually exclusive",
374
+ )
375
+
376
+ def check_pending(self) -> None:
377
+ """Verify that all hooks which have not been verified against a
378
+ hook specification are optional, otherwise raise
379
+ :exc:`PluginValidationError`."""
380
+ for name in self.hook.__dict__:
381
+ if name[0] == "_":
382
+ continue
383
+ hook: HookCaller = getattr(self.hook, name)
384
+ if not hook.has_spec():
385
+ for hookimpl in hook.get_hookimpls():
386
+ if not hookimpl.optionalhook:
387
+ raise PluginValidationError(
388
+ hookimpl.plugin,
389
+ f"unknown hook {name!r} in plugin {hookimpl.plugin!r}",
390
+ )
391
+
392
+ def load_setuptools_entrypoints(self, group: str, name: str | None = None) -> int:
393
+ """Load modules from querying the specified setuptools ``group``.
394
+
395
+ :param group:
396
+ Entry point group to load plugins.
397
+ :param name:
398
+ If given, loads only plugins with the given ``name``.
399
+
400
+ :return:
401
+ The number of plugins loaded by this call.
402
+ """
403
+ import importlib.metadata
404
+
405
+ count = 0
406
+ for dist in list(importlib.metadata.distributions()):
407
+ for ep in dist.entry_points:
408
+ if (
409
+ ep.group != group
410
+ or (name is not None and ep.name != name)
411
+ # already registered
412
+ or self.get_plugin(ep.name)
413
+ or self.is_blocked(ep.name)
414
+ ):
415
+ continue
416
+ plugin = ep.load()
417
+ self.register(plugin, name=ep.name)
418
+ self._plugin_distinfo.append((plugin, DistFacade(dist)))
419
+ count += 1
420
+ return count
421
+
422
+ def list_plugin_distinfo(self) -> list[tuple[_Plugin, DistFacade]]:
423
+ """Return a list of (plugin, distinfo) pairs for all
424
+ setuptools-registered plugins."""
425
+ return list(self._plugin_distinfo)
426
+
427
+ def list_name_plugin(self) -> list[tuple[str, _Plugin]]:
428
+ """Return a list of (name, plugin) pairs for all registered plugins."""
429
+ return list(self._name2plugin.items())
430
+
431
+ def get_hookcallers(self, plugin: _Plugin) -> list[HookCaller] | None:
432
+ """Get all hook callers for the specified plugin.
433
+
434
+ :returns:
435
+ The hook callers, or ``None`` if ``plugin`` is not registered in
436
+ this plugin manager.
437
+ """
438
+ if self.get_name(plugin) is None:
439
+ return None
440
+ hookcallers = []
441
+ for hookcaller in self.hook.__dict__.values():
442
+ for hookimpl in hookcaller.get_hookimpls():
443
+ if hookimpl.plugin is plugin:
444
+ hookcallers.append(hookcaller)
445
+ return hookcallers
446
+
447
+ def add_hookcall_monitoring(
448
+ self, before: _BeforeTrace, after: _AfterTrace
449
+ ) -> Callable[[], None]:
450
+ """Add before/after tracing functions for all hooks.
451
+
452
+ Returns an undo function which, when called, removes the added tracers.
453
+
454
+ ``before(hook_name, hook_impls, kwargs)`` will be called ahead
455
+ of all hook calls and receive a hookcaller instance, a list
456
+ of HookImpl instances and the keyword arguments for the hook call.
457
+
458
+ ``after(outcome, hook_name, hook_impls, kwargs)`` receives the
459
+ same arguments as ``before`` but also a :class:`~pluggy.Result` object
460
+ which represents the result of the overall hook call.
461
+ """
462
+ oldcall = self._inner_hookexec
463
+
464
+ def traced_hookexec(
465
+ hook_name: str,
466
+ hook_impls: Sequence[HookImpl],
467
+ caller_kwargs: Mapping[str, object],
468
+ firstresult: bool,
469
+ ) -> object | list[object]:
470
+ before(hook_name, hook_impls, caller_kwargs)
471
+ outcome = Result.from_call(
472
+ lambda: oldcall(hook_name, hook_impls, caller_kwargs, firstresult)
473
+ )
474
+ after(outcome, hook_name, hook_impls, caller_kwargs)
475
+ return outcome.get_result()
476
+
477
+ self._inner_hookexec = traced_hookexec
478
+
479
+ def undo() -> None:
480
+ self._inner_hookexec = oldcall
481
+
482
+ return undo
483
+
484
+ def enable_tracing(self) -> Callable[[], None]:
485
+ """Enable tracing of hook calls.
486
+
487
+ Returns an undo function which, when called, removes the added tracing.
488
+ """
489
+ hooktrace = self.trace.root.get("hook")
490
+
491
+ def before(
492
+ hook_name: str, methods: Sequence[HookImpl], kwargs: Mapping[str, object]
493
+ ) -> None:
494
+ hooktrace.root.indent += 1
495
+ hooktrace(hook_name, kwargs)
496
+
497
+ def after(
498
+ outcome: Result[object],
499
+ hook_name: str,
500
+ methods: Sequence[HookImpl],
501
+ kwargs: Mapping[str, object],
502
+ ) -> None:
503
+ if outcome.exception is None:
504
+ hooktrace("finish", hook_name, "-->", outcome.get_result())
505
+ hooktrace.root.indent -= 1
506
+
507
+ return self.add_hookcall_monitoring(before, after)
508
+
509
+ def subset_hook_caller(
510
+ self, name: str, remove_plugins: Iterable[_Plugin]
511
+ ) -> HookCaller:
512
+ """Return a proxy :class:`~pluggy.HookCaller` instance for the named
513
+ method which manages calls to all registered plugins except the ones
514
+ from remove_plugins."""
515
+ orig: HookCaller = getattr(self.hook, name)
516
+ plugins_to_remove = {plug for plug in remove_plugins if hasattr(plug, name)}
517
+ if plugins_to_remove:
518
+ return _SubsetHookCaller(orig, plugins_to_remove)
519
+ return orig
520
+
521
+
522
+ def _formatdef(func: Callable[..., object]) -> str:
523
+ return f"{func.__name__}{inspect.signature(func)}"