Browse Source

minor interface improvements

kora 1 year ago
parent
commit
1710eeb3f1
100 changed files with 62 additions and 21300 deletions
  1. 4 1
      .gitignore
  2. 26 27
      app.py
  3. 2 0
      samples/RDF/AR20AUT_Datini.ttl
  4. 0 90
      samples/RDF/OSPEDALE-onomastica-persone-singole.ttl
  5. 23 21
      samples/RDF/form_output.ttl
  6. 7 3
      templates/index.html
  7. 0 247
      venv/bin/Activate.ps1
  8. 0 69
      venv/bin/activate
  9. 0 26
      venv/bin/activate.csh
  10. 0 66
      venv/bin/activate.fish
  11. 0 8
      venv/bin/flask
  12. 0 8
      venv/bin/pip
  13. 0 8
      venv/bin/pip3
  14. 0 8
      venv/bin/pip3.10
  15. 0 1
      venv/bin/python
  16. 0 1
      venv/bin/python3
  17. 0 1
      venv/bin/python3.10
  18. 0 1
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/INSTALLER
  19. 0 28
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/LICENSE.rst
  20. 0 123
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/METADATA
  21. 0 54
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/RECORD
  22. 0 0
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/REQUESTED
  23. 0 5
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/WHEEL
  24. 0 2
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/entry_points.txt
  25. 0 1
      venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/top_level.txt
  26. 0 1
      venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER
  27. 0 28
      venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst
  28. 0 113
      venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA
  29. 0 58
      venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD
  30. 0 5
      venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL
  31. 0 2
      venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt
  32. 0 1
      venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt
  33. 0 1
      venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER
  34. 0 28
      venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst
  35. 0 101
      venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/METADATA
  36. 0 14
      venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/RECORD
  37. 0 5
      venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL
  38. 0 1
      venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt
  39. 0 1
      venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/INSTALLER
  40. 0 28
      venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/LICENSE.rst
  41. 0 126
      venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/METADATA
  42. 0 98
      venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/RECORD
  43. 0 5
      venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/WHEEL
  44. 0 1
      venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/top_level.txt
  45. 0 128
      venv/lib/python3.10/site-packages/_distutils_hack/__init__.py
  46. 0 1
      venv/lib/python3.10/site-packages/_distutils_hack/override.py
  47. 0 1
      venv/lib/python3.10/site-packages/click-8.1.3.dist-info/INSTALLER
  48. 0 28
      venv/lib/python3.10/site-packages/click-8.1.3.dist-info/LICENSE.rst
  49. 0 111
      venv/lib/python3.10/site-packages/click-8.1.3.dist-info/METADATA
  50. 0 39
      venv/lib/python3.10/site-packages/click-8.1.3.dist-info/RECORD
  51. 0 5
      venv/lib/python3.10/site-packages/click-8.1.3.dist-info/WHEEL
  52. 0 1
      venv/lib/python3.10/site-packages/click-8.1.3.dist-info/top_level.txt
  53. 0 73
      venv/lib/python3.10/site-packages/click/__init__.py
  54. 0 626
      venv/lib/python3.10/site-packages/click/_compat.py
  55. 0 717
      venv/lib/python3.10/site-packages/click/_termui_impl.py
  56. 0 49
      venv/lib/python3.10/site-packages/click/_textwrap.py
  57. 0 279
      venv/lib/python3.10/site-packages/click/_winconsole.py
  58. 0 2998
      venv/lib/python3.10/site-packages/click/core.py
  59. 0 497
      venv/lib/python3.10/site-packages/click/decorators.py
  60. 0 287
      venv/lib/python3.10/site-packages/click/exceptions.py
  61. 0 301
      venv/lib/python3.10/site-packages/click/formatting.py
  62. 0 68
      venv/lib/python3.10/site-packages/click/globals.py
  63. 0 529
      venv/lib/python3.10/site-packages/click/parser.py
  64. 0 0
      venv/lib/python3.10/site-packages/click/py.typed
  65. 0 580
      venv/lib/python3.10/site-packages/click/shell_completion.py
  66. 0 787
      venv/lib/python3.10/site-packages/click/termui.py
  67. 0 479
      venv/lib/python3.10/site-packages/click/testing.py
  68. 0 1073
      venv/lib/python3.10/site-packages/click/types.py
  69. 0 580
      venv/lib/python3.10/site-packages/click/utils.py
  70. 0 1
      venv/lib/python3.10/site-packages/distutils-precedence.pth
  71. 0 71
      venv/lib/python3.10/site-packages/flask/__init__.py
  72. 0 3
      venv/lib/python3.10/site-packages/flask/__main__.py
  73. 0 2548
      venv/lib/python3.10/site-packages/flask/app.py
  74. 0 706
      venv/lib/python3.10/site-packages/flask/blueprints.py
  75. 0 1051
      venv/lib/python3.10/site-packages/flask/cli.py
  76. 0 337
      venv/lib/python3.10/site-packages/flask/config.py
  77. 0 438
      venv/lib/python3.10/site-packages/flask/ctx.py
  78. 0 158
      venv/lib/python3.10/site-packages/flask/debughelpers.py
  79. 0 107
      venv/lib/python3.10/site-packages/flask/globals.py
  80. 0 705
      venv/lib/python3.10/site-packages/flask/helpers.py
  81. 0 342
      venv/lib/python3.10/site-packages/flask/json/__init__.py
  82. 0 310
      venv/lib/python3.10/site-packages/flask/json/provider.py
  83. 0 312
      venv/lib/python3.10/site-packages/flask/json/tag.py
  84. 0 74
      venv/lib/python3.10/site-packages/flask/logging.py
  85. 0 0
      venv/lib/python3.10/site-packages/flask/py.typed
  86. 0 898
      venv/lib/python3.10/site-packages/flask/scaffold.py
  87. 0 419
      venv/lib/python3.10/site-packages/flask/sessions.py
  88. 0 56
      venv/lib/python3.10/site-packages/flask/signals.py
  89. 0 212
      venv/lib/python3.10/site-packages/flask/templating.py
  90. 0 286
      venv/lib/python3.10/site-packages/flask/testing.py
  91. 0 80
      venv/lib/python3.10/site-packages/flask/typing.py
  92. 0 188
      venv/lib/python3.10/site-packages/flask/views.py
  93. 0 171
      venv/lib/python3.10/site-packages/flask/wrappers.py
  94. 0 1
      venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER
  95. 0 28
      venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst
  96. 0 97
      venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA
  97. 0 23
      venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD
  98. 0 5
      venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL
  99. 0 1
      venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt
  100. 0 19
      venv/lib/python3.10/site-packages/itsdangerous/__init__.py

+ 4 - 1
.gitignore

@@ -1,5 +1,8 @@
+# Python virtual envs
 fvenv/*
+venv/*
+# Additional Python stuff
 __pycache__
 app.log
-venv/*
+# IDEs
 .vscode/*

+ 26 - 27
app.py

@@ -21,36 +21,35 @@ def main():
 
     if request.method == 'POST':
 
-        outputFolder = appath + 'samples/RDF/'
-
-        fileFromRequest = request.files['FILE']
-        filename = fileFromRequest.filename
-
-        if filename != '':
-            outFileName = fileFromRequest.filename.replace('.csv', '') + '.ttl'
-            outFilePath = appath + outputFolder + outFileName
-            inFile = fileFromRequest.read()
-            # try to create list of dictionaries keyed by header row
-            try:
+        try:
+            outputFolder = appath + 'samples/RDF/'
+            fileFromRequest = request.files['FILE']
+            filename = fileFromRequest.filename
+
+            # If a file was uploaded, read data from file
+            if filename != '':
+                outFileName = filename.replace('.csv', '') + '.ttl'
+                outFilePath = outputFolder + outFileName
+                inFile = fileFromRequest.read()
+                # try to create list of dictionaries keyed by header row
                 parsefromfile(confFilePath, formFields, inFile, outFilePath)
-            except:
-                return redirect(url_for('error'))
-
-        else:
-            # Da completare
-            data =  {}
-            for field in formFields:
-                data[field] = request.form[field]
 
-            check = [val for val in data.values() if val!='']
-
-            if len(check)>0:
-                outFilePath = appath + outputFolder + 'form_output.ttl'
-                parse(confFilePath, formFields,[data], outFilePath)
+            # Else read data from form
             else:
-                return redirect(url_for('error'))
-
-        return redirect(url_for('main'))
+                data =  {}
+                for field in formFields:
+                    data[field] = request.form[field]
+
+                check = [val for val in data.values() if val!='']
+                if len(check)>0:
+                    outFilePath = outputFolder + 'form_output.ttl'
+                    parse(confFilePath, formFields, [data], outFilePath)
+                else:
+                    raise Exception("No data") 
+        except:
+            return redirect(url_for('error'))
+
+        return redirect(url_for('main', success=True))
 
     return render_template('index.html', data=formFields)
 

+ 2 - 0
samples/RDF/AR20AUT_Datini.ttl

@@ -6,6 +6,8 @@
 @prefix schema: <http://www.schema.org/> .
 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix aspo: <http://www.archiviodistato.prato.it/accedi-e-consulta/aspoMV001/scheda/> .
 
 aut:filippo-lippi-1406-1469 rdf:type crm:E21_Person .
 aut:filippo-lippi-1406-1469 rdf:type foaf:person .

+ 0 - 90
samples/RDF/OSPEDALE-onomastica-persone-singole.ttl

@@ -9,93 +9,3 @@
 @prefix owl: <http://www.w3.org/2002/07/owl#> .
 @prefix aspo: <http://www.archiviodistato.prato.it/accedi-e-consulta/aspoMV001/scheda/> .
 
-aspo:IT-ASPO-AU00002-0001230 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0001230 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0001230 foaf:name "Accolti Angelo di Graziasanta da Arezzo" .
-aspo:IT-ASPO-AU00002-0001230 foaf:givenName "Angelo " .
-aspo:IT-ASPO-AU00002-0001230 foaf:familyName "Accolti " .
-aspo:IT-ASPO-AU00002-0001230 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0001230 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0001230 rdfs:label "Accolti Angelo di Graziasanta da Arezzo" .
-
-aspo:IT-ASPO-AU00002-0001275 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0001275 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0001275 foaf:name "Agostino di Andrea di Fioco" .
-aspo:IT-ASPO-AU00002-0001275 foaf:givenName "Agostino " .
-aspo:IT-ASPO-AU00002-0001275 foaf:familyName "" .
-aspo:IT-ASPO-AU00002-0001275 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0001275 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0001275 rdfs:label "Agostino di Andrea di Fioco" .
-
-aspo:IT-ASPO-AU00002-0000001 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0000001 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0000001 foaf:name "Aiazzi Antonio" .
-aspo:IT-ASPO-AU00002-0000001 foaf:givenName "Antonio" .
-aspo:IT-ASPO-AU00002-0000001 foaf:familyName "Aiazzi " .
-aspo:IT-ASPO-AU00002-0000001 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0000001 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0000001 rdfs:label "Aiazzi Antonio" .
-
-aspo:IT-ASPO-AU00002-0000002 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0000002 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0000002 foaf:name "Alamanno di ser Betto" .
-aspo:IT-ASPO-AU00002-0000002 foaf:givenName "Alamanno " .
-aspo:IT-ASPO-AU00002-0000002 foaf:familyName "" .
-aspo:IT-ASPO-AU00002-0000002 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0000002 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0000002 rdfs:label "Alamanno di ser Betto" .
-
-aspo:IT-ASPO-AU00002-0000003 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0000003 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0000003 foaf:name "Albani Giovanni Francesco (papa Clemente XI)" .
-aspo:IT-ASPO-AU00002-0000003 foaf:givenName "Giovanni Francesco " .
-aspo:IT-ASPO-AU00002-0000003 foaf:familyName "Albani" .
-aspo:IT-ASPO-AU00002-0000003 schema:alternateName "Clemente XI" .
-aspo:IT-ASPO-AU00002-0000003 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0000003 rdfs:label "Albani Giovanni Francesco (papa Clemente XI)" .
-
-aspo:IT-ASPO-AU00002-0000004 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0000004 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0000004 foaf:name "Alberto di Teri" .
-aspo:IT-ASPO-AU00002-0000004 foaf:givenName "Alberto " .
-aspo:IT-ASPO-AU00002-0000004 foaf:familyName "" .
-aspo:IT-ASPO-AU00002-0000004 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0000004 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0000004 rdfs:label "Alberto di Teri" .
-
-aspo:IT-ASPO-AU00002-0000005 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0000005 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0000005 foaf:name "Albizzi Rinaldo" .
-aspo:IT-ASPO-AU00002-0000005 foaf:givenName "Rinaldo" .
-aspo:IT-ASPO-AU00002-0000005 foaf:familyName "Albizzi " .
-aspo:IT-ASPO-AU00002-0000005 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0000005 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0000005 rdfs:label "Albizzi Rinaldo" .
-
-aspo:IT-ASPO-AU00002-0001329 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0001329 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0001329 foaf:name "[...] Bice" .
-aspo:IT-ASPO-AU00002-0001329 foaf:givenName "Bice" .
-aspo:IT-ASPO-AU00002-0001329 foaf:familyName "" .
-aspo:IT-ASPO-AU00002-0001329 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0001329 foaf:gender "F" .
-aspo:IT-ASPO-AU00002-0001329 rdfs:label "[...] Bice" .
-
-aspo:IT-ASPO-AU00002-0001325 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0001325 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0001325 foaf:name "[...] Giovanni" .
-aspo:IT-ASPO-AU00002-0001325 foaf:givenName "Giovanni" .
-aspo:IT-ASPO-AU00002-0001325 foaf:familyName "" .
-aspo:IT-ASPO-AU00002-0001325 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0001325 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0001325 rdfs:label "[...] Giovanni" .
-
-aspo:IT-ASPO-AU00002-0001140 rdf:type crm:E21_Person .
-aspo:IT-ASPO-AU00002-0001140 rdf:type foaf:person .
-aspo:IT-ASPO-AU00002-0001140 foaf:name "[...] Giovanni di Andrea" .
-aspo:IT-ASPO-AU00002-0001140 foaf:givenName "Giovanni" .
-aspo:IT-ASPO-AU00002-0001140 foaf:familyName "" .
-aspo:IT-ASPO-AU00002-0001140 schema:alternateName "" .
-aspo:IT-ASPO-AU00002-0001140 foaf:gender "M" .
-aspo:IT-ASPO-AU00002-0001140 rdfs:label "[...] Giovanni di Andrea" .
-

+ 23 - 21
samples/RDF/form_output.ttl

@@ -6,30 +6,32 @@
 @prefix schema: <http://www.schema.org/> .
 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix aspo: <http://www.archiviodistato.prato.it/accedi-e-consulta/aspoMV001/scheda/> .
 
-aut:Ciao rdf:type crm:E21_Person .
-aut:Ciao rdf:type foaf:person .
-aut:Ciao foaf:name "Pippo Jiollo" .
-aut:Ciao foaf:givenName "Pippo Baldini" .
-aut:Ciao foaf:gender "" .
-aut:Ciao rdfs:label "Pippo Jiollo, " .
-aut:Ciao crm:P3_has_note aut:Ciao_E62 .
-aut:Ciao crm:P98i_was_born aut:Ciao_E67 .
-aut:Ciao crm:P100i_died_in aut:Ciao_E69 .
-aut:Ciao crm:P1_is_identified_by aut: .
-aut:Ciao schema:hasOccupation mpp: .
-aut:Ciao_E62 rdf:type crm:E62_String .
-aut:Ciao_E62 rdfs:label "Fonte: Museo di Palazzo Pretorio - Collezione Martini" .
+aut:aa rdf:type crm:E21_Person .
+aut:aa rdf:type foaf:person .
+aut:aa foaf:name "" .
+aut:aa foaf:givenName "" .
+aut:aa foaf:gender "" .
+aut:aa rdfs:label ", " .
+aut:aa crm:P3_has_note aut:aa_E62 .
+aut:aa crm:P98i_was_born aut:aa_E67 .
+aut:aa crm:P100i_died_in aut:aa_E69 .
+aut:aa crm:P1_is_identified_by aut: .
+aut:aa schema:hasOccupation mpp: .
+aut:aa_E62 rdf:type crm:E62_String .
+aut:aa_E62 rdfs:label "Fonte: Museo di Palazzo Pretorio - Collezione Martini" .
 aut: rdf:type crm:E42_Identifier .
 aut: rdfs:label "" .
-aut:Ciao_E67 rdf:type crm:E67_Birth .
-aut:Ciao_E67 rdfs:label "Nascita di Pippo Jiollo" .
-aut:Ciao_E67 crm:P7_took_place_at mpp: .
-aut:Ciao_E67 crm:P4_has_time-span mpp: .
-aut:Ciao_E69 rdf:type crm:E69_Death .
-aut:Ciao_E69 rdfs:label "Morte di Pippo Jiollo" .
-aut:Ciao_E69 crm:P7_took_place_at mpp: .
-aut:Ciao_E69 crm:P4_has_time-span mpp: .
+aut:aa_E67 rdf:type crm:E67_Birth .
+aut:aa_E67 rdfs:label "Nascita di " .
+aut:aa_E67 crm:P7_took_place_at mpp: .
+aut:aa_E67 crm:P4_has_time-span mpp: .
+aut:aa_E69 rdf:type crm:E69_Death .
+aut:aa_E69 rdfs:label "Morte di " .
+aut:aa_E69 crm:P7_took_place_at mpp: .
+aut:aa_E69 crm:P4_has_time-span mpp: .
 mpp: rdf:type crm:E52_Time-Span .
 mpp: rdfs:label "" .
 mpp: rdf:type crm:E53_Place .

+ 7 - 3
templates/index.html

@@ -64,9 +64,13 @@
 
 <p>When you activate this tool, input data is translated into RDF (TTL) via a user-customizable model</p>
 <script>
-    $("#submitted").click(function() {
-       alert("transformation carried out successfully");
-    });
+  const params = new URLSearchParams(window.location.search);
+  console.log('stoca', window.location.search);
+  console.log('zo', params);
+  console.log('z', params.get('success'));
+  if(params.get('success')){
+    alert("Transformation carried out successfully");
+  }
  </script>
 </body>
 </html>

+ 0 - 247
venv/bin/Activate.ps1

@@ -1,247 +0,0 @@
-<#
-.Synopsis
-Activate a Python virtual environment for the current PowerShell session.
-
-.Description
-Pushes the python executable for a virtual environment to the front of the
-$Env:PATH environment variable and sets the prompt to signify that you are
-in a Python virtual environment. Makes use of the command line switches as
-well as the `pyvenv.cfg` file values present in the virtual environment.
-
-.Parameter VenvDir
-Path to the directory that contains the virtual environment to activate. The
-default value for this is the parent of the directory that the Activate.ps1
-script is located within.
-
-.Parameter Prompt
-The prompt prefix to display when this virtual environment is activated. By
-default, this prompt is the name of the virtual environment folder (VenvDir)
-surrounded by parentheses and followed by a single space (ie. '(.venv) ').
-
-.Example
-Activate.ps1
-Activates the Python virtual environment that contains the Activate.ps1 script.
-
-.Example
-Activate.ps1 -Verbose
-Activates the Python virtual environment that contains the Activate.ps1 script,
-and shows extra information about the activation as it executes.
-
-.Example
-Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv
-Activates the Python virtual environment located in the specified location.
-
-.Example
-Activate.ps1 -Prompt "MyPython"
-Activates the Python virtual environment that contains the Activate.ps1 script,
-and prefixes the current prompt with the specified string (surrounded in
-parentheses) while the virtual environment is active.
-
-.Notes
-On Windows, it may be required to enable this Activate.ps1 script by setting the
-execution policy for the user. You can do this by issuing the following PowerShell
-command:
-
-PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
-
-For more information on Execution Policies: 
-https://go.microsoft.com/fwlink/?LinkID=135170
-
-#>
-Param(
-    [Parameter(Mandatory = $false)]
-    [String]
-    $VenvDir,
-    [Parameter(Mandatory = $false)]
-    [String]
-    $Prompt
-)
-
-<# Function declarations --------------------------------------------------- #>
-
-<#
-.Synopsis
-Remove all shell session elements added by the Activate script, including the
-addition of the virtual environment's Python executable from the beginning of
-the PATH variable.
-
-.Parameter NonDestructive
-If present, do not remove this function from the global namespace for the
-session.
-
-#>
-function global:deactivate ([switch]$NonDestructive) {
-    # Revert to original values
-
-    # The prior prompt:
-    if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) {
-        Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt
-        Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT
-    }
-
-    # The prior PYTHONHOME:
-    if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) {
-        Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME
-        Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME
-    }
-
-    # The prior PATH:
-    if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) {
-        Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH
-        Remove-Item -Path Env:_OLD_VIRTUAL_PATH
-    }
-
-    # Just remove the VIRTUAL_ENV altogether:
-    if (Test-Path -Path Env:VIRTUAL_ENV) {
-        Remove-Item -Path env:VIRTUAL_ENV
-    }
-
-    # Just remove VIRTUAL_ENV_PROMPT altogether.
-    if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) {
-        Remove-Item -Path env:VIRTUAL_ENV_PROMPT
-    }
-
-    # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether:
-    if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) {
-        Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force
-    }
-
-    # Leave deactivate function in the global namespace if requested:
-    if (-not $NonDestructive) {
-        Remove-Item -Path function:deactivate
-    }
-}
-
-<#
-.Description
-Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the
-given folder, and returns them in a map.
-
-For each line in the pyvenv.cfg file, if that line can be parsed into exactly
-two strings separated by `=` (with any amount of whitespace surrounding the =)
-then it is considered a `key = value` line. The left hand string is the key,
-the right hand is the value.
-
-If the value starts with a `'` or a `"` then the first and last character is
-stripped from the value before being captured.
-
-.Parameter ConfigDir
-Path to the directory that contains the `pyvenv.cfg` file.
-#>
-function Get-PyVenvConfig(
-    [String]
-    $ConfigDir
-) {
-    Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg"
-
-    # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue).
-    $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue
-
-    # An empty map will be returned if no config file is found.
-    $pyvenvConfig = @{ }
-
-    if ($pyvenvConfigPath) {
-
-        Write-Verbose "File exists, parse `key = value` lines"
-        $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath
-
-        $pyvenvConfigContent | ForEach-Object {
-            $keyval = $PSItem -split "\s*=\s*", 2
-            if ($keyval[0] -and $keyval[1]) {
-                $val = $keyval[1]
-
-                # Remove extraneous quotations around a string value.
-                if ("'""".Contains($val.Substring(0, 1))) {
-                    $val = $val.Substring(1, $val.Length - 2)
-                }
-
-                $pyvenvConfig[$keyval[0]] = $val
-                Write-Verbose "Adding Key: '$($keyval[0])'='$val'"
-            }
-        }
-    }
-    return $pyvenvConfig
-}
-
-
-<# Begin Activate script --------------------------------------------------- #>
-
-# Determine the containing directory of this script
-$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
-$VenvExecDir = Get-Item -Path $VenvExecPath
-
-Write-Verbose "Activation script is located in path: '$VenvExecPath'"
-Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)"
-Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)"
-
-# Set values required in priority: CmdLine, ConfigFile, Default
-# First, get the location of the virtual environment, it might not be
-# VenvExecDir if specified on the command line.
-if ($VenvDir) {
-    Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values"
-}
-else {
-    Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir."
-    $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/")
-    Write-Verbose "VenvDir=$VenvDir"
-}
-
-# Next, read the `pyvenv.cfg` file to determine any required value such
-# as `prompt`.
-$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir
-
-# Next, set the prompt from the command line, or the config file, or
-# just use the name of the virtual environment folder.
-if ($Prompt) {
-    Write-Verbose "Prompt specified as argument, using '$Prompt'"
-}
-else {
-    Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value"
-    if ($pyvenvCfg -and $pyvenvCfg['prompt']) {
-        Write-Verbose "  Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'"
-        $Prompt = $pyvenvCfg['prompt'];
-    }
-    else {
-        Write-Verbose "  Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)"
-        Write-Verbose "  Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'"
-        $Prompt = Split-Path -Path $venvDir -Leaf
-    }
-}
-
-Write-Verbose "Prompt = '$Prompt'"
-Write-Verbose "VenvDir='$VenvDir'"
-
-# Deactivate any currently active virtual environment, but leave the
-# deactivate function in place.
-deactivate -nondestructive
-
-# Now set the environment variable VIRTUAL_ENV, used by many tools to determine
-# that there is an activated venv.
-$env:VIRTUAL_ENV = $VenvDir
-
-if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) {
-
-    Write-Verbose "Setting prompt to '$Prompt'"
-
-    # Set the prompt to include the env name
-    # Make sure _OLD_VIRTUAL_PROMPT is global
-    function global:_OLD_VIRTUAL_PROMPT { "" }
-    Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT
-    New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt
-
-    function global:prompt {
-        Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) "
-        _OLD_VIRTUAL_PROMPT
-    }
-    $env:VIRTUAL_ENV_PROMPT = $Prompt
-}
-
-# Clear PYTHONHOME
-if (Test-Path -Path Env:PYTHONHOME) {
-    Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME
-    Remove-Item -Path Env:PYTHONHOME
-}
-
-# Add the venv to the PATH
-Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH
-$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH"

+ 0 - 69
venv/bin/activate

@@ -1,69 +0,0 @@
-# This file must be used with "source bin/activate" *from bash*
-# you cannot run it directly
-
-deactivate () {
-    # reset old environment variables
-    if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then
-        PATH="${_OLD_VIRTUAL_PATH:-}"
-        export PATH
-        unset _OLD_VIRTUAL_PATH
-    fi
-    if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then
-        PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}"
-        export PYTHONHOME
-        unset _OLD_VIRTUAL_PYTHONHOME
-    fi
-
-    # This should detect bash and zsh, which have a hash command that must
-    # be called to get it to forget past commands.  Without forgetting
-    # past commands the $PATH changes we made may not be respected
-    if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
-        hash -r 2> /dev/null
-    fi
-
-    if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then
-        PS1="${_OLD_VIRTUAL_PS1:-}"
-        export PS1
-        unset _OLD_VIRTUAL_PS1
-    fi
-
-    unset VIRTUAL_ENV
-    unset VIRTUAL_ENV_PROMPT
-    if [ ! "${1:-}" = "nondestructive" ] ; then
-    # Self destruct!
-        unset -f deactivate
-    fi
-}
-
-# unset irrelevant variables
-deactivate nondestructive
-
-VIRTUAL_ENV="/Users/federicaspinelli/Semantization_Interface/venv"
-export VIRTUAL_ENV
-
-_OLD_VIRTUAL_PATH="$PATH"
-PATH="$VIRTUAL_ENV/bin:$PATH"
-export PATH
-
-# unset PYTHONHOME if set
-# this will fail if PYTHONHOME is set to the empty string (which is bad anyway)
-# could use `if (set -u; : $PYTHONHOME) ;` in bash
-if [ -n "${PYTHONHOME:-}" ] ; then
-    _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}"
-    unset PYTHONHOME
-fi
-
-if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then
-    _OLD_VIRTUAL_PS1="${PS1:-}"
-    PS1="(venv) ${PS1:-}"
-    export PS1
-    VIRTUAL_ENV_PROMPT="(venv) "
-    export VIRTUAL_ENV_PROMPT
-fi
-
-# This should detect bash and zsh, which have a hash command that must
-# be called to get it to forget past commands.  Without forgetting
-# past commands the $PATH changes we made may not be respected
-if [ -n "${BASH:-}" -o -n "${ZSH_VERSION:-}" ] ; then
-    hash -r 2> /dev/null
-fi

+ 0 - 26
venv/bin/activate.csh

@@ -1,26 +0,0 @@
-# This file must be used with "source bin/activate.csh" *from csh*.
-# You cannot run it directly.
-# Created by Davide Di Blasi <davidedb@gmail.com>.
-# Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com>
-
-alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate'
-
-# Unset irrelevant variables.
-deactivate nondestructive
-
-setenv VIRTUAL_ENV "/Users/federicaspinelli/Semantization_Interface/venv"
-
-set _OLD_VIRTUAL_PATH="$PATH"
-setenv PATH "$VIRTUAL_ENV/bin:$PATH"
-
-
-set _OLD_VIRTUAL_PROMPT="$prompt"
-
-if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then
-    set prompt = "(venv) $prompt"
-    setenv VIRTUAL_ENV_PROMPT "(venv) "
-endif
-
-alias pydoc python -m pydoc
-
-rehash

+ 0 - 66
venv/bin/activate.fish

@@ -1,66 +0,0 @@
-# This file must be used with "source <venv>/bin/activate.fish" *from fish*
-# (https://fishshell.com/); you cannot run it directly.
-
-function deactivate  -d "Exit virtual environment and return to normal shell environment"
-    # reset old environment variables
-    if test -n "$_OLD_VIRTUAL_PATH"
-        set -gx PATH $_OLD_VIRTUAL_PATH
-        set -e _OLD_VIRTUAL_PATH
-    end
-    if test -n "$_OLD_VIRTUAL_PYTHONHOME"
-        set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME
-        set -e _OLD_VIRTUAL_PYTHONHOME
-    end
-
-    if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
-        functions -e fish_prompt
-        set -e _OLD_FISH_PROMPT_OVERRIDE
-        functions -c _old_fish_prompt fish_prompt
-        functions -e _old_fish_prompt
-    end
-
-    set -e VIRTUAL_ENV
-    set -e VIRTUAL_ENV_PROMPT
-    if test "$argv[1]" != "nondestructive"
-        # Self-destruct!
-        functions -e deactivate
-    end
-end
-
-# Unset irrelevant variables.
-deactivate nondestructive
-
-set -gx VIRTUAL_ENV "/Users/federicaspinelli/Semantization_Interface/venv"
-
-set -gx _OLD_VIRTUAL_PATH $PATH
-set -gx PATH "$VIRTUAL_ENV/bin" $PATH
-
-# Unset PYTHONHOME if set.
-if set -q PYTHONHOME
-    set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME
-    set -e PYTHONHOME
-end
-
-if test -z "$VIRTUAL_ENV_DISABLE_PROMPT"
-    # fish uses a function instead of an env var to generate the prompt.
-
-    # Save the current fish_prompt function as the function _old_fish_prompt.
-    functions -c fish_prompt _old_fish_prompt
-
-    # With the original prompt function renamed, we can override with our own.
-    function fish_prompt
-        # Save the return status of the last command.
-        set -l old_status $status
-
-        # Output the venv prompt; color taken from the blue of the Python logo.
-        printf "%s%s%s" (set_color 4B8BBE) "(venv) " (set_color normal)
-
-        # Restore the return status of the previous command.
-        echo "exit $old_status" | .
-        # Output the original/"old" prompt.
-        _old_fish_prompt
-    end
-
-    set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV"
-    set -gx VIRTUAL_ENV_PROMPT "(venv) "
-end

+ 0 - 8
venv/bin/flask

@@ -1,8 +0,0 @@
-#!/Users/federicaspinelli/Semantization_Interface/venv/bin/python3
-# -*- coding: utf-8 -*-
-import re
-import sys
-from flask.cli import main
-if __name__ == '__main__':
-    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
-    sys.exit(main())

+ 0 - 8
venv/bin/pip

@@ -1,8 +0,0 @@
-#!/Users/federicaspinelli/Semantization_Interface/venv/bin/python3
-# -*- coding: utf-8 -*-
-import re
-import sys
-from pip._internal.cli.main import main
-if __name__ == '__main__':
-    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
-    sys.exit(main())

+ 0 - 8
venv/bin/pip3

@@ -1,8 +0,0 @@
-#!/Users/federicaspinelli/Semantization_Interface/venv/bin/python3
-# -*- coding: utf-8 -*-
-import re
-import sys
-from pip._internal.cli.main import main
-if __name__ == '__main__':
-    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
-    sys.exit(main())

+ 0 - 8
venv/bin/pip3.10

@@ -1,8 +0,0 @@
-#!/Users/federicaspinelli/Semantization_Interface/venv/bin/python3
-# -*- coding: utf-8 -*-
-import re
-import sys
-from pip._internal.cli.main import main
-if __name__ == '__main__':
-    sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0])
-    sys.exit(main())

+ 0 - 1
venv/bin/python

@@ -1 +0,0 @@
-python3

+ 0 - 1
venv/bin/python3

@@ -1 +0,0 @@
-/Library/Frameworks/Python.framework/Versions/3.10/bin/python3

+ 0 - 1
venv/bin/python3.10

@@ -1 +0,0 @@
-python3

+ 0 - 1
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/INSTALLER

@@ -1 +0,0 @@
-pip

+ 0 - 28
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/LICENSE.rst

@@ -1,28 +0,0 @@
-Copyright 2010 Pallets
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1.  Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-2.  Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-3.  Neither the name of the copyright holder nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 123
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/METADATA

@@ -1,123 +0,0 @@
-Metadata-Version: 2.1
-Name: Flask
-Version: 2.2.2
-Summary: A simple framework for building complex web applications.
-Home-page: https://palletsprojects.com/p/flask
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-Maintainer: Pallets
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
-Project-URL: Donate, https://palletsprojects.com/donate
-Project-URL: Documentation, https://flask.palletsprojects.com/
-Project-URL: Changes, https://flask.palletsprojects.com/changes/
-Project-URL: Source Code, https://github.com/pallets/flask/
-Project-URL: Issue Tracker, https://github.com/pallets/flask/issues/
-Project-URL: Twitter, https://twitter.com/PalletsTeam
-Project-URL: Chat, https://discord.gg/pallets
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Framework :: Flask
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
-Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
-Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
-Requires-Python: >=3.7
-Description-Content-Type: text/x-rst
-License-File: LICENSE.rst
-Requires-Dist: Werkzeug (>=2.2.2)
-Requires-Dist: Jinja2 (>=3.0)
-Requires-Dist: itsdangerous (>=2.0)
-Requires-Dist: click (>=8.0)
-Requires-Dist: importlib-metadata (>=3.6.0) ; python_version < "3.10"
-Provides-Extra: async
-Requires-Dist: asgiref (>=3.2) ; extra == 'async'
-Provides-Extra: dotenv
-Requires-Dist: python-dotenv ; extra == 'dotenv'
-
-Flask
-=====
-
-Flask is a lightweight `WSGI`_ web application framework. It is designed
-to make getting started quick and easy, with the ability to scale up to
-complex applications. It began as a simple wrapper around `Werkzeug`_
-and `Jinja`_ and has become one of the most popular Python web
-application frameworks.
-
-Flask offers suggestions, but doesn't enforce any dependencies or
-project layout. It is up to the developer to choose the tools and
-libraries they want to use. There are many extensions provided by the
-community that make adding new functionality easy.
-
-.. _WSGI: https://wsgi.readthedocs.io/
-.. _Werkzeug: https://werkzeug.palletsprojects.com/
-.. _Jinja: https://jinja.palletsprojects.com/
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
-    $ pip install -U Flask
-
-.. _pip: https://pip.pypa.io/en/stable/getting-started/
-
-
-A Simple Example
-----------------
-
-.. code-block:: python
-
-    # save this as app.py
-    from flask import Flask
-
-    app = Flask(__name__)
-
-    @app.route("/")
-    def hello():
-        return "Hello, World!"
-
-.. code-block:: text
-
-    $ flask run
-      * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
-
-
-Contributing
-------------
-
-For guidance on setting up a development environment and how to make a
-contribution to Flask, see the `contributing guidelines`_.
-
-.. _contributing guidelines: https://github.com/pallets/flask/blob/main/CONTRIBUTING.rst
-
-
-Donate
-------
-
-The Pallets organization develops and supports Flask and the libraries
-it uses. In order to grow the community of contributors and users, and
-allow the maintainers to devote more time to the projects, `please
-donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
--   Documentation: https://flask.palletsprojects.com/
--   Changes: https://flask.palletsprojects.com/changes/
--   PyPI Releases: https://pypi.org/project/Flask/
--   Source Code: https://github.com/pallets/flask/
--   Issue Tracker: https://github.com/pallets/flask/issues/
--   Website: https://palletsprojects.com/p/flask/
--   Twitter: https://twitter.com/PalletsTeam
--   Chat: https://discord.gg/pallets

+ 0 - 54
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/RECORD

@@ -1,54 +0,0 @@
-../../../bin/flask,sha256=hCiQS0XiVWwQ6WfTi5CM0OK9EVon9-Wtf7P9cCFC8mM,256
-Flask-2.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-Flask-2.2.2.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
-Flask-2.2.2.dist-info/METADATA,sha256=UXiwRLD1johd_tGlYOlOKXkJFIG82ehR3bxqh4XWFwA,3889
-Flask-2.2.2.dist-info/RECORD,,
-Flask-2.2.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-Flask-2.2.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
-Flask-2.2.2.dist-info/entry_points.txt,sha256=s3MqQpduU25y4dq3ftBYD6bMVdVnbMpZP-sUNw0zw0k,41
-Flask-2.2.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6
-flask/__init__.py,sha256=Y4mEWqAMxj_Oxq9eYv3tWyN-0nU9yVKBGK_t6BxqvvM,2890
-flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30
-flask/__pycache__/__init__.cpython-310.pyc,,
-flask/__pycache__/__main__.cpython-310.pyc,,
-flask/__pycache__/app.cpython-310.pyc,,
-flask/__pycache__/blueprints.cpython-310.pyc,,
-flask/__pycache__/cli.cpython-310.pyc,,
-flask/__pycache__/config.cpython-310.pyc,,
-flask/__pycache__/ctx.cpython-310.pyc,,
-flask/__pycache__/debughelpers.cpython-310.pyc,,
-flask/__pycache__/globals.cpython-310.pyc,,
-flask/__pycache__/helpers.cpython-310.pyc,,
-flask/__pycache__/logging.cpython-310.pyc,,
-flask/__pycache__/scaffold.cpython-310.pyc,,
-flask/__pycache__/sessions.cpython-310.pyc,,
-flask/__pycache__/signals.cpython-310.pyc,,
-flask/__pycache__/templating.cpython-310.pyc,,
-flask/__pycache__/testing.cpython-310.pyc,,
-flask/__pycache__/typing.cpython-310.pyc,,
-flask/__pycache__/views.cpython-310.pyc,,
-flask/__pycache__/wrappers.cpython-310.pyc,,
-flask/app.py,sha256=VfBcGmEVveMcSajkUmDXCEOvAd-2mIBJ355KicvQ4gE,99025
-flask/blueprints.py,sha256=Jbrt-2jlLiFklC3De9EWBioPtDjHYYbXlTDK9Z7L2nk,26936
-flask/cli.py,sha256=foLlD8NiIXcxpxMmRQvvlZPbVM8pxOaJG3sa58c9dAA,33486
-flask/config.py,sha256=IWqHecH4poDxNEUg4U_ZA1CTlL5BKZDX3ofG4UGYyi0,12584
-flask/ctx.py,sha256=ZOGEWuFjsCIk3vm-C9pLME0e4saeBkeGpr2tTSvemSM,14851
-flask/debughelpers.py,sha256=_RvAL3TW5lqMJeCVWtTU6rSDJC7jnRaBL6OEkVmooyU,5511
-flask/globals.py,sha256=1DLZMi8Su-S1gf8zEiR3JPi6VXYIrYqm8C9__Ly66ss,3187
-flask/helpers.py,sha256=ELq27745jihrdyAP9qY8KENlCVDdnWRWTIn35L9a-UU,25334
-flask/json/__init__.py,sha256=TOwldHT3_kFaXHlORKi9yCWt7dbPNB0ovdHHQWlSRzY,11175
-flask/json/__pycache__/__init__.cpython-310.pyc,,
-flask/json/__pycache__/provider.cpython-310.pyc,,
-flask/json/__pycache__/tag.cpython-310.pyc,,
-flask/json/provider.py,sha256=jXCNypf11PN4ngQjEt6LnSdCWQ1yHIAkNLHlXQlCB-A,10674
-flask/json/tag.py,sha256=fys3HBLssWHuMAIJuTcf2K0bCtosePBKXIWASZEEjnU,8857
-flask/logging.py,sha256=WYng0bLTRS_CJrocGcCLJpibHf1lygHE_pg-KoUIQ4w,2293
-flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-flask/scaffold.py,sha256=tiQRK-vMY5nucoN6pewXF87GaxrltsCGOgTVsT6wm7s,33443
-flask/sessions.py,sha256=66oGlE-v9iac-eb54tFN3ILAjJ1FeeuHHWw98UVaoxc,15847
-flask/signals.py,sha256=H7QwDciK-dtBxinjKpexpglP0E6k0MJILiFWTItfmqU,2136
-flask/templating.py,sha256=1P4OzvSnA2fsJTYgQT3G4owVKsuOz8XddCiR6jMHGJ0,7419
-flask/testing.py,sha256=p51f9P7jDc_IDSiZug7jypnfVcxsQrMg3B2tnjlpEFw,10596
-flask/typing.py,sha256=KgxegTF9v9WvuongeF8LooIvpZPauzGrq9ZXf3gBlYc,2969
-flask/views.py,sha256=bveWilivkPP-4HB9w_fOusBz6sHNIl0QTqKUFMCltzE,6738
-flask/wrappers.py,sha256=Wa-bhjNdPPveSHS1dpzD_r-ayZxIYFF1DoWncKOafrk,5695

+ 0 - 0
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/REQUESTED


+ 0 - 5
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/WHEEL

@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.1)
-Root-Is-Purelib: true
-Tag: py3-none-any
-

+ 0 - 2
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/entry_points.txt

@@ -1,2 +0,0 @@
-[console_scripts]
-flask = flask.cli:main

+ 0 - 1
venv/lib/python3.10/site-packages/Flask-2.2.2.dist-info/top_level.txt

@@ -1 +0,0 @@
-flask

+ 0 - 1
venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/INSTALLER

@@ -1 +0,0 @@
-pip

+ 0 - 28
venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/LICENSE.rst

@@ -1,28 +0,0 @@
-Copyright 2007 Pallets
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1.  Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-2.  Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-3.  Neither the name of the copyright holder nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 113
venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/METADATA

@@ -1,113 +0,0 @@
-Metadata-Version: 2.1
-Name: Jinja2
-Version: 3.1.2
-Summary: A very fast and expressive template engine.
-Home-page: https://palletsprojects.com/p/jinja/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-Maintainer: Pallets
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
-Project-URL: Donate, https://palletsprojects.com/donate
-Project-URL: Documentation, https://jinja.palletsprojects.com/
-Project-URL: Changes, https://jinja.palletsprojects.com/changes/
-Project-URL: Source Code, https://github.com/pallets/jinja/
-Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/
-Project-URL: Twitter, https://twitter.com/PalletsTeam
-Project-URL: Chat, https://discord.gg/pallets
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Text Processing :: Markup :: HTML
-Requires-Python: >=3.7
-Description-Content-Type: text/x-rst
-License-File: LICENSE.rst
-Requires-Dist: MarkupSafe (>=2.0)
-Provides-Extra: i18n
-Requires-Dist: Babel (>=2.7) ; extra == 'i18n'
-
-Jinja
-=====
-
-Jinja is a fast, expressive, extensible templating engine. Special
-placeholders in the template allow writing code similar to Python
-syntax. Then the template is passed data to render the final document.
-
-It includes:
-
--   Template inheritance and inclusion.
--   Define and import macros within templates.
--   HTML templates can use autoescaping to prevent XSS from untrusted
-    user input.
--   A sandboxed environment can safely render untrusted templates.
--   AsyncIO support for generating templates and calling async
-    functions.
--   I18N support with Babel.
--   Templates are compiled to optimized Python code just-in-time and
-    cached, or can be compiled ahead-of-time.
--   Exceptions point to the correct line in templates to make debugging
-    easier.
--   Extensible filters, tests, functions, and even syntax.
-
-Jinja's philosophy is that while application logic belongs in Python if
-possible, it shouldn't make the template designer's job difficult by
-restricting functionality too much.
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
-    $ pip install -U Jinja2
-
-.. _pip: https://pip.pypa.io/en/stable/getting-started/
-
-
-In A Nutshell
--------------
-
-.. code-block:: jinja
-
-    {% extends "base.html" %}
-    {% block title %}Members{% endblock %}
-    {% block content %}
-      <ul>
-      {% for user in users %}
-        <li><a href="{{ user.url }}">{{ user.username }}</a></li>
-      {% endfor %}
-      </ul>
-    {% endblock %}
-
-
-Donate
-------
-
-The Pallets organization develops and supports Jinja and other popular
-packages. In order to grow the community of contributors and users, and
-allow the maintainers to devote more time to the projects, `please
-donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
--   Documentation: https://jinja.palletsprojects.com/
--   Changes: https://jinja.palletsprojects.com/changes/
--   PyPI Releases: https://pypi.org/project/Jinja2/
--   Source Code: https://github.com/pallets/jinja/
--   Issue Tracker: https://github.com/pallets/jinja/issues/
--   Website: https://palletsprojects.com/p/jinja/
--   Twitter: https://twitter.com/PalletsTeam
--   Chat: https://discord.gg/pallets
-
-

+ 0 - 58
venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/RECORD

@@ -1,58 +0,0 @@
-Jinja2-3.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-Jinja2-3.1.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475
-Jinja2-3.1.2.dist-info/METADATA,sha256=PZ6v2SIidMNixR7MRUX9f7ZWsPwtXanknqiZUmRbh4U,3539
-Jinja2-3.1.2.dist-info/RECORD,,
-Jinja2-3.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
-Jinja2-3.1.2.dist-info/entry_points.txt,sha256=zRd62fbqIyfUpsRtU7EVIFyiu1tPwfgO7EvPErnxgTE,59
-Jinja2-3.1.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7
-jinja2/__init__.py,sha256=8vGduD8ytwgD6GDSqpYc2m3aU-T7PKOAddvVXgGr_Fs,1927
-jinja2/__pycache__/__init__.cpython-310.pyc,,
-jinja2/__pycache__/_identifier.cpython-310.pyc,,
-jinja2/__pycache__/async_utils.cpython-310.pyc,,
-jinja2/__pycache__/bccache.cpython-310.pyc,,
-jinja2/__pycache__/compiler.cpython-310.pyc,,
-jinja2/__pycache__/constants.cpython-310.pyc,,
-jinja2/__pycache__/debug.cpython-310.pyc,,
-jinja2/__pycache__/defaults.cpython-310.pyc,,
-jinja2/__pycache__/environment.cpython-310.pyc,,
-jinja2/__pycache__/exceptions.cpython-310.pyc,,
-jinja2/__pycache__/ext.cpython-310.pyc,,
-jinja2/__pycache__/filters.cpython-310.pyc,,
-jinja2/__pycache__/idtracking.cpython-310.pyc,,
-jinja2/__pycache__/lexer.cpython-310.pyc,,
-jinja2/__pycache__/loaders.cpython-310.pyc,,
-jinja2/__pycache__/meta.cpython-310.pyc,,
-jinja2/__pycache__/nativetypes.cpython-310.pyc,,
-jinja2/__pycache__/nodes.cpython-310.pyc,,
-jinja2/__pycache__/optimizer.cpython-310.pyc,,
-jinja2/__pycache__/parser.cpython-310.pyc,,
-jinja2/__pycache__/runtime.cpython-310.pyc,,
-jinja2/__pycache__/sandbox.cpython-310.pyc,,
-jinja2/__pycache__/tests.cpython-310.pyc,,
-jinja2/__pycache__/utils.cpython-310.pyc,,
-jinja2/__pycache__/visitor.cpython-310.pyc,,
-jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958
-jinja2/async_utils.py,sha256=dHlbTeaxFPtAOQEYOGYh_PHcDT0rsDaUJAFDl_0XtTg,2472
-jinja2/bccache.py,sha256=mhz5xtLxCcHRAa56azOhphIAe19u1we0ojifNMClDio,14061
-jinja2/compiler.py,sha256=Gs-N8ThJ7OWK4-reKoO8Wh1ZXz95MVphBKNVf75qBr8,72172
-jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433
-jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299
-jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267
-jinja2/environment.py,sha256=6uHIcc7ZblqOMdx_uYNKqRnnwAF0_nzbyeMP9FFtuh4,61349
-jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071
-jinja2/ext.py,sha256=ivr3P7LKbddiXDVez20EflcO3q2aHQwz9P_PgWGHVqE,31502
-jinja2/filters.py,sha256=9js1V-h2RlyW90IhLiBGLM2U-k6SCy2F4BUUMgB3K9Q,53509
-jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704
-jinja2/lexer.py,sha256=DW2nX9zk-6MWp65YR2bqqj0xqCvLtD-u9NWT8AnFRxQ,29726
-jinja2/loaders.py,sha256=BfptfvTVpClUd-leMkHczdyPNYFzp_n7PKOJ98iyHOg,23207
-jinja2/meta.py,sha256=GNPEvifmSaU3CMxlbheBOZjeZ277HThOPUTf1RkppKQ,4396
-jinja2/nativetypes.py,sha256=DXgORDPRmVWgy034H0xL8eF7qYoK3DrMxs-935d0Fzk,4226
-jinja2/nodes.py,sha256=i34GPRAZexXMT6bwuf5SEyvdmS-bRCy9KMjwN5O6pjk,34550
-jinja2/optimizer.py,sha256=tHkMwXxfZkbfA1KmLcqmBMSaz7RLIvvItrJcPoXTyD8,1650
-jinja2/parser.py,sha256=nHd-DFHbiygvfaPtm9rcQXJChZG7DPsWfiEsqfwKerY,39595
-jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-jinja2/runtime.py,sha256=5CmD5BjbEJxSiDNTFBeKCaq8qU4aYD2v6q2EluyExms,33476
-jinja2/sandbox.py,sha256=Y0xZeXQnH6EX5VjaV2YixESxoepnRbW_3UeQosaBU3M,14584
-jinja2/tests.py,sha256=Am5Z6Lmfr2XaH_npIfJJ8MdXtWsbLjMULZJulTAj30E,5905
-jinja2/utils.py,sha256=u9jXESxGn8ATZNVolwmkjUVu4SA-tLgV0W7PcSfPfdQ,23965
-jinja2/visitor.py,sha256=MH14C6yq24G_KVtWzjwaI7Wg14PCJIYlWW1kpkxYak0,3568

+ 0 - 5
venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/WHEEL

@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.1)
-Root-Is-Purelib: true
-Tag: py3-none-any
-

+ 0 - 2
venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/entry_points.txt

@@ -1,2 +0,0 @@
-[babel.extractors]
-jinja2 = jinja2.ext:babel_extract[i18n]

+ 0 - 1
venv/lib/python3.10/site-packages/Jinja2-3.1.2.dist-info/top_level.txt

@@ -1 +0,0 @@
-jinja2

+ 0 - 1
venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/INSTALLER

@@ -1 +0,0 @@
-pip

+ 0 - 28
venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/LICENSE.rst

@@ -1,28 +0,0 @@
-Copyright 2010 Pallets
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1.  Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-2.  Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-3.  Neither the name of the copyright holder nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 101
venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/METADATA

@@ -1,101 +0,0 @@
-Metadata-Version: 2.1
-Name: MarkupSafe
-Version: 2.1.1
-Summary: Safely add untrusted strings to HTML/XML markup.
-Home-page: https://palletsprojects.com/p/markupsafe/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-Maintainer: Pallets
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
-Project-URL: Donate, https://palletsprojects.com/donate
-Project-URL: Documentation, https://markupsafe.palletsprojects.com/
-Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/
-Project-URL: Source Code, https://github.com/pallets/markupsafe/
-Project-URL: Issue Tracker, https://github.com/pallets/markupsafe/issues/
-Project-URL: Twitter, https://twitter.com/PalletsTeam
-Project-URL: Chat, https://discord.gg/pallets
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Text Processing :: Markup :: HTML
-Requires-Python: >=3.7
-Description-Content-Type: text/x-rst
-License-File: LICENSE.rst
-
-MarkupSafe
-==========
-
-MarkupSafe implements a text object that escapes characters so it is
-safe to use in HTML and XML. Characters that have special meanings are
-replaced so that they display as the actual characters. This mitigates
-injection attacks, meaning untrusted user input can safely be displayed
-on a page.
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
-    pip install -U MarkupSafe
-
-.. _pip: https://pip.pypa.io/en/stable/getting-started/
-
-
-Examples
---------
-
-.. code-block:: pycon
-
-    >>> from markupsafe import Markup, escape
-
-    >>> # escape replaces special characters and wraps in Markup
-    >>> escape("<script>alert(document.cookie);</script>")
-    Markup('&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
-
-    >>> # wrap in Markup to mark text "safe" and prevent escaping
-    >>> Markup("<strong>Hello</strong>")
-    Markup('<strong>hello</strong>')
-
-    >>> escape(Markup("<strong>Hello</strong>"))
-    Markup('<strong>hello</strong>')
-
-    >>> # Markup is a str subclass
-    >>> # methods and operators escape their arguments
-    >>> template = Markup("Hello <em>{name}</em>")
-    >>> template.format(name='"World"')
-    Markup('Hello <em>&#34;World&#34;</em>')
-
-
-Donate
-------
-
-The Pallets organization develops and supports MarkupSafe and other
-popular packages. In order to grow the community of contributors and
-users, and allow the maintainers to devote more time to the projects,
-`please donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
--   Documentation: https://markupsafe.palletsprojects.com/
--   Changes: https://markupsafe.palletsprojects.com/changes/
--   PyPI Releases: https://pypi.org/project/MarkupSafe/
--   Source Code: https://github.com/pallets/markupsafe/
--   Issue Tracker: https://github.com/pallets/markupsafe/issues/
--   Website: https://palletsprojects.com/p/markupsafe/
--   Twitter: https://twitter.com/PalletsTeam
--   Chat: https://discord.gg/pallets
-
-

+ 0 - 14
venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/RECORD

@@ -1,14 +0,0 @@
-MarkupSafe-2.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-MarkupSafe-2.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
-MarkupSafe-2.1.1.dist-info/METADATA,sha256=DC93VszmzjLQcrVChRUjtW4XbUwjTdbaplpgdlbFdbs,3242
-MarkupSafe-2.1.1.dist-info/RECORD,,
-MarkupSafe-2.1.1.dist-info/WHEEL,sha256=QN3MNOFrRIeE9ccPTe5mH4Q_A2DBDdD7_qUigvuJeQU,111
-MarkupSafe-2.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
-markupsafe/__init__.py,sha256=xfaUQkKNRTdYWe6HnnJ2HjguFmS-C_0H6g8-Q9VAfkQ,9284
-markupsafe/__pycache__/__init__.cpython-310.pyc,,
-markupsafe/__pycache__/_native.cpython-310.pyc,,
-markupsafe/_native.py,sha256=GR86Qvo_GcgKmKreA1WmYN9ud17OFwkww8E-fiW-57s,1713
-markupsafe/_speedups.c,sha256=X2XvQVtIdcK4Usz70BvkzoOfjTCmQlDkkjYSn-swE0g,7083
-markupsafe/_speedups.cpython-310-darwin.so,sha256=RrUcL36CQAvdE7Xf4OcvU3CVuQ4qkgDwylh52HXTyHM,35136
-markupsafe/_speedups.pyi,sha256=vfMCsOgbAXRNLUXkyuyonG8uEWKYU4PDqNuMaDELAYw,229
-markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0

+ 0 - 5
venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/WHEEL

@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.0)
-Root-Is-Purelib: false
-Tag: cp310-cp310-macosx_10_9_x86_64
-

+ 0 - 1
venv/lib/python3.10/site-packages/MarkupSafe-2.1.1.dist-info/top_level.txt

@@ -1 +0,0 @@
-markupsafe

+ 0 - 1
venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/INSTALLER

@@ -1 +0,0 @@
-pip

+ 0 - 28
venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/LICENSE.rst

@@ -1,28 +0,0 @@
-Copyright 2007 Pallets
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1.  Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-2.  Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-3.  Neither the name of the copyright holder nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 126
venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/METADATA

@@ -1,126 +0,0 @@
-Metadata-Version: 2.1
-Name: Werkzeug
-Version: 2.2.2
-Summary: The comprehensive WSGI web application library.
-Home-page: https://palletsprojects.com/p/werkzeug/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-Maintainer: Pallets
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
-Project-URL: Donate, https://palletsprojects.com/donate
-Project-URL: Documentation, https://werkzeug.palletsprojects.com/
-Project-URL: Changes, https://werkzeug.palletsprojects.com/changes/
-Project-URL: Source Code, https://github.com/pallets/werkzeug/
-Project-URL: Issue Tracker, https://github.com/pallets/werkzeug/issues/
-Project-URL: Twitter, https://twitter.com/PalletsTeam
-Project-URL: Chat, https://discord.gg/pallets
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
-Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
-Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
-Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
-Requires-Python: >=3.7
-Description-Content-Type: text/x-rst
-License-File: LICENSE.rst
-Requires-Dist: MarkupSafe (>=2.1.1)
-Provides-Extra: watchdog
-Requires-Dist: watchdog ; extra == 'watchdog'
-
-Werkzeug
-========
-
-*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff")
-
-Werkzeug is a comprehensive `WSGI`_ web application library. It began as
-a simple collection of various utilities for WSGI applications and has
-become one of the most advanced WSGI utility libraries.
-
-It includes:
-
--   An interactive debugger that allows inspecting stack traces and
-    source code in the browser with an interactive interpreter for any
-    frame in the stack.
--   A full-featured request object with objects to interact with
-    headers, query args, form data, files, and cookies.
--   A response object that can wrap other WSGI applications and handle
-    streaming data.
--   A routing system for matching URLs to endpoints and generating URLs
-    for endpoints, with an extensible system for capturing variables
-    from URLs.
--   HTTP utilities to handle entity tags, cache control, dates, user
-    agents, cookies, files, and more.
--   A threaded WSGI server for use while developing applications
-    locally.
--   A test client for simulating HTTP requests during testing without
-    requiring running a server.
-
-Werkzeug doesn't enforce any dependencies. It is up to the developer to
-choose a template engine, database adapter, and even how to handle
-requests. It can be used to build all sorts of end user applications
-such as blogs, wikis, or bulletin boards.
-
-`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while
-providing more structure and patterns for defining powerful
-applications.
-
-.. _WSGI: https://wsgi.readthedocs.io/en/latest/
-.. _Flask: https://www.palletsprojects.com/p/flask/
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
-    pip install -U Werkzeug
-
-.. _pip: https://pip.pypa.io/en/stable/getting-started/
-
-
-A Simple Example
-----------------
-
-.. code-block:: python
-
-    from werkzeug.wrappers import Request, Response
-
-    @Request.application
-    def application(request):
-        return Response('Hello, World!')
-
-    if __name__ == '__main__':
-        from werkzeug.serving import run_simple
-        run_simple('localhost', 4000, application)
-
-
-Donate
-------
-
-The Pallets organization develops and supports Werkzeug and other
-popular packages. In order to grow the community of contributors and
-users, and allow the maintainers to devote more time to the projects,
-`please donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
--   Documentation: https://werkzeug.palletsprojects.com/
--   Changes: https://werkzeug.palletsprojects.com/changes/
--   PyPI Releases: https://pypi.org/project/Werkzeug/
--   Source Code: https://github.com/pallets/werkzeug/
--   Issue Tracker: https://github.com/pallets/werkzeug/issues/
--   Website: https://palletsprojects.com/p/werkzeug/
--   Twitter: https://twitter.com/PalletsTeam
--   Chat: https://discord.gg/pallets

+ 0 - 98
venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/RECORD

@@ -1,98 +0,0 @@
-Werkzeug-2.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-Werkzeug-2.2.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475
-Werkzeug-2.2.2.dist-info/METADATA,sha256=hz42ndovEQQy3rwXKZDwR7LA4UNthKegxf_7xIQrjsM,4416
-Werkzeug-2.2.2.dist-info/RECORD,,
-Werkzeug-2.2.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
-Werkzeug-2.2.2.dist-info/top_level.txt,sha256=QRyj2VjwJoQkrwjwFIOlB8Xg3r9un0NtqVHQF-15xaw,9
-werkzeug/__init__.py,sha256=UP218Ddd2NYm1dUhTlhvGRQytzAx1Ms1A716UKiPOYk,188
-werkzeug/__pycache__/__init__.cpython-310.pyc,,
-werkzeug/__pycache__/_internal.cpython-310.pyc,,
-werkzeug/__pycache__/_reloader.cpython-310.pyc,,
-werkzeug/__pycache__/datastructures.cpython-310.pyc,,
-werkzeug/__pycache__/exceptions.cpython-310.pyc,,
-werkzeug/__pycache__/formparser.cpython-310.pyc,,
-werkzeug/__pycache__/http.cpython-310.pyc,,
-werkzeug/__pycache__/local.cpython-310.pyc,,
-werkzeug/__pycache__/security.cpython-310.pyc,,
-werkzeug/__pycache__/serving.cpython-310.pyc,,
-werkzeug/__pycache__/test.cpython-310.pyc,,
-werkzeug/__pycache__/testapp.cpython-310.pyc,,
-werkzeug/__pycache__/urls.cpython-310.pyc,,
-werkzeug/__pycache__/user_agent.cpython-310.pyc,,
-werkzeug/__pycache__/utils.cpython-310.pyc,,
-werkzeug/__pycache__/wsgi.cpython-310.pyc,,
-werkzeug/_internal.py,sha256=g8PHJz2z39I3x0vwTvTKbXIg0eUQqGF9UtUzDMWT0Qw,16222
-werkzeug/_reloader.py,sha256=lYStlIDduTxBOB8BSozy_44HQ7YT5fup-x3uuac1-2o,14331
-werkzeug/datastructures.py,sha256=T1SRE_KRuNz9Q7P-Ck4PyKPyil1NOx9zDuNMLgrN1Z0,97083
-werkzeug/datastructures.pyi,sha256=HRzDLc7A6qnwluhNqn6AT76CsLZIkAbVVqxn0AbfV-s,34506
-werkzeug/debug/__init__.py,sha256=Gpq6OpS6mHwHk0mJkHc2fWvvjo6ccJVS9QJwJgoeb9I,18893
-werkzeug/debug/__pycache__/__init__.cpython-310.pyc,,
-werkzeug/debug/__pycache__/console.cpython-310.pyc,,
-werkzeug/debug/__pycache__/repr.cpython-310.pyc,,
-werkzeug/debug/__pycache__/tbtools.cpython-310.pyc,,
-werkzeug/debug/console.py,sha256=dechqiCtHfs0AQZWZofUC1S97tCuvwDgT0gdha5KwWM,6208
-werkzeug/debug/repr.py,sha256=FFczy4yhVfEQjW99HuZtUce-ebtJWMjp9GnfasXa0KA,9488
-werkzeug/debug/shared/ICON_LICENSE.md,sha256=DhA6Y1gUl5Jwfg0NFN9Rj4VWITt8tUx0IvdGf0ux9-s,222
-werkzeug/debug/shared/console.png,sha256=bxax6RXXlvOij_KeqvSNX0ojJf83YbnZ7my-3Gx9w2A,507
-werkzeug/debug/shared/debugger.js,sha256=tg42SZs1SVmYWZ-_Fj5ELK5-FLHnGNQrei0K2By8Bw8,10521
-werkzeug/debug/shared/less.png,sha256=-4-kNRaXJSONVLahrQKUxMwXGm9R4OnZ9SxDGpHlIR4,191
-werkzeug/debug/shared/more.png,sha256=GngN7CioHQoV58rH6ojnkYi8c_qED2Aka5FO5UXrReY,200
-werkzeug/debug/shared/style.css,sha256=-xSxzUEZGw_IqlDR5iZxitNl8LQUjBM-_Y4UAvXVH8g,6078
-werkzeug/debug/tbtools.py,sha256=Fsmlk6Ao3CcXm9iX7i_8MhCp2SQZ8uHm8Cf5wacnlW4,13293
-werkzeug/exceptions.py,sha256=5MFy6RyaU4nokoYzdDafloY51QUDIGVNKeK_FORUFS0,26543
-werkzeug/formparser.py,sha256=rLEu_ZwVpvqshZg6E4Qiv36QsmzmCytTijBeGX3dDGk,16056
-werkzeug/http.py,sha256=i_LrIU9KsOz27zfkwKIK6eifFuFMKgSuW15k57HbMiE,42162
-werkzeug/local.py,sha256=1IRMV9MFrauLaZeliF0Md1n7ZOcOKLbS03bnQ8Gz5WY,22326
-werkzeug/middleware/__init__.py,sha256=qfqgdT5npwG9ses3-FXQJf3aB95JYP1zchetH_T3PUw,500
-werkzeug/middleware/__pycache__/__init__.cpython-310.pyc,,
-werkzeug/middleware/__pycache__/dispatcher.cpython-310.pyc,,
-werkzeug/middleware/__pycache__/http_proxy.cpython-310.pyc,,
-werkzeug/middleware/__pycache__/lint.cpython-310.pyc,,
-werkzeug/middleware/__pycache__/profiler.cpython-310.pyc,,
-werkzeug/middleware/__pycache__/proxy_fix.cpython-310.pyc,,
-werkzeug/middleware/__pycache__/shared_data.cpython-310.pyc,,
-werkzeug/middleware/dispatcher.py,sha256=Fh_w-KyWnTSYF-Lfv5dimQ7THSS7afPAZMmvc4zF1gg,2580
-werkzeug/middleware/http_proxy.py,sha256=HE8VyhS7CR-E1O6_9b68huv8FLgGGR1DLYqkS3Xcp3Q,7558
-werkzeug/middleware/lint.py,sha256=Sr6gV4royDs6ezkqv5trRAyKMDQ60KaEq3-tQ3opUvw,13968
-werkzeug/middleware/profiler.py,sha256=QkXk7cqnaPnF8wQu-5SyPCIOT3_kdABUBorQOghVNOA,4899
-werkzeug/middleware/proxy_fix.py,sha256=l7LC_LDu0Yd4SvUxS5SFigAJMzcIOGm6LNKl9IXJBSU,6974
-werkzeug/middleware/shared_data.py,sha256=fXjrEkuqxUVLG1DLrOdQLc96QQdjftCBZ1oM5oK89h4,9528
-werkzeug/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-werkzeug/routing/__init__.py,sha256=HpvahY7WwkLdV4Cq3Bsc3GrqNon4u6t8-vhbb9E5o00,4819
-werkzeug/routing/__pycache__/__init__.cpython-310.pyc,,
-werkzeug/routing/__pycache__/converters.cpython-310.pyc,,
-werkzeug/routing/__pycache__/exceptions.cpython-310.pyc,,
-werkzeug/routing/__pycache__/map.cpython-310.pyc,,
-werkzeug/routing/__pycache__/matcher.cpython-310.pyc,,
-werkzeug/routing/__pycache__/rules.cpython-310.pyc,,
-werkzeug/routing/converters.py,sha256=05bkekg64vLC6mqqK4ddBh589WH9yBsjtW8IJhdUBvw,6968
-werkzeug/routing/exceptions.py,sha256=RklUDL9ajOv2fTcRNj4pb18Bs4Y-GKk4rIeTSfsqkks,4737
-werkzeug/routing/map.py,sha256=XN4ZjzEF1SfMxtdov89SDE-1_U78KVnnobTfnHzqbmE,36757
-werkzeug/routing/matcher.py,sha256=U8xZTB3e5f3TgbkxdDyVuyxK4w72l1lo_b3tdG2zNrc,7122
-werkzeug/routing/rules.py,sha256=v27RaR5H3sIPRdJ_pdEfOBMN6EivFVpmFzJk7aizdyw,31072
-werkzeug/sansio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-werkzeug/sansio/__pycache__/__init__.cpython-310.pyc,,
-werkzeug/sansio/__pycache__/http.cpython-310.pyc,,
-werkzeug/sansio/__pycache__/multipart.cpython-310.pyc,,
-werkzeug/sansio/__pycache__/request.cpython-310.pyc,,
-werkzeug/sansio/__pycache__/response.cpython-310.pyc,,
-werkzeug/sansio/__pycache__/utils.cpython-310.pyc,,
-werkzeug/sansio/http.py,sha256=9eORg44CDxpmV9i_U_pZ_NR8gdc9UXFCdE7EAP1v-c0,5162
-werkzeug/sansio/multipart.py,sha256=Uyrg2U6s2oft8LXOyuTvFCWTLOEr7INVW8zFTXNwZ7A,9756
-werkzeug/sansio/request.py,sha256=SiGcx2cz-l81TlCCrKrT2fePqC64hN8fSg5Ig6J6vRs,20175
-werkzeug/sansio/response.py,sha256=UTl-teQDDjovrZMkjj3ZQsHw-JtiFak5JfKEk1_vBYU,26026
-werkzeug/sansio/utils.py,sha256=EjbqdHdT-JZWgjUQaaWSgBUIRprXUkrsMQQqJlJHpVU,4847
-werkzeug/security.py,sha256=vrBofh4WZZoUo1eAdJ6F1DrzVRlYauGS2CUDYpbQKj8,4658
-werkzeug/serving.py,sha256=18pfjrHw8b5UCgPPo1ZEoxlYZZ5UREl4jQ9f8LGWMAo,38458
-werkzeug/test.py,sha256=t7T5G-HciIlv1ZXtlydFVpow0VrXnJ_Y3yyEB7T0_Ww,48125
-werkzeug/testapp.py,sha256=RJhT_2JweNiMKe304N3bF1zaIeMpRx-CIMERdeydfTY,9404
-werkzeug/urls.py,sha256=Q9Si-eVh7yxk3rwkzrwGRm146FXVXgg9lBP3k0HUfVM,36600
-werkzeug/user_agent.py,sha256=WclZhpvgLurMF45hsioSbS75H1Zb4iMQGKN3_yZ2oKo,1420
-werkzeug/utils.py,sha256=OYdB2cZPYYgq3C0EVKMIv05BrYzzr9xdefW0H00_IVo,24936
-werkzeug/wrappers/__init__.py,sha256=kGyK7rOud3qCxll_jFyW15YarJhj1xtdf3ocx9ZheB8,120
-werkzeug/wrappers/__pycache__/__init__.cpython-310.pyc,,
-werkzeug/wrappers/__pycache__/request.cpython-310.pyc,,
-werkzeug/wrappers/__pycache__/response.cpython-310.pyc,,
-werkzeug/wrappers/request.py,sha256=UQ559KkGS0Po6HTBgvKMlk1_AsNw5zstzm8o_dRrfdQ,23415
-werkzeug/wrappers/response.py,sha256=c2HUXrrt5Sf8-XEB1fUXxm6jp7Lu80KR0A_tbQFvw1Q,34750
-werkzeug/wsgi.py,sha256=sgkFCzhl23hlSmbvjxbI-hVEjSlPuEBGTDAHmXFcAts,34732

+ 0 - 5
venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/WHEEL

@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.1)
-Root-Is-Purelib: true
-Tag: py3-none-any
-

+ 0 - 1
venv/lib/python3.10/site-packages/Werkzeug-2.2.2.dist-info/top_level.txt

@@ -1 +0,0 @@
-werkzeug

+ 0 - 128
venv/lib/python3.10/site-packages/_distutils_hack/__init__.py

@@ -1,128 +0,0 @@
-import sys
-import os
-import re
-import importlib
-import warnings
-
-
-is_pypy = '__pypy__' in sys.builtin_module_names
-
-
-warnings.filterwarnings('ignore',
-                        r'.+ distutils\b.+ deprecated',
-                        DeprecationWarning)
-
-
-def warn_distutils_present():
-    if 'distutils' not in sys.modules:
-        return
-    if is_pypy and sys.version_info < (3, 7):
-        # PyPy for 3.6 unconditionally imports distutils, so bypass the warning
-        # https://foss.heptapod.net/pypy/pypy/-/blob/be829135bc0d758997b3566062999ee8b23872b4/lib-python/3/site.py#L250
-        return
-    warnings.warn(
-        "Distutils was imported before Setuptools, but importing Setuptools "
-        "also replaces the `distutils` module in `sys.modules`. This may lead "
-        "to undesirable behaviors or errors. To avoid these issues, avoid "
-        "using distutils directly, ensure that setuptools is installed in the "
-        "traditional way (e.g. not an editable install), and/or make sure "
-        "that setuptools is always imported before distutils.")
-
-
-def clear_distutils():
-    if 'distutils' not in sys.modules:
-        return
-    warnings.warn("Setuptools is replacing distutils.")
-    mods = [name for name in sys.modules if re.match(r'distutils\b', name)]
-    for name in mods:
-        del sys.modules[name]
-
-
-def enabled():
-    """
-    Allow selection of distutils by environment variable.
-    """
-    which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'stdlib')
-    return which == 'local'
-
-
-def ensure_local_distutils():
-    clear_distutils()
-    distutils = importlib.import_module('setuptools._distutils')
-    distutils.__name__ = 'distutils'
-    sys.modules['distutils'] = distutils
-
-    # sanity check that submodules load as expected
-    core = importlib.import_module('distutils.core')
-    assert '_distutils' in core.__file__, core.__file__
-
-
-def do_override():
-    """
-    Ensure that the local copy of distutils is preferred over stdlib.
-
-    See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
-    for more motivation.
-    """
-    if enabled():
-        warn_distutils_present()
-        ensure_local_distutils()
-
-
-class DistutilsMetaFinder:
-    def find_spec(self, fullname, path, target=None):
-        if path is not None:
-            return
-
-        method_name = 'spec_for_{fullname}'.format(**locals())
-        method = getattr(self, method_name, lambda: None)
-        return method()
-
-    def spec_for_distutils(self):
-        import importlib.abc
-        import importlib.util
-
-        class DistutilsLoader(importlib.abc.Loader):
-
-            def create_module(self, spec):
-                return importlib.import_module('setuptools._distutils')
-
-            def exec_module(self, module):
-                pass
-
-        return importlib.util.spec_from_loader('distutils', DistutilsLoader())
-
-    def spec_for_pip(self):
-        """
-        Ensure stdlib distutils when running under pip.
-        See pypa/pip#8761 for rationale.
-        """
-        if self.pip_imported_during_build():
-            return
-        clear_distutils()
-        self.spec_for_distutils = lambda: None
-
-    @staticmethod
-    def pip_imported_during_build():
-        """
-        Detect if pip is being imported in a build script. Ref #2355.
-        """
-        import traceback
-        return any(
-            frame.f_globals['__file__'].endswith('setup.py')
-            for frame, line in traceback.walk_stack(None)
-        )
-
-
-DISTUTILS_FINDER = DistutilsMetaFinder()
-
-
-def add_shim():
-    sys.meta_path.insert(0, DISTUTILS_FINDER)
-
-
-def remove_shim():
-    try:
-        sys.meta_path.remove(DISTUTILS_FINDER)
-    except ValueError:
-        pass

+ 0 - 1
venv/lib/python3.10/site-packages/_distutils_hack/override.py

@@ -1 +0,0 @@
-__import__('_distutils_hack').do_override()

+ 0 - 1
venv/lib/python3.10/site-packages/click-8.1.3.dist-info/INSTALLER

@@ -1 +0,0 @@
-pip

+ 0 - 28
venv/lib/python3.10/site-packages/click-8.1.3.dist-info/LICENSE.rst

@@ -1,28 +0,0 @@
-Copyright 2014 Pallets
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1.  Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-2.  Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-3.  Neither the name of the copyright holder nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 111
venv/lib/python3.10/site-packages/click-8.1.3.dist-info/METADATA

@@ -1,111 +0,0 @@
-Metadata-Version: 2.1
-Name: click
-Version: 8.1.3
-Summary: Composable command line interface toolkit
-Home-page: https://palletsprojects.com/p/click/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-Maintainer: Pallets
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
-Project-URL: Donate, https://palletsprojects.com/donate
-Project-URL: Documentation, https://click.palletsprojects.com/
-Project-URL: Changes, https://click.palletsprojects.com/changes/
-Project-URL: Source Code, https://github.com/pallets/click/
-Project-URL: Issue Tracker, https://github.com/pallets/click/issues/
-Project-URL: Twitter, https://twitter.com/PalletsTeam
-Project-URL: Chat, https://discord.gg/pallets
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Requires-Python: >=3.7
-Description-Content-Type: text/x-rst
-License-File: LICENSE.rst
-Requires-Dist: colorama ; platform_system == "Windows"
-Requires-Dist: importlib-metadata ; python_version < "3.8"
-
-\$ click\_
-==========
-
-Click is a Python package for creating beautiful command line interfaces
-in a composable way with as little code as necessary. It's the "Command
-Line Interface Creation Kit". It's highly configurable but comes with
-sensible defaults out of the box.
-
-It aims to make the process of writing command line tools quick and fun
-while also preventing any frustration caused by the inability to
-implement an intended CLI API.
-
-Click in three points:
-
--   Arbitrary nesting of commands
--   Automatic help page generation
--   Supports lazy loading of subcommands at runtime
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
-    $ pip install -U click
-
-.. _pip: https://pip.pypa.io/en/stable/getting-started/
-
-
-A Simple Example
-----------------
-
-.. code-block:: python
-
-    import click
-
-    @click.command()
-    @click.option("--count", default=1, help="Number of greetings.")
-    @click.option("--name", prompt="Your name", help="The person to greet.")
-    def hello(count, name):
-        """Simple program that greets NAME for a total of COUNT times."""
-        for _ in range(count):
-            click.echo(f"Hello, {name}!")
-
-    if __name__ == '__main__':
-        hello()
-
-.. code-block:: text
-
-    $ python hello.py --count=3
-    Your name: Click
-    Hello, Click!
-    Hello, Click!
-    Hello, Click!
-
-
-Donate
-------
-
-The Pallets organization develops and supports Click and other popular
-packages. In order to grow the community of contributors and users, and
-allow the maintainers to devote more time to the projects, `please
-donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
--   Documentation: https://click.palletsprojects.com/
--   Changes: https://click.palletsprojects.com/changes/
--   PyPI Releases: https://pypi.org/project/click/
--   Source Code: https://github.com/pallets/click
--   Issue Tracker: https://github.com/pallets/click/issues
--   Website: https://palletsprojects.com/p/click
--   Twitter: https://twitter.com/PalletsTeam
--   Chat: https://discord.gg/pallets
-
-

+ 0 - 39
venv/lib/python3.10/site-packages/click-8.1.3.dist-info/RECORD

@@ -1,39 +0,0 @@
-click-8.1.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-click-8.1.3.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475
-click-8.1.3.dist-info/METADATA,sha256=tFJIX5lOjx7c5LjZbdTPFVDJSgyv9F74XY0XCPp_gnc,3247
-click-8.1.3.dist-info/RECORD,,
-click-8.1.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
-click-8.1.3.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6
-click/__init__.py,sha256=rQBLutqg-z6m8nOzivIfigDn_emijB_dKv9BZ2FNi5s,3138
-click/__pycache__/__init__.cpython-310.pyc,,
-click/__pycache__/_compat.cpython-310.pyc,,
-click/__pycache__/_termui_impl.cpython-310.pyc,,
-click/__pycache__/_textwrap.cpython-310.pyc,,
-click/__pycache__/_winconsole.cpython-310.pyc,,
-click/__pycache__/core.cpython-310.pyc,,
-click/__pycache__/decorators.cpython-310.pyc,,
-click/__pycache__/exceptions.cpython-310.pyc,,
-click/__pycache__/formatting.cpython-310.pyc,,
-click/__pycache__/globals.cpython-310.pyc,,
-click/__pycache__/parser.cpython-310.pyc,,
-click/__pycache__/shell_completion.cpython-310.pyc,,
-click/__pycache__/termui.cpython-310.pyc,,
-click/__pycache__/testing.cpython-310.pyc,,
-click/__pycache__/types.cpython-310.pyc,,
-click/__pycache__/utils.cpython-310.pyc,,
-click/_compat.py,sha256=JIHLYs7Jzz4KT9t-ds4o4jBzLjnwCiJQKqur-5iwCKI,18810
-click/_termui_impl.py,sha256=qK6Cfy4mRFxvxE8dya8RBhLpSC8HjF-lvBc6aNrPdwg,23451
-click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353
-click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860
-click/core.py,sha256=mz87bYEKzIoNYEa56BFAiOJnvt1Y0L-i7wD4_ZecieE,112782
-click/decorators.py,sha256=yo3zvzgUm5q7h5CXjyV6q3h_PJAiUaem178zXwdWUFI,16350
-click/exceptions.py,sha256=7gDaLGuFZBeCNwY9ERMsF2-Z3R9Fvq09Zc6IZSKjseo,9167
-click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706
-click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961
-click/parser.py,sha256=cAEt1uQR8gq3-S9ysqbVU-fdAZNvilxw4ReJ_T1OQMk,19044
-click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-click/shell_completion.py,sha256=qOp_BeC9esEOSZKyu5G7RIxEUaLsXUX-mTb7hB1r4QY,18018
-click/termui.py,sha256=ACBQVOvFCTSqtD5VREeCAdRtlHd-Imla-Lte4wSfMjA,28355
-click/testing.py,sha256=ptpMYgRY7dVfE3UDgkgwayu9ePw98sQI3D7zZXiCpj4,16063
-click/types.py,sha256=rEb1aZSQKq3ciCMmjpG2Uva9vk498XRL7ThrcK2GRss,35805
-click/utils.py,sha256=33D6E7poH_nrKB-xr-UyDEXnxOcCiQqxuRLtrqeVv6o,18682

+ 0 - 5
venv/lib/python3.10/site-packages/click-8.1.3.dist-info/WHEEL

@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.1)
-Root-Is-Purelib: true
-Tag: py3-none-any
-

+ 0 - 1
venv/lib/python3.10/site-packages/click-8.1.3.dist-info/top_level.txt

@@ -1 +0,0 @@
-click

+ 0 - 73
venv/lib/python3.10/site-packages/click/__init__.py

@@ -1,73 +0,0 @@
-"""
-Click is a simple Python module inspired by the stdlib optparse to make
-writing command line scripts fun. Unlike other modules, it's based
-around a simple API that does not come with too much magic and is
-composable.
-"""
-from .core import Argument as Argument
-from .core import BaseCommand as BaseCommand
-from .core import Command as Command
-from .core import CommandCollection as CommandCollection
-from .core import Context as Context
-from .core import Group as Group
-from .core import MultiCommand as MultiCommand
-from .core import Option as Option
-from .core import Parameter as Parameter
-from .decorators import argument as argument
-from .decorators import command as command
-from .decorators import confirmation_option as confirmation_option
-from .decorators import group as group
-from .decorators import help_option as help_option
-from .decorators import make_pass_decorator as make_pass_decorator
-from .decorators import option as option
-from .decorators import pass_context as pass_context
-from .decorators import pass_obj as pass_obj
-from .decorators import password_option as password_option
-from .decorators import version_option as version_option
-from .exceptions import Abort as Abort
-from .exceptions import BadArgumentUsage as BadArgumentUsage
-from .exceptions import BadOptionUsage as BadOptionUsage
-from .exceptions import BadParameter as BadParameter
-from .exceptions import ClickException as ClickException
-from .exceptions import FileError as FileError
-from .exceptions import MissingParameter as MissingParameter
-from .exceptions import NoSuchOption as NoSuchOption
-from .exceptions import UsageError as UsageError
-from .formatting import HelpFormatter as HelpFormatter
-from .formatting import wrap_text as wrap_text
-from .globals import get_current_context as get_current_context
-from .parser import OptionParser as OptionParser
-from .termui import clear as clear
-from .termui import confirm as confirm
-from .termui import echo_via_pager as echo_via_pager
-from .termui import edit as edit
-from .termui import getchar as getchar
-from .termui import launch as launch
-from .termui import pause as pause
-from .termui import progressbar as progressbar
-from .termui import prompt as prompt
-from .termui import secho as secho
-from .termui import style as style
-from .termui import unstyle as unstyle
-from .types import BOOL as BOOL
-from .types import Choice as Choice
-from .types import DateTime as DateTime
-from .types import File as File
-from .types import FLOAT as FLOAT
-from .types import FloatRange as FloatRange
-from .types import INT as INT
-from .types import IntRange as IntRange
-from .types import ParamType as ParamType
-from .types import Path as Path
-from .types import STRING as STRING
-from .types import Tuple as Tuple
-from .types import UNPROCESSED as UNPROCESSED
-from .types import UUID as UUID
-from .utils import echo as echo
-from .utils import format_filename as format_filename
-from .utils import get_app_dir as get_app_dir
-from .utils import get_binary_stream as get_binary_stream
-from .utils import get_text_stream as get_text_stream
-from .utils import open_file as open_file
-
-__version__ = "8.1.3"

+ 0 - 626
venv/lib/python3.10/site-packages/click/_compat.py

@@ -1,626 +0,0 @@
-import codecs
-import io
-import os
-import re
-import sys
-import typing as t
-from weakref import WeakKeyDictionary
-
-CYGWIN = sys.platform.startswith("cygwin")
-MSYS2 = sys.platform.startswith("win") and ("GCC" in sys.version)
-# Determine local App Engine environment, per Google's own suggestion
-APP_ENGINE = "APPENGINE_RUNTIME" in os.environ and "Development/" in os.environ.get(
-    "SERVER_SOFTWARE", ""
-)
-WIN = sys.platform.startswith("win") and not APP_ENGINE and not MSYS2
-auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None
-_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]")
-
-
-def get_filesystem_encoding() -> str:
-    return sys.getfilesystemencoding() or sys.getdefaultencoding()
-
-
-def _make_text_stream(
-    stream: t.BinaryIO,
-    encoding: t.Optional[str],
-    errors: t.Optional[str],
-    force_readable: bool = False,
-    force_writable: bool = False,
-) -> t.TextIO:
-    if encoding is None:
-        encoding = get_best_encoding(stream)
-    if errors is None:
-        errors = "replace"
-    return _NonClosingTextIOWrapper(
-        stream,
-        encoding,
-        errors,
-        line_buffering=True,
-        force_readable=force_readable,
-        force_writable=force_writable,
-    )
-
-
-def is_ascii_encoding(encoding: str) -> bool:
-    """Checks if a given encoding is ascii."""
-    try:
-        return codecs.lookup(encoding).name == "ascii"
-    except LookupError:
-        return False
-
-
-def get_best_encoding(stream: t.IO) -> str:
-    """Returns the default stream encoding if not found."""
-    rv = getattr(stream, "encoding", None) or sys.getdefaultencoding()
-    if is_ascii_encoding(rv):
-        return "utf-8"
-    return rv
-
-
-class _NonClosingTextIOWrapper(io.TextIOWrapper):
-    def __init__(
-        self,
-        stream: t.BinaryIO,
-        encoding: t.Optional[str],
-        errors: t.Optional[str],
-        force_readable: bool = False,
-        force_writable: bool = False,
-        **extra: t.Any,
-    ) -> None:
-        self._stream = stream = t.cast(
-            t.BinaryIO, _FixupStream(stream, force_readable, force_writable)
-        )
-        super().__init__(stream, encoding, errors, **extra)
-
-    def __del__(self) -> None:
-        try:
-            self.detach()
-        except Exception:
-            pass
-
-    def isatty(self) -> bool:
-        # https://bitbucket.org/pypy/pypy/issue/1803
-        return self._stream.isatty()
-
-
-class _FixupStream:
-    """The new io interface needs more from streams than streams
-    traditionally implement.  As such, this fix-up code is necessary in
-    some circumstances.
-
-    The forcing of readable and writable flags are there because some tools
-    put badly patched objects on sys (one such offender are certain version
-    of jupyter notebook).
-    """
-
-    def __init__(
-        self,
-        stream: t.BinaryIO,
-        force_readable: bool = False,
-        force_writable: bool = False,
-    ):
-        self._stream = stream
-        self._force_readable = force_readable
-        self._force_writable = force_writable
-
-    def __getattr__(self, name: str) -> t.Any:
-        return getattr(self._stream, name)
-
-    def read1(self, size: int) -> bytes:
-        f = getattr(self._stream, "read1", None)
-
-        if f is not None:
-            return t.cast(bytes, f(size))
-
-        return self._stream.read(size)
-
-    def readable(self) -> bool:
-        if self._force_readable:
-            return True
-        x = getattr(self._stream, "readable", None)
-        if x is not None:
-            return t.cast(bool, x())
-        try:
-            self._stream.read(0)
-        except Exception:
-            return False
-        return True
-
-    def writable(self) -> bool:
-        if self._force_writable:
-            return True
-        x = getattr(self._stream, "writable", None)
-        if x is not None:
-            return t.cast(bool, x())
-        try:
-            self._stream.write("")  # type: ignore
-        except Exception:
-            try:
-                self._stream.write(b"")
-            except Exception:
-                return False
-        return True
-
-    def seekable(self) -> bool:
-        x = getattr(self._stream, "seekable", None)
-        if x is not None:
-            return t.cast(bool, x())
-        try:
-            self._stream.seek(self._stream.tell())
-        except Exception:
-            return False
-        return True
-
-
-def _is_binary_reader(stream: t.IO, default: bool = False) -> bool:
-    try:
-        return isinstance(stream.read(0), bytes)
-    except Exception:
-        return default
-        # This happens in some cases where the stream was already
-        # closed.  In this case, we assume the default.
-
-
-def _is_binary_writer(stream: t.IO, default: bool = False) -> bool:
-    try:
-        stream.write(b"")
-    except Exception:
-        try:
-            stream.write("")
-            return False
-        except Exception:
-            pass
-        return default
-    return True
-
-
-def _find_binary_reader(stream: t.IO) -> t.Optional[t.BinaryIO]:
-    # We need to figure out if the given stream is already binary.
-    # This can happen because the official docs recommend detaching
-    # the streams to get binary streams.  Some code might do this, so
-    # we need to deal with this case explicitly.
-    if _is_binary_reader(stream, False):
-        return t.cast(t.BinaryIO, stream)
-
-    buf = getattr(stream, "buffer", None)
-
-    # Same situation here; this time we assume that the buffer is
-    # actually binary in case it's closed.
-    if buf is not None and _is_binary_reader(buf, True):
-        return t.cast(t.BinaryIO, buf)
-
-    return None
-
-
-def _find_binary_writer(stream: t.IO) -> t.Optional[t.BinaryIO]:
-    # We need to figure out if the given stream is already binary.
-    # This can happen because the official docs recommend detaching
-    # the streams to get binary streams.  Some code might do this, so
-    # we need to deal with this case explicitly.
-    if _is_binary_writer(stream, False):
-        return t.cast(t.BinaryIO, stream)
-
-    buf = getattr(stream, "buffer", None)
-
-    # Same situation here; this time we assume that the buffer is
-    # actually binary in case it's closed.
-    if buf is not None and _is_binary_writer(buf, True):
-        return t.cast(t.BinaryIO, buf)
-
-    return None
-
-
-def _stream_is_misconfigured(stream: t.TextIO) -> bool:
-    """A stream is misconfigured if its encoding is ASCII."""
-    # If the stream does not have an encoding set, we assume it's set
-    # to ASCII.  This appears to happen in certain unittest
-    # environments.  It's not quite clear what the correct behavior is
-    # but this at least will force Click to recover somehow.
-    return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii")
-
-
-def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool:
-    """A stream attribute is compatible if it is equal to the
-    desired value or the desired value is unset and the attribute
-    has a value.
-    """
-    stream_value = getattr(stream, attr, None)
-    return stream_value == value or (value is None and stream_value is not None)
-
-
-def _is_compatible_text_stream(
-    stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
-) -> bool:
-    """Check if a stream's encoding and errors attributes are
-    compatible with the desired values.
-    """
-    return _is_compat_stream_attr(
-        stream, "encoding", encoding
-    ) and _is_compat_stream_attr(stream, "errors", errors)
-
-
-def _force_correct_text_stream(
-    text_stream: t.IO,
-    encoding: t.Optional[str],
-    errors: t.Optional[str],
-    is_binary: t.Callable[[t.IO, bool], bool],
-    find_binary: t.Callable[[t.IO], t.Optional[t.BinaryIO]],
-    force_readable: bool = False,
-    force_writable: bool = False,
-) -> t.TextIO:
-    if is_binary(text_stream, False):
-        binary_reader = t.cast(t.BinaryIO, text_stream)
-    else:
-        text_stream = t.cast(t.TextIO, text_stream)
-        # If the stream looks compatible, and won't default to a
-        # misconfigured ascii encoding, return it as-is.
-        if _is_compatible_text_stream(text_stream, encoding, errors) and not (
-            encoding is None and _stream_is_misconfigured(text_stream)
-        ):
-            return text_stream
-
-        # Otherwise, get the underlying binary reader.
-        possible_binary_reader = find_binary(text_stream)
-
-        # If that's not possible, silently use the original reader
-        # and get mojibake instead of exceptions.
-        if possible_binary_reader is None:
-            return text_stream
-
-        binary_reader = possible_binary_reader
-
-    # Default errors to replace instead of strict in order to get
-    # something that works.
-    if errors is None:
-        errors = "replace"
-
-    # Wrap the binary stream in a text stream with the correct
-    # encoding parameters.
-    return _make_text_stream(
-        binary_reader,
-        encoding,
-        errors,
-        force_readable=force_readable,
-        force_writable=force_writable,
-    )
-
-
-def _force_correct_text_reader(
-    text_reader: t.IO,
-    encoding: t.Optional[str],
-    errors: t.Optional[str],
-    force_readable: bool = False,
-) -> t.TextIO:
-    return _force_correct_text_stream(
-        text_reader,
-        encoding,
-        errors,
-        _is_binary_reader,
-        _find_binary_reader,
-        force_readable=force_readable,
-    )
-
-
-def _force_correct_text_writer(
-    text_writer: t.IO,
-    encoding: t.Optional[str],
-    errors: t.Optional[str],
-    force_writable: bool = False,
-) -> t.TextIO:
-    return _force_correct_text_stream(
-        text_writer,
-        encoding,
-        errors,
-        _is_binary_writer,
-        _find_binary_writer,
-        force_writable=force_writable,
-    )
-
-
-def get_binary_stdin() -> t.BinaryIO:
-    reader = _find_binary_reader(sys.stdin)
-    if reader is None:
-        raise RuntimeError("Was not able to determine binary stream for sys.stdin.")
-    return reader
-
-
-def get_binary_stdout() -> t.BinaryIO:
-    writer = _find_binary_writer(sys.stdout)
-    if writer is None:
-        raise RuntimeError("Was not able to determine binary stream for sys.stdout.")
-    return writer
-
-
-def get_binary_stderr() -> t.BinaryIO:
-    writer = _find_binary_writer(sys.stderr)
-    if writer is None:
-        raise RuntimeError("Was not able to determine binary stream for sys.stderr.")
-    return writer
-
-
-def get_text_stdin(
-    encoding: t.Optional[str] = None, errors: t.Optional[str] = None
-) -> t.TextIO:
-    rv = _get_windows_console_stream(sys.stdin, encoding, errors)
-    if rv is not None:
-        return rv
-    return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True)
-
-
-def get_text_stdout(
-    encoding: t.Optional[str] = None, errors: t.Optional[str] = None
-) -> t.TextIO:
-    rv = _get_windows_console_stream(sys.stdout, encoding, errors)
-    if rv is not None:
-        return rv
-    return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True)
-
-
-def get_text_stderr(
-    encoding: t.Optional[str] = None, errors: t.Optional[str] = None
-) -> t.TextIO:
-    rv = _get_windows_console_stream(sys.stderr, encoding, errors)
-    if rv is not None:
-        return rv
-    return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True)
-
-
-def _wrap_io_open(
-    file: t.Union[str, os.PathLike, int],
-    mode: str,
-    encoding: t.Optional[str],
-    errors: t.Optional[str],
-) -> t.IO:
-    """Handles not passing ``encoding`` and ``errors`` in binary mode."""
-    if "b" in mode:
-        return open(file, mode)
-
-    return open(file, mode, encoding=encoding, errors=errors)
-
-
-def open_stream(
-    filename: str,
-    mode: str = "r",
-    encoding: t.Optional[str] = None,
-    errors: t.Optional[str] = "strict",
-    atomic: bool = False,
-) -> t.Tuple[t.IO, bool]:
-    binary = "b" in mode
-
-    # Standard streams first. These are simple because they ignore the
-    # atomic flag. Use fsdecode to handle Path("-").
-    if os.fsdecode(filename) == "-":
-        if any(m in mode for m in ["w", "a", "x"]):
-            if binary:
-                return get_binary_stdout(), False
-            return get_text_stdout(encoding=encoding, errors=errors), False
-        if binary:
-            return get_binary_stdin(), False
-        return get_text_stdin(encoding=encoding, errors=errors), False
-
-    # Non-atomic writes directly go out through the regular open functions.
-    if not atomic:
-        return _wrap_io_open(filename, mode, encoding, errors), True
-
-    # Some usability stuff for atomic writes
-    if "a" in mode:
-        raise ValueError(
-            "Appending to an existing file is not supported, because that"
-            " would involve an expensive `copy`-operation to a temporary"
-            " file. Open the file in normal `w`-mode and copy explicitly"
-            " if that's what you're after."
-        )
-    if "x" in mode:
-        raise ValueError("Use the `overwrite`-parameter instead.")
-    if "w" not in mode:
-        raise ValueError("Atomic writes only make sense with `w`-mode.")
-
-    # Atomic writes are more complicated.  They work by opening a file
-    # as a proxy in the same folder and then using the fdopen
-    # functionality to wrap it in a Python file.  Then we wrap it in an
-    # atomic file that moves the file over on close.
-    import errno
-    import random
-
-    try:
-        perm: t.Optional[int] = os.stat(filename).st_mode
-    except OSError:
-        perm = None
-
-    flags = os.O_RDWR | os.O_CREAT | os.O_EXCL
-
-    if binary:
-        flags |= getattr(os, "O_BINARY", 0)
-
-    while True:
-        tmp_filename = os.path.join(
-            os.path.dirname(filename),
-            f".__atomic-write{random.randrange(1 << 32):08x}",
-        )
-        try:
-            fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm)
-            break
-        except OSError as e:
-            if e.errno == errno.EEXIST or (
-                os.name == "nt"
-                and e.errno == errno.EACCES
-                and os.path.isdir(e.filename)
-                and os.access(e.filename, os.W_OK)
-            ):
-                continue
-            raise
-
-    if perm is not None:
-        os.chmod(tmp_filename, perm)  # in case perm includes bits in umask
-
-    f = _wrap_io_open(fd, mode, encoding, errors)
-    af = _AtomicFile(f, tmp_filename, os.path.realpath(filename))
-    return t.cast(t.IO, af), True
-
-
-class _AtomicFile:
-    def __init__(self, f: t.IO, tmp_filename: str, real_filename: str) -> None:
-        self._f = f
-        self._tmp_filename = tmp_filename
-        self._real_filename = real_filename
-        self.closed = False
-
-    @property
-    def name(self) -> str:
-        return self._real_filename
-
-    def close(self, delete: bool = False) -> None:
-        if self.closed:
-            return
-        self._f.close()
-        os.replace(self._tmp_filename, self._real_filename)
-        self.closed = True
-
-    def __getattr__(self, name: str) -> t.Any:
-        return getattr(self._f, name)
-
-    def __enter__(self) -> "_AtomicFile":
-        return self
-
-    def __exit__(self, exc_type, exc_value, tb):  # type: ignore
-        self.close(delete=exc_type is not None)
-
-    def __repr__(self) -> str:
-        return repr(self._f)
-
-
-def strip_ansi(value: str) -> str:
-    return _ansi_re.sub("", value)
-
-
-def _is_jupyter_kernel_output(stream: t.IO) -> bool:
-    while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)):
-        stream = stream._stream
-
-    return stream.__class__.__module__.startswith("ipykernel.")
-
-
-def should_strip_ansi(
-    stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None
-) -> bool:
-    if color is None:
-        if stream is None:
-            stream = sys.stdin
-        return not isatty(stream) and not _is_jupyter_kernel_output(stream)
-    return not color
-
-
-# On Windows, wrap the output streams with colorama to support ANSI
-# color codes.
-# NOTE: double check is needed so mypy does not analyze this on Linux
-if sys.platform.startswith("win") and WIN:
-    from ._winconsole import _get_windows_console_stream
-
-    def _get_argv_encoding() -> str:
-        import locale
-
-        return locale.getpreferredencoding()
-
-    _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
-
-    def auto_wrap_for_ansi(
-        stream: t.TextIO, color: t.Optional[bool] = None
-    ) -> t.TextIO:
-        """Support ANSI color and style codes on Windows by wrapping a
-        stream with colorama.
-        """
-        try:
-            cached = _ansi_stream_wrappers.get(stream)
-        except Exception:
-            cached = None
-
-        if cached is not None:
-            return cached
-
-        import colorama
-
-        strip = should_strip_ansi(stream, color)
-        ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip)
-        rv = t.cast(t.TextIO, ansi_wrapper.stream)
-        _write = rv.write
-
-        def _safe_write(s):
-            try:
-                return _write(s)
-            except BaseException:
-                ansi_wrapper.reset_all()
-                raise
-
-        rv.write = _safe_write
-
-        try:
-            _ansi_stream_wrappers[stream] = rv
-        except Exception:
-            pass
-
-        return rv
-
-else:
-
-    def _get_argv_encoding() -> str:
-        return getattr(sys.stdin, "encoding", None) or get_filesystem_encoding()
-
-    def _get_windows_console_stream(
-        f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
-    ) -> t.Optional[t.TextIO]:
-        return None
-
-
-def term_len(x: str) -> int:
-    return len(strip_ansi(x))
-
-
-def isatty(stream: t.IO) -> bool:
-    try:
-        return stream.isatty()
-    except Exception:
-        return False
-
-
-def _make_cached_stream_func(
-    src_func: t.Callable[[], t.TextIO], wrapper_func: t.Callable[[], t.TextIO]
-) -> t.Callable[[], t.TextIO]:
-    cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary()
-
-    def func() -> t.TextIO:
-        stream = src_func()
-        try:
-            rv = cache.get(stream)
-        except Exception:
-            rv = None
-        if rv is not None:
-            return rv
-        rv = wrapper_func()
-        try:
-            cache[stream] = rv
-        except Exception:
-            pass
-        return rv
-
-    return func
-
-
-_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin)
-_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout)
-_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr)
-
-
-binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = {
-    "stdin": get_binary_stdin,
-    "stdout": get_binary_stdout,
-    "stderr": get_binary_stderr,
-}
-
-text_streams: t.Mapping[
-    str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO]
-] = {
-    "stdin": get_text_stdin,
-    "stdout": get_text_stdout,
-    "stderr": get_text_stderr,
-}

+ 0 - 717
venv/lib/python3.10/site-packages/click/_termui_impl.py

@@ -1,717 +0,0 @@
-"""
-This module contains implementations for the termui module. To keep the
-import time of Click down, some infrequently used functionality is
-placed in this module and only imported as needed.
-"""
-import contextlib
-import math
-import os
-import sys
-import time
-import typing as t
-from gettext import gettext as _
-
-from ._compat import _default_text_stdout
-from ._compat import CYGWIN
-from ._compat import get_best_encoding
-from ._compat import isatty
-from ._compat import open_stream
-from ._compat import strip_ansi
-from ._compat import term_len
-from ._compat import WIN
-from .exceptions import ClickException
-from .utils import echo
-
-V = t.TypeVar("V")
-
-if os.name == "nt":
-    BEFORE_BAR = "\r"
-    AFTER_BAR = "\n"
-else:
-    BEFORE_BAR = "\r\033[?25l"
-    AFTER_BAR = "\033[?25h\n"
-
-
-class ProgressBar(t.Generic[V]):
-    def __init__(
-        self,
-        iterable: t.Optional[t.Iterable[V]],
-        length: t.Optional[int] = None,
-        fill_char: str = "#",
-        empty_char: str = " ",
-        bar_template: str = "%(bar)s",
-        info_sep: str = "  ",
-        show_eta: bool = True,
-        show_percent: t.Optional[bool] = None,
-        show_pos: bool = False,
-        item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None,
-        label: t.Optional[str] = None,
-        file: t.Optional[t.TextIO] = None,
-        color: t.Optional[bool] = None,
-        update_min_steps: int = 1,
-        width: int = 30,
-    ) -> None:
-        self.fill_char = fill_char
-        self.empty_char = empty_char
-        self.bar_template = bar_template
-        self.info_sep = info_sep
-        self.show_eta = show_eta
-        self.show_percent = show_percent
-        self.show_pos = show_pos
-        self.item_show_func = item_show_func
-        self.label = label or ""
-        if file is None:
-            file = _default_text_stdout()
-        self.file = file
-        self.color = color
-        self.update_min_steps = update_min_steps
-        self._completed_intervals = 0
-        self.width = width
-        self.autowidth = width == 0
-
-        if length is None:
-            from operator import length_hint
-
-            length = length_hint(iterable, -1)
-
-            if length == -1:
-                length = None
-        if iterable is None:
-            if length is None:
-                raise TypeError("iterable or length is required")
-            iterable = t.cast(t.Iterable[V], range(length))
-        self.iter = iter(iterable)
-        self.length = length
-        self.pos = 0
-        self.avg: t.List[float] = []
-        self.start = self.last_eta = time.time()
-        self.eta_known = False
-        self.finished = False
-        self.max_width: t.Optional[int] = None
-        self.entered = False
-        self.current_item: t.Optional[V] = None
-        self.is_hidden = not isatty(self.file)
-        self._last_line: t.Optional[str] = None
-
-    def __enter__(self) -> "ProgressBar":
-        self.entered = True
-        self.render_progress()
-        return self
-
-    def __exit__(self, exc_type, exc_value, tb):  # type: ignore
-        self.render_finish()
-
-    def __iter__(self) -> t.Iterator[V]:
-        if not self.entered:
-            raise RuntimeError("You need to use progress bars in a with block.")
-        self.render_progress()
-        return self.generator()
-
-    def __next__(self) -> V:
-        # Iteration is defined in terms of a generator function,
-        # returned by iter(self); use that to define next(). This works
-        # because `self.iter` is an iterable consumed by that generator,
-        # so it is re-entry safe. Calling `next(self.generator())`
-        # twice works and does "what you want".
-        return next(iter(self))
-
-    def render_finish(self) -> None:
-        if self.is_hidden:
-            return
-        self.file.write(AFTER_BAR)
-        self.file.flush()
-
-    @property
-    def pct(self) -> float:
-        if self.finished:
-            return 1.0
-        return min(self.pos / (float(self.length or 1) or 1), 1.0)
-
-    @property
-    def time_per_iteration(self) -> float:
-        if not self.avg:
-            return 0.0
-        return sum(self.avg) / float(len(self.avg))
-
-    @property
-    def eta(self) -> float:
-        if self.length is not None and not self.finished:
-            return self.time_per_iteration * (self.length - self.pos)
-        return 0.0
-
-    def format_eta(self) -> str:
-        if self.eta_known:
-            t = int(self.eta)
-            seconds = t % 60
-            t //= 60
-            minutes = t % 60
-            t //= 60
-            hours = t % 24
-            t //= 24
-            if t > 0:
-                return f"{t}d {hours:02}:{minutes:02}:{seconds:02}"
-            else:
-                return f"{hours:02}:{minutes:02}:{seconds:02}"
-        return ""
-
-    def format_pos(self) -> str:
-        pos = str(self.pos)
-        if self.length is not None:
-            pos += f"/{self.length}"
-        return pos
-
-    def format_pct(self) -> str:
-        return f"{int(self.pct * 100): 4}%"[1:]
-
-    def format_bar(self) -> str:
-        if self.length is not None:
-            bar_length = int(self.pct * self.width)
-            bar = self.fill_char * bar_length
-            bar += self.empty_char * (self.width - bar_length)
-        elif self.finished:
-            bar = self.fill_char * self.width
-        else:
-            chars = list(self.empty_char * (self.width or 1))
-            if self.time_per_iteration != 0:
-                chars[
-                    int(
-                        (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5)
-                        * self.width
-                    )
-                ] = self.fill_char
-            bar = "".join(chars)
-        return bar
-
-    def format_progress_line(self) -> str:
-        show_percent = self.show_percent
-
-        info_bits = []
-        if self.length is not None and show_percent is None:
-            show_percent = not self.show_pos
-
-        if self.show_pos:
-            info_bits.append(self.format_pos())
-        if show_percent:
-            info_bits.append(self.format_pct())
-        if self.show_eta and self.eta_known and not self.finished:
-            info_bits.append(self.format_eta())
-        if self.item_show_func is not None:
-            item_info = self.item_show_func(self.current_item)
-            if item_info is not None:
-                info_bits.append(item_info)
-
-        return (
-            self.bar_template
-            % {
-                "label": self.label,
-                "bar": self.format_bar(),
-                "info": self.info_sep.join(info_bits),
-            }
-        ).rstrip()
-
-    def render_progress(self) -> None:
-        import shutil
-
-        if self.is_hidden:
-            # Only output the label as it changes if the output is not a
-            # TTY. Use file=stderr if you expect to be piping stdout.
-            if self._last_line != self.label:
-                self._last_line = self.label
-                echo(self.label, file=self.file, color=self.color)
-
-            return
-
-        buf = []
-        # Update width in case the terminal has been resized
-        if self.autowidth:
-            old_width = self.width
-            self.width = 0
-            clutter_length = term_len(self.format_progress_line())
-            new_width = max(0, shutil.get_terminal_size().columns - clutter_length)
-            if new_width < old_width:
-                buf.append(BEFORE_BAR)
-                buf.append(" " * self.max_width)  # type: ignore
-                self.max_width = new_width
-            self.width = new_width
-
-        clear_width = self.width
-        if self.max_width is not None:
-            clear_width = self.max_width
-
-        buf.append(BEFORE_BAR)
-        line = self.format_progress_line()
-        line_len = term_len(line)
-        if self.max_width is None or self.max_width < line_len:
-            self.max_width = line_len
-
-        buf.append(line)
-        buf.append(" " * (clear_width - line_len))
-        line = "".join(buf)
-        # Render the line only if it changed.
-
-        if line != self._last_line:
-            self._last_line = line
-            echo(line, file=self.file, color=self.color, nl=False)
-            self.file.flush()
-
-    def make_step(self, n_steps: int) -> None:
-        self.pos += n_steps
-        if self.length is not None and self.pos >= self.length:
-            self.finished = True
-
-        if (time.time() - self.last_eta) < 1.0:
-            return
-
-        self.last_eta = time.time()
-
-        # self.avg is a rolling list of length <= 7 of steps where steps are
-        # defined as time elapsed divided by the total progress through
-        # self.length.
-        if self.pos:
-            step = (time.time() - self.start) / self.pos
-        else:
-            step = time.time() - self.start
-
-        self.avg = self.avg[-6:] + [step]
-
-        self.eta_known = self.length is not None
-
-    def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None:
-        """Update the progress bar by advancing a specified number of
-        steps, and optionally set the ``current_item`` for this new
-        position.
-
-        :param n_steps: Number of steps to advance.
-        :param current_item: Optional item to set as ``current_item``
-            for the updated position.
-
-        .. versionchanged:: 8.0
-            Added the ``current_item`` optional parameter.
-
-        .. versionchanged:: 8.0
-            Only render when the number of steps meets the
-            ``update_min_steps`` threshold.
-        """
-        if current_item is not None:
-            self.current_item = current_item
-
-        self._completed_intervals += n_steps
-
-        if self._completed_intervals >= self.update_min_steps:
-            self.make_step(self._completed_intervals)
-            self.render_progress()
-            self._completed_intervals = 0
-
-    def finish(self) -> None:
-        self.eta_known = False
-        self.current_item = None
-        self.finished = True
-
-    def generator(self) -> t.Iterator[V]:
-        """Return a generator which yields the items added to the bar
-        during construction, and updates the progress bar *after* the
-        yielded block returns.
-        """
-        # WARNING: the iterator interface for `ProgressBar` relies on
-        # this and only works because this is a simple generator which
-        # doesn't create or manage additional state. If this function
-        # changes, the impact should be evaluated both against
-        # `iter(bar)` and `next(bar)`. `next()` in particular may call
-        # `self.generator()` repeatedly, and this must remain safe in
-        # order for that interface to work.
-        if not self.entered:
-            raise RuntimeError("You need to use progress bars in a with block.")
-
-        if self.is_hidden:
-            yield from self.iter
-        else:
-            for rv in self.iter:
-                self.current_item = rv
-
-                # This allows show_item_func to be updated before the
-                # item is processed. Only trigger at the beginning of
-                # the update interval.
-                if self._completed_intervals == 0:
-                    self.render_progress()
-
-                yield rv
-                self.update(1)
-
-            self.finish()
-            self.render_progress()
-
-
-def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None:
-    """Decide what method to use for paging through text."""
-    stdout = _default_text_stdout()
-    if not isatty(sys.stdin) or not isatty(stdout):
-        return _nullpager(stdout, generator, color)
-    pager_cmd = (os.environ.get("PAGER", None) or "").strip()
-    if pager_cmd:
-        if WIN:
-            return _tempfilepager(generator, pager_cmd, color)
-        return _pipepager(generator, pager_cmd, color)
-    if os.environ.get("TERM") in ("dumb", "emacs"):
-        return _nullpager(stdout, generator, color)
-    if WIN or sys.platform.startswith("os2"):
-        return _tempfilepager(generator, "more <", color)
-    if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0:
-        return _pipepager(generator, "less", color)
-
-    import tempfile
-
-    fd, filename = tempfile.mkstemp()
-    os.close(fd)
-    try:
-        if hasattr(os, "system") and os.system(f'more "{filename}"') == 0:
-            return _pipepager(generator, "more", color)
-        return _nullpager(stdout, generator, color)
-    finally:
-        os.unlink(filename)
-
-
-def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None:
-    """Page through text by feeding it to another program.  Invoking a
-    pager through this might support colors.
-    """
-    import subprocess
-
-    env = dict(os.environ)
-
-    # If we're piping to less we might support colors under the
-    # condition that
-    cmd_detail = cmd.rsplit("/", 1)[-1].split()
-    if color is None and cmd_detail[0] == "less":
-        less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}"
-        if not less_flags:
-            env["LESS"] = "-R"
-            color = True
-        elif "r" in less_flags or "R" in less_flags:
-            color = True
-
-    c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env)
-    stdin = t.cast(t.BinaryIO, c.stdin)
-    encoding = get_best_encoding(stdin)
-    try:
-        for text in generator:
-            if not color:
-                text = strip_ansi(text)
-
-            stdin.write(text.encode(encoding, "replace"))
-    except (OSError, KeyboardInterrupt):
-        pass
-    else:
-        stdin.close()
-
-    # Less doesn't respect ^C, but catches it for its own UI purposes (aborting
-    # search or other commands inside less).
-    #
-    # That means when the user hits ^C, the parent process (click) terminates,
-    # but less is still alive, paging the output and messing up the terminal.
-    #
-    # If the user wants to make the pager exit on ^C, they should set
-    # `LESS='-K'`. It's not our decision to make.
-    while True:
-        try:
-            c.wait()
-        except KeyboardInterrupt:
-            pass
-        else:
-            break
-
-
-def _tempfilepager(
-    generator: t.Iterable[str], cmd: str, color: t.Optional[bool]
-) -> None:
-    """Page through text by invoking a program on a temporary file."""
-    import tempfile
-
-    fd, filename = tempfile.mkstemp()
-    # TODO: This never terminates if the passed generator never terminates.
-    text = "".join(generator)
-    if not color:
-        text = strip_ansi(text)
-    encoding = get_best_encoding(sys.stdout)
-    with open_stream(filename, "wb")[0] as f:
-        f.write(text.encode(encoding))
-    try:
-        os.system(f'{cmd} "{filename}"')
-    finally:
-        os.close(fd)
-        os.unlink(filename)
-
-
-def _nullpager(
-    stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool]
-) -> None:
-    """Simply print unformatted text.  This is the ultimate fallback."""
-    for text in generator:
-        if not color:
-            text = strip_ansi(text)
-        stream.write(text)
-
-
-class Editor:
-    def __init__(
-        self,
-        editor: t.Optional[str] = None,
-        env: t.Optional[t.Mapping[str, str]] = None,
-        require_save: bool = True,
-        extension: str = ".txt",
-    ) -> None:
-        self.editor = editor
-        self.env = env
-        self.require_save = require_save
-        self.extension = extension
-
-    def get_editor(self) -> str:
-        if self.editor is not None:
-            return self.editor
-        for key in "VISUAL", "EDITOR":
-            rv = os.environ.get(key)
-            if rv:
-                return rv
-        if WIN:
-            return "notepad"
-        for editor in "sensible-editor", "vim", "nano":
-            if os.system(f"which {editor} >/dev/null 2>&1") == 0:
-                return editor
-        return "vi"
-
-    def edit_file(self, filename: str) -> None:
-        import subprocess
-
-        editor = self.get_editor()
-        environ: t.Optional[t.Dict[str, str]] = None
-
-        if self.env:
-            environ = os.environ.copy()
-            environ.update(self.env)
-
-        try:
-            c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True)
-            exit_code = c.wait()
-            if exit_code != 0:
-                raise ClickException(
-                    _("{editor}: Editing failed").format(editor=editor)
-                )
-        except OSError as e:
-            raise ClickException(
-                _("{editor}: Editing failed: {e}").format(editor=editor, e=e)
-            ) from e
-
-    def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]:
-        import tempfile
-
-        if not text:
-            data = b""
-        elif isinstance(text, (bytes, bytearray)):
-            data = text
-        else:
-            if text and not text.endswith("\n"):
-                text += "\n"
-
-            if WIN:
-                data = text.replace("\n", "\r\n").encode("utf-8-sig")
-            else:
-                data = text.encode("utf-8")
-
-        fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension)
-        f: t.BinaryIO
-
-        try:
-            with os.fdopen(fd, "wb") as f:
-                f.write(data)
-
-            # If the filesystem resolution is 1 second, like Mac OS
-            # 10.12 Extended, or 2 seconds, like FAT32, and the editor
-            # closes very fast, require_save can fail. Set the modified
-            # time to be 2 seconds in the past to work around this.
-            os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2))
-            # Depending on the resolution, the exact value might not be
-            # recorded, so get the new recorded value.
-            timestamp = os.path.getmtime(name)
-
-            self.edit_file(name)
-
-            if self.require_save and os.path.getmtime(name) == timestamp:
-                return None
-
-            with open(name, "rb") as f:
-                rv = f.read()
-
-            if isinstance(text, (bytes, bytearray)):
-                return rv
-
-            return rv.decode("utf-8-sig").replace("\r\n", "\n")  # type: ignore
-        finally:
-            os.unlink(name)
-
-
-def open_url(url: str, wait: bool = False, locate: bool = False) -> int:
-    import subprocess
-
-    def _unquote_file(url: str) -> str:
-        from urllib.parse import unquote
-
-        if url.startswith("file://"):
-            url = unquote(url[7:])
-
-        return url
-
-    if sys.platform == "darwin":
-        args = ["open"]
-        if wait:
-            args.append("-W")
-        if locate:
-            args.append("-R")
-        args.append(_unquote_file(url))
-        null = open("/dev/null", "w")
-        try:
-            return subprocess.Popen(args, stderr=null).wait()
-        finally:
-            null.close()
-    elif WIN:
-        if locate:
-            url = _unquote_file(url.replace('"', ""))
-            args = f'explorer /select,"{url}"'
-        else:
-            url = url.replace('"', "")
-            wait_str = "/WAIT" if wait else ""
-            args = f'start {wait_str} "" "{url}"'
-        return os.system(args)
-    elif CYGWIN:
-        if locate:
-            url = os.path.dirname(_unquote_file(url).replace('"', ""))
-            args = f'cygstart "{url}"'
-        else:
-            url = url.replace('"', "")
-            wait_str = "-w" if wait else ""
-            args = f'cygstart {wait_str} "{url}"'
-        return os.system(args)
-
-    try:
-        if locate:
-            url = os.path.dirname(_unquote_file(url)) or "."
-        else:
-            url = _unquote_file(url)
-        c = subprocess.Popen(["xdg-open", url])
-        if wait:
-            return c.wait()
-        return 0
-    except OSError:
-        if url.startswith(("http://", "https://")) and not locate and not wait:
-            import webbrowser
-
-            webbrowser.open(url)
-            return 0
-        return 1
-
-
-def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]:
-    if ch == "\x03":
-        raise KeyboardInterrupt()
-
-    if ch == "\x04" and not WIN:  # Unix-like, Ctrl+D
-        raise EOFError()
-
-    if ch == "\x1a" and WIN:  # Windows, Ctrl+Z
-        raise EOFError()
-
-    return None
-
-
-if WIN:
-    import msvcrt
-
-    @contextlib.contextmanager
-    def raw_terminal() -> t.Iterator[int]:
-        yield -1
-
-    def getchar(echo: bool) -> str:
-        # The function `getch` will return a bytes object corresponding to
-        # the pressed character. Since Windows 10 build 1803, it will also
-        # return \x00 when called a second time after pressing a regular key.
-        #
-        # `getwch` does not share this probably-bugged behavior. Moreover, it
-        # returns a Unicode object by default, which is what we want.
-        #
-        # Either of these functions will return \x00 or \xe0 to indicate
-        # a special key, and you need to call the same function again to get
-        # the "rest" of the code. The fun part is that \u00e0 is
-        # "latin small letter a with grave", so if you type that on a French
-        # keyboard, you _also_ get a \xe0.
-        # E.g., consider the Up arrow. This returns \xe0 and then \x48. The
-        # resulting Unicode string reads as "a with grave" + "capital H".
-        # This is indistinguishable from when the user actually types
-        # "a with grave" and then "capital H".
-        #
-        # When \xe0 is returned, we assume it's part of a special-key sequence
-        # and call `getwch` again, but that means that when the user types
-        # the \u00e0 character, `getchar` doesn't return until a second
-        # character is typed.
-        # The alternative is returning immediately, but that would mess up
-        # cross-platform handling of arrow keys and others that start with
-        # \xe0. Another option is using `getch`, but then we can't reliably
-        # read non-ASCII characters, because return values of `getch` are
-        # limited to the current 8-bit codepage.
-        #
-        # Anyway, Click doesn't claim to do this Right(tm), and using `getwch`
-        # is doing the right thing in more situations than with `getch`.
-        func: t.Callable[[], str]
-
-        if echo:
-            func = msvcrt.getwche  # type: ignore
-        else:
-            func = msvcrt.getwch  # type: ignore
-
-        rv = func()
-
-        if rv in ("\x00", "\xe0"):
-            # \x00 and \xe0 are control characters that indicate special key,
-            # see above.
-            rv += func()
-
-        _translate_ch_to_exc(rv)
-        return rv
-
-else:
-    import tty
-    import termios
-
-    @contextlib.contextmanager
-    def raw_terminal() -> t.Iterator[int]:
-        f: t.Optional[t.TextIO]
-        fd: int
-
-        if not isatty(sys.stdin):
-            f = open("/dev/tty")
-            fd = f.fileno()
-        else:
-            fd = sys.stdin.fileno()
-            f = None
-
-        try:
-            old_settings = termios.tcgetattr(fd)
-
-            try:
-                tty.setraw(fd)
-                yield fd
-            finally:
-                termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
-                sys.stdout.flush()
-
-                if f is not None:
-                    f.close()
-        except termios.error:
-            pass
-
-    def getchar(echo: bool) -> str:
-        with raw_terminal() as fd:
-            ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace")
-
-            if echo and isatty(sys.stdout):
-                sys.stdout.write(ch)
-
-            _translate_ch_to_exc(ch)
-            return ch

+ 0 - 49
venv/lib/python3.10/site-packages/click/_textwrap.py

@@ -1,49 +0,0 @@
-import textwrap
-import typing as t
-from contextlib import contextmanager
-
-
-class TextWrapper(textwrap.TextWrapper):
-    def _handle_long_word(
-        self,
-        reversed_chunks: t.List[str],
-        cur_line: t.List[str],
-        cur_len: int,
-        width: int,
-    ) -> None:
-        space_left = max(width - cur_len, 1)
-
-        if self.break_long_words:
-            last = reversed_chunks[-1]
-            cut = last[:space_left]
-            res = last[space_left:]
-            cur_line.append(cut)
-            reversed_chunks[-1] = res
-        elif not cur_line:
-            cur_line.append(reversed_chunks.pop())
-
-    @contextmanager
-    def extra_indent(self, indent: str) -> t.Iterator[None]:
-        old_initial_indent = self.initial_indent
-        old_subsequent_indent = self.subsequent_indent
-        self.initial_indent += indent
-        self.subsequent_indent += indent
-
-        try:
-            yield
-        finally:
-            self.initial_indent = old_initial_indent
-            self.subsequent_indent = old_subsequent_indent
-
-    def indent_only(self, text: str) -> str:
-        rv = []
-
-        for idx, line in enumerate(text.splitlines()):
-            indent = self.initial_indent
-
-            if idx > 0:
-                indent = self.subsequent_indent
-
-            rv.append(f"{indent}{line}")
-
-        return "\n".join(rv)

+ 0 - 279
venv/lib/python3.10/site-packages/click/_winconsole.py

@@ -1,279 +0,0 @@
-# This module is based on the excellent work by Adam Bartoš who
-# provided a lot of what went into the implementation here in
-# the discussion to issue1602 in the Python bug tracker.
-#
-# There are some general differences in regards to how this works
-# compared to the original patches as we do not need to patch
-# the entire interpreter but just work in our little world of
-# echo and prompt.
-import io
-import sys
-import time
-import typing as t
-from ctypes import byref
-from ctypes import c_char
-from ctypes import c_char_p
-from ctypes import c_int
-from ctypes import c_ssize_t
-from ctypes import c_ulong
-from ctypes import c_void_p
-from ctypes import POINTER
-from ctypes import py_object
-from ctypes import Structure
-from ctypes.wintypes import DWORD
-from ctypes.wintypes import HANDLE
-from ctypes.wintypes import LPCWSTR
-from ctypes.wintypes import LPWSTR
-
-from ._compat import _NonClosingTextIOWrapper
-
-assert sys.platform == "win32"
-import msvcrt  # noqa: E402
-from ctypes import windll  # noqa: E402
-from ctypes import WINFUNCTYPE  # noqa: E402
-
-c_ssize_p = POINTER(c_ssize_t)
-
-kernel32 = windll.kernel32
-GetStdHandle = kernel32.GetStdHandle
-ReadConsoleW = kernel32.ReadConsoleW
-WriteConsoleW = kernel32.WriteConsoleW
-GetConsoleMode = kernel32.GetConsoleMode
-GetLastError = kernel32.GetLastError
-GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32))
-CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))(
-    ("CommandLineToArgvW", windll.shell32)
-)
-LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32))
-
-STDIN_HANDLE = GetStdHandle(-10)
-STDOUT_HANDLE = GetStdHandle(-11)
-STDERR_HANDLE = GetStdHandle(-12)
-
-PyBUF_SIMPLE = 0
-PyBUF_WRITABLE = 1
-
-ERROR_SUCCESS = 0
-ERROR_NOT_ENOUGH_MEMORY = 8
-ERROR_OPERATION_ABORTED = 995
-
-STDIN_FILENO = 0
-STDOUT_FILENO = 1
-STDERR_FILENO = 2
-
-EOF = b"\x1a"
-MAX_BYTES_WRITTEN = 32767
-
-try:
-    from ctypes import pythonapi
-except ImportError:
-    # On PyPy we cannot get buffers so our ability to operate here is
-    # severely limited.
-    get_buffer = None
-else:
-
-    class Py_buffer(Structure):
-        _fields_ = [
-            ("buf", c_void_p),
-            ("obj", py_object),
-            ("len", c_ssize_t),
-            ("itemsize", c_ssize_t),
-            ("readonly", c_int),
-            ("ndim", c_int),
-            ("format", c_char_p),
-            ("shape", c_ssize_p),
-            ("strides", c_ssize_p),
-            ("suboffsets", c_ssize_p),
-            ("internal", c_void_p),
-        ]
-
-    PyObject_GetBuffer = pythonapi.PyObject_GetBuffer
-    PyBuffer_Release = pythonapi.PyBuffer_Release
-
-    def get_buffer(obj, writable=False):
-        buf = Py_buffer()
-        flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE
-        PyObject_GetBuffer(py_object(obj), byref(buf), flags)
-
-        try:
-            buffer_type = c_char * buf.len
-            return buffer_type.from_address(buf.buf)
-        finally:
-            PyBuffer_Release(byref(buf))
-
-
-class _WindowsConsoleRawIOBase(io.RawIOBase):
-    def __init__(self, handle):
-        self.handle = handle
-
-    def isatty(self):
-        super().isatty()
-        return True
-
-
-class _WindowsConsoleReader(_WindowsConsoleRawIOBase):
-    def readable(self):
-        return True
-
-    def readinto(self, b):
-        bytes_to_be_read = len(b)
-        if not bytes_to_be_read:
-            return 0
-        elif bytes_to_be_read % 2:
-            raise ValueError(
-                "cannot read odd number of bytes from UTF-16-LE encoded console"
-            )
-
-        buffer = get_buffer(b, writable=True)
-        code_units_to_be_read = bytes_to_be_read // 2
-        code_units_read = c_ulong()
-
-        rv = ReadConsoleW(
-            HANDLE(self.handle),
-            buffer,
-            code_units_to_be_read,
-            byref(code_units_read),
-            None,
-        )
-        if GetLastError() == ERROR_OPERATION_ABORTED:
-            # wait for KeyboardInterrupt
-            time.sleep(0.1)
-        if not rv:
-            raise OSError(f"Windows error: {GetLastError()}")
-
-        if buffer[0] == EOF:
-            return 0
-        return 2 * code_units_read.value
-
-
-class _WindowsConsoleWriter(_WindowsConsoleRawIOBase):
-    def writable(self):
-        return True
-
-    @staticmethod
-    def _get_error_message(errno):
-        if errno == ERROR_SUCCESS:
-            return "ERROR_SUCCESS"
-        elif errno == ERROR_NOT_ENOUGH_MEMORY:
-            return "ERROR_NOT_ENOUGH_MEMORY"
-        return f"Windows error {errno}"
-
-    def write(self, b):
-        bytes_to_be_written = len(b)
-        buf = get_buffer(b)
-        code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2
-        code_units_written = c_ulong()
-
-        WriteConsoleW(
-            HANDLE(self.handle),
-            buf,
-            code_units_to_be_written,
-            byref(code_units_written),
-            None,
-        )
-        bytes_written = 2 * code_units_written.value
-
-        if bytes_written == 0 and bytes_to_be_written > 0:
-            raise OSError(self._get_error_message(GetLastError()))
-        return bytes_written
-
-
-class ConsoleStream:
-    def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None:
-        self._text_stream = text_stream
-        self.buffer = byte_stream
-
-    @property
-    def name(self) -> str:
-        return self.buffer.name
-
-    def write(self, x: t.AnyStr) -> int:
-        if isinstance(x, str):
-            return self._text_stream.write(x)
-        try:
-            self.flush()
-        except Exception:
-            pass
-        return self.buffer.write(x)
-
-    def writelines(self, lines: t.Iterable[t.AnyStr]) -> None:
-        for line in lines:
-            self.write(line)
-
-    def __getattr__(self, name: str) -> t.Any:
-        return getattr(self._text_stream, name)
-
-    def isatty(self) -> bool:
-        return self.buffer.isatty()
-
-    def __repr__(self):
-        return f"<ConsoleStream name={self.name!r} encoding={self.encoding!r}>"
-
-
-def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO:
-    text_stream = _NonClosingTextIOWrapper(
-        io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)),
-        "utf-16-le",
-        "strict",
-        line_buffering=True,
-    )
-    return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream))
-
-
-def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO:
-    text_stream = _NonClosingTextIOWrapper(
-        io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)),
-        "utf-16-le",
-        "strict",
-        line_buffering=True,
-    )
-    return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream))
-
-
-def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO:
-    text_stream = _NonClosingTextIOWrapper(
-        io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)),
-        "utf-16-le",
-        "strict",
-        line_buffering=True,
-    )
-    return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream))
-
-
-_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = {
-    0: _get_text_stdin,
-    1: _get_text_stdout,
-    2: _get_text_stderr,
-}
-
-
-def _is_console(f: t.TextIO) -> bool:
-    if not hasattr(f, "fileno"):
-        return False
-
-    try:
-        fileno = f.fileno()
-    except (OSError, io.UnsupportedOperation):
-        return False
-
-    handle = msvcrt.get_osfhandle(fileno)
-    return bool(GetConsoleMode(handle, byref(DWORD())))
-
-
-def _get_windows_console_stream(
-    f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str]
-) -> t.Optional[t.TextIO]:
-    if (
-        get_buffer is not None
-        and encoding in {"utf-16-le", None}
-        and errors in {"strict", None}
-        and _is_console(f)
-    ):
-        func = _stream_factories.get(f.fileno())
-        if func is not None:
-            b = getattr(f, "buffer", None)
-
-            if b is None:
-                return None
-
-            return func(b)

+ 0 - 2998
venv/lib/python3.10/site-packages/click/core.py

@@ -1,2998 +0,0 @@
-import enum
-import errno
-import inspect
-import os
-import sys
-import typing as t
-from collections import abc
-from contextlib import contextmanager
-from contextlib import ExitStack
-from functools import partial
-from functools import update_wrapper
-from gettext import gettext as _
-from gettext import ngettext
-from itertools import repeat
-
-from . import types
-from .exceptions import Abort
-from .exceptions import BadParameter
-from .exceptions import ClickException
-from .exceptions import Exit
-from .exceptions import MissingParameter
-from .exceptions import UsageError
-from .formatting import HelpFormatter
-from .formatting import join_options
-from .globals import pop_context
-from .globals import push_context
-from .parser import _flag_needs_value
-from .parser import OptionParser
-from .parser import split_opt
-from .termui import confirm
-from .termui import prompt
-from .termui import style
-from .utils import _detect_program_name
-from .utils import _expand_args
-from .utils import echo
-from .utils import make_default_short_help
-from .utils import make_str
-from .utils import PacifyFlushWrapper
-
-if t.TYPE_CHECKING:
-    import typing_extensions as te
-    from .shell_completion import CompletionItem
-
-F = t.TypeVar("F", bound=t.Callable[..., t.Any])
-V = t.TypeVar("V")
-
-
-def _complete_visible_commands(
-    ctx: "Context", incomplete: str
-) -> t.Iterator[t.Tuple[str, "Command"]]:
-    """List all the subcommands of a group that start with the
-    incomplete value and aren't hidden.
-
-    :param ctx: Invocation context for the group.
-    :param incomplete: Value being completed. May be empty.
-    """
-    multi = t.cast(MultiCommand, ctx.command)
-
-    for name in multi.list_commands(ctx):
-        if name.startswith(incomplete):
-            command = multi.get_command(ctx, name)
-
-            if command is not None and not command.hidden:
-                yield name, command
-
-
-def _check_multicommand(
-    base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False
-) -> None:
-    if not base_command.chain or not isinstance(cmd, MultiCommand):
-        return
-    if register:
-        hint = (
-            "It is not possible to add multi commands as children to"
-            " another multi command that is in chain mode."
-        )
-    else:
-        hint = (
-            "Found a multi command as subcommand to a multi command"
-            " that is in chain mode. This is not supported."
-        )
-    raise RuntimeError(
-        f"{hint}. Command {base_command.name!r} is set to chain and"
-        f" {cmd_name!r} was added as a subcommand but it in itself is a"
-        f" multi command. ({cmd_name!r} is a {type(cmd).__name__}"
-        f" within a chained {type(base_command).__name__} named"
-        f" {base_command.name!r})."
-    )
-
-
-def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]:
-    return list(zip(*repeat(iter(iterable), batch_size)))
-
-
-@contextmanager
-def augment_usage_errors(
-    ctx: "Context", param: t.Optional["Parameter"] = None
-) -> t.Iterator[None]:
-    """Context manager that attaches extra information to exceptions."""
-    try:
-        yield
-    except BadParameter as e:
-        if e.ctx is None:
-            e.ctx = ctx
-        if param is not None and e.param is None:
-            e.param = param
-        raise
-    except UsageError as e:
-        if e.ctx is None:
-            e.ctx = ctx
-        raise
-
-
-def iter_params_for_processing(
-    invocation_order: t.Sequence["Parameter"],
-    declaration_order: t.Sequence["Parameter"],
-) -> t.List["Parameter"]:
-    """Given a sequence of parameters in the order as should be considered
-    for processing and an iterable of parameters that exist, this returns
-    a list in the correct order as they should be processed.
-    """
-
-    def sort_key(item: "Parameter") -> t.Tuple[bool, float]:
-        try:
-            idx: float = invocation_order.index(item)
-        except ValueError:
-            idx = float("inf")
-
-        return not item.is_eager, idx
-
-    return sorted(declaration_order, key=sort_key)
-
-
-class ParameterSource(enum.Enum):
-    """This is an :class:`~enum.Enum` that indicates the source of a
-    parameter's value.
-
-    Use :meth:`click.Context.get_parameter_source` to get the
-    source for a parameter by name.
-
-    .. versionchanged:: 8.0
-        Use :class:`~enum.Enum` and drop the ``validate`` method.
-
-    .. versionchanged:: 8.0
-        Added the ``PROMPT`` value.
-    """
-
-    COMMANDLINE = enum.auto()
-    """The value was provided by the command line args."""
-    ENVIRONMENT = enum.auto()
-    """The value was provided with an environment variable."""
-    DEFAULT = enum.auto()
-    """Used the default specified by the parameter."""
-    DEFAULT_MAP = enum.auto()
-    """Used a default provided by :attr:`Context.default_map`."""
-    PROMPT = enum.auto()
-    """Used a prompt to confirm a default or provide a value."""
-
-
-class Context:
-    """The context is a special internal object that holds state relevant
-    for the script execution at every single level.  It's normally invisible
-    to commands unless they opt-in to getting access to it.
-
-    The context is useful as it can pass internal objects around and can
-    control special execution features such as reading data from
-    environment variables.
-
-    A context can be used as context manager in which case it will call
-    :meth:`close` on teardown.
-
-    :param command: the command class for this context.
-    :param parent: the parent context.
-    :param info_name: the info name for this invocation.  Generally this
-                      is the most descriptive name for the script or
-                      command.  For the toplevel script it is usually
-                      the name of the script, for commands below it it's
-                      the name of the script.
-    :param obj: an arbitrary object of user data.
-    :param auto_envvar_prefix: the prefix to use for automatic environment
-                               variables.  If this is `None` then reading
-                               from environment variables is disabled.  This
-                               does not affect manually set environment
-                               variables which are always read.
-    :param default_map: a dictionary (like object) with default values
-                        for parameters.
-    :param terminal_width: the width of the terminal.  The default is
-                           inherit from parent context.  If no context
-                           defines the terminal width then auto
-                           detection will be applied.
-    :param max_content_width: the maximum width for content rendered by
-                              Click (this currently only affects help
-                              pages).  This defaults to 80 characters if
-                              not overridden.  In other words: even if the
-                              terminal is larger than that, Click will not
-                              format things wider than 80 characters by
-                              default.  In addition to that, formatters might
-                              add some safety mapping on the right.
-    :param resilient_parsing: if this flag is enabled then Click will
-                              parse without any interactivity or callback
-                              invocation.  Default values will also be
-                              ignored.  This is useful for implementing
-                              things such as completion support.
-    :param allow_extra_args: if this is set to `True` then extra arguments
-                             at the end will not raise an error and will be
-                             kept on the context.  The default is to inherit
-                             from the command.
-    :param allow_interspersed_args: if this is set to `False` then options
-                                    and arguments cannot be mixed.  The
-                                    default is to inherit from the command.
-    :param ignore_unknown_options: instructs click to ignore options it does
-                                   not know and keeps them for later
-                                   processing.
-    :param help_option_names: optionally a list of strings that define how
-                              the default help parameter is named.  The
-                              default is ``['--help']``.
-    :param token_normalize_func: an optional function that is used to
-                                 normalize tokens (options, choices,
-                                 etc.).  This for instance can be used to
-                                 implement case insensitive behavior.
-    :param color: controls if the terminal supports ANSI colors or not.  The
-                  default is autodetection.  This is only needed if ANSI
-                  codes are used in texts that Click prints which is by
-                  default not the case.  This for instance would affect
-                  help output.
-    :param show_default: Show the default value for commands. If this
-        value is not set, it defaults to the value from the parent
-        context. ``Command.show_default`` overrides this default for the
-        specific command.
-
-    .. versionchanged:: 8.1
-        The ``show_default`` parameter is overridden by
-        ``Command.show_default``, instead of the other way around.
-
-    .. versionchanged:: 8.0
-        The ``show_default`` parameter defaults to the value from the
-        parent context.
-
-    .. versionchanged:: 7.1
-       Added the ``show_default`` parameter.
-
-    .. versionchanged:: 4.0
-        Added the ``color``, ``ignore_unknown_options``, and
-        ``max_content_width`` parameters.
-
-    .. versionchanged:: 3.0
-        Added the ``allow_extra_args`` and ``allow_interspersed_args``
-        parameters.
-
-    .. versionchanged:: 2.0
-        Added the ``resilient_parsing``, ``help_option_names``, and
-        ``token_normalize_func`` parameters.
-    """
-
-    #: The formatter class to create with :meth:`make_formatter`.
-    #:
-    #: .. versionadded:: 8.0
-    formatter_class: t.Type["HelpFormatter"] = HelpFormatter
-
-    def __init__(
-        self,
-        command: "Command",
-        parent: t.Optional["Context"] = None,
-        info_name: t.Optional[str] = None,
-        obj: t.Optional[t.Any] = None,
-        auto_envvar_prefix: t.Optional[str] = None,
-        default_map: t.Optional[t.Dict[str, t.Any]] = None,
-        terminal_width: t.Optional[int] = None,
-        max_content_width: t.Optional[int] = None,
-        resilient_parsing: bool = False,
-        allow_extra_args: t.Optional[bool] = None,
-        allow_interspersed_args: t.Optional[bool] = None,
-        ignore_unknown_options: t.Optional[bool] = None,
-        help_option_names: t.Optional[t.List[str]] = None,
-        token_normalize_func: t.Optional[t.Callable[[str], str]] = None,
-        color: t.Optional[bool] = None,
-        show_default: t.Optional[bool] = None,
-    ) -> None:
-        #: the parent context or `None` if none exists.
-        self.parent = parent
-        #: the :class:`Command` for this context.
-        self.command = command
-        #: the descriptive information name
-        self.info_name = info_name
-        #: Map of parameter names to their parsed values. Parameters
-        #: with ``expose_value=False`` are not stored.
-        self.params: t.Dict[str, t.Any] = {}
-        #: the leftover arguments.
-        self.args: t.List[str] = []
-        #: protected arguments.  These are arguments that are prepended
-        #: to `args` when certain parsing scenarios are encountered but
-        #: must be never propagated to another arguments.  This is used
-        #: to implement nested parsing.
-        self.protected_args: t.List[str] = []
-        #: the collected prefixes of the command's options.
-        self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set()
-
-        if obj is None and parent is not None:
-            obj = parent.obj
-
-        #: the user object stored.
-        self.obj: t.Any = obj
-        self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {})
-
-        #: A dictionary (-like object) with defaults for parameters.
-        if (
-            default_map is None
-            and info_name is not None
-            and parent is not None
-            and parent.default_map is not None
-        ):
-            default_map = parent.default_map.get(info_name)
-
-        self.default_map: t.Optional[t.Dict[str, t.Any]] = default_map
-
-        #: This flag indicates if a subcommand is going to be executed. A
-        #: group callback can use this information to figure out if it's
-        #: being executed directly or because the execution flow passes
-        #: onwards to a subcommand. By default it's None, but it can be
-        #: the name of the subcommand to execute.
-        #:
-        #: If chaining is enabled this will be set to ``'*'`` in case
-        #: any commands are executed.  It is however not possible to
-        #: figure out which ones.  If you require this knowledge you
-        #: should use a :func:`result_callback`.
-        self.invoked_subcommand: t.Optional[str] = None
-
-        if terminal_width is None and parent is not None:
-            terminal_width = parent.terminal_width
-
-        #: The width of the terminal (None is autodetection).
-        self.terminal_width: t.Optional[int] = terminal_width
-
-        if max_content_width is None and parent is not None:
-            max_content_width = parent.max_content_width
-
-        #: The maximum width of formatted content (None implies a sensible
-        #: default which is 80 for most things).
-        self.max_content_width: t.Optional[int] = max_content_width
-
-        if allow_extra_args is None:
-            allow_extra_args = command.allow_extra_args
-
-        #: Indicates if the context allows extra args or if it should
-        #: fail on parsing.
-        #:
-        #: .. versionadded:: 3.0
-        self.allow_extra_args = allow_extra_args
-
-        if allow_interspersed_args is None:
-            allow_interspersed_args = command.allow_interspersed_args
-
-        #: Indicates if the context allows mixing of arguments and
-        #: options or not.
-        #:
-        #: .. versionadded:: 3.0
-        self.allow_interspersed_args: bool = allow_interspersed_args
-
-        if ignore_unknown_options is None:
-            ignore_unknown_options = command.ignore_unknown_options
-
-        #: Instructs click to ignore options that a command does not
-        #: understand and will store it on the context for later
-        #: processing.  This is primarily useful for situations where you
-        #: want to call into external programs.  Generally this pattern is
-        #: strongly discouraged because it's not possibly to losslessly
-        #: forward all arguments.
-        #:
-        #: .. versionadded:: 4.0
-        self.ignore_unknown_options: bool = ignore_unknown_options
-
-        if help_option_names is None:
-            if parent is not None:
-                help_option_names = parent.help_option_names
-            else:
-                help_option_names = ["--help"]
-
-        #: The names for the help options.
-        self.help_option_names: t.List[str] = help_option_names
-
-        if token_normalize_func is None and parent is not None:
-            token_normalize_func = parent.token_normalize_func
-
-        #: An optional normalization function for tokens.  This is
-        #: options, choices, commands etc.
-        self.token_normalize_func: t.Optional[
-            t.Callable[[str], str]
-        ] = token_normalize_func
-
-        #: Indicates if resilient parsing is enabled.  In that case Click
-        #: will do its best to not cause any failures and default values
-        #: will be ignored. Useful for completion.
-        self.resilient_parsing: bool = resilient_parsing
-
-        # If there is no envvar prefix yet, but the parent has one and
-        # the command on this level has a name, we can expand the envvar
-        # prefix automatically.
-        if auto_envvar_prefix is None:
-            if (
-                parent is not None
-                and parent.auto_envvar_prefix is not None
-                and self.info_name is not None
-            ):
-                auto_envvar_prefix = (
-                    f"{parent.auto_envvar_prefix}_{self.info_name.upper()}"
-                )
-        else:
-            auto_envvar_prefix = auto_envvar_prefix.upper()
-
-        if auto_envvar_prefix is not None:
-            auto_envvar_prefix = auto_envvar_prefix.replace("-", "_")
-
-        self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix
-
-        if color is None and parent is not None:
-            color = parent.color
-
-        #: Controls if styling output is wanted or not.
-        self.color: t.Optional[bool] = color
-
-        if show_default is None and parent is not None:
-            show_default = parent.show_default
-
-        #: Show option default values when formatting help text.
-        self.show_default: t.Optional[bool] = show_default
-
-        self._close_callbacks: t.List[t.Callable[[], t.Any]] = []
-        self._depth = 0
-        self._parameter_source: t.Dict[str, ParameterSource] = {}
-        self._exit_stack = ExitStack()
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        """Gather information that could be useful for a tool generating
-        user-facing documentation. This traverses the entire CLI
-        structure.
-
-        .. code-block:: python
-
-            with Context(cli) as ctx:
-                info = ctx.to_info_dict()
-
-        .. versionadded:: 8.0
-        """
-        return {
-            "command": self.command.to_info_dict(self),
-            "info_name": self.info_name,
-            "allow_extra_args": self.allow_extra_args,
-            "allow_interspersed_args": self.allow_interspersed_args,
-            "ignore_unknown_options": self.ignore_unknown_options,
-            "auto_envvar_prefix": self.auto_envvar_prefix,
-        }
-
-    def __enter__(self) -> "Context":
-        self._depth += 1
-        push_context(self)
-        return self
-
-    def __exit__(self, exc_type, exc_value, tb):  # type: ignore
-        self._depth -= 1
-        if self._depth == 0:
-            self.close()
-        pop_context()
-
-    @contextmanager
-    def scope(self, cleanup: bool = True) -> t.Iterator["Context"]:
-        """This helper method can be used with the context object to promote
-        it to the current thread local (see :func:`get_current_context`).
-        The default behavior of this is to invoke the cleanup functions which
-        can be disabled by setting `cleanup` to `False`.  The cleanup
-        functions are typically used for things such as closing file handles.
-
-        If the cleanup is intended the context object can also be directly
-        used as a context manager.
-
-        Example usage::
-
-            with ctx.scope():
-                assert get_current_context() is ctx
-
-        This is equivalent::
-
-            with ctx:
-                assert get_current_context() is ctx
-
-        .. versionadded:: 5.0
-
-        :param cleanup: controls if the cleanup functions should be run or
-                        not.  The default is to run these functions.  In
-                        some situations the context only wants to be
-                        temporarily pushed in which case this can be disabled.
-                        Nested pushes automatically defer the cleanup.
-        """
-        if not cleanup:
-            self._depth += 1
-        try:
-            with self as rv:
-                yield rv
-        finally:
-            if not cleanup:
-                self._depth -= 1
-
-    @property
-    def meta(self) -> t.Dict[str, t.Any]:
-        """This is a dictionary which is shared with all the contexts
-        that are nested.  It exists so that click utilities can store some
-        state here if they need to.  It is however the responsibility of
-        that code to manage this dictionary well.
-
-        The keys are supposed to be unique dotted strings.  For instance
-        module paths are a good choice for it.  What is stored in there is
-        irrelevant for the operation of click.  However what is important is
-        that code that places data here adheres to the general semantics of
-        the system.
-
-        Example usage::
-
-            LANG_KEY = f'{__name__}.lang'
-
-            def set_language(value):
-                ctx = get_current_context()
-                ctx.meta[LANG_KEY] = value
-
-            def get_language():
-                return get_current_context().meta.get(LANG_KEY, 'en_US')
-
-        .. versionadded:: 5.0
-        """
-        return self._meta
-
-    def make_formatter(self) -> HelpFormatter:
-        """Creates the :class:`~click.HelpFormatter` for the help and
-        usage output.
-
-        To quickly customize the formatter class used without overriding
-        this method, set the :attr:`formatter_class` attribute.
-
-        .. versionchanged:: 8.0
-            Added the :attr:`formatter_class` attribute.
-        """
-        return self.formatter_class(
-            width=self.terminal_width, max_width=self.max_content_width
-        )
-
-    def with_resource(self, context_manager: t.ContextManager[V]) -> V:
-        """Register a resource as if it were used in a ``with``
-        statement. The resource will be cleaned up when the context is
-        popped.
-
-        Uses :meth:`contextlib.ExitStack.enter_context`. It calls the
-        resource's ``__enter__()`` method and returns the result. When
-        the context is popped, it closes the stack, which calls the
-        resource's ``__exit__()`` method.
-
-        To register a cleanup function for something that isn't a
-        context manager, use :meth:`call_on_close`. Or use something
-        from :mod:`contextlib` to turn it into a context manager first.
-
-        .. code-block:: python
-
-            @click.group()
-            @click.option("--name")
-            @click.pass_context
-            def cli(ctx):
-                ctx.obj = ctx.with_resource(connect_db(name))
-
-        :param context_manager: The context manager to enter.
-        :return: Whatever ``context_manager.__enter__()`` returns.
-
-        .. versionadded:: 8.0
-        """
-        return self._exit_stack.enter_context(context_manager)
-
-    def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]:
-        """Register a function to be called when the context tears down.
-
-        This can be used to close resources opened during the script
-        execution. Resources that support Python's context manager
-        protocol which would be used in a ``with`` statement should be
-        registered with :meth:`with_resource` instead.
-
-        :param f: The function to execute on teardown.
-        """
-        return self._exit_stack.callback(f)
-
-    def close(self) -> None:
-        """Invoke all close callbacks registered with
-        :meth:`call_on_close`, and exit all context managers entered
-        with :meth:`with_resource`.
-        """
-        self._exit_stack.close()
-        # In case the context is reused, create a new exit stack.
-        self._exit_stack = ExitStack()
-
-    @property
-    def command_path(self) -> str:
-        """The computed command path.  This is used for the ``usage``
-        information on the help page.  It's automatically created by
-        combining the info names of the chain of contexts to the root.
-        """
-        rv = ""
-        if self.info_name is not None:
-            rv = self.info_name
-        if self.parent is not None:
-            parent_command_path = [self.parent.command_path]
-
-            if isinstance(self.parent.command, Command):
-                for param in self.parent.command.get_params(self):
-                    parent_command_path.extend(param.get_usage_pieces(self))
-
-            rv = f"{' '.join(parent_command_path)} {rv}"
-        return rv.lstrip()
-
-    def find_root(self) -> "Context":
-        """Finds the outermost context."""
-        node = self
-        while node.parent is not None:
-            node = node.parent
-        return node
-
-    def find_object(self, object_type: t.Type[V]) -> t.Optional[V]:
-        """Finds the closest object of a given type."""
-        node: t.Optional["Context"] = self
-
-        while node is not None:
-            if isinstance(node.obj, object_type):
-                return node.obj
-
-            node = node.parent
-
-        return None
-
-    def ensure_object(self, object_type: t.Type[V]) -> V:
-        """Like :meth:`find_object` but sets the innermost object to a
-        new instance of `object_type` if it does not exist.
-        """
-        rv = self.find_object(object_type)
-        if rv is None:
-            self.obj = rv = object_type()
-        return rv
-
-    @t.overload
-    def lookup_default(
-        self, name: str, call: "te.Literal[True]" = True
-    ) -> t.Optional[t.Any]:
-        ...
-
-    @t.overload
-    def lookup_default(
-        self, name: str, call: "te.Literal[False]" = ...
-    ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]:
-        ...
-
-    def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]:
-        """Get the default for a parameter from :attr:`default_map`.
-
-        :param name: Name of the parameter.
-        :param call: If the default is a callable, call it. Disable to
-            return the callable instead.
-
-        .. versionchanged:: 8.0
-            Added the ``call`` parameter.
-        """
-        if self.default_map is not None:
-            value = self.default_map.get(name)
-
-            if call and callable(value):
-                return value()
-
-            return value
-
-        return None
-
-    def fail(self, message: str) -> "te.NoReturn":
-        """Aborts the execution of the program with a specific error
-        message.
-
-        :param message: the error message to fail with.
-        """
-        raise UsageError(message, self)
-
-    def abort(self) -> "te.NoReturn":
-        """Aborts the script."""
-        raise Abort()
-
-    def exit(self, code: int = 0) -> "te.NoReturn":
-        """Exits the application with a given exit code."""
-        raise Exit(code)
-
-    def get_usage(self) -> str:
-        """Helper method to get formatted usage string for the current
-        context and command.
-        """
-        return self.command.get_usage(self)
-
-    def get_help(self) -> str:
-        """Helper method to get formatted help page for the current
-        context and command.
-        """
-        return self.command.get_help(self)
-
-    def _make_sub_context(self, command: "Command") -> "Context":
-        """Create a new context of the same type as this context, but
-        for a new command.
-
-        :meta private:
-        """
-        return type(self)(command, info_name=command.name, parent=self)
-
-    def invoke(
-        __self,  # noqa: B902
-        __callback: t.Union["Command", t.Callable[..., t.Any]],
-        *args: t.Any,
-        **kwargs: t.Any,
-    ) -> t.Any:
-        """Invokes a command callback in exactly the way it expects.  There
-        are two ways to invoke this method:
-
-        1.  the first argument can be a callback and all other arguments and
-            keyword arguments are forwarded directly to the function.
-        2.  the first argument is a click command object.  In that case all
-            arguments are forwarded as well but proper click parameters
-            (options and click arguments) must be keyword arguments and Click
-            will fill in defaults.
-
-        Note that before Click 3.2 keyword arguments were not properly filled
-        in against the intention of this code and no context was created.  For
-        more information about this change and why it was done in a bugfix
-        release see :ref:`upgrade-to-3.2`.
-
-        .. versionchanged:: 8.0
-            All ``kwargs`` are tracked in :attr:`params` so they will be
-            passed if :meth:`forward` is called at multiple levels.
-        """
-        if isinstance(__callback, Command):
-            other_cmd = __callback
-
-            if other_cmd.callback is None:
-                raise TypeError(
-                    "The given command does not have a callback that can be invoked."
-                )
-            else:
-                __callback = other_cmd.callback
-
-            ctx = __self._make_sub_context(other_cmd)
-
-            for param in other_cmd.params:
-                if param.name not in kwargs and param.expose_value:
-                    kwargs[param.name] = param.type_cast_value(  # type: ignore
-                        ctx, param.get_default(ctx)
-                    )
-
-            # Track all kwargs as params, so that forward() will pass
-            # them on in subsequent calls.
-            ctx.params.update(kwargs)
-        else:
-            ctx = __self
-
-        with augment_usage_errors(__self):
-            with ctx:
-                return __callback(*args, **kwargs)
-
-    def forward(
-        __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any  # noqa: B902
-    ) -> t.Any:
-        """Similar to :meth:`invoke` but fills in default keyword
-        arguments from the current context if the other command expects
-        it.  This cannot invoke callbacks directly, only other commands.
-
-        .. versionchanged:: 8.0
-            All ``kwargs`` are tracked in :attr:`params` so they will be
-            passed if ``forward`` is called at multiple levels.
-        """
-        # Can only forward to other commands, not direct callbacks.
-        if not isinstance(__cmd, Command):
-            raise TypeError("Callback is not a command.")
-
-        for param in __self.params:
-            if param not in kwargs:
-                kwargs[param] = __self.params[param]
-
-        return __self.invoke(__cmd, *args, **kwargs)
-
-    def set_parameter_source(self, name: str, source: ParameterSource) -> None:
-        """Set the source of a parameter. This indicates the location
-        from which the value of the parameter was obtained.
-
-        :param name: The name of the parameter.
-        :param source: A member of :class:`~click.core.ParameterSource`.
-        """
-        self._parameter_source[name] = source
-
-    def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]:
-        """Get the source of a parameter. This indicates the location
-        from which the value of the parameter was obtained.
-
-        This can be useful for determining when a user specified a value
-        on the command line that is the same as the default value. It
-        will be :attr:`~click.core.ParameterSource.DEFAULT` only if the
-        value was actually taken from the default.
-
-        :param name: The name of the parameter.
-        :rtype: ParameterSource
-
-        .. versionchanged:: 8.0
-            Returns ``None`` if the parameter was not provided from any
-            source.
-        """
-        return self._parameter_source.get(name)
-
-
-class BaseCommand:
-    """The base command implements the minimal API contract of commands.
-    Most code will never use this as it does not implement a lot of useful
-    functionality but it can act as the direct subclass of alternative
-    parsing methods that do not depend on the Click parser.
-
-    For instance, this can be used to bridge Click and other systems like
-    argparse or docopt.
-
-    Because base commands do not implement a lot of the API that other
-    parts of Click take for granted, they are not supported for all
-    operations.  For instance, they cannot be used with the decorators
-    usually and they have no built-in callback system.
-
-    .. versionchanged:: 2.0
-       Added the `context_settings` parameter.
-
-    :param name: the name of the command to use unless a group overrides it.
-    :param context_settings: an optional dictionary with defaults that are
-                             passed to the context object.
-    """
-
-    #: The context class to create with :meth:`make_context`.
-    #:
-    #: .. versionadded:: 8.0
-    context_class: t.Type[Context] = Context
-    #: the default for the :attr:`Context.allow_extra_args` flag.
-    allow_extra_args = False
-    #: the default for the :attr:`Context.allow_interspersed_args` flag.
-    allow_interspersed_args = True
-    #: the default for the :attr:`Context.ignore_unknown_options` flag.
-    ignore_unknown_options = False
-
-    def __init__(
-        self,
-        name: t.Optional[str],
-        context_settings: t.Optional[t.Dict[str, t.Any]] = None,
-    ) -> None:
-        #: the name the command thinks it has.  Upon registering a command
-        #: on a :class:`Group` the group will default the command name
-        #: with this information.  You should instead use the
-        #: :class:`Context`\'s :attr:`~Context.info_name` attribute.
-        self.name = name
-
-        if context_settings is None:
-            context_settings = {}
-
-        #: an optional dictionary with defaults passed to the context.
-        self.context_settings: t.Dict[str, t.Any] = context_settings
-
-    def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]:
-        """Gather information that could be useful for a tool generating
-        user-facing documentation. This traverses the entire structure
-        below this command.
-
-        Use :meth:`click.Context.to_info_dict` to traverse the entire
-        CLI structure.
-
-        :param ctx: A :class:`Context` representing this command.
-
-        .. versionadded:: 8.0
-        """
-        return {"name": self.name}
-
-    def __repr__(self) -> str:
-        return f"<{self.__class__.__name__} {self.name}>"
-
-    def get_usage(self, ctx: Context) -> str:
-        raise NotImplementedError("Base commands cannot get usage")
-
-    def get_help(self, ctx: Context) -> str:
-        raise NotImplementedError("Base commands cannot get help")
-
-    def make_context(
-        self,
-        info_name: t.Optional[str],
-        args: t.List[str],
-        parent: t.Optional[Context] = None,
-        **extra: t.Any,
-    ) -> Context:
-        """This function when given an info name and arguments will kick
-        off the parsing and create a new :class:`Context`.  It does not
-        invoke the actual command callback though.
-
-        To quickly customize the context class used without overriding
-        this method, set the :attr:`context_class` attribute.
-
-        :param info_name: the info name for this invocation.  Generally this
-                          is the most descriptive name for the script or
-                          command.  For the toplevel script it's usually
-                          the name of the script, for commands below it it's
-                          the name of the command.
-        :param args: the arguments to parse as list of strings.
-        :param parent: the parent context if available.
-        :param extra: extra keyword arguments forwarded to the context
-                      constructor.
-
-        .. versionchanged:: 8.0
-            Added the :attr:`context_class` attribute.
-        """
-        for key, value in self.context_settings.items():
-            if key not in extra:
-                extra[key] = value
-
-        ctx = self.context_class(
-            self, info_name=info_name, parent=parent, **extra  # type: ignore
-        )
-
-        with ctx.scope(cleanup=False):
-            self.parse_args(ctx, args)
-        return ctx
-
-    def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]:
-        """Given a context and a list of arguments this creates the parser
-        and parses the arguments, then modifies the context as necessary.
-        This is automatically invoked by :meth:`make_context`.
-        """
-        raise NotImplementedError("Base commands do not know how to parse arguments.")
-
-    def invoke(self, ctx: Context) -> t.Any:
-        """Given a context, this invokes the command.  The default
-        implementation is raising a not implemented error.
-        """
-        raise NotImplementedError("Base commands are not invokable by default")
-
-    def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]:
-        """Return a list of completions for the incomplete value. Looks
-        at the names of chained multi-commands.
-
-        Any command could be part of a chained multi-command, so sibling
-        commands are valid at any point during command completion. Other
-        command classes will return more completions.
-
-        :param ctx: Invocation context for this command.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        from click.shell_completion import CompletionItem
-
-        results: t.List["CompletionItem"] = []
-
-        while ctx.parent is not None:
-            ctx = ctx.parent
-
-            if isinstance(ctx.command, MultiCommand) and ctx.command.chain:
-                results.extend(
-                    CompletionItem(name, help=command.get_short_help_str())
-                    for name, command in _complete_visible_commands(ctx, incomplete)
-                    if name not in ctx.protected_args
-                )
-
-        return results
-
-    @t.overload
-    def main(
-        self,
-        args: t.Optional[t.Sequence[str]] = None,
-        prog_name: t.Optional[str] = None,
-        complete_var: t.Optional[str] = None,
-        standalone_mode: "te.Literal[True]" = True,
-        **extra: t.Any,
-    ) -> "te.NoReturn":
-        ...
-
-    @t.overload
-    def main(
-        self,
-        args: t.Optional[t.Sequence[str]] = None,
-        prog_name: t.Optional[str] = None,
-        complete_var: t.Optional[str] = None,
-        standalone_mode: bool = ...,
-        **extra: t.Any,
-    ) -> t.Any:
-        ...
-
-    def main(
-        self,
-        args: t.Optional[t.Sequence[str]] = None,
-        prog_name: t.Optional[str] = None,
-        complete_var: t.Optional[str] = None,
-        standalone_mode: bool = True,
-        windows_expand_args: bool = True,
-        **extra: t.Any,
-    ) -> t.Any:
-        """This is the way to invoke a script with all the bells and
-        whistles as a command line application.  This will always terminate
-        the application after a call.  If this is not wanted, ``SystemExit``
-        needs to be caught.
-
-        This method is also available by directly calling the instance of
-        a :class:`Command`.
-
-        :param args: the arguments that should be used for parsing.  If not
-                     provided, ``sys.argv[1:]`` is used.
-        :param prog_name: the program name that should be used.  By default
-                          the program name is constructed by taking the file
-                          name from ``sys.argv[0]``.
-        :param complete_var: the environment variable that controls the
-                             bash completion support.  The default is
-                             ``"_<prog_name>_COMPLETE"`` with prog_name in
-                             uppercase.
-        :param standalone_mode: the default behavior is to invoke the script
-                                in standalone mode.  Click will then
-                                handle exceptions and convert them into
-                                error messages and the function will never
-                                return but shut down the interpreter.  If
-                                this is set to `False` they will be
-                                propagated to the caller and the return
-                                value of this function is the return value
-                                of :meth:`invoke`.
-        :param windows_expand_args: Expand glob patterns, user dir, and
-            env vars in command line args on Windows.
-        :param extra: extra keyword arguments are forwarded to the context
-                      constructor.  See :class:`Context` for more information.
-
-        .. versionchanged:: 8.0.1
-            Added the ``windows_expand_args`` parameter to allow
-            disabling command line arg expansion on Windows.
-
-        .. versionchanged:: 8.0
-            When taking arguments from ``sys.argv`` on Windows, glob
-            patterns, user dir, and env vars are expanded.
-
-        .. versionchanged:: 3.0
-           Added the ``standalone_mode`` parameter.
-        """
-        if args is None:
-            args = sys.argv[1:]
-
-            if os.name == "nt" and windows_expand_args:
-                args = _expand_args(args)
-        else:
-            args = list(args)
-
-        if prog_name is None:
-            prog_name = _detect_program_name()
-
-        # Process shell completion requests and exit early.
-        self._main_shell_completion(extra, prog_name, complete_var)
-
-        try:
-            try:
-                with self.make_context(prog_name, args, **extra) as ctx:
-                    rv = self.invoke(ctx)
-                    if not standalone_mode:
-                        return rv
-                    # it's not safe to `ctx.exit(rv)` here!
-                    # note that `rv` may actually contain data like "1" which
-                    # has obvious effects
-                    # more subtle case: `rv=[None, None]` can come out of
-                    # chained commands which all returned `None` -- so it's not
-                    # even always obvious that `rv` indicates success/failure
-                    # by its truthiness/falsiness
-                    ctx.exit()
-            except (EOFError, KeyboardInterrupt):
-                echo(file=sys.stderr)
-                raise Abort() from None
-            except ClickException as e:
-                if not standalone_mode:
-                    raise
-                e.show()
-                sys.exit(e.exit_code)
-            except OSError as e:
-                if e.errno == errno.EPIPE:
-                    sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout))
-                    sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr))
-                    sys.exit(1)
-                else:
-                    raise
-        except Exit as e:
-            if standalone_mode:
-                sys.exit(e.exit_code)
-            else:
-                # in non-standalone mode, return the exit code
-                # note that this is only reached if `self.invoke` above raises
-                # an Exit explicitly -- thus bypassing the check there which
-                # would return its result
-                # the results of non-standalone execution may therefore be
-                # somewhat ambiguous: if there are codepaths which lead to
-                # `ctx.exit(1)` and to `return 1`, the caller won't be able to
-                # tell the difference between the two
-                return e.exit_code
-        except Abort:
-            if not standalone_mode:
-                raise
-            echo(_("Aborted!"), file=sys.stderr)
-            sys.exit(1)
-
-    def _main_shell_completion(
-        self,
-        ctx_args: t.Dict[str, t.Any],
-        prog_name: str,
-        complete_var: t.Optional[str] = None,
-    ) -> None:
-        """Check if the shell is asking for tab completion, process
-        that, then exit early. Called from :meth:`main` before the
-        program is invoked.
-
-        :param prog_name: Name of the executable in the shell.
-        :param complete_var: Name of the environment variable that holds
-            the completion instruction. Defaults to
-            ``_{PROG_NAME}_COMPLETE``.
-        """
-        if complete_var is None:
-            complete_var = f"_{prog_name}_COMPLETE".replace("-", "_").upper()
-
-        instruction = os.environ.get(complete_var)
-
-        if not instruction:
-            return
-
-        from .shell_completion import shell_complete
-
-        rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction)
-        sys.exit(rv)
-
-    def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
-        """Alias for :meth:`main`."""
-        return self.main(*args, **kwargs)
-
-
-class Command(BaseCommand):
-    """Commands are the basic building block of command line interfaces in
-    Click.  A basic command handles command line parsing and might dispatch
-    more parsing to commands nested below it.
-
-    :param name: the name of the command to use unless a group overrides it.
-    :param context_settings: an optional dictionary with defaults that are
-                             passed to the context object.
-    :param callback: the callback to invoke.  This is optional.
-    :param params: the parameters to register with this command.  This can
-                   be either :class:`Option` or :class:`Argument` objects.
-    :param help: the help string to use for this command.
-    :param epilog: like the help string but it's printed at the end of the
-                   help page after everything else.
-    :param short_help: the short help to use for this command.  This is
-                       shown on the command listing of the parent command.
-    :param add_help_option: by default each command registers a ``--help``
-                            option.  This can be disabled by this parameter.
-    :param no_args_is_help: this controls what happens if no arguments are
-                            provided.  This option is disabled by default.
-                            If enabled this will add ``--help`` as argument
-                            if no arguments are passed
-    :param hidden: hide this command from help outputs.
-
-    :param deprecated: issues a message indicating that
-                             the command is deprecated.
-
-    .. versionchanged:: 8.1
-        ``help``, ``epilog``, and ``short_help`` are stored unprocessed,
-        all formatting is done when outputting help text, not at init,
-        and is done even if not using the ``@command`` decorator.
-
-    .. versionchanged:: 8.0
-        Added a ``repr`` showing the command name.
-
-    .. versionchanged:: 7.1
-        Added the ``no_args_is_help`` parameter.
-
-    .. versionchanged:: 2.0
-        Added the ``context_settings`` parameter.
-    """
-
-    def __init__(
-        self,
-        name: t.Optional[str],
-        context_settings: t.Optional[t.Dict[str, t.Any]] = None,
-        callback: t.Optional[t.Callable[..., t.Any]] = None,
-        params: t.Optional[t.List["Parameter"]] = None,
-        help: t.Optional[str] = None,
-        epilog: t.Optional[str] = None,
-        short_help: t.Optional[str] = None,
-        options_metavar: t.Optional[str] = "[OPTIONS]",
-        add_help_option: bool = True,
-        no_args_is_help: bool = False,
-        hidden: bool = False,
-        deprecated: bool = False,
-    ) -> None:
-        super().__init__(name, context_settings)
-        #: the callback to execute when the command fires.  This might be
-        #: `None` in which case nothing happens.
-        self.callback = callback
-        #: the list of parameters for this command in the order they
-        #: should show up in the help page and execute.  Eager parameters
-        #: will automatically be handled before non eager ones.
-        self.params: t.List["Parameter"] = params or []
-        self.help = help
-        self.epilog = epilog
-        self.options_metavar = options_metavar
-        self.short_help = short_help
-        self.add_help_option = add_help_option
-        self.no_args_is_help = no_args_is_help
-        self.hidden = hidden
-        self.deprecated = deprecated
-
-    def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict(ctx)
-        info_dict.update(
-            params=[param.to_info_dict() for param in self.get_params(ctx)],
-            help=self.help,
-            epilog=self.epilog,
-            short_help=self.short_help,
-            hidden=self.hidden,
-            deprecated=self.deprecated,
-        )
-        return info_dict
-
-    def get_usage(self, ctx: Context) -> str:
-        """Formats the usage line into a string and returns it.
-
-        Calls :meth:`format_usage` internally.
-        """
-        formatter = ctx.make_formatter()
-        self.format_usage(ctx, formatter)
-        return formatter.getvalue().rstrip("\n")
-
-    def get_params(self, ctx: Context) -> t.List["Parameter"]:
-        rv = self.params
-        help_option = self.get_help_option(ctx)
-
-        if help_option is not None:
-            rv = [*rv, help_option]
-
-        return rv
-
-    def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None:
-        """Writes the usage line into the formatter.
-
-        This is a low-level method called by :meth:`get_usage`.
-        """
-        pieces = self.collect_usage_pieces(ctx)
-        formatter.write_usage(ctx.command_path, " ".join(pieces))
-
-    def collect_usage_pieces(self, ctx: Context) -> t.List[str]:
-        """Returns all the pieces that go into the usage line and returns
-        it as a list of strings.
-        """
-        rv = [self.options_metavar] if self.options_metavar else []
-
-        for param in self.get_params(ctx):
-            rv.extend(param.get_usage_pieces(ctx))
-
-        return rv
-
-    def get_help_option_names(self, ctx: Context) -> t.List[str]:
-        """Returns the names for the help option."""
-        all_names = set(ctx.help_option_names)
-        for param in self.params:
-            all_names.difference_update(param.opts)
-            all_names.difference_update(param.secondary_opts)
-        return list(all_names)
-
-    def get_help_option(self, ctx: Context) -> t.Optional["Option"]:
-        """Returns the help option object."""
-        help_options = self.get_help_option_names(ctx)
-
-        if not help_options or not self.add_help_option:
-            return None
-
-        def show_help(ctx: Context, param: "Parameter", value: str) -> None:
-            if value and not ctx.resilient_parsing:
-                echo(ctx.get_help(), color=ctx.color)
-                ctx.exit()
-
-        return Option(
-            help_options,
-            is_flag=True,
-            is_eager=True,
-            expose_value=False,
-            callback=show_help,
-            help=_("Show this message and exit."),
-        )
-
-    def make_parser(self, ctx: Context) -> OptionParser:
-        """Creates the underlying option parser for this command."""
-        parser = OptionParser(ctx)
-        for param in self.get_params(ctx):
-            param.add_to_parser(parser, ctx)
-        return parser
-
-    def get_help(self, ctx: Context) -> str:
-        """Formats the help into a string and returns it.
-
-        Calls :meth:`format_help` internally.
-        """
-        formatter = ctx.make_formatter()
-        self.format_help(ctx, formatter)
-        return formatter.getvalue().rstrip("\n")
-
-    def get_short_help_str(self, limit: int = 45) -> str:
-        """Gets short help for the command or makes it by shortening the
-        long help string.
-        """
-        if self.short_help:
-            text = inspect.cleandoc(self.short_help)
-        elif self.help:
-            text = make_default_short_help(self.help, limit)
-        else:
-            text = ""
-
-        if self.deprecated:
-            text = _("(Deprecated) {text}").format(text=text)
-
-        return text.strip()
-
-    def format_help(self, ctx: Context, formatter: HelpFormatter) -> None:
-        """Writes the help into the formatter if it exists.
-
-        This is a low-level method called by :meth:`get_help`.
-
-        This calls the following methods:
-
-        -   :meth:`format_usage`
-        -   :meth:`format_help_text`
-        -   :meth:`format_options`
-        -   :meth:`format_epilog`
-        """
-        self.format_usage(ctx, formatter)
-        self.format_help_text(ctx, formatter)
-        self.format_options(ctx, formatter)
-        self.format_epilog(ctx, formatter)
-
-    def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None:
-        """Writes the help text to the formatter if it exists."""
-        text = self.help if self.help is not None else ""
-
-        if self.deprecated:
-            text = _("(Deprecated) {text}").format(text=text)
-
-        if text:
-            text = inspect.cleandoc(text).partition("\f")[0]
-            formatter.write_paragraph()
-
-            with formatter.indentation():
-                formatter.write_text(text)
-
-    def format_options(self, ctx: Context, formatter: HelpFormatter) -> None:
-        """Writes all the options into the formatter if they exist."""
-        opts = []
-        for param in self.get_params(ctx):
-            rv = param.get_help_record(ctx)
-            if rv is not None:
-                opts.append(rv)
-
-        if opts:
-            with formatter.section(_("Options")):
-                formatter.write_dl(opts)
-
-    def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None:
-        """Writes the epilog into the formatter if it exists."""
-        if self.epilog:
-            epilog = inspect.cleandoc(self.epilog)
-            formatter.write_paragraph()
-
-            with formatter.indentation():
-                formatter.write_text(epilog)
-
-    def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]:
-        if not args and self.no_args_is_help and not ctx.resilient_parsing:
-            echo(ctx.get_help(), color=ctx.color)
-            ctx.exit()
-
-        parser = self.make_parser(ctx)
-        opts, args, param_order = parser.parse_args(args=args)
-
-        for param in iter_params_for_processing(param_order, self.get_params(ctx)):
-            value, args = param.handle_parse_result(ctx, opts, args)
-
-        if args and not ctx.allow_extra_args and not ctx.resilient_parsing:
-            ctx.fail(
-                ngettext(
-                    "Got unexpected extra argument ({args})",
-                    "Got unexpected extra arguments ({args})",
-                    len(args),
-                ).format(args=" ".join(map(str, args)))
-            )
-
-        ctx.args = args
-        ctx._opt_prefixes.update(parser._opt_prefixes)
-        return args
-
-    def invoke(self, ctx: Context) -> t.Any:
-        """Given a context, this invokes the attached callback (if it exists)
-        in the right way.
-        """
-        if self.deprecated:
-            message = _(
-                "DeprecationWarning: The command {name!r} is deprecated."
-            ).format(name=self.name)
-            echo(style(message, fg="red"), err=True)
-
-        if self.callback is not None:
-            return ctx.invoke(self.callback, **ctx.params)
-
-    def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]:
-        """Return a list of completions for the incomplete value. Looks
-        at the names of options and chained multi-commands.
-
-        :param ctx: Invocation context for this command.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        from click.shell_completion import CompletionItem
-
-        results: t.List["CompletionItem"] = []
-
-        if incomplete and not incomplete[0].isalnum():
-            for param in self.get_params(ctx):
-                if (
-                    not isinstance(param, Option)
-                    or param.hidden
-                    or (
-                        not param.multiple
-                        and ctx.get_parameter_source(param.name)  # type: ignore
-                        is ParameterSource.COMMANDLINE
-                    )
-                ):
-                    continue
-
-                results.extend(
-                    CompletionItem(name, help=param.help)
-                    for name in [*param.opts, *param.secondary_opts]
-                    if name.startswith(incomplete)
-                )
-
-        results.extend(super().shell_complete(ctx, incomplete))
-        return results
-
-
-class MultiCommand(Command):
-    """A multi command is the basic implementation of a command that
-    dispatches to subcommands.  The most common version is the
-    :class:`Group`.
-
-    :param invoke_without_command: this controls how the multi command itself
-                                   is invoked.  By default it's only invoked
-                                   if a subcommand is provided.
-    :param no_args_is_help: this controls what happens if no arguments are
-                            provided.  This option is enabled by default if
-                            `invoke_without_command` is disabled or disabled
-                            if it's enabled.  If enabled this will add
-                            ``--help`` as argument if no arguments are
-                            passed.
-    :param subcommand_metavar: the string that is used in the documentation
-                               to indicate the subcommand place.
-    :param chain: if this is set to `True` chaining of multiple subcommands
-                  is enabled.  This restricts the form of commands in that
-                  they cannot have optional arguments but it allows
-                  multiple commands to be chained together.
-    :param result_callback: The result callback to attach to this multi
-        command. This can be set or changed later with the
-        :meth:`result_callback` decorator.
-    """
-
-    allow_extra_args = True
-    allow_interspersed_args = False
-
-    def __init__(
-        self,
-        name: t.Optional[str] = None,
-        invoke_without_command: bool = False,
-        no_args_is_help: t.Optional[bool] = None,
-        subcommand_metavar: t.Optional[str] = None,
-        chain: bool = False,
-        result_callback: t.Optional[t.Callable[..., t.Any]] = None,
-        **attrs: t.Any,
-    ) -> None:
-        super().__init__(name, **attrs)
-
-        if no_args_is_help is None:
-            no_args_is_help = not invoke_without_command
-
-        self.no_args_is_help = no_args_is_help
-        self.invoke_without_command = invoke_without_command
-
-        if subcommand_metavar is None:
-            if chain:
-                subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..."
-            else:
-                subcommand_metavar = "COMMAND [ARGS]..."
-
-        self.subcommand_metavar = subcommand_metavar
-        self.chain = chain
-        # The result callback that is stored. This can be set or
-        # overridden with the :func:`result_callback` decorator.
-        self._result_callback = result_callback
-
-        if self.chain:
-            for param in self.params:
-                if isinstance(param, Argument) and not param.required:
-                    raise RuntimeError(
-                        "Multi commands in chain mode cannot have"
-                        " optional arguments."
-                    )
-
-    def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict(ctx)
-        commands = {}
-
-        for name in self.list_commands(ctx):
-            command = self.get_command(ctx, name)
-
-            if command is None:
-                continue
-
-            sub_ctx = ctx._make_sub_context(command)
-
-            with sub_ctx.scope(cleanup=False):
-                commands[name] = command.to_info_dict(sub_ctx)
-
-        info_dict.update(commands=commands, chain=self.chain)
-        return info_dict
-
-    def collect_usage_pieces(self, ctx: Context) -> t.List[str]:
-        rv = super().collect_usage_pieces(ctx)
-        rv.append(self.subcommand_metavar)
-        return rv
-
-    def format_options(self, ctx: Context, formatter: HelpFormatter) -> None:
-        super().format_options(ctx, formatter)
-        self.format_commands(ctx, formatter)
-
-    def result_callback(self, replace: bool = False) -> t.Callable[[F], F]:
-        """Adds a result callback to the command.  By default if a
-        result callback is already registered this will chain them but
-        this can be disabled with the `replace` parameter.  The result
-        callback is invoked with the return value of the subcommand
-        (or the list of return values from all subcommands if chaining
-        is enabled) as well as the parameters as they would be passed
-        to the main callback.
-
-        Example::
-
-            @click.group()
-            @click.option('-i', '--input', default=23)
-            def cli(input):
-                return 42
-
-            @cli.result_callback()
-            def process_result(result, input):
-                return result + input
-
-        :param replace: if set to `True` an already existing result
-                        callback will be removed.
-
-        .. versionchanged:: 8.0
-            Renamed from ``resultcallback``.
-
-        .. versionadded:: 3.0
-        """
-
-        def decorator(f: F) -> F:
-            old_callback = self._result_callback
-
-            if old_callback is None or replace:
-                self._result_callback = f
-                return f
-
-            def function(__value, *args, **kwargs):  # type: ignore
-                inner = old_callback(__value, *args, **kwargs)  # type: ignore
-                return f(inner, *args, **kwargs)
-
-            self._result_callback = rv = update_wrapper(t.cast(F, function), f)
-            return rv
-
-        return decorator
-
-    def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None:
-        """Extra format methods for multi methods that adds all the commands
-        after the options.
-        """
-        commands = []
-        for subcommand in self.list_commands(ctx):
-            cmd = self.get_command(ctx, subcommand)
-            # What is this, the tool lied about a command.  Ignore it
-            if cmd is None:
-                continue
-            if cmd.hidden:
-                continue
-
-            commands.append((subcommand, cmd))
-
-        # allow for 3 times the default spacing
-        if len(commands):
-            limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands)
-
-            rows = []
-            for subcommand, cmd in commands:
-                help = cmd.get_short_help_str(limit)
-                rows.append((subcommand, help))
-
-            if rows:
-                with formatter.section(_("Commands")):
-                    formatter.write_dl(rows)
-
-    def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]:
-        if not args and self.no_args_is_help and not ctx.resilient_parsing:
-            echo(ctx.get_help(), color=ctx.color)
-            ctx.exit()
-
-        rest = super().parse_args(ctx, args)
-
-        if self.chain:
-            ctx.protected_args = rest
-            ctx.args = []
-        elif rest:
-            ctx.protected_args, ctx.args = rest[:1], rest[1:]
-
-        return ctx.args
-
-    def invoke(self, ctx: Context) -> t.Any:
-        def _process_result(value: t.Any) -> t.Any:
-            if self._result_callback is not None:
-                value = ctx.invoke(self._result_callback, value, **ctx.params)
-            return value
-
-        if not ctx.protected_args:
-            if self.invoke_without_command:
-                # No subcommand was invoked, so the result callback is
-                # invoked with the group return value for regular
-                # groups, or an empty list for chained groups.
-                with ctx:
-                    rv = super().invoke(ctx)
-                    return _process_result([] if self.chain else rv)
-            ctx.fail(_("Missing command."))
-
-        # Fetch args back out
-        args = [*ctx.protected_args, *ctx.args]
-        ctx.args = []
-        ctx.protected_args = []
-
-        # If we're not in chain mode, we only allow the invocation of a
-        # single command but we also inform the current context about the
-        # name of the command to invoke.
-        if not self.chain:
-            # Make sure the context is entered so we do not clean up
-            # resources until the result processor has worked.
-            with ctx:
-                cmd_name, cmd, args = self.resolve_command(ctx, args)
-                assert cmd is not None
-                ctx.invoked_subcommand = cmd_name
-                super().invoke(ctx)
-                sub_ctx = cmd.make_context(cmd_name, args, parent=ctx)
-                with sub_ctx:
-                    return _process_result(sub_ctx.command.invoke(sub_ctx))
-
-        # In chain mode we create the contexts step by step, but after the
-        # base command has been invoked.  Because at that point we do not
-        # know the subcommands yet, the invoked subcommand attribute is
-        # set to ``*`` to inform the command that subcommands are executed
-        # but nothing else.
-        with ctx:
-            ctx.invoked_subcommand = "*" if args else None
-            super().invoke(ctx)
-
-            # Otherwise we make every single context and invoke them in a
-            # chain.  In that case the return value to the result processor
-            # is the list of all invoked subcommand's results.
-            contexts = []
-            while args:
-                cmd_name, cmd, args = self.resolve_command(ctx, args)
-                assert cmd is not None
-                sub_ctx = cmd.make_context(
-                    cmd_name,
-                    args,
-                    parent=ctx,
-                    allow_extra_args=True,
-                    allow_interspersed_args=False,
-                )
-                contexts.append(sub_ctx)
-                args, sub_ctx.args = sub_ctx.args, []
-
-            rv = []
-            for sub_ctx in contexts:
-                with sub_ctx:
-                    rv.append(sub_ctx.command.invoke(sub_ctx))
-            return _process_result(rv)
-
-    def resolve_command(
-        self, ctx: Context, args: t.List[str]
-    ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]:
-        cmd_name = make_str(args[0])
-        original_cmd_name = cmd_name
-
-        # Get the command
-        cmd = self.get_command(ctx, cmd_name)
-
-        # If we can't find the command but there is a normalization
-        # function available, we try with that one.
-        if cmd is None and ctx.token_normalize_func is not None:
-            cmd_name = ctx.token_normalize_func(cmd_name)
-            cmd = self.get_command(ctx, cmd_name)
-
-        # If we don't find the command we want to show an error message
-        # to the user that it was not provided.  However, there is
-        # something else we should do: if the first argument looks like
-        # an option we want to kick off parsing again for arguments to
-        # resolve things like --help which now should go to the main
-        # place.
-        if cmd is None and not ctx.resilient_parsing:
-            if split_opt(cmd_name)[0]:
-                self.parse_args(ctx, ctx.args)
-            ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name))
-        return cmd_name if cmd else None, cmd, args[1:]
-
-    def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]:
-        """Given a context and a command name, this returns a
-        :class:`Command` object if it exists or returns `None`.
-        """
-        raise NotImplementedError
-
-    def list_commands(self, ctx: Context) -> t.List[str]:
-        """Returns a list of subcommand names in the order they should
-        appear.
-        """
-        return []
-
-    def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]:
-        """Return a list of completions for the incomplete value. Looks
-        at the names of options, subcommands, and chained
-        multi-commands.
-
-        :param ctx: Invocation context for this command.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        from click.shell_completion import CompletionItem
-
-        results = [
-            CompletionItem(name, help=command.get_short_help_str())
-            for name, command in _complete_visible_commands(ctx, incomplete)
-        ]
-        results.extend(super().shell_complete(ctx, incomplete))
-        return results
-
-
-class Group(MultiCommand):
-    """A group allows a command to have subcommands attached. This is
-    the most common way to implement nesting in Click.
-
-    :param name: The name of the group command.
-    :param commands: A dict mapping names to :class:`Command` objects.
-        Can also be a list of :class:`Command`, which will use
-        :attr:`Command.name` to create the dict.
-    :param attrs: Other command arguments described in
-        :class:`MultiCommand`, :class:`Command`, and
-        :class:`BaseCommand`.
-
-    .. versionchanged:: 8.0
-        The ``commmands`` argument can be a list of command objects.
-    """
-
-    #: If set, this is used by the group's :meth:`command` decorator
-    #: as the default :class:`Command` class. This is useful to make all
-    #: subcommands use a custom command class.
-    #:
-    #: .. versionadded:: 8.0
-    command_class: t.Optional[t.Type[Command]] = None
-
-    #: If set, this is used by the group's :meth:`group` decorator
-    #: as the default :class:`Group` class. This is useful to make all
-    #: subgroups use a custom group class.
-    #:
-    #: If set to the special value :class:`type` (literally
-    #: ``group_class = type``), this group's class will be used as the
-    #: default class. This makes a custom group class continue to make
-    #: custom groups.
-    #:
-    #: .. versionadded:: 8.0
-    group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None
-    # Literal[type] isn't valid, so use Type[type]
-
-    def __init__(
-        self,
-        name: t.Optional[str] = None,
-        commands: t.Optional[t.Union[t.Dict[str, Command], t.Sequence[Command]]] = None,
-        **attrs: t.Any,
-    ) -> None:
-        super().__init__(name, **attrs)
-
-        if commands is None:
-            commands = {}
-        elif isinstance(commands, abc.Sequence):
-            commands = {c.name: c for c in commands if c.name is not None}
-
-        #: The registered subcommands by their exported names.
-        self.commands: t.Dict[str, Command] = commands
-
-    def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None:
-        """Registers another :class:`Command` with this group.  If the name
-        is not provided, the name of the command is used.
-        """
-        name = name or cmd.name
-        if name is None:
-            raise TypeError("Command has no name.")
-        _check_multicommand(self, name, cmd, register=True)
-        self.commands[name] = cmd
-
-    @t.overload
-    def command(self, __func: t.Callable[..., t.Any]) -> Command:
-        ...
-
-    @t.overload
-    def command(
-        self, *args: t.Any, **kwargs: t.Any
-    ) -> t.Callable[[t.Callable[..., t.Any]], Command]:
-        ...
-
-    def command(
-        self, *args: t.Any, **kwargs: t.Any
-    ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]:
-        """A shortcut decorator for declaring and attaching a command to
-        the group. This takes the same arguments as :func:`command` and
-        immediately registers the created command with this group by
-        calling :meth:`add_command`.
-
-        To customize the command class used, set the
-        :attr:`command_class` attribute.
-
-        .. versionchanged:: 8.1
-            This decorator can be applied without parentheses.
-
-        .. versionchanged:: 8.0
-            Added the :attr:`command_class` attribute.
-        """
-        from .decorators import command
-
-        if self.command_class and kwargs.get("cls") is None:
-            kwargs["cls"] = self.command_class
-
-        func: t.Optional[t.Callable] = None
-
-        if args and callable(args[0]):
-            assert (
-                len(args) == 1 and not kwargs
-            ), "Use 'command(**kwargs)(callable)' to provide arguments."
-            (func,) = args
-            args = ()
-
-        def decorator(f: t.Callable[..., t.Any]) -> Command:
-            cmd: Command = command(*args, **kwargs)(f)
-            self.add_command(cmd)
-            return cmd
-
-        if func is not None:
-            return decorator(func)
-
-        return decorator
-
-    @t.overload
-    def group(self, __func: t.Callable[..., t.Any]) -> "Group":
-        ...
-
-    @t.overload
-    def group(
-        self, *args: t.Any, **kwargs: t.Any
-    ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]:
-        ...
-
-    def group(
-        self, *args: t.Any, **kwargs: t.Any
-    ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]:
-        """A shortcut decorator for declaring and attaching a group to
-        the group. This takes the same arguments as :func:`group` and
-        immediately registers the created group with this group by
-        calling :meth:`add_command`.
-
-        To customize the group class used, set the :attr:`group_class`
-        attribute.
-
-        .. versionchanged:: 8.1
-            This decorator can be applied without parentheses.
-
-        .. versionchanged:: 8.0
-            Added the :attr:`group_class` attribute.
-        """
-        from .decorators import group
-
-        func: t.Optional[t.Callable] = None
-
-        if args and callable(args[0]):
-            assert (
-                len(args) == 1 and not kwargs
-            ), "Use 'group(**kwargs)(callable)' to provide arguments."
-            (func,) = args
-            args = ()
-
-        if self.group_class is not None and kwargs.get("cls") is None:
-            if self.group_class is type:
-                kwargs["cls"] = type(self)
-            else:
-                kwargs["cls"] = self.group_class
-
-        def decorator(f: t.Callable[..., t.Any]) -> "Group":
-            cmd: Group = group(*args, **kwargs)(f)
-            self.add_command(cmd)
-            return cmd
-
-        if func is not None:
-            return decorator(func)
-
-        return decorator
-
-    def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]:
-        return self.commands.get(cmd_name)
-
-    def list_commands(self, ctx: Context) -> t.List[str]:
-        return sorted(self.commands)
-
-
-class CommandCollection(MultiCommand):
-    """A command collection is a multi command that merges multiple multi
-    commands together into one.  This is a straightforward implementation
-    that accepts a list of different multi commands as sources and
-    provides all the commands for each of them.
-    """
-
-    def __init__(
-        self,
-        name: t.Optional[str] = None,
-        sources: t.Optional[t.List[MultiCommand]] = None,
-        **attrs: t.Any,
-    ) -> None:
-        super().__init__(name, **attrs)
-        #: The list of registered multi commands.
-        self.sources: t.List[MultiCommand] = sources or []
-
-    def add_source(self, multi_cmd: MultiCommand) -> None:
-        """Adds a new multi command to the chain dispatcher."""
-        self.sources.append(multi_cmd)
-
-    def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]:
-        for source in self.sources:
-            rv = source.get_command(ctx, cmd_name)
-
-            if rv is not None:
-                if self.chain:
-                    _check_multicommand(self, cmd_name, rv)
-
-                return rv
-
-        return None
-
-    def list_commands(self, ctx: Context) -> t.List[str]:
-        rv: t.Set[str] = set()
-
-        for source in self.sources:
-            rv.update(source.list_commands(ctx))
-
-        return sorted(rv)
-
-
-def _check_iter(value: t.Any) -> t.Iterator[t.Any]:
-    """Check if the value is iterable but not a string. Raises a type
-    error, or return an iterator over the value.
-    """
-    if isinstance(value, str):
-        raise TypeError
-
-    return iter(value)
-
-
-class Parameter:
-    r"""A parameter to a command comes in two versions: they are either
-    :class:`Option`\s or :class:`Argument`\s.  Other subclasses are currently
-    not supported by design as some of the internals for parsing are
-    intentionally not finalized.
-
-    Some settings are supported by both options and arguments.
-
-    :param param_decls: the parameter declarations for this option or
-                        argument.  This is a list of flags or argument
-                        names.
-    :param type: the type that should be used.  Either a :class:`ParamType`
-                 or a Python type.  The later is converted into the former
-                 automatically if supported.
-    :param required: controls if this is optional or not.
-    :param default: the default value if omitted.  This can also be a callable,
-                    in which case it's invoked when the default is needed
-                    without any arguments.
-    :param callback: A function to further process or validate the value
-        after type conversion. It is called as ``f(ctx, param, value)``
-        and must return the value. It is called for all sources,
-        including prompts.
-    :param nargs: the number of arguments to match.  If not ``1`` the return
-                  value is a tuple instead of single value.  The default for
-                  nargs is ``1`` (except if the type is a tuple, then it's
-                  the arity of the tuple). If ``nargs=-1``, all remaining
-                  parameters are collected.
-    :param metavar: how the value is represented in the help page.
-    :param expose_value: if this is `True` then the value is passed onwards
-                         to the command callback and stored on the context,
-                         otherwise it's skipped.
-    :param is_eager: eager values are processed before non eager ones.  This
-                     should not be set for arguments or it will inverse the
-                     order of processing.
-    :param envvar: a string or list of strings that are environment variables
-                   that should be checked.
-    :param shell_complete: A function that returns custom shell
-        completions. Used instead of the param's type completion if
-        given. Takes ``ctx, param, incomplete`` and must return a list
-        of :class:`~click.shell_completion.CompletionItem` or a list of
-        strings.
-
-    .. versionchanged:: 8.0
-        ``process_value`` validates required parameters and bounded
-        ``nargs``, and invokes the parameter callback before returning
-        the value. This allows the callback to validate prompts.
-        ``full_process_value`` is removed.
-
-    .. versionchanged:: 8.0
-        ``autocompletion`` is renamed to ``shell_complete`` and has new
-        semantics described above. The old name is deprecated and will
-        be removed in 8.1, until then it will be wrapped to match the
-        new requirements.
-
-    .. versionchanged:: 8.0
-        For ``multiple=True, nargs>1``, the default must be a list of
-        tuples.
-
-    .. versionchanged:: 8.0
-        Setting a default is no longer required for ``nargs>1``, it will
-        default to ``None``. ``multiple=True`` or ``nargs=-1`` will
-        default to ``()``.
-
-    .. versionchanged:: 7.1
-        Empty environment variables are ignored rather than taking the
-        empty string value. This makes it possible for scripts to clear
-        variables if they can't unset them.
-
-    .. versionchanged:: 2.0
-        Changed signature for parameter callback to also be passed the
-        parameter. The old callback format will still work, but it will
-        raise a warning to give you a chance to migrate the code easier.
-    """
-
-    param_type_name = "parameter"
-
-    def __init__(
-        self,
-        param_decls: t.Optional[t.Sequence[str]] = None,
-        type: t.Optional[t.Union[types.ParamType, t.Any]] = None,
-        required: bool = False,
-        default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None,
-        callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None,
-        nargs: t.Optional[int] = None,
-        multiple: bool = False,
-        metavar: t.Optional[str] = None,
-        expose_value: bool = True,
-        is_eager: bool = False,
-        envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None,
-        shell_complete: t.Optional[
-            t.Callable[
-                [Context, "Parameter", str],
-                t.Union[t.List["CompletionItem"], t.List[str]],
-            ]
-        ] = None,
-    ) -> None:
-        self.name, self.opts, self.secondary_opts = self._parse_decls(
-            param_decls or (), expose_value
-        )
-        self.type = types.convert_type(type, default)
-
-        # Default nargs to what the type tells us if we have that
-        # information available.
-        if nargs is None:
-            if self.type.is_composite:
-                nargs = self.type.arity
-            else:
-                nargs = 1
-
-        self.required = required
-        self.callback = callback
-        self.nargs = nargs
-        self.multiple = multiple
-        self.expose_value = expose_value
-        self.default = default
-        self.is_eager = is_eager
-        self.metavar = metavar
-        self.envvar = envvar
-        self._custom_shell_complete = shell_complete
-
-        if __debug__:
-            if self.type.is_composite and nargs != self.type.arity:
-                raise ValueError(
-                    f"'nargs' must be {self.type.arity} (or None) for"
-                    f" type {self.type!r}, but it was {nargs}."
-                )
-
-            # Skip no default or callable default.
-            check_default = default if not callable(default) else None
-
-            if check_default is not None:
-                if multiple:
-                    try:
-                        # Only check the first value against nargs.
-                        check_default = next(_check_iter(check_default), None)
-                    except TypeError:
-                        raise ValueError(
-                            "'default' must be a list when 'multiple' is true."
-                        ) from None
-
-                # Can be None for multiple with empty default.
-                if nargs != 1 and check_default is not None:
-                    try:
-                        _check_iter(check_default)
-                    except TypeError:
-                        if multiple:
-                            message = (
-                                "'default' must be a list of lists when 'multiple' is"
-                                " true and 'nargs' != 1."
-                            )
-                        else:
-                            message = "'default' must be a list when 'nargs' != 1."
-
-                        raise ValueError(message) from None
-
-                    if nargs > 1 and len(check_default) != nargs:
-                        subject = "item length" if multiple else "length"
-                        raise ValueError(
-                            f"'default' {subject} must match nargs={nargs}."
-                        )
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        """Gather information that could be useful for a tool generating
-        user-facing documentation.
-
-        Use :meth:`click.Context.to_info_dict` to traverse the entire
-        CLI structure.
-
-        .. versionadded:: 8.0
-        """
-        return {
-            "name": self.name,
-            "param_type_name": self.param_type_name,
-            "opts": self.opts,
-            "secondary_opts": self.secondary_opts,
-            "type": self.type.to_info_dict(),
-            "required": self.required,
-            "nargs": self.nargs,
-            "multiple": self.multiple,
-            "default": self.default,
-            "envvar": self.envvar,
-        }
-
-    def __repr__(self) -> str:
-        return f"<{self.__class__.__name__} {self.name}>"
-
-    def _parse_decls(
-        self, decls: t.Sequence[str], expose_value: bool
-    ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]:
-        raise NotImplementedError()
-
-    @property
-    def human_readable_name(self) -> str:
-        """Returns the human readable name of this parameter.  This is the
-        same as the name for options, but the metavar for arguments.
-        """
-        return self.name  # type: ignore
-
-    def make_metavar(self) -> str:
-        if self.metavar is not None:
-            return self.metavar
-
-        metavar = self.type.get_metavar(self)
-
-        if metavar is None:
-            metavar = self.type.name.upper()
-
-        if self.nargs != 1:
-            metavar += "..."
-
-        return metavar
-
-    @t.overload
-    def get_default(
-        self, ctx: Context, call: "te.Literal[True]" = True
-    ) -> t.Optional[t.Any]:
-        ...
-
-    @t.overload
-    def get_default(
-        self, ctx: Context, call: bool = ...
-    ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]:
-        ...
-
-    def get_default(
-        self, ctx: Context, call: bool = True
-    ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]:
-        """Get the default for the parameter. Tries
-        :meth:`Context.lookup_default` first, then the local default.
-
-        :param ctx: Current context.
-        :param call: If the default is a callable, call it. Disable to
-            return the callable instead.
-
-        .. versionchanged:: 8.0.2
-            Type casting is no longer performed when getting a default.
-
-        .. versionchanged:: 8.0.1
-            Type casting can fail in resilient parsing mode. Invalid
-            defaults will not prevent showing help text.
-
-        .. versionchanged:: 8.0
-            Looks at ``ctx.default_map`` first.
-
-        .. versionchanged:: 8.0
-            Added the ``call`` parameter.
-        """
-        value = ctx.lookup_default(self.name, call=False)  # type: ignore
-
-        if value is None:
-            value = self.default
-
-        if call and callable(value):
-            value = value()
-
-        return value
-
-    def add_to_parser(self, parser: OptionParser, ctx: Context) -> None:
-        raise NotImplementedError()
-
-    def consume_value(
-        self, ctx: Context, opts: t.Mapping[str, t.Any]
-    ) -> t.Tuple[t.Any, ParameterSource]:
-        value = opts.get(self.name)  # type: ignore
-        source = ParameterSource.COMMANDLINE
-
-        if value is None:
-            value = self.value_from_envvar(ctx)
-            source = ParameterSource.ENVIRONMENT
-
-        if value is None:
-            value = ctx.lookup_default(self.name)  # type: ignore
-            source = ParameterSource.DEFAULT_MAP
-
-        if value is None:
-            value = self.get_default(ctx)
-            source = ParameterSource.DEFAULT
-
-        return value, source
-
-    def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any:
-        """Convert and validate a value against the option's
-        :attr:`type`, :attr:`multiple`, and :attr:`nargs`.
-        """
-        if value is None:
-            return () if self.multiple or self.nargs == -1 else None
-
-        def check_iter(value: t.Any) -> t.Iterator:
-            try:
-                return _check_iter(value)
-            except TypeError:
-                # This should only happen when passing in args manually,
-                # the parser should construct an iterable when parsing
-                # the command line.
-                raise BadParameter(
-                    _("Value must be an iterable."), ctx=ctx, param=self
-                ) from None
-
-        if self.nargs == 1 or self.type.is_composite:
-            convert: t.Callable[[t.Any], t.Any] = partial(
-                self.type, param=self, ctx=ctx
-            )
-        elif self.nargs == -1:
-
-            def convert(value: t.Any) -> t.Tuple:
-                return tuple(self.type(x, self, ctx) for x in check_iter(value))
-
-        else:  # nargs > 1
-
-            def convert(value: t.Any) -> t.Tuple:
-                value = tuple(check_iter(value))
-
-                if len(value) != self.nargs:
-                    raise BadParameter(
-                        ngettext(
-                            "Takes {nargs} values but 1 was given.",
-                            "Takes {nargs} values but {len} were given.",
-                            len(value),
-                        ).format(nargs=self.nargs, len=len(value)),
-                        ctx=ctx,
-                        param=self,
-                    )
-
-                return tuple(self.type(x, self, ctx) for x in value)
-
-        if self.multiple:
-            return tuple(convert(x) for x in check_iter(value))
-
-        return convert(value)
-
-    def value_is_missing(self, value: t.Any) -> bool:
-        if value is None:
-            return True
-
-        if (self.nargs != 1 or self.multiple) and value == ():
-            return True
-
-        return False
-
-    def process_value(self, ctx: Context, value: t.Any) -> t.Any:
-        value = self.type_cast_value(ctx, value)
-
-        if self.required and self.value_is_missing(value):
-            raise MissingParameter(ctx=ctx, param=self)
-
-        if self.callback is not None:
-            value = self.callback(ctx, self, value)
-
-        return value
-
-    def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]:
-        if self.envvar is None:
-            return None
-
-        if isinstance(self.envvar, str):
-            rv = os.environ.get(self.envvar)
-
-            if rv:
-                return rv
-        else:
-            for envvar in self.envvar:
-                rv = os.environ.get(envvar)
-
-                if rv:
-                    return rv
-
-        return None
-
-    def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]:
-        rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx)
-
-        if rv is not None and self.nargs != 1:
-            rv = self.type.split_envvar_value(rv)
-
-        return rv
-
-    def handle_parse_result(
-        self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str]
-    ) -> t.Tuple[t.Any, t.List[str]]:
-        with augment_usage_errors(ctx, param=self):
-            value, source = self.consume_value(ctx, opts)
-            ctx.set_parameter_source(self.name, source)  # type: ignore
-
-            try:
-                value = self.process_value(ctx, value)
-            except Exception:
-                if not ctx.resilient_parsing:
-                    raise
-
-                value = None
-
-        if self.expose_value:
-            ctx.params[self.name] = value  # type: ignore
-
-        return value, args
-
-    def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]:
-        pass
-
-    def get_usage_pieces(self, ctx: Context) -> t.List[str]:
-        return []
-
-    def get_error_hint(self, ctx: Context) -> str:
-        """Get a stringified version of the param for use in error messages to
-        indicate which param caused the error.
-        """
-        hint_list = self.opts or [self.human_readable_name]
-        return " / ".join(f"'{x}'" for x in hint_list)
-
-    def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]:
-        """Return a list of completions for the incomplete value. If a
-        ``shell_complete`` function was given during init, it is used.
-        Otherwise, the :attr:`type`
-        :meth:`~click.types.ParamType.shell_complete` function is used.
-
-        :param ctx: Invocation context for this command.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        if self._custom_shell_complete is not None:
-            results = self._custom_shell_complete(ctx, self, incomplete)
-
-            if results and isinstance(results[0], str):
-                from click.shell_completion import CompletionItem
-
-                results = [CompletionItem(c) for c in results]
-
-            return t.cast(t.List["CompletionItem"], results)
-
-        return self.type.shell_complete(ctx, self, incomplete)
-
-
-class Option(Parameter):
-    """Options are usually optional values on the command line and
-    have some extra features that arguments don't have.
-
-    All other parameters are passed onwards to the parameter constructor.
-
-    :param show_default: Show the default value for this option in its
-        help text. Values are not shown by default, unless
-        :attr:`Context.show_default` is ``True``. If this value is a
-        string, it shows that string in parentheses instead of the
-        actual value. This is particularly useful for dynamic options.
-        For single option boolean flags, the default remains hidden if
-        its value is ``False``.
-    :param show_envvar: Controls if an environment variable should be
-        shown on the help page. Normally, environment variables are not
-        shown.
-    :param prompt: If set to ``True`` or a non empty string then the
-        user will be prompted for input. If set to ``True`` the prompt
-        will be the option name capitalized.
-    :param confirmation_prompt: Prompt a second time to confirm the
-        value if it was prompted for. Can be set to a string instead of
-        ``True`` to customize the message.
-    :param prompt_required: If set to ``False``, the user will be
-        prompted for input only when the option was specified as a flag
-        without a value.
-    :param hide_input: If this is ``True`` then the input on the prompt
-        will be hidden from the user. This is useful for password input.
-    :param is_flag: forces this option to act as a flag.  The default is
-                    auto detection.
-    :param flag_value: which value should be used for this flag if it's
-                       enabled.  This is set to a boolean automatically if
-                       the option string contains a slash to mark two options.
-    :param multiple: if this is set to `True` then the argument is accepted
-                     multiple times and recorded.  This is similar to ``nargs``
-                     in how it works but supports arbitrary number of
-                     arguments.
-    :param count: this flag makes an option increment an integer.
-    :param allow_from_autoenv: if this is enabled then the value of this
-                               parameter will be pulled from an environment
-                               variable in case a prefix is defined on the
-                               context.
-    :param help: the help string.
-    :param hidden: hide this option from help outputs.
-
-    .. versionchanged:: 8.1.0
-        Help text indentation is cleaned here instead of only in the
-        ``@option`` decorator.
-
-    .. versionchanged:: 8.1.0
-        The ``show_default`` parameter overrides
-        ``Context.show_default``.
-
-    .. versionchanged:: 8.1.0
-        The default of a single option boolean flag is not shown if the
-        default value is ``False``.
-
-    .. versionchanged:: 8.0.1
-        ``type`` is detected from ``flag_value`` if given.
-    """
-
-    param_type_name = "option"
-
-    def __init__(
-        self,
-        param_decls: t.Optional[t.Sequence[str]] = None,
-        show_default: t.Union[bool, str, None] = None,
-        prompt: t.Union[bool, str] = False,
-        confirmation_prompt: t.Union[bool, str] = False,
-        prompt_required: bool = True,
-        hide_input: bool = False,
-        is_flag: t.Optional[bool] = None,
-        flag_value: t.Optional[t.Any] = None,
-        multiple: bool = False,
-        count: bool = False,
-        allow_from_autoenv: bool = True,
-        type: t.Optional[t.Union[types.ParamType, t.Any]] = None,
-        help: t.Optional[str] = None,
-        hidden: bool = False,
-        show_choices: bool = True,
-        show_envvar: bool = False,
-        **attrs: t.Any,
-    ) -> None:
-        if help:
-            help = inspect.cleandoc(help)
-
-        default_is_missing = "default" not in attrs
-        super().__init__(param_decls, type=type, multiple=multiple, **attrs)
-
-        if prompt is True:
-            if self.name is None:
-                raise TypeError("'name' is required with 'prompt=True'.")
-
-            prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize()
-        elif prompt is False:
-            prompt_text = None
-        else:
-            prompt_text = prompt
-
-        self.prompt = prompt_text
-        self.confirmation_prompt = confirmation_prompt
-        self.prompt_required = prompt_required
-        self.hide_input = hide_input
-        self.hidden = hidden
-
-        # If prompt is enabled but not required, then the option can be
-        # used as a flag to indicate using prompt or flag_value.
-        self._flag_needs_value = self.prompt is not None and not self.prompt_required
-
-        if is_flag is None:
-            if flag_value is not None:
-                # Implicitly a flag because flag_value was set.
-                is_flag = True
-            elif self._flag_needs_value:
-                # Not a flag, but when used as a flag it shows a prompt.
-                is_flag = False
-            else:
-                # Implicitly a flag because flag options were given.
-                is_flag = bool(self.secondary_opts)
-        elif is_flag is False and not self._flag_needs_value:
-            # Not a flag, and prompt is not enabled, can be used as a
-            # flag if flag_value is set.
-            self._flag_needs_value = flag_value is not None
-
-        if is_flag and default_is_missing and not self.required:
-            self.default: t.Union[t.Any, t.Callable[[], t.Any]] = False
-
-        if flag_value is None:
-            flag_value = not self.default
-
-        if is_flag and type is None:
-            # Re-guess the type from the flag value instead of the
-            # default.
-            self.type = types.convert_type(None, flag_value)
-
-        self.is_flag: bool = is_flag
-        self.is_bool_flag = is_flag and isinstance(self.type, types.BoolParamType)
-        self.flag_value: t.Any = flag_value
-
-        # Counting
-        self.count = count
-        if count:
-            if type is None:
-                self.type = types.IntRange(min=0)
-            if default_is_missing:
-                self.default = 0
-
-        self.allow_from_autoenv = allow_from_autoenv
-        self.help = help
-        self.show_default = show_default
-        self.show_choices = show_choices
-        self.show_envvar = show_envvar
-
-        if __debug__:
-            if self.nargs == -1:
-                raise TypeError("nargs=-1 is not supported for options.")
-
-            if self.prompt and self.is_flag and not self.is_bool_flag:
-                raise TypeError("'prompt' is not valid for non-boolean flag.")
-
-            if not self.is_bool_flag and self.secondary_opts:
-                raise TypeError("Secondary flag is not valid for non-boolean flag.")
-
-            if self.is_bool_flag and self.hide_input and self.prompt is not None:
-                raise TypeError(
-                    "'prompt' with 'hide_input' is not valid for boolean flag."
-                )
-
-            if self.count:
-                if self.multiple:
-                    raise TypeError("'count' is not valid with 'multiple'.")
-
-                if self.is_flag:
-                    raise TypeError("'count' is not valid with 'is_flag'.")
-
-            if self.multiple and self.is_flag:
-                raise TypeError("'multiple' is not valid with 'is_flag', use 'count'.")
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict.update(
-            help=self.help,
-            prompt=self.prompt,
-            is_flag=self.is_flag,
-            flag_value=self.flag_value,
-            count=self.count,
-            hidden=self.hidden,
-        )
-        return info_dict
-
-    def _parse_decls(
-        self, decls: t.Sequence[str], expose_value: bool
-    ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]:
-        opts = []
-        secondary_opts = []
-        name = None
-        possible_names = []
-
-        for decl in decls:
-            if decl.isidentifier():
-                if name is not None:
-                    raise TypeError(f"Name '{name}' defined twice")
-                name = decl
-            else:
-                split_char = ";" if decl[:1] == "/" else "/"
-                if split_char in decl:
-                    first, second = decl.split(split_char, 1)
-                    first = first.rstrip()
-                    if first:
-                        possible_names.append(split_opt(first))
-                        opts.append(first)
-                    second = second.lstrip()
-                    if second:
-                        secondary_opts.append(second.lstrip())
-                    if first == second:
-                        raise ValueError(
-                            f"Boolean option {decl!r} cannot use the"
-                            " same flag for true/false."
-                        )
-                else:
-                    possible_names.append(split_opt(decl))
-                    opts.append(decl)
-
-        if name is None and possible_names:
-            possible_names.sort(key=lambda x: -len(x[0]))  # group long options first
-            name = possible_names[0][1].replace("-", "_").lower()
-            if not name.isidentifier():
-                name = None
-
-        if name is None:
-            if not expose_value:
-                return None, opts, secondary_opts
-            raise TypeError("Could not determine name for option")
-
-        if not opts and not secondary_opts:
-            raise TypeError(
-                f"No options defined but a name was passed ({name})."
-                " Did you mean to declare an argument instead? Did"
-                f" you mean to pass '--{name}'?"
-            )
-
-        return name, opts, secondary_opts
-
-    def add_to_parser(self, parser: OptionParser, ctx: Context) -> None:
-        if self.multiple:
-            action = "append"
-        elif self.count:
-            action = "count"
-        else:
-            action = "store"
-
-        if self.is_flag:
-            action = f"{action}_const"
-
-            if self.is_bool_flag and self.secondary_opts:
-                parser.add_option(
-                    obj=self, opts=self.opts, dest=self.name, action=action, const=True
-                )
-                parser.add_option(
-                    obj=self,
-                    opts=self.secondary_opts,
-                    dest=self.name,
-                    action=action,
-                    const=False,
-                )
-            else:
-                parser.add_option(
-                    obj=self,
-                    opts=self.opts,
-                    dest=self.name,
-                    action=action,
-                    const=self.flag_value,
-                )
-        else:
-            parser.add_option(
-                obj=self,
-                opts=self.opts,
-                dest=self.name,
-                action=action,
-                nargs=self.nargs,
-            )
-
-    def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]:
-        if self.hidden:
-            return None
-
-        any_prefix_is_slash = False
-
-        def _write_opts(opts: t.Sequence[str]) -> str:
-            nonlocal any_prefix_is_slash
-
-            rv, any_slashes = join_options(opts)
-
-            if any_slashes:
-                any_prefix_is_slash = True
-
-            if not self.is_flag and not self.count:
-                rv += f" {self.make_metavar()}"
-
-            return rv
-
-        rv = [_write_opts(self.opts)]
-
-        if self.secondary_opts:
-            rv.append(_write_opts(self.secondary_opts))
-
-        help = self.help or ""
-        extra = []
-
-        if self.show_envvar:
-            envvar = self.envvar
-
-            if envvar is None:
-                if (
-                    self.allow_from_autoenv
-                    and ctx.auto_envvar_prefix is not None
-                    and self.name is not None
-                ):
-                    envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}"
-
-            if envvar is not None:
-                var_str = (
-                    envvar
-                    if isinstance(envvar, str)
-                    else ", ".join(str(d) for d in envvar)
-                )
-                extra.append(_("env var: {var}").format(var=var_str))
-
-        # Temporarily enable resilient parsing to avoid type casting
-        # failing for the default. Might be possible to extend this to
-        # help formatting in general.
-        resilient = ctx.resilient_parsing
-        ctx.resilient_parsing = True
-
-        try:
-            default_value = self.get_default(ctx, call=False)
-        finally:
-            ctx.resilient_parsing = resilient
-
-        show_default = False
-        show_default_is_str = False
-
-        if self.show_default is not None:
-            if isinstance(self.show_default, str):
-                show_default_is_str = show_default = True
-            else:
-                show_default = self.show_default
-        elif ctx.show_default is not None:
-            show_default = ctx.show_default
-
-        if show_default_is_str or (show_default and (default_value is not None)):
-            if show_default_is_str:
-                default_string = f"({self.show_default})"
-            elif isinstance(default_value, (list, tuple)):
-                default_string = ", ".join(str(d) for d in default_value)
-            elif inspect.isfunction(default_value):
-                default_string = _("(dynamic)")
-            elif self.is_bool_flag and self.secondary_opts:
-                # For boolean flags that have distinct True/False opts,
-                # use the opt without prefix instead of the value.
-                default_string = split_opt(
-                    (self.opts if self.default else self.secondary_opts)[0]
-                )[1]
-            elif self.is_bool_flag and not self.secondary_opts and not default_value:
-                default_string = ""
-            else:
-                default_string = str(default_value)
-
-            if default_string:
-                extra.append(_("default: {default}").format(default=default_string))
-
-        if (
-            isinstance(self.type, types._NumberRangeBase)
-            # skip count with default range type
-            and not (self.count and self.type.min == 0 and self.type.max is None)
-        ):
-            range_str = self.type._describe_range()
-
-            if range_str:
-                extra.append(range_str)
-
-        if self.required:
-            extra.append(_("required"))
-
-        if extra:
-            extra_str = "; ".join(extra)
-            help = f"{help}  [{extra_str}]" if help else f"[{extra_str}]"
-
-        return ("; " if any_prefix_is_slash else " / ").join(rv), help
-
-    @t.overload
-    def get_default(
-        self, ctx: Context, call: "te.Literal[True]" = True
-    ) -> t.Optional[t.Any]:
-        ...
-
-    @t.overload
-    def get_default(
-        self, ctx: Context, call: bool = ...
-    ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]:
-        ...
-
-    def get_default(
-        self, ctx: Context, call: bool = True
-    ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]:
-        # If we're a non boolean flag our default is more complex because
-        # we need to look at all flags in the same group to figure out
-        # if we're the default one in which case we return the flag
-        # value as default.
-        if self.is_flag and not self.is_bool_flag:
-            for param in ctx.command.params:
-                if param.name == self.name and param.default:
-                    return param.flag_value  # type: ignore
-
-            return None
-
-        return super().get_default(ctx, call=call)
-
-    def prompt_for_value(self, ctx: Context) -> t.Any:
-        """This is an alternative flow that can be activated in the full
-        value processing if a value does not exist.  It will prompt the
-        user until a valid value exists and then returns the processed
-        value as result.
-        """
-        assert self.prompt is not None
-
-        # Calculate the default before prompting anything to be stable.
-        default = self.get_default(ctx)
-
-        # If this is a prompt for a flag we need to handle this
-        # differently.
-        if self.is_bool_flag:
-            return confirm(self.prompt, default)
-
-        return prompt(
-            self.prompt,
-            default=default,
-            type=self.type,
-            hide_input=self.hide_input,
-            show_choices=self.show_choices,
-            confirmation_prompt=self.confirmation_prompt,
-            value_proc=lambda x: self.process_value(ctx, x),
-        )
-
-    def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]:
-        rv = super().resolve_envvar_value(ctx)
-
-        if rv is not None:
-            return rv
-
-        if (
-            self.allow_from_autoenv
-            and ctx.auto_envvar_prefix is not None
-            and self.name is not None
-        ):
-            envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}"
-            rv = os.environ.get(envvar)
-
-            if rv:
-                return rv
-
-        return None
-
-    def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]:
-        rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx)
-
-        if rv is None:
-            return None
-
-        value_depth = (self.nargs != 1) + bool(self.multiple)
-
-        if value_depth > 0:
-            rv = self.type.split_envvar_value(rv)
-
-            if self.multiple and self.nargs != 1:
-                rv = batch(rv, self.nargs)
-
-        return rv
-
-    def consume_value(
-        self, ctx: Context, opts: t.Mapping[str, "Parameter"]
-    ) -> t.Tuple[t.Any, ParameterSource]:
-        value, source = super().consume_value(ctx, opts)
-
-        # The parser will emit a sentinel value if the option can be
-        # given as a flag without a value. This is different from None
-        # to distinguish from the flag not being given at all.
-        if value is _flag_needs_value:
-            if self.prompt is not None and not ctx.resilient_parsing:
-                value = self.prompt_for_value(ctx)
-                source = ParameterSource.PROMPT
-            else:
-                value = self.flag_value
-                source = ParameterSource.COMMANDLINE
-
-        elif (
-            self.multiple
-            and value is not None
-            and any(v is _flag_needs_value for v in value)
-        ):
-            value = [self.flag_value if v is _flag_needs_value else v for v in value]
-            source = ParameterSource.COMMANDLINE
-
-        # The value wasn't set, or used the param's default, prompt if
-        # prompting is enabled.
-        elif (
-            source in {None, ParameterSource.DEFAULT}
-            and self.prompt is not None
-            and (self.required or self.prompt_required)
-            and not ctx.resilient_parsing
-        ):
-            value = self.prompt_for_value(ctx)
-            source = ParameterSource.PROMPT
-
-        return value, source
-
-
-class Argument(Parameter):
-    """Arguments are positional parameters to a command.  They generally
-    provide fewer features than options but can have infinite ``nargs``
-    and are required by default.
-
-    All parameters are passed onwards to the parameter constructor.
-    """
-
-    param_type_name = "argument"
-
-    def __init__(
-        self,
-        param_decls: t.Sequence[str],
-        required: t.Optional[bool] = None,
-        **attrs: t.Any,
-    ) -> None:
-        if required is None:
-            if attrs.get("default") is not None:
-                required = False
-            else:
-                required = attrs.get("nargs", 1) > 0
-
-        if "multiple" in attrs:
-            raise TypeError("__init__() got an unexpected keyword argument 'multiple'.")
-
-        super().__init__(param_decls, required=required, **attrs)
-
-        if __debug__:
-            if self.default is not None and self.nargs == -1:
-                raise TypeError("'default' is not supported for nargs=-1.")
-
-    @property
-    def human_readable_name(self) -> str:
-        if self.metavar is not None:
-            return self.metavar
-        return self.name.upper()  # type: ignore
-
-    def make_metavar(self) -> str:
-        if self.metavar is not None:
-            return self.metavar
-        var = self.type.get_metavar(self)
-        if not var:
-            var = self.name.upper()  # type: ignore
-        if not self.required:
-            var = f"[{var}]"
-        if self.nargs != 1:
-            var += "..."
-        return var
-
-    def _parse_decls(
-        self, decls: t.Sequence[str], expose_value: bool
-    ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]:
-        if not decls:
-            if not expose_value:
-                return None, [], []
-            raise TypeError("Could not determine name for argument")
-        if len(decls) == 1:
-            name = arg = decls[0]
-            name = name.replace("-", "_").lower()
-        else:
-            raise TypeError(
-                "Arguments take exactly one parameter declaration, got"
-                f" {len(decls)}."
-            )
-        return name, [arg], []
-
-    def get_usage_pieces(self, ctx: Context) -> t.List[str]:
-        return [self.make_metavar()]
-
-    def get_error_hint(self, ctx: Context) -> str:
-        return f"'{self.make_metavar()}'"
-
-    def add_to_parser(self, parser: OptionParser, ctx: Context) -> None:
-        parser.add_argument(dest=self.name, nargs=self.nargs, obj=self)

+ 0 - 497
venv/lib/python3.10/site-packages/click/decorators.py

@@ -1,497 +0,0 @@
-import inspect
-import types
-import typing as t
-from functools import update_wrapper
-from gettext import gettext as _
-
-from .core import Argument
-from .core import Command
-from .core import Context
-from .core import Group
-from .core import Option
-from .core import Parameter
-from .globals import get_current_context
-from .utils import echo
-
-F = t.TypeVar("F", bound=t.Callable[..., t.Any])
-FC = t.TypeVar("FC", bound=t.Union[t.Callable[..., t.Any], Command])
-
-
-def pass_context(f: F) -> F:
-    """Marks a callback as wanting to receive the current context
-    object as first argument.
-    """
-
-    def new_func(*args, **kwargs):  # type: ignore
-        return f(get_current_context(), *args, **kwargs)
-
-    return update_wrapper(t.cast(F, new_func), f)
-
-
-def pass_obj(f: F) -> F:
-    """Similar to :func:`pass_context`, but only pass the object on the
-    context onwards (:attr:`Context.obj`).  This is useful if that object
-    represents the state of a nested system.
-    """
-
-    def new_func(*args, **kwargs):  # type: ignore
-        return f(get_current_context().obj, *args, **kwargs)
-
-    return update_wrapper(t.cast(F, new_func), f)
-
-
-def make_pass_decorator(
-    object_type: t.Type, ensure: bool = False
-) -> "t.Callable[[F], F]":
-    """Given an object type this creates a decorator that will work
-    similar to :func:`pass_obj` but instead of passing the object of the
-    current context, it will find the innermost context of type
-    :func:`object_type`.
-
-    This generates a decorator that works roughly like this::
-
-        from functools import update_wrapper
-
-        def decorator(f):
-            @pass_context
-            def new_func(ctx, *args, **kwargs):
-                obj = ctx.find_object(object_type)
-                return ctx.invoke(f, obj, *args, **kwargs)
-            return update_wrapper(new_func, f)
-        return decorator
-
-    :param object_type: the type of the object to pass.
-    :param ensure: if set to `True`, a new object will be created and
-                   remembered on the context if it's not there yet.
-    """
-
-    def decorator(f: F) -> F:
-        def new_func(*args, **kwargs):  # type: ignore
-            ctx = get_current_context()
-
-            if ensure:
-                obj = ctx.ensure_object(object_type)
-            else:
-                obj = ctx.find_object(object_type)
-
-            if obj is None:
-                raise RuntimeError(
-                    "Managed to invoke callback without a context"
-                    f" object of type {object_type.__name__!r}"
-                    " existing."
-                )
-
-            return ctx.invoke(f, obj, *args, **kwargs)
-
-        return update_wrapper(t.cast(F, new_func), f)
-
-    return decorator
-
-
-def pass_meta_key(
-    key: str, *, doc_description: t.Optional[str] = None
-) -> "t.Callable[[F], F]":
-    """Create a decorator that passes a key from
-    :attr:`click.Context.meta` as the first argument to the decorated
-    function.
-
-    :param key: Key in ``Context.meta`` to pass.
-    :param doc_description: Description of the object being passed,
-        inserted into the decorator's docstring. Defaults to "the 'key'
-        key from Context.meta".
-
-    .. versionadded:: 8.0
-    """
-
-    def decorator(f: F) -> F:
-        def new_func(*args, **kwargs):  # type: ignore
-            ctx = get_current_context()
-            obj = ctx.meta[key]
-            return ctx.invoke(f, obj, *args, **kwargs)
-
-        return update_wrapper(t.cast(F, new_func), f)
-
-    if doc_description is None:
-        doc_description = f"the {key!r} key from :attr:`click.Context.meta`"
-
-    decorator.__doc__ = (
-        f"Decorator that passes {doc_description} as the first argument"
-        " to the decorated function."
-    )
-    return decorator
-
-
-CmdType = t.TypeVar("CmdType", bound=Command)
-
-
-@t.overload
-def command(
-    __func: t.Callable[..., t.Any],
-) -> Command:
-    ...
-
-
-@t.overload
-def command(
-    name: t.Optional[str] = None,
-    **attrs: t.Any,
-) -> t.Callable[..., Command]:
-    ...
-
-
-@t.overload
-def command(
-    name: t.Optional[str] = None,
-    cls: t.Type[CmdType] = ...,
-    **attrs: t.Any,
-) -> t.Callable[..., CmdType]:
-    ...
-
-
-def command(
-    name: t.Union[str, t.Callable[..., t.Any], None] = None,
-    cls: t.Optional[t.Type[Command]] = None,
-    **attrs: t.Any,
-) -> t.Union[Command, t.Callable[..., Command]]:
-    r"""Creates a new :class:`Command` and uses the decorated function as
-    callback.  This will also automatically attach all decorated
-    :func:`option`\s and :func:`argument`\s as parameters to the command.
-
-    The name of the command defaults to the name of the function with
-    underscores replaced by dashes.  If you want to change that, you can
-    pass the intended name as the first argument.
-
-    All keyword arguments are forwarded to the underlying command class.
-    For the ``params`` argument, any decorated params are appended to
-    the end of the list.
-
-    Once decorated the function turns into a :class:`Command` instance
-    that can be invoked as a command line utility or be attached to a
-    command :class:`Group`.
-
-    :param name: the name of the command.  This defaults to the function
-                 name with underscores replaced by dashes.
-    :param cls: the command class to instantiate.  This defaults to
-                :class:`Command`.
-
-    .. versionchanged:: 8.1
-        This decorator can be applied without parentheses.
-
-    .. versionchanged:: 8.1
-        The ``params`` argument can be used. Decorated params are
-        appended to the end of the list.
-    """
-
-    func: t.Optional[t.Callable[..., t.Any]] = None
-
-    if callable(name):
-        func = name
-        name = None
-        assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class."
-        assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments."
-
-    if cls is None:
-        cls = Command
-
-    def decorator(f: t.Callable[..., t.Any]) -> Command:
-        if isinstance(f, Command):
-            raise TypeError("Attempted to convert a callback into a command twice.")
-
-        attr_params = attrs.pop("params", None)
-        params = attr_params if attr_params is not None else []
-
-        try:
-            decorator_params = f.__click_params__  # type: ignore
-        except AttributeError:
-            pass
-        else:
-            del f.__click_params__  # type: ignore
-            params.extend(reversed(decorator_params))
-
-        if attrs.get("help") is None:
-            attrs["help"] = f.__doc__
-
-        cmd = cls(  # type: ignore[misc]
-            name=name or f.__name__.lower().replace("_", "-"),  # type: ignore[arg-type]
-            callback=f,
-            params=params,
-            **attrs,
-        )
-        cmd.__doc__ = f.__doc__
-        return cmd
-
-    if func is not None:
-        return decorator(func)
-
-    return decorator
-
-
-@t.overload
-def group(
-    __func: t.Callable[..., t.Any],
-) -> Group:
-    ...
-
-
-@t.overload
-def group(
-    name: t.Optional[str] = None,
-    **attrs: t.Any,
-) -> t.Callable[[F], Group]:
-    ...
-
-
-def group(
-    name: t.Union[str, t.Callable[..., t.Any], None] = None, **attrs: t.Any
-) -> t.Union[Group, t.Callable[[F], Group]]:
-    """Creates a new :class:`Group` with a function as callback.  This
-    works otherwise the same as :func:`command` just that the `cls`
-    parameter is set to :class:`Group`.
-
-    .. versionchanged:: 8.1
-        This decorator can be applied without parentheses.
-    """
-    if attrs.get("cls") is None:
-        attrs["cls"] = Group
-
-    if callable(name):
-        grp: t.Callable[[F], Group] = t.cast(Group, command(**attrs))
-        return grp(name)
-
-    return t.cast(Group, command(name, **attrs))
-
-
-def _param_memo(f: FC, param: Parameter) -> None:
-    if isinstance(f, Command):
-        f.params.append(param)
-    else:
-        if not hasattr(f, "__click_params__"):
-            f.__click_params__ = []  # type: ignore
-
-        f.__click_params__.append(param)  # type: ignore
-
-
-def argument(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]:
-    """Attaches an argument to the command.  All positional arguments are
-    passed as parameter declarations to :class:`Argument`; all keyword
-    arguments are forwarded unchanged (except ``cls``).
-    This is equivalent to creating an :class:`Argument` instance manually
-    and attaching it to the :attr:`Command.params` list.
-
-    :param cls: the argument class to instantiate.  This defaults to
-                :class:`Argument`.
-    """
-
-    def decorator(f: FC) -> FC:
-        ArgumentClass = attrs.pop("cls", None) or Argument
-        _param_memo(f, ArgumentClass(param_decls, **attrs))
-        return f
-
-    return decorator
-
-
-def option(*param_decls: str, **attrs: t.Any) -> t.Callable[[FC], FC]:
-    """Attaches an option to the command.  All positional arguments are
-    passed as parameter declarations to :class:`Option`; all keyword
-    arguments are forwarded unchanged (except ``cls``).
-    This is equivalent to creating an :class:`Option` instance manually
-    and attaching it to the :attr:`Command.params` list.
-
-    :param cls: the option class to instantiate.  This defaults to
-                :class:`Option`.
-    """
-
-    def decorator(f: FC) -> FC:
-        # Issue 926, copy attrs, so pre-defined options can re-use the same cls=
-        option_attrs = attrs.copy()
-        OptionClass = option_attrs.pop("cls", None) or Option
-        _param_memo(f, OptionClass(param_decls, **option_attrs))
-        return f
-
-    return decorator
-
-
-def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
-    """Add a ``--yes`` option which shows a prompt before continuing if
-    not passed. If the prompt is declined, the program will exit.
-
-    :param param_decls: One or more option names. Defaults to the single
-        value ``"--yes"``.
-    :param kwargs: Extra arguments are passed to :func:`option`.
-    """
-
-    def callback(ctx: Context, param: Parameter, value: bool) -> None:
-        if not value:
-            ctx.abort()
-
-    if not param_decls:
-        param_decls = ("--yes",)
-
-    kwargs.setdefault("is_flag", True)
-    kwargs.setdefault("callback", callback)
-    kwargs.setdefault("expose_value", False)
-    kwargs.setdefault("prompt", "Do you want to continue?")
-    kwargs.setdefault("help", "Confirm the action without prompting.")
-    return option(*param_decls, **kwargs)
-
-
-def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
-    """Add a ``--password`` option which prompts for a password, hiding
-    input and asking to enter the value again for confirmation.
-
-    :param param_decls: One or more option names. Defaults to the single
-        value ``"--password"``.
-    :param kwargs: Extra arguments are passed to :func:`option`.
-    """
-    if not param_decls:
-        param_decls = ("--password",)
-
-    kwargs.setdefault("prompt", True)
-    kwargs.setdefault("confirmation_prompt", True)
-    kwargs.setdefault("hide_input", True)
-    return option(*param_decls, **kwargs)
-
-
-def version_option(
-    version: t.Optional[str] = None,
-    *param_decls: str,
-    package_name: t.Optional[str] = None,
-    prog_name: t.Optional[str] = None,
-    message: t.Optional[str] = None,
-    **kwargs: t.Any,
-) -> t.Callable[[FC], FC]:
-    """Add a ``--version`` option which immediately prints the version
-    number and exits the program.
-
-    If ``version`` is not provided, Click will try to detect it using
-    :func:`importlib.metadata.version` to get the version for the
-    ``package_name``. On Python < 3.8, the ``importlib_metadata``
-    backport must be installed.
-
-    If ``package_name`` is not provided, Click will try to detect it by
-    inspecting the stack frames. This will be used to detect the
-    version, so it must match the name of the installed package.
-
-    :param version: The version number to show. If not provided, Click
-        will try to detect it.
-    :param param_decls: One or more option names. Defaults to the single
-        value ``"--version"``.
-    :param package_name: The package name to detect the version from. If
-        not provided, Click will try to detect it.
-    :param prog_name: The name of the CLI to show in the message. If not
-        provided, it will be detected from the command.
-    :param message: The message to show. The values ``%(prog)s``,
-        ``%(package)s``, and ``%(version)s`` are available. Defaults to
-        ``"%(prog)s, version %(version)s"``.
-    :param kwargs: Extra arguments are passed to :func:`option`.
-    :raise RuntimeError: ``version`` could not be detected.
-
-    .. versionchanged:: 8.0
-        Add the ``package_name`` parameter, and the ``%(package)s``
-        value for messages.
-
-    .. versionchanged:: 8.0
-        Use :mod:`importlib.metadata` instead of ``pkg_resources``. The
-        version is detected based on the package name, not the entry
-        point name. The Python package name must match the installed
-        package name, or be passed with ``package_name=``.
-    """
-    if message is None:
-        message = _("%(prog)s, version %(version)s")
-
-    if version is None and package_name is None:
-        frame = inspect.currentframe()
-        f_back = frame.f_back if frame is not None else None
-        f_globals = f_back.f_globals if f_back is not None else None
-        # break reference cycle
-        # https://docs.python.org/3/library/inspect.html#the-interpreter-stack
-        del frame
-
-        if f_globals is not None:
-            package_name = f_globals.get("__name__")
-
-            if package_name == "__main__":
-                package_name = f_globals.get("__package__")
-
-            if package_name:
-                package_name = package_name.partition(".")[0]
-
-    def callback(ctx: Context, param: Parameter, value: bool) -> None:
-        if not value or ctx.resilient_parsing:
-            return
-
-        nonlocal prog_name
-        nonlocal version
-
-        if prog_name is None:
-            prog_name = ctx.find_root().info_name
-
-        if version is None and package_name is not None:
-            metadata: t.Optional[types.ModuleType]
-
-            try:
-                from importlib import metadata  # type: ignore
-            except ImportError:
-                # Python < 3.8
-                import importlib_metadata as metadata  # type: ignore
-
-            try:
-                version = metadata.version(package_name)  # type: ignore
-            except metadata.PackageNotFoundError:  # type: ignore
-                raise RuntimeError(
-                    f"{package_name!r} is not installed. Try passing"
-                    " 'package_name' instead."
-                ) from None
-
-        if version is None:
-            raise RuntimeError(
-                f"Could not determine the version for {package_name!r} automatically."
-            )
-
-        echo(
-            t.cast(str, message)
-            % {"prog": prog_name, "package": package_name, "version": version},
-            color=ctx.color,
-        )
-        ctx.exit()
-
-    if not param_decls:
-        param_decls = ("--version",)
-
-    kwargs.setdefault("is_flag", True)
-    kwargs.setdefault("expose_value", False)
-    kwargs.setdefault("is_eager", True)
-    kwargs.setdefault("help", _("Show the version and exit."))
-    kwargs["callback"] = callback
-    return option(*param_decls, **kwargs)
-
-
-def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]:
-    """Add a ``--help`` option which immediately prints the help page
-    and exits the program.
-
-    This is usually unnecessary, as the ``--help`` option is added to
-    each command automatically unless ``add_help_option=False`` is
-    passed.
-
-    :param param_decls: One or more option names. Defaults to the single
-        value ``"--help"``.
-    :param kwargs: Extra arguments are passed to :func:`option`.
-    """
-
-    def callback(ctx: Context, param: Parameter, value: bool) -> None:
-        if not value or ctx.resilient_parsing:
-            return
-
-        echo(ctx.get_help(), color=ctx.color)
-        ctx.exit()
-
-    if not param_decls:
-        param_decls = ("--help",)
-
-    kwargs.setdefault("is_flag", True)
-    kwargs.setdefault("expose_value", False)
-    kwargs.setdefault("is_eager", True)
-    kwargs.setdefault("help", _("Show this message and exit."))
-    kwargs["callback"] = callback
-    return option(*param_decls, **kwargs)

+ 0 - 287
venv/lib/python3.10/site-packages/click/exceptions.py

@@ -1,287 +0,0 @@
-import os
-import typing as t
-from gettext import gettext as _
-from gettext import ngettext
-
-from ._compat import get_text_stderr
-from .utils import echo
-
-if t.TYPE_CHECKING:
-    from .core import Context
-    from .core import Parameter
-
-
-def _join_param_hints(
-    param_hint: t.Optional[t.Union[t.Sequence[str], str]]
-) -> t.Optional[str]:
-    if param_hint is not None and not isinstance(param_hint, str):
-        return " / ".join(repr(x) for x in param_hint)
-
-    return param_hint
-
-
-class ClickException(Exception):
-    """An exception that Click can handle and show to the user."""
-
-    #: The exit code for this exception.
-    exit_code = 1
-
-    def __init__(self, message: str) -> None:
-        super().__init__(message)
-        self.message = message
-
-    def format_message(self) -> str:
-        return self.message
-
-    def __str__(self) -> str:
-        return self.message
-
-    def show(self, file: t.Optional[t.IO] = None) -> None:
-        if file is None:
-            file = get_text_stderr()
-
-        echo(_("Error: {message}").format(message=self.format_message()), file=file)
-
-
-class UsageError(ClickException):
-    """An internal exception that signals a usage error.  This typically
-    aborts any further handling.
-
-    :param message: the error message to display.
-    :param ctx: optionally the context that caused this error.  Click will
-                fill in the context automatically in some situations.
-    """
-
-    exit_code = 2
-
-    def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None:
-        super().__init__(message)
-        self.ctx = ctx
-        self.cmd = self.ctx.command if self.ctx else None
-
-    def show(self, file: t.Optional[t.IO] = None) -> None:
-        if file is None:
-            file = get_text_stderr()
-        color = None
-        hint = ""
-        if (
-            self.ctx is not None
-            and self.ctx.command.get_help_option(self.ctx) is not None
-        ):
-            hint = _("Try '{command} {option}' for help.").format(
-                command=self.ctx.command_path, option=self.ctx.help_option_names[0]
-            )
-            hint = f"{hint}\n"
-        if self.ctx is not None:
-            color = self.ctx.color
-            echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color)
-        echo(
-            _("Error: {message}").format(message=self.format_message()),
-            file=file,
-            color=color,
-        )
-
-
-class BadParameter(UsageError):
-    """An exception that formats out a standardized error message for a
-    bad parameter.  This is useful when thrown from a callback or type as
-    Click will attach contextual information to it (for instance, which
-    parameter it is).
-
-    .. versionadded:: 2.0
-
-    :param param: the parameter object that caused this error.  This can
-                  be left out, and Click will attach this info itself
-                  if possible.
-    :param param_hint: a string that shows up as parameter name.  This
-                       can be used as alternative to `param` in cases
-                       where custom validation should happen.  If it is
-                       a string it's used as such, if it's a list then
-                       each item is quoted and separated.
-    """
-
-    def __init__(
-        self,
-        message: str,
-        ctx: t.Optional["Context"] = None,
-        param: t.Optional["Parameter"] = None,
-        param_hint: t.Optional[str] = None,
-    ) -> None:
-        super().__init__(message, ctx)
-        self.param = param
-        self.param_hint = param_hint
-
-    def format_message(self) -> str:
-        if self.param_hint is not None:
-            param_hint = self.param_hint
-        elif self.param is not None:
-            param_hint = self.param.get_error_hint(self.ctx)  # type: ignore
-        else:
-            return _("Invalid value: {message}").format(message=self.message)
-
-        return _("Invalid value for {param_hint}: {message}").format(
-            param_hint=_join_param_hints(param_hint), message=self.message
-        )
-
-
-class MissingParameter(BadParameter):
-    """Raised if click required an option or argument but it was not
-    provided when invoking the script.
-
-    .. versionadded:: 4.0
-
-    :param param_type: a string that indicates the type of the parameter.
-                       The default is to inherit the parameter type from
-                       the given `param`.  Valid values are ``'parameter'``,
-                       ``'option'`` or ``'argument'``.
-    """
-
-    def __init__(
-        self,
-        message: t.Optional[str] = None,
-        ctx: t.Optional["Context"] = None,
-        param: t.Optional["Parameter"] = None,
-        param_hint: t.Optional[str] = None,
-        param_type: t.Optional[str] = None,
-    ) -> None:
-        super().__init__(message or "", ctx, param, param_hint)
-        self.param_type = param_type
-
-    def format_message(self) -> str:
-        if self.param_hint is not None:
-            param_hint: t.Optional[str] = self.param_hint
-        elif self.param is not None:
-            param_hint = self.param.get_error_hint(self.ctx)  # type: ignore
-        else:
-            param_hint = None
-
-        param_hint = _join_param_hints(param_hint)
-        param_hint = f" {param_hint}" if param_hint else ""
-
-        param_type = self.param_type
-        if param_type is None and self.param is not None:
-            param_type = self.param.param_type_name
-
-        msg = self.message
-        if self.param is not None:
-            msg_extra = self.param.type.get_missing_message(self.param)
-            if msg_extra:
-                if msg:
-                    msg += f". {msg_extra}"
-                else:
-                    msg = msg_extra
-
-        msg = f" {msg}" if msg else ""
-
-        # Translate param_type for known types.
-        if param_type == "argument":
-            missing = _("Missing argument")
-        elif param_type == "option":
-            missing = _("Missing option")
-        elif param_type == "parameter":
-            missing = _("Missing parameter")
-        else:
-            missing = _("Missing {param_type}").format(param_type=param_type)
-
-        return f"{missing}{param_hint}.{msg}"
-
-    def __str__(self) -> str:
-        if not self.message:
-            param_name = self.param.name if self.param else None
-            return _("Missing parameter: {param_name}").format(param_name=param_name)
-        else:
-            return self.message
-
-
-class NoSuchOption(UsageError):
-    """Raised if click attempted to handle an option that does not
-    exist.
-
-    .. versionadded:: 4.0
-    """
-
-    def __init__(
-        self,
-        option_name: str,
-        message: t.Optional[str] = None,
-        possibilities: t.Optional[t.Sequence[str]] = None,
-        ctx: t.Optional["Context"] = None,
-    ) -> None:
-        if message is None:
-            message = _("No such option: {name}").format(name=option_name)
-
-        super().__init__(message, ctx)
-        self.option_name = option_name
-        self.possibilities = possibilities
-
-    def format_message(self) -> str:
-        if not self.possibilities:
-            return self.message
-
-        possibility_str = ", ".join(sorted(self.possibilities))
-        suggest = ngettext(
-            "Did you mean {possibility}?",
-            "(Possible options: {possibilities})",
-            len(self.possibilities),
-        ).format(possibility=possibility_str, possibilities=possibility_str)
-        return f"{self.message} {suggest}"
-
-
-class BadOptionUsage(UsageError):
-    """Raised if an option is generally supplied but the use of the option
-    was incorrect.  This is for instance raised if the number of arguments
-    for an option is not correct.
-
-    .. versionadded:: 4.0
-
-    :param option_name: the name of the option being used incorrectly.
-    """
-
-    def __init__(
-        self, option_name: str, message: str, ctx: t.Optional["Context"] = None
-    ) -> None:
-        super().__init__(message, ctx)
-        self.option_name = option_name
-
-
-class BadArgumentUsage(UsageError):
-    """Raised if an argument is generally supplied but the use of the argument
-    was incorrect.  This is for instance raised if the number of values
-    for an argument is not correct.
-
-    .. versionadded:: 6.0
-    """
-
-
-class FileError(ClickException):
-    """Raised if a file cannot be opened."""
-
-    def __init__(self, filename: str, hint: t.Optional[str] = None) -> None:
-        if hint is None:
-            hint = _("unknown error")
-
-        super().__init__(hint)
-        self.ui_filename = os.fsdecode(filename)
-        self.filename = filename
-
-    def format_message(self) -> str:
-        return _("Could not open file {filename!r}: {message}").format(
-            filename=self.ui_filename, message=self.message
-        )
-
-
-class Abort(RuntimeError):
-    """An internal signalling exception that signals Click to abort."""
-
-
-class Exit(RuntimeError):
-    """An exception that indicates that the application should exit with some
-    status code.
-
-    :param code: the status code to exit with.
-    """
-
-    __slots__ = ("exit_code",)
-
-    def __init__(self, code: int = 0) -> None:
-        self.exit_code = code

+ 0 - 301
venv/lib/python3.10/site-packages/click/formatting.py

@@ -1,301 +0,0 @@
-import typing as t
-from contextlib import contextmanager
-from gettext import gettext as _
-
-from ._compat import term_len
-from .parser import split_opt
-
-# Can force a width.  This is used by the test system
-FORCED_WIDTH: t.Optional[int] = None
-
-
-def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]:
-    widths: t.Dict[int, int] = {}
-
-    for row in rows:
-        for idx, col in enumerate(row):
-            widths[idx] = max(widths.get(idx, 0), term_len(col))
-
-    return tuple(y for x, y in sorted(widths.items()))
-
-
-def iter_rows(
-    rows: t.Iterable[t.Tuple[str, str]], col_count: int
-) -> t.Iterator[t.Tuple[str, ...]]:
-    for row in rows:
-        yield row + ("",) * (col_count - len(row))
-
-
-def wrap_text(
-    text: str,
-    width: int = 78,
-    initial_indent: str = "",
-    subsequent_indent: str = "",
-    preserve_paragraphs: bool = False,
-) -> str:
-    """A helper function that intelligently wraps text.  By default, it
-    assumes that it operates on a single paragraph of text but if the
-    `preserve_paragraphs` parameter is provided it will intelligently
-    handle paragraphs (defined by two empty lines).
-
-    If paragraphs are handled, a paragraph can be prefixed with an empty
-    line containing the ``\\b`` character (``\\x08``) to indicate that
-    no rewrapping should happen in that block.
-
-    :param text: the text that should be rewrapped.
-    :param width: the maximum width for the text.
-    :param initial_indent: the initial indent that should be placed on the
-                           first line as a string.
-    :param subsequent_indent: the indent string that should be placed on
-                              each consecutive line.
-    :param preserve_paragraphs: if this flag is set then the wrapping will
-                                intelligently handle paragraphs.
-    """
-    from ._textwrap import TextWrapper
-
-    text = text.expandtabs()
-    wrapper = TextWrapper(
-        width,
-        initial_indent=initial_indent,
-        subsequent_indent=subsequent_indent,
-        replace_whitespace=False,
-    )
-    if not preserve_paragraphs:
-        return wrapper.fill(text)
-
-    p: t.List[t.Tuple[int, bool, str]] = []
-    buf: t.List[str] = []
-    indent = None
-
-    def _flush_par() -> None:
-        if not buf:
-            return
-        if buf[0].strip() == "\b":
-            p.append((indent or 0, True, "\n".join(buf[1:])))
-        else:
-            p.append((indent or 0, False, " ".join(buf)))
-        del buf[:]
-
-    for line in text.splitlines():
-        if not line:
-            _flush_par()
-            indent = None
-        else:
-            if indent is None:
-                orig_len = term_len(line)
-                line = line.lstrip()
-                indent = orig_len - term_len(line)
-            buf.append(line)
-    _flush_par()
-
-    rv = []
-    for indent, raw, text in p:
-        with wrapper.extra_indent(" " * indent):
-            if raw:
-                rv.append(wrapper.indent_only(text))
-            else:
-                rv.append(wrapper.fill(text))
-
-    return "\n\n".join(rv)
-
-
-class HelpFormatter:
-    """This class helps with formatting text-based help pages.  It's
-    usually just needed for very special internal cases, but it's also
-    exposed so that developers can write their own fancy outputs.
-
-    At present, it always writes into memory.
-
-    :param indent_increment: the additional increment for each level.
-    :param width: the width for the text.  This defaults to the terminal
-                  width clamped to a maximum of 78.
-    """
-
-    def __init__(
-        self,
-        indent_increment: int = 2,
-        width: t.Optional[int] = None,
-        max_width: t.Optional[int] = None,
-    ) -> None:
-        import shutil
-
-        self.indent_increment = indent_increment
-        if max_width is None:
-            max_width = 80
-        if width is None:
-            width = FORCED_WIDTH
-            if width is None:
-                width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50)
-        self.width = width
-        self.current_indent = 0
-        self.buffer: t.List[str] = []
-
-    def write(self, string: str) -> None:
-        """Writes a unicode string into the internal buffer."""
-        self.buffer.append(string)
-
-    def indent(self) -> None:
-        """Increases the indentation."""
-        self.current_indent += self.indent_increment
-
-    def dedent(self) -> None:
-        """Decreases the indentation."""
-        self.current_indent -= self.indent_increment
-
-    def write_usage(
-        self, prog: str, args: str = "", prefix: t.Optional[str] = None
-    ) -> None:
-        """Writes a usage line into the buffer.
-
-        :param prog: the program name.
-        :param args: whitespace separated list of arguments.
-        :param prefix: The prefix for the first line. Defaults to
-            ``"Usage: "``.
-        """
-        if prefix is None:
-            prefix = f"{_('Usage:')} "
-
-        usage_prefix = f"{prefix:>{self.current_indent}}{prog} "
-        text_width = self.width - self.current_indent
-
-        if text_width >= (term_len(usage_prefix) + 20):
-            # The arguments will fit to the right of the prefix.
-            indent = " " * term_len(usage_prefix)
-            self.write(
-                wrap_text(
-                    args,
-                    text_width,
-                    initial_indent=usage_prefix,
-                    subsequent_indent=indent,
-                )
-            )
-        else:
-            # The prefix is too long, put the arguments on the next line.
-            self.write(usage_prefix)
-            self.write("\n")
-            indent = " " * (max(self.current_indent, term_len(prefix)) + 4)
-            self.write(
-                wrap_text(
-                    args, text_width, initial_indent=indent, subsequent_indent=indent
-                )
-            )
-
-        self.write("\n")
-
-    def write_heading(self, heading: str) -> None:
-        """Writes a heading into the buffer."""
-        self.write(f"{'':>{self.current_indent}}{heading}:\n")
-
-    def write_paragraph(self) -> None:
-        """Writes a paragraph into the buffer."""
-        if self.buffer:
-            self.write("\n")
-
-    def write_text(self, text: str) -> None:
-        """Writes re-indented text into the buffer.  This rewraps and
-        preserves paragraphs.
-        """
-        indent = " " * self.current_indent
-        self.write(
-            wrap_text(
-                text,
-                self.width,
-                initial_indent=indent,
-                subsequent_indent=indent,
-                preserve_paragraphs=True,
-            )
-        )
-        self.write("\n")
-
-    def write_dl(
-        self,
-        rows: t.Sequence[t.Tuple[str, str]],
-        col_max: int = 30,
-        col_spacing: int = 2,
-    ) -> None:
-        """Writes a definition list into the buffer.  This is how options
-        and commands are usually formatted.
-
-        :param rows: a list of two item tuples for the terms and values.
-        :param col_max: the maximum width of the first column.
-        :param col_spacing: the number of spaces between the first and
-                            second column.
-        """
-        rows = list(rows)
-        widths = measure_table(rows)
-        if len(widths) != 2:
-            raise TypeError("Expected two columns for definition list")
-
-        first_col = min(widths[0], col_max) + col_spacing
-
-        for first, second in iter_rows(rows, len(widths)):
-            self.write(f"{'':>{self.current_indent}}{first}")
-            if not second:
-                self.write("\n")
-                continue
-            if term_len(first) <= first_col - col_spacing:
-                self.write(" " * (first_col - term_len(first)))
-            else:
-                self.write("\n")
-                self.write(" " * (first_col + self.current_indent))
-
-            text_width = max(self.width - first_col - 2, 10)
-            wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True)
-            lines = wrapped_text.splitlines()
-
-            if lines:
-                self.write(f"{lines[0]}\n")
-
-                for line in lines[1:]:
-                    self.write(f"{'':>{first_col + self.current_indent}}{line}\n")
-            else:
-                self.write("\n")
-
-    @contextmanager
-    def section(self, name: str) -> t.Iterator[None]:
-        """Helpful context manager that writes a paragraph, a heading,
-        and the indents.
-
-        :param name: the section name that is written as heading.
-        """
-        self.write_paragraph()
-        self.write_heading(name)
-        self.indent()
-        try:
-            yield
-        finally:
-            self.dedent()
-
-    @contextmanager
-    def indentation(self) -> t.Iterator[None]:
-        """A context manager that increases the indentation."""
-        self.indent()
-        try:
-            yield
-        finally:
-            self.dedent()
-
-    def getvalue(self) -> str:
-        """Returns the buffer contents."""
-        return "".join(self.buffer)
-
-
-def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]:
-    """Given a list of option strings this joins them in the most appropriate
-    way and returns them in the form ``(formatted_string,
-    any_prefix_is_slash)`` where the second item in the tuple is a flag that
-    indicates if any of the option prefixes was a slash.
-    """
-    rv = []
-    any_prefix_is_slash = False
-
-    for opt in options:
-        prefix = split_opt(opt)[0]
-
-        if prefix == "/":
-            any_prefix_is_slash = True
-
-        rv.append((len(prefix), opt))
-
-    rv.sort(key=lambda x: x[0])
-    return ", ".join(x[1] for x in rv), any_prefix_is_slash

+ 0 - 68
venv/lib/python3.10/site-packages/click/globals.py

@@ -1,68 +0,0 @@
-import typing as t
-from threading import local
-
-if t.TYPE_CHECKING:
-    import typing_extensions as te
-    from .core import Context
-
-_local = local()
-
-
-@t.overload
-def get_current_context(silent: "te.Literal[False]" = False) -> "Context":
-    ...
-
-
-@t.overload
-def get_current_context(silent: bool = ...) -> t.Optional["Context"]:
-    ...
-
-
-def get_current_context(silent: bool = False) -> t.Optional["Context"]:
-    """Returns the current click context.  This can be used as a way to
-    access the current context object from anywhere.  This is a more implicit
-    alternative to the :func:`pass_context` decorator.  This function is
-    primarily useful for helpers such as :func:`echo` which might be
-    interested in changing its behavior based on the current context.
-
-    To push the current context, :meth:`Context.scope` can be used.
-
-    .. versionadded:: 5.0
-
-    :param silent: if set to `True` the return value is `None` if no context
-                   is available.  The default behavior is to raise a
-                   :exc:`RuntimeError`.
-    """
-    try:
-        return t.cast("Context", _local.stack[-1])
-    except (AttributeError, IndexError) as e:
-        if not silent:
-            raise RuntimeError("There is no active click context.") from e
-
-    return None
-
-
-def push_context(ctx: "Context") -> None:
-    """Pushes a new context to the current stack."""
-    _local.__dict__.setdefault("stack", []).append(ctx)
-
-
-def pop_context() -> None:
-    """Removes the top level from the stack."""
-    _local.stack.pop()
-
-
-def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]:
-    """Internal helper to get the default value of the color flag.  If a
-    value is passed it's returned unchanged, otherwise it's looked up from
-    the current context.
-    """
-    if color is not None:
-        return color
-
-    ctx = get_current_context(silent=True)
-
-    if ctx is not None:
-        return ctx.color
-
-    return None

+ 0 - 529
venv/lib/python3.10/site-packages/click/parser.py

@@ -1,529 +0,0 @@
-"""
-This module started out as largely a copy paste from the stdlib's
-optparse module with the features removed that we do not need from
-optparse because we implement them in Click on a higher level (for
-instance type handling, help formatting and a lot more).
-
-The plan is to remove more and more from here over time.
-
-The reason this is a different module and not optparse from the stdlib
-is that there are differences in 2.x and 3.x about the error messages
-generated and optparse in the stdlib uses gettext for no good reason
-and might cause us issues.
-
-Click uses parts of optparse written by Gregory P. Ward and maintained
-by the Python Software Foundation. This is limited to code in parser.py.
-
-Copyright 2001-2006 Gregory P. Ward. All rights reserved.
-Copyright 2002-2006 Python Software Foundation. All rights reserved.
-"""
-# This code uses parts of optparse written by Gregory P. Ward and
-# maintained by the Python Software Foundation.
-# Copyright 2001-2006 Gregory P. Ward
-# Copyright 2002-2006 Python Software Foundation
-import typing as t
-from collections import deque
-from gettext import gettext as _
-from gettext import ngettext
-
-from .exceptions import BadArgumentUsage
-from .exceptions import BadOptionUsage
-from .exceptions import NoSuchOption
-from .exceptions import UsageError
-
-if t.TYPE_CHECKING:
-    import typing_extensions as te
-    from .core import Argument as CoreArgument
-    from .core import Context
-    from .core import Option as CoreOption
-    from .core import Parameter as CoreParameter
-
-V = t.TypeVar("V")
-
-# Sentinel value that indicates an option was passed as a flag without a
-# value but is not a flag option. Option.consume_value uses this to
-# prompt or use the flag_value.
-_flag_needs_value = object()
-
-
-def _unpack_args(
-    args: t.Sequence[str], nargs_spec: t.Sequence[int]
-) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]:
-    """Given an iterable of arguments and an iterable of nargs specifications,
-    it returns a tuple with all the unpacked arguments at the first index
-    and all remaining arguments as the second.
-
-    The nargs specification is the number of arguments that should be consumed
-    or `-1` to indicate that this position should eat up all the remainders.
-
-    Missing items are filled with `None`.
-    """
-    args = deque(args)
-    nargs_spec = deque(nargs_spec)
-    rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = []
-    spos: t.Optional[int] = None
-
-    def _fetch(c: "te.Deque[V]") -> t.Optional[V]:
-        try:
-            if spos is None:
-                return c.popleft()
-            else:
-                return c.pop()
-        except IndexError:
-            return None
-
-    while nargs_spec:
-        nargs = _fetch(nargs_spec)
-
-        if nargs is None:
-            continue
-
-        if nargs == 1:
-            rv.append(_fetch(args))
-        elif nargs > 1:
-            x = [_fetch(args) for _ in range(nargs)]
-
-            # If we're reversed, we're pulling in the arguments in reverse,
-            # so we need to turn them around.
-            if spos is not None:
-                x.reverse()
-
-            rv.append(tuple(x))
-        elif nargs < 0:
-            if spos is not None:
-                raise TypeError("Cannot have two nargs < 0")
-
-            spos = len(rv)
-            rv.append(None)
-
-    # spos is the position of the wildcard (star).  If it's not `None`,
-    # we fill it with the remainder.
-    if spos is not None:
-        rv[spos] = tuple(args)
-        args = []
-        rv[spos + 1 :] = reversed(rv[spos + 1 :])
-
-    return tuple(rv), list(args)
-
-
-def split_opt(opt: str) -> t.Tuple[str, str]:
-    first = opt[:1]
-    if first.isalnum():
-        return "", opt
-    if opt[1:2] == first:
-        return opt[:2], opt[2:]
-    return first, opt[1:]
-
-
-def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str:
-    if ctx is None or ctx.token_normalize_func is None:
-        return opt
-    prefix, opt = split_opt(opt)
-    return f"{prefix}{ctx.token_normalize_func(opt)}"
-
-
-def split_arg_string(string: str) -> t.List[str]:
-    """Split an argument string as with :func:`shlex.split`, but don't
-    fail if the string is incomplete. Ignores a missing closing quote or
-    incomplete escape sequence and uses the partial token as-is.
-
-    .. code-block:: python
-
-        split_arg_string("example 'my file")
-        ["example", "my file"]
-
-        split_arg_string("example my\\")
-        ["example", "my"]
-
-    :param string: String to split.
-    """
-    import shlex
-
-    lex = shlex.shlex(string, posix=True)
-    lex.whitespace_split = True
-    lex.commenters = ""
-    out = []
-
-    try:
-        for token in lex:
-            out.append(token)
-    except ValueError:
-        # Raised when end-of-string is reached in an invalid state. Use
-        # the partial token as-is. The quote or escape character is in
-        # lex.state, not lex.token.
-        out.append(lex.token)
-
-    return out
-
-
-class Option:
-    def __init__(
-        self,
-        obj: "CoreOption",
-        opts: t.Sequence[str],
-        dest: t.Optional[str],
-        action: t.Optional[str] = None,
-        nargs: int = 1,
-        const: t.Optional[t.Any] = None,
-    ):
-        self._short_opts = []
-        self._long_opts = []
-        self.prefixes = set()
-
-        for opt in opts:
-            prefix, value = split_opt(opt)
-            if not prefix:
-                raise ValueError(f"Invalid start character for option ({opt})")
-            self.prefixes.add(prefix[0])
-            if len(prefix) == 1 and len(value) == 1:
-                self._short_opts.append(opt)
-            else:
-                self._long_opts.append(opt)
-                self.prefixes.add(prefix)
-
-        if action is None:
-            action = "store"
-
-        self.dest = dest
-        self.action = action
-        self.nargs = nargs
-        self.const = const
-        self.obj = obj
-
-    @property
-    def takes_value(self) -> bool:
-        return self.action in ("store", "append")
-
-    def process(self, value: str, state: "ParsingState") -> None:
-        if self.action == "store":
-            state.opts[self.dest] = value  # type: ignore
-        elif self.action == "store_const":
-            state.opts[self.dest] = self.const  # type: ignore
-        elif self.action == "append":
-            state.opts.setdefault(self.dest, []).append(value)  # type: ignore
-        elif self.action == "append_const":
-            state.opts.setdefault(self.dest, []).append(self.const)  # type: ignore
-        elif self.action == "count":
-            state.opts[self.dest] = state.opts.get(self.dest, 0) + 1  # type: ignore
-        else:
-            raise ValueError(f"unknown action '{self.action}'")
-        state.order.append(self.obj)
-
-
-class Argument:
-    def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1):
-        self.dest = dest
-        self.nargs = nargs
-        self.obj = obj
-
-    def process(
-        self,
-        value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]],
-        state: "ParsingState",
-    ) -> None:
-        if self.nargs > 1:
-            assert value is not None
-            holes = sum(1 for x in value if x is None)
-            if holes == len(value):
-                value = None
-            elif holes != 0:
-                raise BadArgumentUsage(
-                    _("Argument {name!r} takes {nargs} values.").format(
-                        name=self.dest, nargs=self.nargs
-                    )
-                )
-
-        if self.nargs == -1 and self.obj.envvar is not None and value == ():
-            # Replace empty tuple with None so that a value from the
-            # environment may be tried.
-            value = None
-
-        state.opts[self.dest] = value  # type: ignore
-        state.order.append(self.obj)
-
-
-class ParsingState:
-    def __init__(self, rargs: t.List[str]) -> None:
-        self.opts: t.Dict[str, t.Any] = {}
-        self.largs: t.List[str] = []
-        self.rargs = rargs
-        self.order: t.List["CoreParameter"] = []
-
-
-class OptionParser:
-    """The option parser is an internal class that is ultimately used to
-    parse options and arguments.  It's modelled after optparse and brings
-    a similar but vastly simplified API.  It should generally not be used
-    directly as the high level Click classes wrap it for you.
-
-    It's not nearly as extensible as optparse or argparse as it does not
-    implement features that are implemented on a higher level (such as
-    types or defaults).
-
-    :param ctx: optionally the :class:`~click.Context` where this parser
-                should go with.
-    """
-
-    def __init__(self, ctx: t.Optional["Context"] = None) -> None:
-        #: The :class:`~click.Context` for this parser.  This might be
-        #: `None` for some advanced use cases.
-        self.ctx = ctx
-        #: This controls how the parser deals with interspersed arguments.
-        #: If this is set to `False`, the parser will stop on the first
-        #: non-option.  Click uses this to implement nested subcommands
-        #: safely.
-        self.allow_interspersed_args = True
-        #: This tells the parser how to deal with unknown options.  By
-        #: default it will error out (which is sensible), but there is a
-        #: second mode where it will ignore it and continue processing
-        #: after shifting all the unknown options into the resulting args.
-        self.ignore_unknown_options = False
-
-        if ctx is not None:
-            self.allow_interspersed_args = ctx.allow_interspersed_args
-            self.ignore_unknown_options = ctx.ignore_unknown_options
-
-        self._short_opt: t.Dict[str, Option] = {}
-        self._long_opt: t.Dict[str, Option] = {}
-        self._opt_prefixes = {"-", "--"}
-        self._args: t.List[Argument] = []
-
-    def add_option(
-        self,
-        obj: "CoreOption",
-        opts: t.Sequence[str],
-        dest: t.Optional[str],
-        action: t.Optional[str] = None,
-        nargs: int = 1,
-        const: t.Optional[t.Any] = None,
-    ) -> None:
-        """Adds a new option named `dest` to the parser.  The destination
-        is not inferred (unlike with optparse) and needs to be explicitly
-        provided.  Action can be any of ``store``, ``store_const``,
-        ``append``, ``append_const`` or ``count``.
-
-        The `obj` can be used to identify the option in the order list
-        that is returned from the parser.
-        """
-        opts = [normalize_opt(opt, self.ctx) for opt in opts]
-        option = Option(obj, opts, dest, action=action, nargs=nargs, const=const)
-        self._opt_prefixes.update(option.prefixes)
-        for opt in option._short_opts:
-            self._short_opt[opt] = option
-        for opt in option._long_opts:
-            self._long_opt[opt] = option
-
-    def add_argument(
-        self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1
-    ) -> None:
-        """Adds a positional argument named `dest` to the parser.
-
-        The `obj` can be used to identify the option in the order list
-        that is returned from the parser.
-        """
-        self._args.append(Argument(obj, dest=dest, nargs=nargs))
-
-    def parse_args(
-        self, args: t.List[str]
-    ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]:
-        """Parses positional arguments and returns ``(values, args, order)``
-        for the parsed options and arguments as well as the leftover
-        arguments if there are any.  The order is a list of objects as they
-        appear on the command line.  If arguments appear multiple times they
-        will be memorized multiple times as well.
-        """
-        state = ParsingState(args)
-        try:
-            self._process_args_for_options(state)
-            self._process_args_for_args(state)
-        except UsageError:
-            if self.ctx is None or not self.ctx.resilient_parsing:
-                raise
-        return state.opts, state.largs, state.order
-
-    def _process_args_for_args(self, state: ParsingState) -> None:
-        pargs, args = _unpack_args(
-            state.largs + state.rargs, [x.nargs for x in self._args]
-        )
-
-        for idx, arg in enumerate(self._args):
-            arg.process(pargs[idx], state)
-
-        state.largs = args
-        state.rargs = []
-
-    def _process_args_for_options(self, state: ParsingState) -> None:
-        while state.rargs:
-            arg = state.rargs.pop(0)
-            arglen = len(arg)
-            # Double dashes always handled explicitly regardless of what
-            # prefixes are valid.
-            if arg == "--":
-                return
-            elif arg[:1] in self._opt_prefixes and arglen > 1:
-                self._process_opts(arg, state)
-            elif self.allow_interspersed_args:
-                state.largs.append(arg)
-            else:
-                state.rargs.insert(0, arg)
-                return
-
-        # Say this is the original argument list:
-        # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)]
-        #                            ^
-        # (we are about to process arg(i)).
-        #
-        # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of
-        # [arg0, ..., arg(i-1)] (any options and their arguments will have
-        # been removed from largs).
-        #
-        # The while loop will usually consume 1 or more arguments per pass.
-        # If it consumes 1 (eg. arg is an option that takes no arguments),
-        # then after _process_arg() is done the situation is:
-        #
-        #   largs = subset of [arg0, ..., arg(i)]
-        #   rargs = [arg(i+1), ..., arg(N-1)]
-        #
-        # If allow_interspersed_args is false, largs will always be
-        # *empty* -- still a subset of [arg0, ..., arg(i-1)], but
-        # not a very interesting subset!
-
-    def _match_long_opt(
-        self, opt: str, explicit_value: t.Optional[str], state: ParsingState
-    ) -> None:
-        if opt not in self._long_opt:
-            from difflib import get_close_matches
-
-            possibilities = get_close_matches(opt, self._long_opt)
-            raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx)
-
-        option = self._long_opt[opt]
-        if option.takes_value:
-            # At this point it's safe to modify rargs by injecting the
-            # explicit value, because no exception is raised in this
-            # branch.  This means that the inserted value will be fully
-            # consumed.
-            if explicit_value is not None:
-                state.rargs.insert(0, explicit_value)
-
-            value = self._get_value_from_state(opt, option, state)
-
-        elif explicit_value is not None:
-            raise BadOptionUsage(
-                opt, _("Option {name!r} does not take a value.").format(name=opt)
-            )
-
-        else:
-            value = None
-
-        option.process(value, state)
-
-    def _match_short_opt(self, arg: str, state: ParsingState) -> None:
-        stop = False
-        i = 1
-        prefix = arg[0]
-        unknown_options = []
-
-        for ch in arg[1:]:
-            opt = normalize_opt(f"{prefix}{ch}", self.ctx)
-            option = self._short_opt.get(opt)
-            i += 1
-
-            if not option:
-                if self.ignore_unknown_options:
-                    unknown_options.append(ch)
-                    continue
-                raise NoSuchOption(opt, ctx=self.ctx)
-            if option.takes_value:
-                # Any characters left in arg?  Pretend they're the
-                # next arg, and stop consuming characters of arg.
-                if i < len(arg):
-                    state.rargs.insert(0, arg[i:])
-                    stop = True
-
-                value = self._get_value_from_state(opt, option, state)
-
-            else:
-                value = None
-
-            option.process(value, state)
-
-            if stop:
-                break
-
-        # If we got any unknown options we re-combinate the string of the
-        # remaining options and re-attach the prefix, then report that
-        # to the state as new larg.  This way there is basic combinatorics
-        # that can be achieved while still ignoring unknown arguments.
-        if self.ignore_unknown_options and unknown_options:
-            state.largs.append(f"{prefix}{''.join(unknown_options)}")
-
-    def _get_value_from_state(
-        self, option_name: str, option: Option, state: ParsingState
-    ) -> t.Any:
-        nargs = option.nargs
-
-        if len(state.rargs) < nargs:
-            if option.obj._flag_needs_value:
-                # Option allows omitting the value.
-                value = _flag_needs_value
-            else:
-                raise BadOptionUsage(
-                    option_name,
-                    ngettext(
-                        "Option {name!r} requires an argument.",
-                        "Option {name!r} requires {nargs} arguments.",
-                        nargs,
-                    ).format(name=option_name, nargs=nargs),
-                )
-        elif nargs == 1:
-            next_rarg = state.rargs[0]
-
-            if (
-                option.obj._flag_needs_value
-                and isinstance(next_rarg, str)
-                and next_rarg[:1] in self._opt_prefixes
-                and len(next_rarg) > 1
-            ):
-                # The next arg looks like the start of an option, don't
-                # use it as the value if omitting the value is allowed.
-                value = _flag_needs_value
-            else:
-                value = state.rargs.pop(0)
-        else:
-            value = tuple(state.rargs[:nargs])
-            del state.rargs[:nargs]
-
-        return value
-
-    def _process_opts(self, arg: str, state: ParsingState) -> None:
-        explicit_value = None
-        # Long option handling happens in two parts.  The first part is
-        # supporting explicitly attached values.  In any case, we will try
-        # to long match the option first.
-        if "=" in arg:
-            long_opt, explicit_value = arg.split("=", 1)
-        else:
-            long_opt = arg
-        norm_long_opt = normalize_opt(long_opt, self.ctx)
-
-        # At this point we will match the (assumed) long option through
-        # the long option matching code.  Note that this allows options
-        # like "-foo" to be matched as long options.
-        try:
-            self._match_long_opt(norm_long_opt, explicit_value, state)
-        except NoSuchOption:
-            # At this point the long option matching failed, and we need
-            # to try with short options.  However there is a special rule
-            # which says, that if we have a two character options prefix
-            # (applies to "--foo" for instance), we do not dispatch to the
-            # short option code and will instead raise the no option
-            # error.
-            if arg[:2] not in self._opt_prefixes:
-                self._match_short_opt(arg, state)
-                return
-
-            if not self.ignore_unknown_options:
-                raise
-
-            state.largs.append(arg)

+ 0 - 0
venv/lib/python3.10/site-packages/click/py.typed


+ 0 - 580
venv/lib/python3.10/site-packages/click/shell_completion.py

@@ -1,580 +0,0 @@
-import os
-import re
-import typing as t
-from gettext import gettext as _
-
-from .core import Argument
-from .core import BaseCommand
-from .core import Context
-from .core import MultiCommand
-from .core import Option
-from .core import Parameter
-from .core import ParameterSource
-from .parser import split_arg_string
-from .utils import echo
-
-
-def shell_complete(
-    cli: BaseCommand,
-    ctx_args: t.Dict[str, t.Any],
-    prog_name: str,
-    complete_var: str,
-    instruction: str,
-) -> int:
-    """Perform shell completion for the given CLI program.
-
-    :param cli: Command being called.
-    :param ctx_args: Extra arguments to pass to
-        ``cli.make_context``.
-    :param prog_name: Name of the executable in the shell.
-    :param complete_var: Name of the environment variable that holds
-        the completion instruction.
-    :param instruction: Value of ``complete_var`` with the completion
-        instruction and shell, in the form ``instruction_shell``.
-    :return: Status code to exit with.
-    """
-    shell, _, instruction = instruction.partition("_")
-    comp_cls = get_completion_class(shell)
-
-    if comp_cls is None:
-        return 1
-
-    comp = comp_cls(cli, ctx_args, prog_name, complete_var)
-
-    if instruction == "source":
-        echo(comp.source())
-        return 0
-
-    if instruction == "complete":
-        echo(comp.complete())
-        return 0
-
-    return 1
-
-
-class CompletionItem:
-    """Represents a completion value and metadata about the value. The
-    default metadata is ``type`` to indicate special shell handling,
-    and ``help`` if a shell supports showing a help string next to the
-    value.
-
-    Arbitrary parameters can be passed when creating the object, and
-    accessed using ``item.attr``. If an attribute wasn't passed,
-    accessing it returns ``None``.
-
-    :param value: The completion suggestion.
-    :param type: Tells the shell script to provide special completion
-        support for the type. Click uses ``"dir"`` and ``"file"``.
-    :param help: String shown next to the value if supported.
-    :param kwargs: Arbitrary metadata. The built-in implementations
-        don't use this, but custom type completions paired with custom
-        shell support could use it.
-    """
-
-    __slots__ = ("value", "type", "help", "_info")
-
-    def __init__(
-        self,
-        value: t.Any,
-        type: str = "plain",
-        help: t.Optional[str] = None,
-        **kwargs: t.Any,
-    ) -> None:
-        self.value = value
-        self.type = type
-        self.help = help
-        self._info = kwargs
-
-    def __getattr__(self, name: str) -> t.Any:
-        return self._info.get(name)
-
-
-# Only Bash >= 4.4 has the nosort option.
-_SOURCE_BASH = """\
-%(complete_func)s() {
-    local IFS=$'\\n'
-    local response
-
-    response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \
-%(complete_var)s=bash_complete $1)
-
-    for completion in $response; do
-        IFS=',' read type value <<< "$completion"
-
-        if [[ $type == 'dir' ]]; then
-            COMPREPLY=()
-            compopt -o dirnames
-        elif [[ $type == 'file' ]]; then
-            COMPREPLY=()
-            compopt -o default
-        elif [[ $type == 'plain' ]]; then
-            COMPREPLY+=($value)
-        fi
-    done
-
-    return 0
-}
-
-%(complete_func)s_setup() {
-    complete -o nosort -F %(complete_func)s %(prog_name)s
-}
-
-%(complete_func)s_setup;
-"""
-
-_SOURCE_ZSH = """\
-#compdef %(prog_name)s
-
-%(complete_func)s() {
-    local -a completions
-    local -a completions_with_descriptions
-    local -a response
-    (( ! $+commands[%(prog_name)s] )) && return 1
-
-    response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \
-%(complete_var)s=zsh_complete %(prog_name)s)}")
-
-    for type key descr in ${response}; do
-        if [[ "$type" == "plain" ]]; then
-            if [[ "$descr" == "_" ]]; then
-                completions+=("$key")
-            else
-                completions_with_descriptions+=("$key":"$descr")
-            fi
-        elif [[ "$type" == "dir" ]]; then
-            _path_files -/
-        elif [[ "$type" == "file" ]]; then
-            _path_files -f
-        fi
-    done
-
-    if [ -n "$completions_with_descriptions" ]; then
-        _describe -V unsorted completions_with_descriptions -U
-    fi
-
-    if [ -n "$completions" ]; then
-        compadd -U -V unsorted -a completions
-    fi
-}
-
-compdef %(complete_func)s %(prog_name)s;
-"""
-
-_SOURCE_FISH = """\
-function %(complete_func)s;
-    set -l response;
-
-    for value in (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \
-COMP_CWORD=(commandline -t) %(prog_name)s);
-        set response $response $value;
-    end;
-
-    for completion in $response;
-        set -l metadata (string split "," $completion);
-
-        if test $metadata[1] = "dir";
-            __fish_complete_directories $metadata[2];
-        else if test $metadata[1] = "file";
-            __fish_complete_path $metadata[2];
-        else if test $metadata[1] = "plain";
-            echo $metadata[2];
-        end;
-    end;
-end;
-
-complete --no-files --command %(prog_name)s --arguments \
-"(%(complete_func)s)";
-"""
-
-
-class ShellComplete:
-    """Base class for providing shell completion support. A subclass for
-    a given shell will override attributes and methods to implement the
-    completion instructions (``source`` and ``complete``).
-
-    :param cli: Command being called.
-    :param prog_name: Name of the executable in the shell.
-    :param complete_var: Name of the environment variable that holds
-        the completion instruction.
-
-    .. versionadded:: 8.0
-    """
-
-    name: t.ClassVar[str]
-    """Name to register the shell as with :func:`add_completion_class`.
-    This is used in completion instructions (``{name}_source`` and
-    ``{name}_complete``).
-    """
-
-    source_template: t.ClassVar[str]
-    """Completion script template formatted by :meth:`source`. This must
-    be provided by subclasses.
-    """
-
-    def __init__(
-        self,
-        cli: BaseCommand,
-        ctx_args: t.Dict[str, t.Any],
-        prog_name: str,
-        complete_var: str,
-    ) -> None:
-        self.cli = cli
-        self.ctx_args = ctx_args
-        self.prog_name = prog_name
-        self.complete_var = complete_var
-
-    @property
-    def func_name(self) -> str:
-        """The name of the shell function defined by the completion
-        script.
-        """
-        safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), re.ASCII)
-        return f"_{safe_name}_completion"
-
-    def source_vars(self) -> t.Dict[str, t.Any]:
-        """Vars for formatting :attr:`source_template`.
-
-        By default this provides ``complete_func``, ``complete_var``,
-        and ``prog_name``.
-        """
-        return {
-            "complete_func": self.func_name,
-            "complete_var": self.complete_var,
-            "prog_name": self.prog_name,
-        }
-
-    def source(self) -> str:
-        """Produce the shell script that defines the completion
-        function. By default this ``%``-style formats
-        :attr:`source_template` with the dict returned by
-        :meth:`source_vars`.
-        """
-        return self.source_template % self.source_vars()
-
-    def get_completion_args(self) -> t.Tuple[t.List[str], str]:
-        """Use the env vars defined by the shell script to return a
-        tuple of ``args, incomplete``. This must be implemented by
-        subclasses.
-        """
-        raise NotImplementedError
-
-    def get_completions(
-        self, args: t.List[str], incomplete: str
-    ) -> t.List[CompletionItem]:
-        """Determine the context and last complete command or parameter
-        from the complete args. Call that object's ``shell_complete``
-        method to get the completions for the incomplete value.
-
-        :param args: List of complete args before the incomplete value.
-        :param incomplete: Value being completed. May be empty.
-        """
-        ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args)
-        obj, incomplete = _resolve_incomplete(ctx, args, incomplete)
-        return obj.shell_complete(ctx, incomplete)
-
-    def format_completion(self, item: CompletionItem) -> str:
-        """Format a completion item into the form recognized by the
-        shell script. This must be implemented by subclasses.
-
-        :param item: Completion item to format.
-        """
-        raise NotImplementedError
-
-    def complete(self) -> str:
-        """Produce the completion data to send back to the shell.
-
-        By default this calls :meth:`get_completion_args`, gets the
-        completions, then calls :meth:`format_completion` for each
-        completion.
-        """
-        args, incomplete = self.get_completion_args()
-        completions = self.get_completions(args, incomplete)
-        out = [self.format_completion(item) for item in completions]
-        return "\n".join(out)
-
-
-class BashComplete(ShellComplete):
-    """Shell completion for Bash."""
-
-    name = "bash"
-    source_template = _SOURCE_BASH
-
-    def _check_version(self) -> None:
-        import subprocess
-
-        output = subprocess.run(
-            ["bash", "-c", "echo ${BASH_VERSION}"], stdout=subprocess.PIPE
-        )
-        match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode())
-
-        if match is not None:
-            major, minor = match.groups()
-
-            if major < "4" or major == "4" and minor < "4":
-                raise RuntimeError(
-                    _(
-                        "Shell completion is not supported for Bash"
-                        " versions older than 4.4."
-                    )
-                )
-        else:
-            raise RuntimeError(
-                _("Couldn't detect Bash version, shell completion is not supported.")
-            )
-
-    def source(self) -> str:
-        self._check_version()
-        return super().source()
-
-    def get_completion_args(self) -> t.Tuple[t.List[str], str]:
-        cwords = split_arg_string(os.environ["COMP_WORDS"])
-        cword = int(os.environ["COMP_CWORD"])
-        args = cwords[1:cword]
-
-        try:
-            incomplete = cwords[cword]
-        except IndexError:
-            incomplete = ""
-
-        return args, incomplete
-
-    def format_completion(self, item: CompletionItem) -> str:
-        return f"{item.type},{item.value}"
-
-
-class ZshComplete(ShellComplete):
-    """Shell completion for Zsh."""
-
-    name = "zsh"
-    source_template = _SOURCE_ZSH
-
-    def get_completion_args(self) -> t.Tuple[t.List[str], str]:
-        cwords = split_arg_string(os.environ["COMP_WORDS"])
-        cword = int(os.environ["COMP_CWORD"])
-        args = cwords[1:cword]
-
-        try:
-            incomplete = cwords[cword]
-        except IndexError:
-            incomplete = ""
-
-        return args, incomplete
-
-    def format_completion(self, item: CompletionItem) -> str:
-        return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}"
-
-
-class FishComplete(ShellComplete):
-    """Shell completion for Fish."""
-
-    name = "fish"
-    source_template = _SOURCE_FISH
-
-    def get_completion_args(self) -> t.Tuple[t.List[str], str]:
-        cwords = split_arg_string(os.environ["COMP_WORDS"])
-        incomplete = os.environ["COMP_CWORD"]
-        args = cwords[1:]
-
-        # Fish stores the partial word in both COMP_WORDS and
-        # COMP_CWORD, remove it from complete args.
-        if incomplete and args and args[-1] == incomplete:
-            args.pop()
-
-        return args, incomplete
-
-    def format_completion(self, item: CompletionItem) -> str:
-        if item.help:
-            return f"{item.type},{item.value}\t{item.help}"
-
-        return f"{item.type},{item.value}"
-
-
-_available_shells: t.Dict[str, t.Type[ShellComplete]] = {
-    "bash": BashComplete,
-    "fish": FishComplete,
-    "zsh": ZshComplete,
-}
-
-
-def add_completion_class(
-    cls: t.Type[ShellComplete], name: t.Optional[str] = None
-) -> None:
-    """Register a :class:`ShellComplete` subclass under the given name.
-    The name will be provided by the completion instruction environment
-    variable during completion.
-
-    :param cls: The completion class that will handle completion for the
-        shell.
-    :param name: Name to register the class under. Defaults to the
-        class's ``name`` attribute.
-    """
-    if name is None:
-        name = cls.name
-
-    _available_shells[name] = cls
-
-
-def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]:
-    """Look up a registered :class:`ShellComplete` subclass by the name
-    provided by the completion instruction environment variable. If the
-    name isn't registered, returns ``None``.
-
-    :param shell: Name the class is registered under.
-    """
-    return _available_shells.get(shell)
-
-
-def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool:
-    """Determine if the given parameter is an argument that can still
-    accept values.
-
-    :param ctx: Invocation context for the command represented by the
-        parsed complete args.
-    :param param: Argument object being checked.
-    """
-    if not isinstance(param, Argument):
-        return False
-
-    assert param.name is not None
-    value = ctx.params[param.name]
-    return (
-        param.nargs == -1
-        or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE
-        or (
-            param.nargs > 1
-            and isinstance(value, (tuple, list))
-            and len(value) < param.nargs
-        )
-    )
-
-
-def _start_of_option(ctx: Context, value: str) -> bool:
-    """Check if the value looks like the start of an option."""
-    if not value:
-        return False
-
-    c = value[0]
-    return c in ctx._opt_prefixes
-
-
-def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool:
-    """Determine if the given parameter is an option that needs a value.
-
-    :param args: List of complete args before the incomplete value.
-    :param param: Option object being checked.
-    """
-    if not isinstance(param, Option):
-        return False
-
-    if param.is_flag or param.count:
-        return False
-
-    last_option = None
-
-    for index, arg in enumerate(reversed(args)):
-        if index + 1 > param.nargs:
-            break
-
-        if _start_of_option(ctx, arg):
-            last_option = arg
-
-    return last_option is not None and last_option in param.opts
-
-
-def _resolve_context(
-    cli: BaseCommand, ctx_args: t.Dict[str, t.Any], prog_name: str, args: t.List[str]
-) -> Context:
-    """Produce the context hierarchy starting with the command and
-    traversing the complete arguments. This only follows the commands,
-    it doesn't trigger input prompts or callbacks.
-
-    :param cli: Command being called.
-    :param prog_name: Name of the executable in the shell.
-    :param args: List of complete args before the incomplete value.
-    """
-    ctx_args["resilient_parsing"] = True
-    ctx = cli.make_context(prog_name, args.copy(), **ctx_args)
-    args = ctx.protected_args + ctx.args
-
-    while args:
-        command = ctx.command
-
-        if isinstance(command, MultiCommand):
-            if not command.chain:
-                name, cmd, args = command.resolve_command(ctx, args)
-
-                if cmd is None:
-                    return ctx
-
-                ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True)
-                args = ctx.protected_args + ctx.args
-            else:
-                while args:
-                    name, cmd, args = command.resolve_command(ctx, args)
-
-                    if cmd is None:
-                        return ctx
-
-                    sub_ctx = cmd.make_context(
-                        name,
-                        args,
-                        parent=ctx,
-                        allow_extra_args=True,
-                        allow_interspersed_args=False,
-                        resilient_parsing=True,
-                    )
-                    args = sub_ctx.args
-
-                ctx = sub_ctx
-                args = [*sub_ctx.protected_args, *sub_ctx.args]
-        else:
-            break
-
-    return ctx
-
-
-def _resolve_incomplete(
-    ctx: Context, args: t.List[str], incomplete: str
-) -> t.Tuple[t.Union[BaseCommand, Parameter], str]:
-    """Find the Click object that will handle the completion of the
-    incomplete value. Return the object and the incomplete value.
-
-    :param ctx: Invocation context for the command represented by
-        the parsed complete args.
-    :param args: List of complete args before the incomplete value.
-    :param incomplete: Value being completed. May be empty.
-    """
-    # Different shells treat an "=" between a long option name and
-    # value differently. Might keep the value joined, return the "="
-    # as a separate item, or return the split name and value. Always
-    # split and discard the "=" to make completion easier.
-    if incomplete == "=":
-        incomplete = ""
-    elif "=" in incomplete and _start_of_option(ctx, incomplete):
-        name, _, incomplete = incomplete.partition("=")
-        args.append(name)
-
-    # The "--" marker tells Click to stop treating values as options
-    # even if they start with the option character. If it hasn't been
-    # given and the incomplete arg looks like an option, the current
-    # command will provide option name completions.
-    if "--" not in args and _start_of_option(ctx, incomplete):
-        return ctx.command, incomplete
-
-    params = ctx.command.get_params(ctx)
-
-    # If the last complete arg is an option name with an incomplete
-    # value, the option will provide value completions.
-    for param in params:
-        if _is_incomplete_option(ctx, args, param):
-            return param, incomplete
-
-    # It's not an option name or value. The first argument without a
-    # parsed value will provide value completions.
-    for param in params:
-        if _is_incomplete_argument(ctx, param):
-            return param, incomplete
-
-    # There were no unparsed arguments, the command may be a group that
-    # will provide command name completions.
-    return ctx.command, incomplete

+ 0 - 787
venv/lib/python3.10/site-packages/click/termui.py

@@ -1,787 +0,0 @@
-import inspect
-import io
-import itertools
-import os
-import sys
-import typing as t
-from gettext import gettext as _
-
-from ._compat import isatty
-from ._compat import strip_ansi
-from ._compat import WIN
-from .exceptions import Abort
-from .exceptions import UsageError
-from .globals import resolve_color_default
-from .types import Choice
-from .types import convert_type
-from .types import ParamType
-from .utils import echo
-from .utils import LazyFile
-
-if t.TYPE_CHECKING:
-    from ._termui_impl import ProgressBar
-
-V = t.TypeVar("V")
-
-# The prompt functions to use.  The doc tools currently override these
-# functions to customize how they work.
-visible_prompt_func: t.Callable[[str], str] = input
-
-_ansi_colors = {
-    "black": 30,
-    "red": 31,
-    "green": 32,
-    "yellow": 33,
-    "blue": 34,
-    "magenta": 35,
-    "cyan": 36,
-    "white": 37,
-    "reset": 39,
-    "bright_black": 90,
-    "bright_red": 91,
-    "bright_green": 92,
-    "bright_yellow": 93,
-    "bright_blue": 94,
-    "bright_magenta": 95,
-    "bright_cyan": 96,
-    "bright_white": 97,
-}
-_ansi_reset_all = "\033[0m"
-
-
-def hidden_prompt_func(prompt: str) -> str:
-    import getpass
-
-    return getpass.getpass(prompt)
-
-
-def _build_prompt(
-    text: str,
-    suffix: str,
-    show_default: bool = False,
-    default: t.Optional[t.Any] = None,
-    show_choices: bool = True,
-    type: t.Optional[ParamType] = None,
-) -> str:
-    prompt = text
-    if type is not None and show_choices and isinstance(type, Choice):
-        prompt += f" ({', '.join(map(str, type.choices))})"
-    if default is not None and show_default:
-        prompt = f"{prompt} [{_format_default(default)}]"
-    return f"{prompt}{suffix}"
-
-
-def _format_default(default: t.Any) -> t.Any:
-    if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"):
-        return default.name  # type: ignore
-
-    return default
-
-
-def prompt(
-    text: str,
-    default: t.Optional[t.Any] = None,
-    hide_input: bool = False,
-    confirmation_prompt: t.Union[bool, str] = False,
-    type: t.Optional[t.Union[ParamType, t.Any]] = None,
-    value_proc: t.Optional[t.Callable[[str], t.Any]] = None,
-    prompt_suffix: str = ": ",
-    show_default: bool = True,
-    err: bool = False,
-    show_choices: bool = True,
-) -> t.Any:
-    """Prompts a user for input.  This is a convenience function that can
-    be used to prompt a user for input later.
-
-    If the user aborts the input by sending an interrupt signal, this
-    function will catch it and raise a :exc:`Abort` exception.
-
-    :param text: the text to show for the prompt.
-    :param default: the default value to use if no input happens.  If this
-                    is not given it will prompt until it's aborted.
-    :param hide_input: if this is set to true then the input value will
-                       be hidden.
-    :param confirmation_prompt: Prompt a second time to confirm the
-        value. Can be set to a string instead of ``True`` to customize
-        the message.
-    :param type: the type to use to check the value against.
-    :param value_proc: if this parameter is provided it's a function that
-                       is invoked instead of the type conversion to
-                       convert a value.
-    :param prompt_suffix: a suffix that should be added to the prompt.
-    :param show_default: shows or hides the default value in the prompt.
-    :param err: if set to true the file defaults to ``stderr`` instead of
-                ``stdout``, the same as with echo.
-    :param show_choices: Show or hide choices if the passed type is a Choice.
-                         For example if type is a Choice of either day or week,
-                         show_choices is true and text is "Group by" then the
-                         prompt will be "Group by (day, week): ".
-
-    .. versionadded:: 8.0
-        ``confirmation_prompt`` can be a custom string.
-
-    .. versionadded:: 7.0
-        Added the ``show_choices`` parameter.
-
-    .. versionadded:: 6.0
-        Added unicode support for cmd.exe on Windows.
-
-    .. versionadded:: 4.0
-        Added the `err` parameter.
-
-    """
-
-    def prompt_func(text: str) -> str:
-        f = hidden_prompt_func if hide_input else visible_prompt_func
-        try:
-            # Write the prompt separately so that we get nice
-            # coloring through colorama on Windows
-            echo(text.rstrip(" "), nl=False, err=err)
-            # Echo a space to stdout to work around an issue where
-            # readline causes backspace to clear the whole line.
-            return f(" ")
-        except (KeyboardInterrupt, EOFError):
-            # getpass doesn't print a newline if the user aborts input with ^C.
-            # Allegedly this behavior is inherited from getpass(3).
-            # A doc bug has been filed at https://bugs.python.org/issue24711
-            if hide_input:
-                echo(None, err=err)
-            raise Abort() from None
-
-    if value_proc is None:
-        value_proc = convert_type(type, default)
-
-    prompt = _build_prompt(
-        text, prompt_suffix, show_default, default, show_choices, type
-    )
-
-    if confirmation_prompt:
-        if confirmation_prompt is True:
-            confirmation_prompt = _("Repeat for confirmation")
-
-        confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix)
-
-    while True:
-        while True:
-            value = prompt_func(prompt)
-            if value:
-                break
-            elif default is not None:
-                value = default
-                break
-        try:
-            result = value_proc(value)
-        except UsageError as e:
-            if hide_input:
-                echo(_("Error: The value you entered was invalid."), err=err)
-            else:
-                echo(_("Error: {e.message}").format(e=e), err=err)  # noqa: B306
-            continue
-        if not confirmation_prompt:
-            return result
-        while True:
-            value2 = prompt_func(confirmation_prompt)
-            is_empty = not value and not value2
-            if value2 or is_empty:
-                break
-        if value == value2:
-            return result
-        echo(_("Error: The two entered values do not match."), err=err)
-
-
-def confirm(
-    text: str,
-    default: t.Optional[bool] = False,
-    abort: bool = False,
-    prompt_suffix: str = ": ",
-    show_default: bool = True,
-    err: bool = False,
-) -> bool:
-    """Prompts for confirmation (yes/no question).
-
-    If the user aborts the input by sending a interrupt signal this
-    function will catch it and raise a :exc:`Abort` exception.
-
-    :param text: the question to ask.
-    :param default: The default value to use when no input is given. If
-        ``None``, repeat until input is given.
-    :param abort: if this is set to `True` a negative answer aborts the
-                  exception by raising :exc:`Abort`.
-    :param prompt_suffix: a suffix that should be added to the prompt.
-    :param show_default: shows or hides the default value in the prompt.
-    :param err: if set to true the file defaults to ``stderr`` instead of
-                ``stdout``, the same as with echo.
-
-    .. versionchanged:: 8.0
-        Repeat until input is given if ``default`` is ``None``.
-
-    .. versionadded:: 4.0
-        Added the ``err`` parameter.
-    """
-    prompt = _build_prompt(
-        text,
-        prompt_suffix,
-        show_default,
-        "y/n" if default is None else ("Y/n" if default else "y/N"),
-    )
-
-    while True:
-        try:
-            # Write the prompt separately so that we get nice
-            # coloring through colorama on Windows
-            echo(prompt.rstrip(" "), nl=False, err=err)
-            # Echo a space to stdout to work around an issue where
-            # readline causes backspace to clear the whole line.
-            value = visible_prompt_func(" ").lower().strip()
-        except (KeyboardInterrupt, EOFError):
-            raise Abort() from None
-        if value in ("y", "yes"):
-            rv = True
-        elif value in ("n", "no"):
-            rv = False
-        elif default is not None and value == "":
-            rv = default
-        else:
-            echo(_("Error: invalid input"), err=err)
-            continue
-        break
-    if abort and not rv:
-        raise Abort()
-    return rv
-
-
-def echo_via_pager(
-    text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str],
-    color: t.Optional[bool] = None,
-) -> None:
-    """This function takes a text and shows it via an environment specific
-    pager on stdout.
-
-    .. versionchanged:: 3.0
-       Added the `color` flag.
-
-    :param text_or_generator: the text to page, or alternatively, a
-                              generator emitting the text to page.
-    :param color: controls if the pager supports ANSI colors or not.  The
-                  default is autodetection.
-    """
-    color = resolve_color_default(color)
-
-    if inspect.isgeneratorfunction(text_or_generator):
-        i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)()
-    elif isinstance(text_or_generator, str):
-        i = [text_or_generator]
-    else:
-        i = iter(t.cast(t.Iterable[str], text_or_generator))
-
-    # convert every element of i to a text type if necessary
-    text_generator = (el if isinstance(el, str) else str(el) for el in i)
-
-    from ._termui_impl import pager
-
-    return pager(itertools.chain(text_generator, "\n"), color)
-
-
-def progressbar(
-    iterable: t.Optional[t.Iterable[V]] = None,
-    length: t.Optional[int] = None,
-    label: t.Optional[str] = None,
-    show_eta: bool = True,
-    show_percent: t.Optional[bool] = None,
-    show_pos: bool = False,
-    item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None,
-    fill_char: str = "#",
-    empty_char: str = "-",
-    bar_template: str = "%(label)s  [%(bar)s]  %(info)s",
-    info_sep: str = "  ",
-    width: int = 36,
-    file: t.Optional[t.TextIO] = None,
-    color: t.Optional[bool] = None,
-    update_min_steps: int = 1,
-) -> "ProgressBar[V]":
-    """This function creates an iterable context manager that can be used
-    to iterate over something while showing a progress bar.  It will
-    either iterate over the `iterable` or `length` items (that are counted
-    up).  While iteration happens, this function will print a rendered
-    progress bar to the given `file` (defaults to stdout) and will attempt
-    to calculate remaining time and more.  By default, this progress bar
-    will not be rendered if the file is not a terminal.
-
-    The context manager creates the progress bar.  When the context
-    manager is entered the progress bar is already created.  With every
-    iteration over the progress bar, the iterable passed to the bar is
-    advanced and the bar is updated.  When the context manager exits,
-    a newline is printed and the progress bar is finalized on screen.
-
-    Note: The progress bar is currently designed for use cases where the
-    total progress can be expected to take at least several seconds.
-    Because of this, the ProgressBar class object won't display
-    progress that is considered too fast, and progress where the time
-    between steps is less than a second.
-
-    No printing must happen or the progress bar will be unintentionally
-    destroyed.
-
-    Example usage::
-
-        with progressbar(items) as bar:
-            for item in bar:
-                do_something_with(item)
-
-    Alternatively, if no iterable is specified, one can manually update the
-    progress bar through the `update()` method instead of directly
-    iterating over the progress bar.  The update method accepts the number
-    of steps to increment the bar with::
-
-        with progressbar(length=chunks.total_bytes) as bar:
-            for chunk in chunks:
-                process_chunk(chunk)
-                bar.update(chunks.bytes)
-
-    The ``update()`` method also takes an optional value specifying the
-    ``current_item`` at the new position. This is useful when used
-    together with ``item_show_func`` to customize the output for each
-    manual step::
-
-        with click.progressbar(
-            length=total_size,
-            label='Unzipping archive',
-            item_show_func=lambda a: a.filename
-        ) as bar:
-            for archive in zip_file:
-                archive.extract()
-                bar.update(archive.size, archive)
-
-    :param iterable: an iterable to iterate over.  If not provided the length
-                     is required.
-    :param length: the number of items to iterate over.  By default the
-                   progressbar will attempt to ask the iterator about its
-                   length, which might or might not work.  If an iterable is
-                   also provided this parameter can be used to override the
-                   length.  If an iterable is not provided the progress bar
-                   will iterate over a range of that length.
-    :param label: the label to show next to the progress bar.
-    :param show_eta: enables or disables the estimated time display.  This is
-                     automatically disabled if the length cannot be
-                     determined.
-    :param show_percent: enables or disables the percentage display.  The
-                         default is `True` if the iterable has a length or
-                         `False` if not.
-    :param show_pos: enables or disables the absolute position display.  The
-                     default is `False`.
-    :param item_show_func: A function called with the current item which
-        can return a string to show next to the progress bar. If the
-        function returns ``None`` nothing is shown. The current item can
-        be ``None``, such as when entering and exiting the bar.
-    :param fill_char: the character to use to show the filled part of the
-                      progress bar.
-    :param empty_char: the character to use to show the non-filled part of
-                       the progress bar.
-    :param bar_template: the format string to use as template for the bar.
-                         The parameters in it are ``label`` for the label,
-                         ``bar`` for the progress bar and ``info`` for the
-                         info section.
-    :param info_sep: the separator between multiple info items (eta etc.)
-    :param width: the width of the progress bar in characters, 0 means full
-                  terminal width
-    :param file: The file to write to. If this is not a terminal then
-        only the label is printed.
-    :param color: controls if the terminal supports ANSI colors or not.  The
-                  default is autodetection.  This is only needed if ANSI
-                  codes are included anywhere in the progress bar output
-                  which is not the case by default.
-    :param update_min_steps: Render only when this many updates have
-        completed. This allows tuning for very fast iterators.
-
-    .. versionchanged:: 8.0
-        Output is shown even if execution time is less than 0.5 seconds.
-
-    .. versionchanged:: 8.0
-        ``item_show_func`` shows the current item, not the previous one.
-
-    .. versionchanged:: 8.0
-        Labels are echoed if the output is not a TTY. Reverts a change
-        in 7.0 that removed all output.
-
-    .. versionadded:: 8.0
-       Added the ``update_min_steps`` parameter.
-
-    .. versionchanged:: 4.0
-        Added the ``color`` parameter. Added the ``update`` method to
-        the object.
-
-    .. versionadded:: 2.0
-    """
-    from ._termui_impl import ProgressBar
-
-    color = resolve_color_default(color)
-    return ProgressBar(
-        iterable=iterable,
-        length=length,
-        show_eta=show_eta,
-        show_percent=show_percent,
-        show_pos=show_pos,
-        item_show_func=item_show_func,
-        fill_char=fill_char,
-        empty_char=empty_char,
-        bar_template=bar_template,
-        info_sep=info_sep,
-        file=file,
-        label=label,
-        width=width,
-        color=color,
-        update_min_steps=update_min_steps,
-    )
-
-
-def clear() -> None:
-    """Clears the terminal screen.  This will have the effect of clearing
-    the whole visible space of the terminal and moving the cursor to the
-    top left.  This does not do anything if not connected to a terminal.
-
-    .. versionadded:: 2.0
-    """
-    if not isatty(sys.stdout):
-        return
-    if WIN:
-        os.system("cls")
-    else:
-        sys.stdout.write("\033[2J\033[1;1H")
-
-
-def _interpret_color(
-    color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0
-) -> str:
-    if isinstance(color, int):
-        return f"{38 + offset};5;{color:d}"
-
-    if isinstance(color, (tuple, list)):
-        r, g, b = color
-        return f"{38 + offset};2;{r:d};{g:d};{b:d}"
-
-    return str(_ansi_colors[color] + offset)
-
-
-def style(
-    text: t.Any,
-    fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None,
-    bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None,
-    bold: t.Optional[bool] = None,
-    dim: t.Optional[bool] = None,
-    underline: t.Optional[bool] = None,
-    overline: t.Optional[bool] = None,
-    italic: t.Optional[bool] = None,
-    blink: t.Optional[bool] = None,
-    reverse: t.Optional[bool] = None,
-    strikethrough: t.Optional[bool] = None,
-    reset: bool = True,
-) -> str:
-    """Styles a text with ANSI styles and returns the new string.  By
-    default the styling is self contained which means that at the end
-    of the string a reset code is issued.  This can be prevented by
-    passing ``reset=False``.
-
-    Examples::
-
-        click.echo(click.style('Hello World!', fg='green'))
-        click.echo(click.style('ATTENTION!', blink=True))
-        click.echo(click.style('Some things', reverse=True, fg='cyan'))
-        click.echo(click.style('More colors', fg=(255, 12, 128), bg=117))
-
-    Supported color names:
-
-    * ``black`` (might be a gray)
-    * ``red``
-    * ``green``
-    * ``yellow`` (might be an orange)
-    * ``blue``
-    * ``magenta``
-    * ``cyan``
-    * ``white`` (might be light gray)
-    * ``bright_black``
-    * ``bright_red``
-    * ``bright_green``
-    * ``bright_yellow``
-    * ``bright_blue``
-    * ``bright_magenta``
-    * ``bright_cyan``
-    * ``bright_white``
-    * ``reset`` (reset the color code only)
-
-    If the terminal supports it, color may also be specified as:
-
-    -   An integer in the interval [0, 255]. The terminal must support
-        8-bit/256-color mode.
-    -   An RGB tuple of three integers in [0, 255]. The terminal must
-        support 24-bit/true-color mode.
-
-    See https://en.wikipedia.org/wiki/ANSI_color and
-    https://gist.github.com/XVilka/8346728 for more information.
-
-    :param text: the string to style with ansi codes.
-    :param fg: if provided this will become the foreground color.
-    :param bg: if provided this will become the background color.
-    :param bold: if provided this will enable or disable bold mode.
-    :param dim: if provided this will enable or disable dim mode.  This is
-                badly supported.
-    :param underline: if provided this will enable or disable underline.
-    :param overline: if provided this will enable or disable overline.
-    :param italic: if provided this will enable or disable italic.
-    :param blink: if provided this will enable or disable blinking.
-    :param reverse: if provided this will enable or disable inverse
-                    rendering (foreground becomes background and the
-                    other way round).
-    :param strikethrough: if provided this will enable or disable
-        striking through text.
-    :param reset: by default a reset-all code is added at the end of the
-                  string which means that styles do not carry over.  This
-                  can be disabled to compose styles.
-
-    .. versionchanged:: 8.0
-        A non-string ``message`` is converted to a string.
-
-    .. versionchanged:: 8.0
-       Added support for 256 and RGB color codes.
-
-    .. versionchanged:: 8.0
-        Added the ``strikethrough``, ``italic``, and ``overline``
-        parameters.
-
-    .. versionchanged:: 7.0
-        Added support for bright colors.
-
-    .. versionadded:: 2.0
-    """
-    if not isinstance(text, str):
-        text = str(text)
-
-    bits = []
-
-    if fg:
-        try:
-            bits.append(f"\033[{_interpret_color(fg)}m")
-        except KeyError:
-            raise TypeError(f"Unknown color {fg!r}") from None
-
-    if bg:
-        try:
-            bits.append(f"\033[{_interpret_color(bg, 10)}m")
-        except KeyError:
-            raise TypeError(f"Unknown color {bg!r}") from None
-
-    if bold is not None:
-        bits.append(f"\033[{1 if bold else 22}m")
-    if dim is not None:
-        bits.append(f"\033[{2 if dim else 22}m")
-    if underline is not None:
-        bits.append(f"\033[{4 if underline else 24}m")
-    if overline is not None:
-        bits.append(f"\033[{53 if overline else 55}m")
-    if italic is not None:
-        bits.append(f"\033[{3 if italic else 23}m")
-    if blink is not None:
-        bits.append(f"\033[{5 if blink else 25}m")
-    if reverse is not None:
-        bits.append(f"\033[{7 if reverse else 27}m")
-    if strikethrough is not None:
-        bits.append(f"\033[{9 if strikethrough else 29}m")
-    bits.append(text)
-    if reset:
-        bits.append(_ansi_reset_all)
-    return "".join(bits)
-
-
-def unstyle(text: str) -> str:
-    """Removes ANSI styling information from a string.  Usually it's not
-    necessary to use this function as Click's echo function will
-    automatically remove styling if necessary.
-
-    .. versionadded:: 2.0
-
-    :param text: the text to remove style information from.
-    """
-    return strip_ansi(text)
-
-
-def secho(
-    message: t.Optional[t.Any] = None,
-    file: t.Optional[t.IO[t.AnyStr]] = None,
-    nl: bool = True,
-    err: bool = False,
-    color: t.Optional[bool] = None,
-    **styles: t.Any,
-) -> None:
-    """This function combines :func:`echo` and :func:`style` into one
-    call.  As such the following two calls are the same::
-
-        click.secho('Hello World!', fg='green')
-        click.echo(click.style('Hello World!', fg='green'))
-
-    All keyword arguments are forwarded to the underlying functions
-    depending on which one they go with.
-
-    Non-string types will be converted to :class:`str`. However,
-    :class:`bytes` are passed directly to :meth:`echo` without applying
-    style. If you want to style bytes that represent text, call
-    :meth:`bytes.decode` first.
-
-    .. versionchanged:: 8.0
-        A non-string ``message`` is converted to a string. Bytes are
-        passed through without style applied.
-
-    .. versionadded:: 2.0
-    """
-    if message is not None and not isinstance(message, (bytes, bytearray)):
-        message = style(message, **styles)
-
-    return echo(message, file=file, nl=nl, err=err, color=color)
-
-
-def edit(
-    text: t.Optional[t.AnyStr] = None,
-    editor: t.Optional[str] = None,
-    env: t.Optional[t.Mapping[str, str]] = None,
-    require_save: bool = True,
-    extension: str = ".txt",
-    filename: t.Optional[str] = None,
-) -> t.Optional[t.AnyStr]:
-    r"""Edits the given text in the defined editor.  If an editor is given
-    (should be the full path to the executable but the regular operating
-    system search path is used for finding the executable) it overrides
-    the detected editor.  Optionally, some environment variables can be
-    used.  If the editor is closed without changes, `None` is returned.  In
-    case a file is edited directly the return value is always `None` and
-    `require_save` and `extension` are ignored.
-
-    If the editor cannot be opened a :exc:`UsageError` is raised.
-
-    Note for Windows: to simplify cross-platform usage, the newlines are
-    automatically converted from POSIX to Windows and vice versa.  As such,
-    the message here will have ``\n`` as newline markers.
-
-    :param text: the text to edit.
-    :param editor: optionally the editor to use.  Defaults to automatic
-                   detection.
-    :param env: environment variables to forward to the editor.
-    :param require_save: if this is true, then not saving in the editor
-                         will make the return value become `None`.
-    :param extension: the extension to tell the editor about.  This defaults
-                      to `.txt` but changing this might change syntax
-                      highlighting.
-    :param filename: if provided it will edit this file instead of the
-                     provided text contents.  It will not use a temporary
-                     file as an indirection in that case.
-    """
-    from ._termui_impl import Editor
-
-    ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension)
-
-    if filename is None:
-        return ed.edit(text)
-
-    ed.edit_file(filename)
-    return None
-
-
-def launch(url: str, wait: bool = False, locate: bool = False) -> int:
-    """This function launches the given URL (or filename) in the default
-    viewer application for this file type.  If this is an executable, it
-    might launch the executable in a new session.  The return value is
-    the exit code of the launched application.  Usually, ``0`` indicates
-    success.
-
-    Examples::
-
-        click.launch('https://click.palletsprojects.com/')
-        click.launch('/my/downloaded/file', locate=True)
-
-    .. versionadded:: 2.0
-
-    :param url: URL or filename of the thing to launch.
-    :param wait: Wait for the program to exit before returning. This
-        only works if the launched program blocks. In particular,
-        ``xdg-open`` on Linux does not block.
-    :param locate: if this is set to `True` then instead of launching the
-                   application associated with the URL it will attempt to
-                   launch a file manager with the file located.  This
-                   might have weird effects if the URL does not point to
-                   the filesystem.
-    """
-    from ._termui_impl import open_url
-
-    return open_url(url, wait=wait, locate=locate)
-
-
-# If this is provided, getchar() calls into this instead.  This is used
-# for unittesting purposes.
-_getchar: t.Optional[t.Callable[[bool], str]] = None
-
-
-def getchar(echo: bool = False) -> str:
-    """Fetches a single character from the terminal and returns it.  This
-    will always return a unicode character and under certain rare
-    circumstances this might return more than one character.  The
-    situations which more than one character is returned is when for
-    whatever reason multiple characters end up in the terminal buffer or
-    standard input was not actually a terminal.
-
-    Note that this will always read from the terminal, even if something
-    is piped into the standard input.
-
-    Note for Windows: in rare cases when typing non-ASCII characters, this
-    function might wait for a second character and then return both at once.
-    This is because certain Unicode characters look like special-key markers.
-
-    .. versionadded:: 2.0
-
-    :param echo: if set to `True`, the character read will also show up on
-                 the terminal.  The default is to not show it.
-    """
-    global _getchar
-
-    if _getchar is None:
-        from ._termui_impl import getchar as f
-
-        _getchar = f
-
-    return _getchar(echo)
-
-
-def raw_terminal() -> t.ContextManager[int]:
-    from ._termui_impl import raw_terminal as f
-
-    return f()
-
-
-def pause(info: t.Optional[str] = None, err: bool = False) -> None:
-    """This command stops execution and waits for the user to press any
-    key to continue.  This is similar to the Windows batch "pause"
-    command.  If the program is not run through a terminal, this command
-    will instead do nothing.
-
-    .. versionadded:: 2.0
-
-    .. versionadded:: 4.0
-       Added the `err` parameter.
-
-    :param info: The message to print before pausing. Defaults to
-        ``"Press any key to continue..."``.
-    :param err: if set to message goes to ``stderr`` instead of
-                ``stdout``, the same as with echo.
-    """
-    if not isatty(sys.stdin) or not isatty(sys.stdout):
-        return
-
-    if info is None:
-        info = _("Press any key to continue...")
-
-    try:
-        if info:
-            echo(info, nl=False, err=err)
-        try:
-            getchar()
-        except (KeyboardInterrupt, EOFError):
-            pass
-    finally:
-        if info:
-            echo(err=err)

+ 0 - 479
venv/lib/python3.10/site-packages/click/testing.py

@@ -1,479 +0,0 @@
-import contextlib
-import io
-import os
-import shlex
-import shutil
-import sys
-import tempfile
-import typing as t
-from types import TracebackType
-
-from . import formatting
-from . import termui
-from . import utils
-from ._compat import _find_binary_reader
-
-if t.TYPE_CHECKING:
-    from .core import BaseCommand
-
-
-class EchoingStdin:
-    def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None:
-        self._input = input
-        self._output = output
-        self._paused = False
-
-    def __getattr__(self, x: str) -> t.Any:
-        return getattr(self._input, x)
-
-    def _echo(self, rv: bytes) -> bytes:
-        if not self._paused:
-            self._output.write(rv)
-
-        return rv
-
-    def read(self, n: int = -1) -> bytes:
-        return self._echo(self._input.read(n))
-
-    def read1(self, n: int = -1) -> bytes:
-        return self._echo(self._input.read1(n))  # type: ignore
-
-    def readline(self, n: int = -1) -> bytes:
-        return self._echo(self._input.readline(n))
-
-    def readlines(self) -> t.List[bytes]:
-        return [self._echo(x) for x in self._input.readlines()]
-
-    def __iter__(self) -> t.Iterator[bytes]:
-        return iter(self._echo(x) for x in self._input)
-
-    def __repr__(self) -> str:
-        return repr(self._input)
-
-
-@contextlib.contextmanager
-def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]:
-    if stream is None:
-        yield
-    else:
-        stream._paused = True
-        yield
-        stream._paused = False
-
-
-class _NamedTextIOWrapper(io.TextIOWrapper):
-    def __init__(
-        self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any
-    ) -> None:
-        super().__init__(buffer, **kwargs)
-        self._name = name
-        self._mode = mode
-
-    @property
-    def name(self) -> str:
-        return self._name
-
-    @property
-    def mode(self) -> str:
-        return self._mode
-
-
-def make_input_stream(
-    input: t.Optional[t.Union[str, bytes, t.IO]], charset: str
-) -> t.BinaryIO:
-    # Is already an input stream.
-    if hasattr(input, "read"):
-        rv = _find_binary_reader(t.cast(t.IO, input))
-
-        if rv is not None:
-            return rv
-
-        raise TypeError("Could not find binary reader for input stream.")
-
-    if input is None:
-        input = b""
-    elif isinstance(input, str):
-        input = input.encode(charset)
-
-    return io.BytesIO(t.cast(bytes, input))
-
-
-class Result:
-    """Holds the captured result of an invoked CLI script."""
-
-    def __init__(
-        self,
-        runner: "CliRunner",
-        stdout_bytes: bytes,
-        stderr_bytes: t.Optional[bytes],
-        return_value: t.Any,
-        exit_code: int,
-        exception: t.Optional[BaseException],
-        exc_info: t.Optional[
-            t.Tuple[t.Type[BaseException], BaseException, TracebackType]
-        ] = None,
-    ):
-        #: The runner that created the result
-        self.runner = runner
-        #: The standard output as bytes.
-        self.stdout_bytes = stdout_bytes
-        #: The standard error as bytes, or None if not available
-        self.stderr_bytes = stderr_bytes
-        #: The value returned from the invoked command.
-        #:
-        #: .. versionadded:: 8.0
-        self.return_value = return_value
-        #: The exit code as integer.
-        self.exit_code = exit_code
-        #: The exception that happened if one did.
-        self.exception = exception
-        #: The traceback
-        self.exc_info = exc_info
-
-    @property
-    def output(self) -> str:
-        """The (standard) output as unicode string."""
-        return self.stdout
-
-    @property
-    def stdout(self) -> str:
-        """The standard output as unicode string."""
-        return self.stdout_bytes.decode(self.runner.charset, "replace").replace(
-            "\r\n", "\n"
-        )
-
-    @property
-    def stderr(self) -> str:
-        """The standard error as unicode string."""
-        if self.stderr_bytes is None:
-            raise ValueError("stderr not separately captured")
-        return self.stderr_bytes.decode(self.runner.charset, "replace").replace(
-            "\r\n", "\n"
-        )
-
-    def __repr__(self) -> str:
-        exc_str = repr(self.exception) if self.exception else "okay"
-        return f"<{type(self).__name__} {exc_str}>"
-
-
-class CliRunner:
-    """The CLI runner provides functionality to invoke a Click command line
-    script for unittesting purposes in a isolated environment.  This only
-    works in single-threaded systems without any concurrency as it changes the
-    global interpreter state.
-
-    :param charset: the character set for the input and output data.
-    :param env: a dictionary with environment variables for overriding.
-    :param echo_stdin: if this is set to `True`, then reading from stdin writes
-                       to stdout.  This is useful for showing examples in
-                       some circumstances.  Note that regular prompts
-                       will automatically echo the input.
-    :param mix_stderr: if this is set to `False`, then stdout and stderr are
-                       preserved as independent streams.  This is useful for
-                       Unix-philosophy apps that have predictable stdout and
-                       noisy stderr, such that each may be measured
-                       independently
-    """
-
-    def __init__(
-        self,
-        charset: str = "utf-8",
-        env: t.Optional[t.Mapping[str, t.Optional[str]]] = None,
-        echo_stdin: bool = False,
-        mix_stderr: bool = True,
-    ) -> None:
-        self.charset = charset
-        self.env = env or {}
-        self.echo_stdin = echo_stdin
-        self.mix_stderr = mix_stderr
-
-    def get_default_prog_name(self, cli: "BaseCommand") -> str:
-        """Given a command object it will return the default program name
-        for it.  The default is the `name` attribute or ``"root"`` if not
-        set.
-        """
-        return cli.name or "root"
-
-    def make_env(
-        self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None
-    ) -> t.Mapping[str, t.Optional[str]]:
-        """Returns the environment overrides for invoking a script."""
-        rv = dict(self.env)
-        if overrides:
-            rv.update(overrides)
-        return rv
-
-    @contextlib.contextmanager
-    def isolation(
-        self,
-        input: t.Optional[t.Union[str, bytes, t.IO]] = None,
-        env: t.Optional[t.Mapping[str, t.Optional[str]]] = None,
-        color: bool = False,
-    ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]:
-        """A context manager that sets up the isolation for invoking of a
-        command line tool.  This sets up stdin with the given input data
-        and `os.environ` with the overrides from the given dictionary.
-        This also rebinds some internals in Click to be mocked (like the
-        prompt functionality).
-
-        This is automatically done in the :meth:`invoke` method.
-
-        :param input: the input stream to put into sys.stdin.
-        :param env: the environment overrides as dictionary.
-        :param color: whether the output should contain color codes. The
-                      application can still override this explicitly.
-
-        .. versionchanged:: 8.0
-            ``stderr`` is opened with ``errors="backslashreplace"``
-            instead of the default ``"strict"``.
-
-        .. versionchanged:: 4.0
-            Added the ``color`` parameter.
-        """
-        bytes_input = make_input_stream(input, self.charset)
-        echo_input = None
-
-        old_stdin = sys.stdin
-        old_stdout = sys.stdout
-        old_stderr = sys.stderr
-        old_forced_width = formatting.FORCED_WIDTH
-        formatting.FORCED_WIDTH = 80
-
-        env = self.make_env(env)
-
-        bytes_output = io.BytesIO()
-
-        if self.echo_stdin:
-            bytes_input = echo_input = t.cast(
-                t.BinaryIO, EchoingStdin(bytes_input, bytes_output)
-            )
-
-        sys.stdin = text_input = _NamedTextIOWrapper(
-            bytes_input, encoding=self.charset, name="<stdin>", mode="r"
-        )
-
-        if self.echo_stdin:
-            # Force unbuffered reads, otherwise TextIOWrapper reads a
-            # large chunk which is echoed early.
-            text_input._CHUNK_SIZE = 1  # type: ignore
-
-        sys.stdout = _NamedTextIOWrapper(
-            bytes_output, encoding=self.charset, name="<stdout>", mode="w"
-        )
-
-        bytes_error = None
-        if self.mix_stderr:
-            sys.stderr = sys.stdout
-        else:
-            bytes_error = io.BytesIO()
-            sys.stderr = _NamedTextIOWrapper(
-                bytes_error,
-                encoding=self.charset,
-                name="<stderr>",
-                mode="w",
-                errors="backslashreplace",
-            )
-
-        @_pause_echo(echo_input)  # type: ignore
-        def visible_input(prompt: t.Optional[str] = None) -> str:
-            sys.stdout.write(prompt or "")
-            val = text_input.readline().rstrip("\r\n")
-            sys.stdout.write(f"{val}\n")
-            sys.stdout.flush()
-            return val
-
-        @_pause_echo(echo_input)  # type: ignore
-        def hidden_input(prompt: t.Optional[str] = None) -> str:
-            sys.stdout.write(f"{prompt or ''}\n")
-            sys.stdout.flush()
-            return text_input.readline().rstrip("\r\n")
-
-        @_pause_echo(echo_input)  # type: ignore
-        def _getchar(echo: bool) -> str:
-            char = sys.stdin.read(1)
-
-            if echo:
-                sys.stdout.write(char)
-
-            sys.stdout.flush()
-            return char
-
-        default_color = color
-
-        def should_strip_ansi(
-            stream: t.Optional[t.IO] = None, color: t.Optional[bool] = None
-        ) -> bool:
-            if color is None:
-                return not default_color
-            return not color
-
-        old_visible_prompt_func = termui.visible_prompt_func
-        old_hidden_prompt_func = termui.hidden_prompt_func
-        old__getchar_func = termui._getchar
-        old_should_strip_ansi = utils.should_strip_ansi  # type: ignore
-        termui.visible_prompt_func = visible_input
-        termui.hidden_prompt_func = hidden_input
-        termui._getchar = _getchar
-        utils.should_strip_ansi = should_strip_ansi  # type: ignore
-
-        old_env = {}
-        try:
-            for key, value in env.items():
-                old_env[key] = os.environ.get(key)
-                if value is None:
-                    try:
-                        del os.environ[key]
-                    except Exception:
-                        pass
-                else:
-                    os.environ[key] = value
-            yield (bytes_output, bytes_error)
-        finally:
-            for key, value in old_env.items():
-                if value is None:
-                    try:
-                        del os.environ[key]
-                    except Exception:
-                        pass
-                else:
-                    os.environ[key] = value
-            sys.stdout = old_stdout
-            sys.stderr = old_stderr
-            sys.stdin = old_stdin
-            termui.visible_prompt_func = old_visible_prompt_func
-            termui.hidden_prompt_func = old_hidden_prompt_func
-            termui._getchar = old__getchar_func
-            utils.should_strip_ansi = old_should_strip_ansi  # type: ignore
-            formatting.FORCED_WIDTH = old_forced_width
-
-    def invoke(
-        self,
-        cli: "BaseCommand",
-        args: t.Optional[t.Union[str, t.Sequence[str]]] = None,
-        input: t.Optional[t.Union[str, bytes, t.IO]] = None,
-        env: t.Optional[t.Mapping[str, t.Optional[str]]] = None,
-        catch_exceptions: bool = True,
-        color: bool = False,
-        **extra: t.Any,
-    ) -> Result:
-        """Invokes a command in an isolated environment.  The arguments are
-        forwarded directly to the command line script, the `extra` keyword
-        arguments are passed to the :meth:`~clickpkg.Command.main` function of
-        the command.
-
-        This returns a :class:`Result` object.
-
-        :param cli: the command to invoke
-        :param args: the arguments to invoke. It may be given as an iterable
-                     or a string. When given as string it will be interpreted
-                     as a Unix shell command. More details at
-                     :func:`shlex.split`.
-        :param input: the input data for `sys.stdin`.
-        :param env: the environment overrides.
-        :param catch_exceptions: Whether to catch any other exceptions than
-                                 ``SystemExit``.
-        :param extra: the keyword arguments to pass to :meth:`main`.
-        :param color: whether the output should contain color codes. The
-                      application can still override this explicitly.
-
-        .. versionchanged:: 8.0
-            The result object has the ``return_value`` attribute with
-            the value returned from the invoked command.
-
-        .. versionchanged:: 4.0
-            Added the ``color`` parameter.
-
-        .. versionchanged:: 3.0
-            Added the ``catch_exceptions`` parameter.
-
-        .. versionchanged:: 3.0
-            The result object has the ``exc_info`` attribute with the
-            traceback if available.
-        """
-        exc_info = None
-        with self.isolation(input=input, env=env, color=color) as outstreams:
-            return_value = None
-            exception: t.Optional[BaseException] = None
-            exit_code = 0
-
-            if isinstance(args, str):
-                args = shlex.split(args)
-
-            try:
-                prog_name = extra.pop("prog_name")
-            except KeyError:
-                prog_name = self.get_default_prog_name(cli)
-
-            try:
-                return_value = cli.main(args=args or (), prog_name=prog_name, **extra)
-            except SystemExit as e:
-                exc_info = sys.exc_info()
-                e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code)
-
-                if e_code is None:
-                    e_code = 0
-
-                if e_code != 0:
-                    exception = e
-
-                if not isinstance(e_code, int):
-                    sys.stdout.write(str(e_code))
-                    sys.stdout.write("\n")
-                    e_code = 1
-
-                exit_code = e_code
-
-            except Exception as e:
-                if not catch_exceptions:
-                    raise
-                exception = e
-                exit_code = 1
-                exc_info = sys.exc_info()
-            finally:
-                sys.stdout.flush()
-                stdout = outstreams[0].getvalue()
-                if self.mix_stderr:
-                    stderr = None
-                else:
-                    stderr = outstreams[1].getvalue()  # type: ignore
-
-        return Result(
-            runner=self,
-            stdout_bytes=stdout,
-            stderr_bytes=stderr,
-            return_value=return_value,
-            exit_code=exit_code,
-            exception=exception,
-            exc_info=exc_info,  # type: ignore
-        )
-
-    @contextlib.contextmanager
-    def isolated_filesystem(
-        self, temp_dir: t.Optional[t.Union[str, os.PathLike]] = None
-    ) -> t.Iterator[str]:
-        """A context manager that creates a temporary directory and
-        changes the current working directory to it. This isolates tests
-        that affect the contents of the CWD to prevent them from
-        interfering with each other.
-
-        :param temp_dir: Create the temporary directory under this
-            directory. If given, the created directory is not removed
-            when exiting.
-
-        .. versionchanged:: 8.0
-            Added the ``temp_dir`` parameter.
-        """
-        cwd = os.getcwd()
-        dt = tempfile.mkdtemp(dir=temp_dir)  # type: ignore[type-var]
-        os.chdir(dt)
-
-        try:
-            yield t.cast(str, dt)
-        finally:
-            os.chdir(cwd)
-
-            if temp_dir is None:
-                try:
-                    shutil.rmtree(dt)
-                except OSError:  # noqa: B014
-                    pass

+ 0 - 1073
venv/lib/python3.10/site-packages/click/types.py

@@ -1,1073 +0,0 @@
-import os
-import stat
-import typing as t
-from datetime import datetime
-from gettext import gettext as _
-from gettext import ngettext
-
-from ._compat import _get_argv_encoding
-from ._compat import get_filesystem_encoding
-from ._compat import open_stream
-from .exceptions import BadParameter
-from .utils import LazyFile
-from .utils import safecall
-
-if t.TYPE_CHECKING:
-    import typing_extensions as te
-    from .core import Context
-    from .core import Parameter
-    from .shell_completion import CompletionItem
-
-
-class ParamType:
-    """Represents the type of a parameter. Validates and converts values
-    from the command line or Python into the correct type.
-
-    To implement a custom type, subclass and implement at least the
-    following:
-
-    -   The :attr:`name` class attribute must be set.
-    -   Calling an instance of the type with ``None`` must return
-        ``None``. This is already implemented by default.
-    -   :meth:`convert` must convert string values to the correct type.
-    -   :meth:`convert` must accept values that are already the correct
-        type.
-    -   It must be able to convert a value if the ``ctx`` and ``param``
-        arguments are ``None``. This can occur when converting prompt
-        input.
-    """
-
-    is_composite: t.ClassVar[bool] = False
-    arity: t.ClassVar[int] = 1
-
-    #: the descriptive name of this type
-    name: str
-
-    #: if a list of this type is expected and the value is pulled from a
-    #: string environment variable, this is what splits it up.  `None`
-    #: means any whitespace.  For all parameters the general rule is that
-    #: whitespace splits them up.  The exception are paths and files which
-    #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on
-    #: Windows).
-    envvar_list_splitter: t.ClassVar[t.Optional[str]] = None
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        """Gather information that could be useful for a tool generating
-        user-facing documentation.
-
-        Use :meth:`click.Context.to_info_dict` to traverse the entire
-        CLI structure.
-
-        .. versionadded:: 8.0
-        """
-        # The class name without the "ParamType" suffix.
-        param_type = type(self).__name__.partition("ParamType")[0]
-        param_type = param_type.partition("ParameterType")[0]
-
-        # Custom subclasses might not remember to set a name.
-        if hasattr(self, "name"):
-            name = self.name
-        else:
-            name = param_type
-
-        return {"param_type": param_type, "name": name}
-
-    def __call__(
-        self,
-        value: t.Any,
-        param: t.Optional["Parameter"] = None,
-        ctx: t.Optional["Context"] = None,
-    ) -> t.Any:
-        if value is not None:
-            return self.convert(value, param, ctx)
-
-    def get_metavar(self, param: "Parameter") -> t.Optional[str]:
-        """Returns the metavar default for this param if it provides one."""
-
-    def get_missing_message(self, param: "Parameter") -> t.Optional[str]:
-        """Optionally might return extra information about a missing
-        parameter.
-
-        .. versionadded:: 2.0
-        """
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        """Convert the value to the correct type. This is not called if
-        the value is ``None`` (the missing value).
-
-        This must accept string values from the command line, as well as
-        values that are already the correct type. It may also convert
-        other compatible types.
-
-        The ``param`` and ``ctx`` arguments may be ``None`` in certain
-        situations, such as when converting prompt input.
-
-        If the value cannot be converted, call :meth:`fail` with a
-        descriptive message.
-
-        :param value: The value to convert.
-        :param param: The parameter that is using this type to convert
-            its value. May be ``None``.
-        :param ctx: The current context that arrived at this value. May
-            be ``None``.
-        """
-        return value
-
-    def split_envvar_value(self, rv: str) -> t.Sequence[str]:
-        """Given a value from an environment variable this splits it up
-        into small chunks depending on the defined envvar list splitter.
-
-        If the splitter is set to `None`, which means that whitespace splits,
-        then leading and trailing whitespace is ignored.  Otherwise, leading
-        and trailing splitters usually lead to empty items being included.
-        """
-        return (rv or "").split(self.envvar_list_splitter)
-
-    def fail(
-        self,
-        message: str,
-        param: t.Optional["Parameter"] = None,
-        ctx: t.Optional["Context"] = None,
-    ) -> "t.NoReturn":
-        """Helper method to fail with an invalid value message."""
-        raise BadParameter(message, ctx=ctx, param=param)
-
-    def shell_complete(
-        self, ctx: "Context", param: "Parameter", incomplete: str
-    ) -> t.List["CompletionItem"]:
-        """Return a list of
-        :class:`~click.shell_completion.CompletionItem` objects for the
-        incomplete value. Most types do not provide completions, but
-        some do, and this allows custom types to provide custom
-        completions as well.
-
-        :param ctx: Invocation context for this command.
-        :param param: The parameter that is requesting completion.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        return []
-
-
-class CompositeParamType(ParamType):
-    is_composite = True
-
-    @property
-    def arity(self) -> int:  # type: ignore
-        raise NotImplementedError()
-
-
-class FuncParamType(ParamType):
-    def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None:
-        self.name = func.__name__
-        self.func = func
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict["func"] = self.func
-        return info_dict
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        try:
-            return self.func(value)
-        except ValueError:
-            try:
-                value = str(value)
-            except UnicodeError:
-                value = value.decode("utf-8", "replace")
-
-            self.fail(value, param, ctx)
-
-
-class UnprocessedParamType(ParamType):
-    name = "text"
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        return value
-
-    def __repr__(self) -> str:
-        return "UNPROCESSED"
-
-
-class StringParamType(ParamType):
-    name = "text"
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        if isinstance(value, bytes):
-            enc = _get_argv_encoding()
-            try:
-                value = value.decode(enc)
-            except UnicodeError:
-                fs_enc = get_filesystem_encoding()
-                if fs_enc != enc:
-                    try:
-                        value = value.decode(fs_enc)
-                    except UnicodeError:
-                        value = value.decode("utf-8", "replace")
-                else:
-                    value = value.decode("utf-8", "replace")
-            return value
-        return str(value)
-
-    def __repr__(self) -> str:
-        return "STRING"
-
-
-class Choice(ParamType):
-    """The choice type allows a value to be checked against a fixed set
-    of supported values. All of these values have to be strings.
-
-    You should only pass a list or tuple of choices. Other iterables
-    (like generators) may lead to surprising results.
-
-    The resulting value will always be one of the originally passed choices
-    regardless of ``case_sensitive`` or any ``ctx.token_normalize_func``
-    being specified.
-
-    See :ref:`choice-opts` for an example.
-
-    :param case_sensitive: Set to false to make choices case
-        insensitive. Defaults to true.
-    """
-
-    name = "choice"
-
-    def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None:
-        self.choices = choices
-        self.case_sensitive = case_sensitive
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict["choices"] = self.choices
-        info_dict["case_sensitive"] = self.case_sensitive
-        return info_dict
-
-    def get_metavar(self, param: "Parameter") -> str:
-        choices_str = "|".join(self.choices)
-
-        # Use curly braces to indicate a required argument.
-        if param.required and param.param_type_name == "argument":
-            return f"{{{choices_str}}}"
-
-        # Use square braces to indicate an option or optional argument.
-        return f"[{choices_str}]"
-
-    def get_missing_message(self, param: "Parameter") -> str:
-        return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices))
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        # Match through normalization and case sensitivity
-        # first do token_normalize_func, then lowercase
-        # preserve original `value` to produce an accurate message in
-        # `self.fail`
-        normed_value = value
-        normed_choices = {choice: choice for choice in self.choices}
-
-        if ctx is not None and ctx.token_normalize_func is not None:
-            normed_value = ctx.token_normalize_func(value)
-            normed_choices = {
-                ctx.token_normalize_func(normed_choice): original
-                for normed_choice, original in normed_choices.items()
-            }
-
-        if not self.case_sensitive:
-            normed_value = normed_value.casefold()
-            normed_choices = {
-                normed_choice.casefold(): original
-                for normed_choice, original in normed_choices.items()
-            }
-
-        if normed_value in normed_choices:
-            return normed_choices[normed_value]
-
-        choices_str = ", ".join(map(repr, self.choices))
-        self.fail(
-            ngettext(
-                "{value!r} is not {choice}.",
-                "{value!r} is not one of {choices}.",
-                len(self.choices),
-            ).format(value=value, choice=choices_str, choices=choices_str),
-            param,
-            ctx,
-        )
-
-    def __repr__(self) -> str:
-        return f"Choice({list(self.choices)})"
-
-    def shell_complete(
-        self, ctx: "Context", param: "Parameter", incomplete: str
-    ) -> t.List["CompletionItem"]:
-        """Complete choices that start with the incomplete value.
-
-        :param ctx: Invocation context for this command.
-        :param param: The parameter that is requesting completion.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        from click.shell_completion import CompletionItem
-
-        str_choices = map(str, self.choices)
-
-        if self.case_sensitive:
-            matched = (c for c in str_choices if c.startswith(incomplete))
-        else:
-            incomplete = incomplete.lower()
-            matched = (c for c in str_choices if c.lower().startswith(incomplete))
-
-        return [CompletionItem(c) for c in matched]
-
-
-class DateTime(ParamType):
-    """The DateTime type converts date strings into `datetime` objects.
-
-    The format strings which are checked are configurable, but default to some
-    common (non-timezone aware) ISO 8601 formats.
-
-    When specifying *DateTime* formats, you should only pass a list or a tuple.
-    Other iterables, like generators, may lead to surprising results.
-
-    The format strings are processed using ``datetime.strptime``, and this
-    consequently defines the format strings which are allowed.
-
-    Parsing is tried using each format, in order, and the first format which
-    parses successfully is used.
-
-    :param formats: A list or tuple of date format strings, in the order in
-                    which they should be tried. Defaults to
-                    ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``,
-                    ``'%Y-%m-%d %H:%M:%S'``.
-    """
-
-    name = "datetime"
-
-    def __init__(self, formats: t.Optional[t.Sequence[str]] = None):
-        self.formats = formats or ["%Y-%m-%d", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M:%S"]
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict["formats"] = self.formats
-        return info_dict
-
-    def get_metavar(self, param: "Parameter") -> str:
-        return f"[{'|'.join(self.formats)}]"
-
-    def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]:
-        try:
-            return datetime.strptime(value, format)
-        except ValueError:
-            return None
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        if isinstance(value, datetime):
-            return value
-
-        for format in self.formats:
-            converted = self._try_to_convert_date(value, format)
-
-            if converted is not None:
-                return converted
-
-        formats_str = ", ".join(map(repr, self.formats))
-        self.fail(
-            ngettext(
-                "{value!r} does not match the format {format}.",
-                "{value!r} does not match the formats {formats}.",
-                len(self.formats),
-            ).format(value=value, format=formats_str, formats=formats_str),
-            param,
-            ctx,
-        )
-
-    def __repr__(self) -> str:
-        return "DateTime"
-
-
-class _NumberParamTypeBase(ParamType):
-    _number_class: t.ClassVar[t.Type]
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        try:
-            return self._number_class(value)
-        except ValueError:
-            self.fail(
-                _("{value!r} is not a valid {number_type}.").format(
-                    value=value, number_type=self.name
-                ),
-                param,
-                ctx,
-            )
-
-
-class _NumberRangeBase(_NumberParamTypeBase):
-    def __init__(
-        self,
-        min: t.Optional[float] = None,
-        max: t.Optional[float] = None,
-        min_open: bool = False,
-        max_open: bool = False,
-        clamp: bool = False,
-    ) -> None:
-        self.min = min
-        self.max = max
-        self.min_open = min_open
-        self.max_open = max_open
-        self.clamp = clamp
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict.update(
-            min=self.min,
-            max=self.max,
-            min_open=self.min_open,
-            max_open=self.max_open,
-            clamp=self.clamp,
-        )
-        return info_dict
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        import operator
-
-        rv = super().convert(value, param, ctx)
-        lt_min: bool = self.min is not None and (
-            operator.le if self.min_open else operator.lt
-        )(rv, self.min)
-        gt_max: bool = self.max is not None and (
-            operator.ge if self.max_open else operator.gt
-        )(rv, self.max)
-
-        if self.clamp:
-            if lt_min:
-                return self._clamp(self.min, 1, self.min_open)  # type: ignore
-
-            if gt_max:
-                return self._clamp(self.max, -1, self.max_open)  # type: ignore
-
-        if lt_min or gt_max:
-            self.fail(
-                _("{value} is not in the range {range}.").format(
-                    value=rv, range=self._describe_range()
-                ),
-                param,
-                ctx,
-            )
-
-        return rv
-
-    def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float:
-        """Find the valid value to clamp to bound in the given
-        direction.
-
-        :param bound: The boundary value.
-        :param dir: 1 or -1 indicating the direction to move.
-        :param open: If true, the range does not include the bound.
-        """
-        raise NotImplementedError
-
-    def _describe_range(self) -> str:
-        """Describe the range for use in help text."""
-        if self.min is None:
-            op = "<" if self.max_open else "<="
-            return f"x{op}{self.max}"
-
-        if self.max is None:
-            op = ">" if self.min_open else ">="
-            return f"x{op}{self.min}"
-
-        lop = "<" if self.min_open else "<="
-        rop = "<" if self.max_open else "<="
-        return f"{self.min}{lop}x{rop}{self.max}"
-
-    def __repr__(self) -> str:
-        clamp = " clamped" if self.clamp else ""
-        return f"<{type(self).__name__} {self._describe_range()}{clamp}>"
-
-
-class IntParamType(_NumberParamTypeBase):
-    name = "integer"
-    _number_class = int
-
-    def __repr__(self) -> str:
-        return "INT"
-
-
-class IntRange(_NumberRangeBase, IntParamType):
-    """Restrict an :data:`click.INT` value to a range of accepted
-    values. See :ref:`ranges`.
-
-    If ``min`` or ``max`` are not passed, any value is accepted in that
-    direction. If ``min_open`` or ``max_open`` are enabled, the
-    corresponding boundary is not included in the range.
-
-    If ``clamp`` is enabled, a value outside the range is clamped to the
-    boundary instead of failing.
-
-    .. versionchanged:: 8.0
-        Added the ``min_open`` and ``max_open`` parameters.
-    """
-
-    name = "integer range"
-
-    def _clamp(  # type: ignore
-        self, bound: int, dir: "te.Literal[1, -1]", open: bool
-    ) -> int:
-        if not open:
-            return bound
-
-        return bound + dir
-
-
-class FloatParamType(_NumberParamTypeBase):
-    name = "float"
-    _number_class = float
-
-    def __repr__(self) -> str:
-        return "FLOAT"
-
-
-class FloatRange(_NumberRangeBase, FloatParamType):
-    """Restrict a :data:`click.FLOAT` value to a range of accepted
-    values. See :ref:`ranges`.
-
-    If ``min`` or ``max`` are not passed, any value is accepted in that
-    direction. If ``min_open`` or ``max_open`` are enabled, the
-    corresponding boundary is not included in the range.
-
-    If ``clamp`` is enabled, a value outside the range is clamped to the
-    boundary instead of failing. This is not supported if either
-    boundary is marked ``open``.
-
-    .. versionchanged:: 8.0
-        Added the ``min_open`` and ``max_open`` parameters.
-    """
-
-    name = "float range"
-
-    def __init__(
-        self,
-        min: t.Optional[float] = None,
-        max: t.Optional[float] = None,
-        min_open: bool = False,
-        max_open: bool = False,
-        clamp: bool = False,
-    ) -> None:
-        super().__init__(
-            min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp
-        )
-
-        if (min_open or max_open) and clamp:
-            raise TypeError("Clamping is not supported for open bounds.")
-
-    def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float:
-        if not open:
-            return bound
-
-        # Could use Python 3.9's math.nextafter here, but clamping an
-        # open float range doesn't seem to be particularly useful. It's
-        # left up to the user to write a callback to do it if needed.
-        raise RuntimeError("Clamping is not supported for open bounds.")
-
-
-class BoolParamType(ParamType):
-    name = "boolean"
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        if value in {False, True}:
-            return bool(value)
-
-        norm = value.strip().lower()
-
-        if norm in {"1", "true", "t", "yes", "y", "on"}:
-            return True
-
-        if norm in {"0", "false", "f", "no", "n", "off"}:
-            return False
-
-        self.fail(
-            _("{value!r} is not a valid boolean.").format(value=value), param, ctx
-        )
-
-    def __repr__(self) -> str:
-        return "BOOL"
-
-
-class UUIDParameterType(ParamType):
-    name = "uuid"
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        import uuid
-
-        if isinstance(value, uuid.UUID):
-            return value
-
-        value = value.strip()
-
-        try:
-            return uuid.UUID(value)
-        except ValueError:
-            self.fail(
-                _("{value!r} is not a valid UUID.").format(value=value), param, ctx
-            )
-
-    def __repr__(self) -> str:
-        return "UUID"
-
-
-class File(ParamType):
-    """Declares a parameter to be a file for reading or writing.  The file
-    is automatically closed once the context tears down (after the command
-    finished working).
-
-    Files can be opened for reading or writing.  The special value ``-``
-    indicates stdin or stdout depending on the mode.
-
-    By default, the file is opened for reading text data, but it can also be
-    opened in binary mode or for writing.  The encoding parameter can be used
-    to force a specific encoding.
-
-    The `lazy` flag controls if the file should be opened immediately or upon
-    first IO. The default is to be non-lazy for standard input and output
-    streams as well as files opened for reading, `lazy` otherwise. When opening a
-    file lazily for reading, it is still opened temporarily for validation, but
-    will not be held open until first IO. lazy is mainly useful when opening
-    for writing to avoid creating the file until it is needed.
-
-    Starting with Click 2.0, files can also be opened atomically in which
-    case all writes go into a separate file in the same folder and upon
-    completion the file will be moved over to the original location.  This
-    is useful if a file regularly read by other users is modified.
-
-    See :ref:`file-args` for more information.
-    """
-
-    name = "filename"
-    envvar_list_splitter = os.path.pathsep
-
-    def __init__(
-        self,
-        mode: str = "r",
-        encoding: t.Optional[str] = None,
-        errors: t.Optional[str] = "strict",
-        lazy: t.Optional[bool] = None,
-        atomic: bool = False,
-    ) -> None:
-        self.mode = mode
-        self.encoding = encoding
-        self.errors = errors
-        self.lazy = lazy
-        self.atomic = atomic
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict.update(mode=self.mode, encoding=self.encoding)
-        return info_dict
-
-    def resolve_lazy_flag(self, value: t.Any) -> bool:
-        if self.lazy is not None:
-            return self.lazy
-        if value == "-":
-            return False
-        elif "w" in self.mode:
-            return True
-        return False
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        try:
-            if hasattr(value, "read") or hasattr(value, "write"):
-                return value
-
-            lazy = self.resolve_lazy_flag(value)
-
-            if lazy:
-                f: t.IO = t.cast(
-                    t.IO,
-                    LazyFile(
-                        value, self.mode, self.encoding, self.errors, atomic=self.atomic
-                    ),
-                )
-
-                if ctx is not None:
-                    ctx.call_on_close(f.close_intelligently)  # type: ignore
-
-                return f
-
-            f, should_close = open_stream(
-                value, self.mode, self.encoding, self.errors, atomic=self.atomic
-            )
-
-            # If a context is provided, we automatically close the file
-            # at the end of the context execution (or flush out).  If a
-            # context does not exist, it's the caller's responsibility to
-            # properly close the file.  This for instance happens when the
-            # type is used with prompts.
-            if ctx is not None:
-                if should_close:
-                    ctx.call_on_close(safecall(f.close))
-                else:
-                    ctx.call_on_close(safecall(f.flush))
-
-            return f
-        except OSError as e:  # noqa: B014
-            self.fail(f"'{os.fsdecode(value)}': {e.strerror}", param, ctx)
-
-    def shell_complete(
-        self, ctx: "Context", param: "Parameter", incomplete: str
-    ) -> t.List["CompletionItem"]:
-        """Return a special completion marker that tells the completion
-        system to use the shell to provide file path completions.
-
-        :param ctx: Invocation context for this command.
-        :param param: The parameter that is requesting completion.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        from click.shell_completion import CompletionItem
-
-        return [CompletionItem(incomplete, type="file")]
-
-
-class Path(ParamType):
-    """The ``Path`` type is similar to the :class:`File` type, but
-    returns the filename instead of an open file. Various checks can be
-    enabled to validate the type of file and permissions.
-
-    :param exists: The file or directory needs to exist for the value to
-        be valid. If this is not set to ``True``, and the file does not
-        exist, then all further checks are silently skipped.
-    :param file_okay: Allow a file as a value.
-    :param dir_okay: Allow a directory as a value.
-    :param readable: if true, a readable check is performed.
-    :param writable: if true, a writable check is performed.
-    :param executable: if true, an executable check is performed.
-    :param resolve_path: Make the value absolute and resolve any
-        symlinks. A ``~`` is not expanded, as this is supposed to be
-        done by the shell only.
-    :param allow_dash: Allow a single dash as a value, which indicates
-        a standard stream (but does not open it). Use
-        :func:`~click.open_file` to handle opening this value.
-    :param path_type: Convert the incoming path value to this type. If
-        ``None``, keep Python's default, which is ``str``. Useful to
-        convert to :class:`pathlib.Path`.
-
-    .. versionchanged:: 8.1
-        Added the ``executable`` parameter.
-
-    .. versionchanged:: 8.0
-        Allow passing ``type=pathlib.Path``.
-
-    .. versionchanged:: 6.0
-        Added the ``allow_dash`` parameter.
-    """
-
-    envvar_list_splitter = os.path.pathsep
-
-    def __init__(
-        self,
-        exists: bool = False,
-        file_okay: bool = True,
-        dir_okay: bool = True,
-        writable: bool = False,
-        readable: bool = True,
-        resolve_path: bool = False,
-        allow_dash: bool = False,
-        path_type: t.Optional[t.Type] = None,
-        executable: bool = False,
-    ):
-        self.exists = exists
-        self.file_okay = file_okay
-        self.dir_okay = dir_okay
-        self.readable = readable
-        self.writable = writable
-        self.executable = executable
-        self.resolve_path = resolve_path
-        self.allow_dash = allow_dash
-        self.type = path_type
-
-        if self.file_okay and not self.dir_okay:
-            self.name = _("file")
-        elif self.dir_okay and not self.file_okay:
-            self.name = _("directory")
-        else:
-            self.name = _("path")
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict.update(
-            exists=self.exists,
-            file_okay=self.file_okay,
-            dir_okay=self.dir_okay,
-            writable=self.writable,
-            readable=self.readable,
-            allow_dash=self.allow_dash,
-        )
-        return info_dict
-
-    def coerce_path_result(self, rv: t.Any) -> t.Any:
-        if self.type is not None and not isinstance(rv, self.type):
-            if self.type is str:
-                rv = os.fsdecode(rv)
-            elif self.type is bytes:
-                rv = os.fsencode(rv)
-            else:
-                rv = self.type(rv)
-
-        return rv
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        rv = value
-
-        is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-")
-
-        if not is_dash:
-            if self.resolve_path:
-                # os.path.realpath doesn't resolve symlinks on Windows
-                # until Python 3.8. Use pathlib for now.
-                import pathlib
-
-                rv = os.fsdecode(pathlib.Path(rv).resolve())
-
-            try:
-                st = os.stat(rv)
-            except OSError:
-                if not self.exists:
-                    return self.coerce_path_result(rv)
-                self.fail(
-                    _("{name} {filename!r} does not exist.").format(
-                        name=self.name.title(), filename=os.fsdecode(value)
-                    ),
-                    param,
-                    ctx,
-                )
-
-            if not self.file_okay and stat.S_ISREG(st.st_mode):
-                self.fail(
-                    _("{name} {filename!r} is a file.").format(
-                        name=self.name.title(), filename=os.fsdecode(value)
-                    ),
-                    param,
-                    ctx,
-                )
-            if not self.dir_okay and stat.S_ISDIR(st.st_mode):
-                self.fail(
-                    _("{name} '{filename}' is a directory.").format(
-                        name=self.name.title(), filename=os.fsdecode(value)
-                    ),
-                    param,
-                    ctx,
-                )
-
-            if self.readable and not os.access(rv, os.R_OK):
-                self.fail(
-                    _("{name} {filename!r} is not readable.").format(
-                        name=self.name.title(), filename=os.fsdecode(value)
-                    ),
-                    param,
-                    ctx,
-                )
-
-            if self.writable and not os.access(rv, os.W_OK):
-                self.fail(
-                    _("{name} {filename!r} is not writable.").format(
-                        name=self.name.title(), filename=os.fsdecode(value)
-                    ),
-                    param,
-                    ctx,
-                )
-
-            if self.executable and not os.access(value, os.X_OK):
-                self.fail(
-                    _("{name} {filename!r} is not executable.").format(
-                        name=self.name.title(), filename=os.fsdecode(value)
-                    ),
-                    param,
-                    ctx,
-                )
-
-        return self.coerce_path_result(rv)
-
-    def shell_complete(
-        self, ctx: "Context", param: "Parameter", incomplete: str
-    ) -> t.List["CompletionItem"]:
-        """Return a special completion marker that tells the completion
-        system to use the shell to provide path completions for only
-        directories or any paths.
-
-        :param ctx: Invocation context for this command.
-        :param param: The parameter that is requesting completion.
-        :param incomplete: Value being completed. May be empty.
-
-        .. versionadded:: 8.0
-        """
-        from click.shell_completion import CompletionItem
-
-        type = "dir" if self.dir_okay and not self.file_okay else "file"
-        return [CompletionItem(incomplete, type=type)]
-
-
-class Tuple(CompositeParamType):
-    """The default behavior of Click is to apply a type on a value directly.
-    This works well in most cases, except for when `nargs` is set to a fixed
-    count and different types should be used for different items.  In this
-    case the :class:`Tuple` type can be used.  This type can only be used
-    if `nargs` is set to a fixed number.
-
-    For more information see :ref:`tuple-type`.
-
-    This can be selected by using a Python tuple literal as a type.
-
-    :param types: a list of types that should be used for the tuple items.
-    """
-
-    def __init__(self, types: t.Sequence[t.Union[t.Type, ParamType]]) -> None:
-        self.types = [convert_type(ty) for ty in types]
-
-    def to_info_dict(self) -> t.Dict[str, t.Any]:
-        info_dict = super().to_info_dict()
-        info_dict["types"] = [t.to_info_dict() for t in self.types]
-        return info_dict
-
-    @property
-    def name(self) -> str:  # type: ignore
-        return f"<{' '.join(ty.name for ty in self.types)}>"
-
-    @property
-    def arity(self) -> int:  # type: ignore
-        return len(self.types)
-
-    def convert(
-        self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"]
-    ) -> t.Any:
-        len_type = len(self.types)
-        len_value = len(value)
-
-        if len_value != len_type:
-            self.fail(
-                ngettext(
-                    "{len_type} values are required, but {len_value} was given.",
-                    "{len_type} values are required, but {len_value} were given.",
-                    len_value,
-                ).format(len_type=len_type, len_value=len_value),
-                param=param,
-                ctx=ctx,
-            )
-
-        return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value))
-
-
-def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType:
-    """Find the most appropriate :class:`ParamType` for the given Python
-    type. If the type isn't provided, it can be inferred from a default
-    value.
-    """
-    guessed_type = False
-
-    if ty is None and default is not None:
-        if isinstance(default, (tuple, list)):
-            # If the default is empty, ty will remain None and will
-            # return STRING.
-            if default:
-                item = default[0]
-
-                # A tuple of tuples needs to detect the inner types.
-                # Can't call convert recursively because that would
-                # incorrectly unwind the tuple to a single type.
-                if isinstance(item, (tuple, list)):
-                    ty = tuple(map(type, item))
-                else:
-                    ty = type(item)
-        else:
-            ty = type(default)
-
-        guessed_type = True
-
-    if isinstance(ty, tuple):
-        return Tuple(ty)
-
-    if isinstance(ty, ParamType):
-        return ty
-
-    if ty is str or ty is None:
-        return STRING
-
-    if ty is int:
-        return INT
-
-    if ty is float:
-        return FLOAT
-
-    if ty is bool:
-        return BOOL
-
-    if guessed_type:
-        return STRING
-
-    if __debug__:
-        try:
-            if issubclass(ty, ParamType):
-                raise AssertionError(
-                    f"Attempted to use an uninstantiated parameter type ({ty})."
-                )
-        except TypeError:
-            # ty is an instance (correct), so issubclass fails.
-            pass
-
-    return FuncParamType(ty)
-
-
-#: A dummy parameter type that just does nothing.  From a user's
-#: perspective this appears to just be the same as `STRING` but
-#: internally no string conversion takes place if the input was bytes.
-#: This is usually useful when working with file paths as they can
-#: appear in bytes and unicode.
-#:
-#: For path related uses the :class:`Path` type is a better choice but
-#: there are situations where an unprocessed type is useful which is why
-#: it is is provided.
-#:
-#: .. versionadded:: 4.0
-UNPROCESSED = UnprocessedParamType()
-
-#: A unicode string parameter type which is the implicit default.  This
-#: can also be selected by using ``str`` as type.
-STRING = StringParamType()
-
-#: An integer parameter.  This can also be selected by using ``int`` as
-#: type.
-INT = IntParamType()
-
-#: A floating point value parameter.  This can also be selected by using
-#: ``float`` as type.
-FLOAT = FloatParamType()
-
-#: A boolean parameter.  This is the default for boolean flags.  This can
-#: also be selected by using ``bool`` as a type.
-BOOL = BoolParamType()
-
-#: A UUID parameter.
-UUID = UUIDParameterType()

+ 0 - 580
venv/lib/python3.10/site-packages/click/utils.py

@@ -1,580 +0,0 @@
-import os
-import re
-import sys
-import typing as t
-from functools import update_wrapper
-from types import ModuleType
-
-from ._compat import _default_text_stderr
-from ._compat import _default_text_stdout
-from ._compat import _find_binary_writer
-from ._compat import auto_wrap_for_ansi
-from ._compat import binary_streams
-from ._compat import get_filesystem_encoding
-from ._compat import open_stream
-from ._compat import should_strip_ansi
-from ._compat import strip_ansi
-from ._compat import text_streams
-from ._compat import WIN
-from .globals import resolve_color_default
-
-if t.TYPE_CHECKING:
-    import typing_extensions as te
-
-F = t.TypeVar("F", bound=t.Callable[..., t.Any])
-
-
-def _posixify(name: str) -> str:
-    return "-".join(name.split()).lower()
-
-
-def safecall(func: F) -> F:
-    """Wraps a function so that it swallows exceptions."""
-
-    def wrapper(*args, **kwargs):  # type: ignore
-        try:
-            return func(*args, **kwargs)
-        except Exception:
-            pass
-
-    return update_wrapper(t.cast(F, wrapper), func)
-
-
-def make_str(value: t.Any) -> str:
-    """Converts a value into a valid string."""
-    if isinstance(value, bytes):
-        try:
-            return value.decode(get_filesystem_encoding())
-        except UnicodeError:
-            return value.decode("utf-8", "replace")
-    return str(value)
-
-
-def make_default_short_help(help: str, max_length: int = 45) -> str:
-    """Returns a condensed version of help string."""
-    # Consider only the first paragraph.
-    paragraph_end = help.find("\n\n")
-
-    if paragraph_end != -1:
-        help = help[:paragraph_end]
-
-    # Collapse newlines, tabs, and spaces.
-    words = help.split()
-
-    if not words:
-        return ""
-
-    # The first paragraph started with a "no rewrap" marker, ignore it.
-    if words[0] == "\b":
-        words = words[1:]
-
-    total_length = 0
-    last_index = len(words) - 1
-
-    for i, word in enumerate(words):
-        total_length += len(word) + (i > 0)
-
-        if total_length > max_length:  # too long, truncate
-            break
-
-        if word[-1] == ".":  # sentence end, truncate without "..."
-            return " ".join(words[: i + 1])
-
-        if total_length == max_length and i != last_index:
-            break  # not at sentence end, truncate with "..."
-    else:
-        return " ".join(words)  # no truncation needed
-
-    # Account for the length of the suffix.
-    total_length += len("...")
-
-    # remove words until the length is short enough
-    while i > 0:
-        total_length -= len(words[i]) + (i > 0)
-
-        if total_length <= max_length:
-            break
-
-        i -= 1
-
-    return " ".join(words[:i]) + "..."
-
-
-class LazyFile:
-    """A lazy file works like a regular file but it does not fully open
-    the file but it does perform some basic checks early to see if the
-    filename parameter does make sense.  This is useful for safely opening
-    files for writing.
-    """
-
-    def __init__(
-        self,
-        filename: str,
-        mode: str = "r",
-        encoding: t.Optional[str] = None,
-        errors: t.Optional[str] = "strict",
-        atomic: bool = False,
-    ):
-        self.name = filename
-        self.mode = mode
-        self.encoding = encoding
-        self.errors = errors
-        self.atomic = atomic
-        self._f: t.Optional[t.IO]
-
-        if filename == "-":
-            self._f, self.should_close = open_stream(filename, mode, encoding, errors)
-        else:
-            if "r" in mode:
-                # Open and close the file in case we're opening it for
-                # reading so that we can catch at least some errors in
-                # some cases early.
-                open(filename, mode).close()
-            self._f = None
-            self.should_close = True
-
-    def __getattr__(self, name: str) -> t.Any:
-        return getattr(self.open(), name)
-
-    def __repr__(self) -> str:
-        if self._f is not None:
-            return repr(self._f)
-        return f"<unopened file '{self.name}' {self.mode}>"
-
-    def open(self) -> t.IO:
-        """Opens the file if it's not yet open.  This call might fail with
-        a :exc:`FileError`.  Not handling this error will produce an error
-        that Click shows.
-        """
-        if self._f is not None:
-            return self._f
-        try:
-            rv, self.should_close = open_stream(
-                self.name, self.mode, self.encoding, self.errors, atomic=self.atomic
-            )
-        except OSError as e:  # noqa: E402
-            from .exceptions import FileError
-
-            raise FileError(self.name, hint=e.strerror) from e
-        self._f = rv
-        return rv
-
-    def close(self) -> None:
-        """Closes the underlying file, no matter what."""
-        if self._f is not None:
-            self._f.close()
-
-    def close_intelligently(self) -> None:
-        """This function only closes the file if it was opened by the lazy
-        file wrapper.  For instance this will never close stdin.
-        """
-        if self.should_close:
-            self.close()
-
-    def __enter__(self) -> "LazyFile":
-        return self
-
-    def __exit__(self, exc_type, exc_value, tb):  # type: ignore
-        self.close_intelligently()
-
-    def __iter__(self) -> t.Iterator[t.AnyStr]:
-        self.open()
-        return iter(self._f)  # type: ignore
-
-
-class KeepOpenFile:
-    def __init__(self, file: t.IO) -> None:
-        self._file = file
-
-    def __getattr__(self, name: str) -> t.Any:
-        return getattr(self._file, name)
-
-    def __enter__(self) -> "KeepOpenFile":
-        return self
-
-    def __exit__(self, exc_type, exc_value, tb):  # type: ignore
-        pass
-
-    def __repr__(self) -> str:
-        return repr(self._file)
-
-    def __iter__(self) -> t.Iterator[t.AnyStr]:
-        return iter(self._file)
-
-
-def echo(
-    message: t.Optional[t.Any] = None,
-    file: t.Optional[t.IO[t.Any]] = None,
-    nl: bool = True,
-    err: bool = False,
-    color: t.Optional[bool] = None,
-) -> None:
-    """Print a message and newline to stdout or a file. This should be
-    used instead of :func:`print` because it provides better support
-    for different data, files, and environments.
-
-    Compared to :func:`print`, this does the following:
-
-    -   Ensures that the output encoding is not misconfigured on Linux.
-    -   Supports Unicode in the Windows console.
-    -   Supports writing to binary outputs, and supports writing bytes
-        to text outputs.
-    -   Supports colors and styles on Windows.
-    -   Removes ANSI color and style codes if the output does not look
-        like an interactive terminal.
-    -   Always flushes the output.
-
-    :param message: The string or bytes to output. Other objects are
-        converted to strings.
-    :param file: The file to write to. Defaults to ``stdout``.
-    :param err: Write to ``stderr`` instead of ``stdout``.
-    :param nl: Print a newline after the message. Enabled by default.
-    :param color: Force showing or hiding colors and other styles. By
-        default Click will remove color if the output does not look like
-        an interactive terminal.
-
-    .. versionchanged:: 6.0
-        Support Unicode output on the Windows console. Click does not
-        modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()``
-        will still not support Unicode.
-
-    .. versionchanged:: 4.0
-        Added the ``color`` parameter.
-
-    .. versionadded:: 3.0
-        Added the ``err`` parameter.
-
-    .. versionchanged:: 2.0
-        Support colors on Windows if colorama is installed.
-    """
-    if file is None:
-        if err:
-            file = _default_text_stderr()
-        else:
-            file = _default_text_stdout()
-
-    # Convert non bytes/text into the native string type.
-    if message is not None and not isinstance(message, (str, bytes, bytearray)):
-        out: t.Optional[t.Union[str, bytes]] = str(message)
-    else:
-        out = message
-
-    if nl:
-        out = out or ""
-        if isinstance(out, str):
-            out += "\n"
-        else:
-            out += b"\n"
-
-    if not out:
-        file.flush()
-        return
-
-    # If there is a message and the value looks like bytes, we manually
-    # need to find the binary stream and write the message in there.
-    # This is done separately so that most stream types will work as you
-    # would expect. Eg: you can write to StringIO for other cases.
-    if isinstance(out, (bytes, bytearray)):
-        binary_file = _find_binary_writer(file)
-
-        if binary_file is not None:
-            file.flush()
-            binary_file.write(out)
-            binary_file.flush()
-            return
-
-    # ANSI style code support. For no message or bytes, nothing happens.
-    # When outputting to a file instead of a terminal, strip codes.
-    else:
-        color = resolve_color_default(color)
-
-        if should_strip_ansi(file, color):
-            out = strip_ansi(out)
-        elif WIN:
-            if auto_wrap_for_ansi is not None:
-                file = auto_wrap_for_ansi(file)  # type: ignore
-            elif not color:
-                out = strip_ansi(out)
-
-    file.write(out)  # type: ignore
-    file.flush()
-
-
-def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO:
-    """Returns a system stream for byte processing.
-
-    :param name: the name of the stream to open.  Valid names are ``'stdin'``,
-                 ``'stdout'`` and ``'stderr'``
-    """
-    opener = binary_streams.get(name)
-    if opener is None:
-        raise TypeError(f"Unknown standard stream '{name}'")
-    return opener()
-
-
-def get_text_stream(
-    name: "te.Literal['stdin', 'stdout', 'stderr']",
-    encoding: t.Optional[str] = None,
-    errors: t.Optional[str] = "strict",
-) -> t.TextIO:
-    """Returns a system stream for text processing.  This usually returns
-    a wrapped stream around a binary stream returned from
-    :func:`get_binary_stream` but it also can take shortcuts for already
-    correctly configured streams.
-
-    :param name: the name of the stream to open.  Valid names are ``'stdin'``,
-                 ``'stdout'`` and ``'stderr'``
-    :param encoding: overrides the detected default encoding.
-    :param errors: overrides the default error mode.
-    """
-    opener = text_streams.get(name)
-    if opener is None:
-        raise TypeError(f"Unknown standard stream '{name}'")
-    return opener(encoding, errors)
-
-
-def open_file(
-    filename: str,
-    mode: str = "r",
-    encoding: t.Optional[str] = None,
-    errors: t.Optional[str] = "strict",
-    lazy: bool = False,
-    atomic: bool = False,
-) -> t.IO:
-    """Open a file, with extra behavior to handle ``'-'`` to indicate
-    a standard stream, lazy open on write, and atomic write. Similar to
-    the behavior of the :class:`~click.File` param type.
-
-    If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is
-    wrapped so that using it in a context manager will not close it.
-    This makes it possible to use the function without accidentally
-    closing a standard stream:
-
-    .. code-block:: python
-
-        with open_file(filename) as f:
-            ...
-
-    :param filename: The name of the file to open, or ``'-'`` for
-        ``stdin``/``stdout``.
-    :param mode: The mode in which to open the file.
-    :param encoding: The encoding to decode or encode a file opened in
-        text mode.
-    :param errors: The error handling mode.
-    :param lazy: Wait to open the file until it is accessed. For read
-        mode, the file is temporarily opened to raise access errors
-        early, then closed until it is read again.
-    :param atomic: Write to a temporary file and replace the given file
-        on close.
-
-    .. versionadded:: 3.0
-    """
-    if lazy:
-        return t.cast(t.IO, LazyFile(filename, mode, encoding, errors, atomic=atomic))
-
-    f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic)
-
-    if not should_close:
-        f = t.cast(t.IO, KeepOpenFile(f))
-
-    return f
-
-
-def format_filename(
-    filename: t.Union[str, bytes, os.PathLike], shorten: bool = False
-) -> str:
-    """Formats a filename for user display.  The main purpose of this
-    function is to ensure that the filename can be displayed at all.  This
-    will decode the filename to unicode if necessary in a way that it will
-    not fail.  Optionally, it can shorten the filename to not include the
-    full path to the filename.
-
-    :param filename: formats a filename for UI display.  This will also convert
-                     the filename into unicode without failing.
-    :param shorten: this optionally shortens the filename to strip of the
-                    path that leads up to it.
-    """
-    if shorten:
-        filename = os.path.basename(filename)
-
-    return os.fsdecode(filename)
-
-
-def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str:
-    r"""Returns the config folder for the application.  The default behavior
-    is to return whatever is most appropriate for the operating system.
-
-    To give you an idea, for an app called ``"Foo Bar"``, something like
-    the following folders could be returned:
-
-    Mac OS X:
-      ``~/Library/Application Support/Foo Bar``
-    Mac OS X (POSIX):
-      ``~/.foo-bar``
-    Unix:
-      ``~/.config/foo-bar``
-    Unix (POSIX):
-      ``~/.foo-bar``
-    Windows (roaming):
-      ``C:\Users\<user>\AppData\Roaming\Foo Bar``
-    Windows (not roaming):
-      ``C:\Users\<user>\AppData\Local\Foo Bar``
-
-    .. versionadded:: 2.0
-
-    :param app_name: the application name.  This should be properly capitalized
-                     and can contain whitespace.
-    :param roaming: controls if the folder should be roaming or not on Windows.
-                    Has no affect otherwise.
-    :param force_posix: if this is set to `True` then on any POSIX system the
-                        folder will be stored in the home folder with a leading
-                        dot instead of the XDG config home or darwin's
-                        application support folder.
-    """
-    if WIN:
-        key = "APPDATA" if roaming else "LOCALAPPDATA"
-        folder = os.environ.get(key)
-        if folder is None:
-            folder = os.path.expanduser("~")
-        return os.path.join(folder, app_name)
-    if force_posix:
-        return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}"))
-    if sys.platform == "darwin":
-        return os.path.join(
-            os.path.expanduser("~/Library/Application Support"), app_name
-        )
-    return os.path.join(
-        os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")),
-        _posixify(app_name),
-    )
-
-
-class PacifyFlushWrapper:
-    """This wrapper is used to catch and suppress BrokenPipeErrors resulting
-    from ``.flush()`` being called on broken pipe during the shutdown/final-GC
-    of the Python interpreter. Notably ``.flush()`` is always called on
-    ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any
-    other cleanup code, and the case where the underlying file is not a broken
-    pipe, all calls and attributes are proxied.
-    """
-
-    def __init__(self, wrapped: t.IO) -> None:
-        self.wrapped = wrapped
-
-    def flush(self) -> None:
-        try:
-            self.wrapped.flush()
-        except OSError as e:
-            import errno
-
-            if e.errno != errno.EPIPE:
-                raise
-
-    def __getattr__(self, attr: str) -> t.Any:
-        return getattr(self.wrapped, attr)
-
-
-def _detect_program_name(
-    path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None
-) -> str:
-    """Determine the command used to run the program, for use in help
-    text. If a file or entry point was executed, the file name is
-    returned. If ``python -m`` was used to execute a module or package,
-    ``python -m name`` is returned.
-
-    This doesn't try to be too precise, the goal is to give a concise
-    name for help text. Files are only shown as their name without the
-    path. ``python`` is only shown for modules, and the full path to
-    ``sys.executable`` is not shown.
-
-    :param path: The Python file being executed. Python puts this in
-        ``sys.argv[0]``, which is used by default.
-    :param _main: The ``__main__`` module. This should only be passed
-        during internal testing.
-
-    .. versionadded:: 8.0
-        Based on command args detection in the Werkzeug reloader.
-
-    :meta private:
-    """
-    if _main is None:
-        _main = sys.modules["__main__"]
-
-    if not path:
-        path = sys.argv[0]
-
-    # The value of __package__ indicates how Python was called. It may
-    # not exist if a setuptools script is installed as an egg. It may be
-    # set incorrectly for entry points created with pip on Windows.
-    if getattr(_main, "__package__", None) is None or (
-        os.name == "nt"
-        and _main.__package__ == ""
-        and not os.path.exists(path)
-        and os.path.exists(f"{path}.exe")
-    ):
-        # Executed a file, like "python app.py".
-        return os.path.basename(path)
-
-    # Executed a module, like "python -m example".
-    # Rewritten by Python from "-m script" to "/path/to/script.py".
-    # Need to look at main module to determine how it was executed.
-    py_module = t.cast(str, _main.__package__)
-    name = os.path.splitext(os.path.basename(path))[0]
-
-    # A submodule like "example.cli".
-    if name != "__main__":
-        py_module = f"{py_module}.{name}"
-
-    return f"python -m {py_module.lstrip('.')}"
-
-
-def _expand_args(
-    args: t.Iterable[str],
-    *,
-    user: bool = True,
-    env: bool = True,
-    glob_recursive: bool = True,
-) -> t.List[str]:
-    """Simulate Unix shell expansion with Python functions.
-
-    See :func:`glob.glob`, :func:`os.path.expanduser`, and
-    :func:`os.path.expandvars`.
-
-    This is intended for use on Windows, where the shell does not do any
-    expansion. It may not exactly match what a Unix shell would do.
-
-    :param args: List of command line arguments to expand.
-    :param user: Expand user home directory.
-    :param env: Expand environment variables.
-    :param glob_recursive: ``**`` matches directories recursively.
-
-    .. versionchanged:: 8.1
-        Invalid glob patterns are treated as empty expansions rather
-        than raising an error.
-
-    .. versionadded:: 8.0
-
-    :meta private:
-    """
-    from glob import glob
-
-    out = []
-
-    for arg in args:
-        if user:
-            arg = os.path.expanduser(arg)
-
-        if env:
-            arg = os.path.expandvars(arg)
-
-        try:
-            matches = glob(arg, recursive=glob_recursive)
-        except re.error:
-            matches = []
-
-        if not matches:
-            out.append(arg)
-        else:
-            out.extend(matches)
-
-    return out

+ 0 - 1
venv/lib/python3.10/site-packages/distutils-precedence.pth

@@ -1 +0,0 @@
-import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'stdlib') == 'local'; enabled and __import__('_distutils_hack').add_shim(); 

+ 0 - 71
venv/lib/python3.10/site-packages/flask/__init__.py

@@ -1,71 +0,0 @@
-from markupsafe import escape
-from markupsafe import Markup
-
-from . import json as json
-from .app import Flask as Flask
-from .app import Request as Request
-from .app import Response as Response
-from .blueprints import Blueprint as Blueprint
-from .config import Config as Config
-from .ctx import after_this_request as after_this_request
-from .ctx import copy_current_request_context as copy_current_request_context
-from .ctx import has_app_context as has_app_context
-from .ctx import has_request_context as has_request_context
-from .globals import current_app as current_app
-from .globals import g as g
-from .globals import request as request
-from .globals import session as session
-from .helpers import abort as abort
-from .helpers import flash as flash
-from .helpers import get_flashed_messages as get_flashed_messages
-from .helpers import get_template_attribute as get_template_attribute
-from .helpers import make_response as make_response
-from .helpers import redirect as redirect
-from .helpers import send_file as send_file
-from .helpers import send_from_directory as send_from_directory
-from .helpers import stream_with_context as stream_with_context
-from .helpers import url_for as url_for
-from .json import jsonify as jsonify
-from .signals import appcontext_popped as appcontext_popped
-from .signals import appcontext_pushed as appcontext_pushed
-from .signals import appcontext_tearing_down as appcontext_tearing_down
-from .signals import before_render_template as before_render_template
-from .signals import got_request_exception as got_request_exception
-from .signals import message_flashed as message_flashed
-from .signals import request_finished as request_finished
-from .signals import request_started as request_started
-from .signals import request_tearing_down as request_tearing_down
-from .signals import signals_available as signals_available
-from .signals import template_rendered as template_rendered
-from .templating import render_template as render_template
-from .templating import render_template_string as render_template_string
-from .templating import stream_template as stream_template
-from .templating import stream_template_string as stream_template_string
-
-__version__ = "2.2.2"
-
-
-def __getattr__(name):
-    if name == "_app_ctx_stack":
-        import warnings
-        from .globals import __app_ctx_stack
-
-        warnings.warn(
-            "'_app_ctx_stack' is deprecated and will be removed in Flask 2.3.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return __app_ctx_stack
-
-    if name == "_request_ctx_stack":
-        import warnings
-        from .globals import __request_ctx_stack
-
-        warnings.warn(
-            "'_request_ctx_stack' is deprecated and will be removed in Flask 2.3.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return __request_ctx_stack
-
-    raise AttributeError(name)

+ 0 - 3
venv/lib/python3.10/site-packages/flask/__main__.py

@@ -1,3 +0,0 @@
-from .cli import main
-
-main()

+ 0 - 2548
venv/lib/python3.10/site-packages/flask/app.py

@@ -1,2548 +0,0 @@
-import functools
-import inspect
-import json
-import logging
-import os
-import sys
-import typing as t
-import weakref
-from collections.abc import Iterator as _abc_Iterator
-from datetime import timedelta
-from itertools import chain
-from threading import Lock
-from types import TracebackType
-
-import click
-from werkzeug.datastructures import Headers
-from werkzeug.datastructures import ImmutableDict
-from werkzeug.exceptions import Aborter
-from werkzeug.exceptions import BadRequest
-from werkzeug.exceptions import BadRequestKeyError
-from werkzeug.exceptions import HTTPException
-from werkzeug.exceptions import InternalServerError
-from werkzeug.routing import BuildError
-from werkzeug.routing import Map
-from werkzeug.routing import MapAdapter
-from werkzeug.routing import RequestRedirect
-from werkzeug.routing import RoutingException
-from werkzeug.routing import Rule
-from werkzeug.serving import is_running_from_reloader
-from werkzeug.urls import url_quote
-from werkzeug.utils import redirect as _wz_redirect
-from werkzeug.wrappers import Response as BaseResponse
-
-from . import cli
-from . import typing as ft
-from .config import Config
-from .config import ConfigAttribute
-from .ctx import _AppCtxGlobals
-from .ctx import AppContext
-from .ctx import RequestContext
-from .globals import _cv_app
-from .globals import _cv_request
-from .globals import g
-from .globals import request
-from .globals import request_ctx
-from .globals import session
-from .helpers import _split_blueprint_path
-from .helpers import get_debug_flag
-from .helpers import get_flashed_messages
-from .helpers import get_load_dotenv
-from .helpers import locked_cached_property
-from .json.provider import DefaultJSONProvider
-from .json.provider import JSONProvider
-from .logging import create_logger
-from .scaffold import _endpoint_from_view_func
-from .scaffold import _sentinel
-from .scaffold import find_package
-from .scaffold import Scaffold
-from .scaffold import setupmethod
-from .sessions import SecureCookieSessionInterface
-from .sessions import SessionInterface
-from .signals import appcontext_tearing_down
-from .signals import got_request_exception
-from .signals import request_finished
-from .signals import request_started
-from .signals import request_tearing_down
-from .templating import DispatchingJinjaLoader
-from .templating import Environment
-from .wrappers import Request
-from .wrappers import Response
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    import typing_extensions as te
-    from .blueprints import Blueprint
-    from .testing import FlaskClient
-    from .testing import FlaskCliRunner
-
-T_before_first_request = t.TypeVar(
-    "T_before_first_request", bound=ft.BeforeFirstRequestCallable
-)
-T_shell_context_processor = t.TypeVar(
-    "T_shell_context_processor", bound=ft.ShellContextProcessorCallable
-)
-T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
-T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable)
-T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable)
-T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable)
-
-if sys.version_info >= (3, 8):
-    iscoroutinefunction = inspect.iscoroutinefunction
-else:
-
-    def iscoroutinefunction(func: t.Any) -> bool:
-        while inspect.ismethod(func):
-            func = func.__func__
-
-        while isinstance(func, functools.partial):
-            func = func.func
-
-        return inspect.iscoroutinefunction(func)
-
-
-def _make_timedelta(value: t.Union[timedelta, int, None]) -> t.Optional[timedelta]:
-    if value is None or isinstance(value, timedelta):
-        return value
-
-    return timedelta(seconds=value)
-
-
-class Flask(Scaffold):
-    """The flask object implements a WSGI application and acts as the central
-    object.  It is passed the name of the module or package of the
-    application.  Once it is created it will act as a central registry for
-    the view functions, the URL rules, template configuration and much more.
-
-    The name of the package is used to resolve resources from inside the
-    package or the folder the module is contained in depending on if the
-    package parameter resolves to an actual python package (a folder with
-    an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file).
-
-    For more information about resource loading, see :func:`open_resource`.
-
-    Usually you create a :class:`Flask` instance in your main module or
-    in the :file:`__init__.py` file of your package like this::
-
-        from flask import Flask
-        app = Flask(__name__)
-
-    .. admonition:: About the First Parameter
-
-        The idea of the first parameter is to give Flask an idea of what
-        belongs to your application.  This name is used to find resources
-        on the filesystem, can be used by extensions to improve debugging
-        information and a lot more.
-
-        So it's important what you provide there.  If you are using a single
-        module, `__name__` is always the correct value.  If you however are
-        using a package, it's usually recommended to hardcode the name of
-        your package there.
-
-        For example if your application is defined in :file:`yourapplication/app.py`
-        you should create it with one of the two versions below::
-
-            app = Flask('yourapplication')
-            app = Flask(__name__.split('.')[0])
-
-        Why is that?  The application will work even with `__name__`, thanks
-        to how resources are looked up.  However it will make debugging more
-        painful.  Certain extensions can make assumptions based on the
-        import name of your application.  For example the Flask-SQLAlchemy
-        extension will look for the code in your application that triggered
-        an SQL query in debug mode.  If the import name is not properly set
-        up, that debugging information is lost.  (For example it would only
-        pick up SQL queries in `yourapplication.app` and not
-        `yourapplication.views.frontend`)
-
-    .. versionadded:: 0.7
-       The `static_url_path`, `static_folder`, and `template_folder`
-       parameters were added.
-
-    .. versionadded:: 0.8
-       The `instance_path` and `instance_relative_config` parameters were
-       added.
-
-    .. versionadded:: 0.11
-       The `root_path` parameter was added.
-
-    .. versionadded:: 1.0
-       The ``host_matching`` and ``static_host`` parameters were added.
-
-    .. versionadded:: 1.0
-       The ``subdomain_matching`` parameter was added. Subdomain
-       matching needs to be enabled manually now. Setting
-       :data:`SERVER_NAME` does not implicitly enable it.
-
-    :param import_name: the name of the application package
-    :param static_url_path: can be used to specify a different path for the
-                            static files on the web.  Defaults to the name
-                            of the `static_folder` folder.
-    :param static_folder: The folder with static files that is served at
-        ``static_url_path``. Relative to the application ``root_path``
-        or an absolute path. Defaults to ``'static'``.
-    :param static_host: the host to use when adding the static route.
-        Defaults to None. Required when using ``host_matching=True``
-        with a ``static_folder`` configured.
-    :param host_matching: set ``url_map.host_matching`` attribute.
-        Defaults to False.
-    :param subdomain_matching: consider the subdomain relative to
-        :data:`SERVER_NAME` when matching routes. Defaults to False.
-    :param template_folder: the folder that contains the templates that should
-                            be used by the application.  Defaults to
-                            ``'templates'`` folder in the root path of the
-                            application.
-    :param instance_path: An alternative instance path for the application.
-                          By default the folder ``'instance'`` next to the
-                          package or module is assumed to be the instance
-                          path.
-    :param instance_relative_config: if set to ``True`` relative filenames
-                                     for loading the config are assumed to
-                                     be relative to the instance path instead
-                                     of the application root.
-    :param root_path: The path to the root of the application files.
-        This should only be set manually when it can't be detected
-        automatically, such as for namespace packages.
-    """
-
-    #: The class that is used for request objects.  See :class:`~flask.Request`
-    #: for more information.
-    request_class = Request
-
-    #: The class that is used for response objects.  See
-    #: :class:`~flask.Response` for more information.
-    response_class = Response
-
-    #: The class of the object assigned to :attr:`aborter`, created by
-    #: :meth:`create_aborter`. That object is called by
-    #: :func:`flask.abort` to raise HTTP errors, and can be
-    #: called directly as well.
-    #:
-    #: Defaults to :class:`werkzeug.exceptions.Aborter`.
-    #:
-    #: .. versionadded:: 2.2
-    aborter_class = Aborter
-
-    #: The class that is used for the Jinja environment.
-    #:
-    #: .. versionadded:: 0.11
-    jinja_environment = Environment
-
-    #: The class that is used for the :data:`~flask.g` instance.
-    #:
-    #: Example use cases for a custom class:
-    #:
-    #: 1. Store arbitrary attributes on flask.g.
-    #: 2. Add a property for lazy per-request database connectors.
-    #: 3. Return None instead of AttributeError on unexpected attributes.
-    #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g.
-    #:
-    #: In Flask 0.9 this property was called `request_globals_class` but it
-    #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the
-    #: flask.g object is now application context scoped.
-    #:
-    #: .. versionadded:: 0.10
-    app_ctx_globals_class = _AppCtxGlobals
-
-    #: The class that is used for the ``config`` attribute of this app.
-    #: Defaults to :class:`~flask.Config`.
-    #:
-    #: Example use cases for a custom class:
-    #:
-    #: 1. Default values for certain config options.
-    #: 2. Access to config values through attributes in addition to keys.
-    #:
-    #: .. versionadded:: 0.11
-    config_class = Config
-
-    #: The testing flag.  Set this to ``True`` to enable the test mode of
-    #: Flask extensions (and in the future probably also Flask itself).
-    #: For example this might activate test helpers that have an
-    #: additional runtime cost which should not be enabled by default.
-    #:
-    #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the
-    #: default it's implicitly enabled.
-    #:
-    #: This attribute can also be configured from the config with the
-    #: ``TESTING`` configuration key.  Defaults to ``False``.
-    testing = ConfigAttribute("TESTING")
-
-    #: If a secret key is set, cryptographic components can use this to
-    #: sign cookies and other things. Set this to a complex random value
-    #: when you want to use the secure cookie for instance.
-    #:
-    #: This attribute can also be configured from the config with the
-    #: :data:`SECRET_KEY` configuration key. Defaults to ``None``.
-    secret_key = ConfigAttribute("SECRET_KEY")
-
-    @property
-    def session_cookie_name(self) -> str:
-        """The name of the cookie set by the session interface.
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3. Use ``app.config["SESSION_COOKIE_NAME"]``
-            instead.
-        """
-        import warnings
-
-        warnings.warn(
-            "'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use"
-            " 'SESSION_COOKIE_NAME' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return self.config["SESSION_COOKIE_NAME"]
-
-    @session_cookie_name.setter
-    def session_cookie_name(self, value: str) -> None:
-        import warnings
-
-        warnings.warn(
-            "'session_cookie_name' is deprecated and will be removed in Flask 2.3. Use"
-            " 'SESSION_COOKIE_NAME' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self.config["SESSION_COOKIE_NAME"] = value
-
-    #: A :class:`~datetime.timedelta` which is used to set the expiration
-    #: date of a permanent session.  The default is 31 days which makes a
-    #: permanent session survive for roughly one month.
-    #:
-    #: This attribute can also be configured from the config with the
-    #: ``PERMANENT_SESSION_LIFETIME`` configuration key.  Defaults to
-    #: ``timedelta(days=31)``
-    permanent_session_lifetime = ConfigAttribute(
-        "PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta
-    )
-
-    @property
-    def send_file_max_age_default(self) -> t.Optional[timedelta]:
-        """The default value for ``max_age`` for :func:`~flask.send_file`. The default
-        is ``None``, which tells the browser to use conditional requests instead of a
-        timed cache.
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3. Use
-            ``app.config["SEND_FILE_MAX_AGE_DEFAULT"]`` instead.
-
-        .. versionchanged:: 2.0
-            Defaults to ``None`` instead of 12 hours.
-        """
-        import warnings
-
-        warnings.warn(
-            "'send_file_max_age_default' is deprecated and will be removed in Flask"
-            " 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return _make_timedelta(self.config["SEND_FILE_MAX_AGE_DEFAULT"])
-
-    @send_file_max_age_default.setter
-    def send_file_max_age_default(self, value: t.Union[int, timedelta, None]) -> None:
-        import warnings
-
-        warnings.warn(
-            "'send_file_max_age_default' is deprecated and will be removed in Flask"
-            " 2.3. Use 'SEND_FILE_MAX_AGE_DEFAULT' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self.config["SEND_FILE_MAX_AGE_DEFAULT"] = _make_timedelta(value)
-
-    @property
-    def use_x_sendfile(self) -> bool:
-        """Enable this to use the ``X-Sendfile`` feature, assuming the server supports
-        it, from :func:`~flask.send_file`.
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3. Use ``app.config["USE_X_SENDFILE"]`` instead.
-        """
-        import warnings
-
-        warnings.warn(
-            "'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use"
-            " 'USE_X_SENDFILE' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return self.config["USE_X_SENDFILE"]
-
-    @use_x_sendfile.setter
-    def use_x_sendfile(self, value: bool) -> None:
-        import warnings
-
-        warnings.warn(
-            "'use_x_sendfile' is deprecated and will be removed in Flask 2.3. Use"
-            " 'USE_X_SENDFILE' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self.config["USE_X_SENDFILE"] = value
-
-    _json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
-    _json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
-
-    @property  # type: ignore[override]
-    def json_encoder(self) -> t.Type[json.JSONEncoder]:  # type: ignore[override]
-        """The JSON encoder class to use. Defaults to
-        :class:`~flask.json.JSONEncoder`.
-
-        .. deprecated:: 2.2
-             Will be removed in Flask 2.3. Customize
-             :attr:`json_provider_class` instead.
-
-        .. versionadded:: 0.10
-        """
-        import warnings
-
-        warnings.warn(
-            "'app.json_encoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-
-        if self._json_encoder is None:
-            from . import json
-
-            return json.JSONEncoder
-
-        return self._json_encoder
-
-    @json_encoder.setter
-    def json_encoder(self, value: t.Type[json.JSONEncoder]) -> None:
-        import warnings
-
-        warnings.warn(
-            "'app.json_encoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self._json_encoder = value
-
-    @property  # type: ignore[override]
-    def json_decoder(self) -> t.Type[json.JSONDecoder]:  # type: ignore[override]
-        """The JSON decoder class to use. Defaults to
-        :class:`~flask.json.JSONDecoder`.
-
-        .. deprecated:: 2.2
-             Will be removed in Flask 2.3. Customize
-             :attr:`json_provider_class` instead.
-
-        .. versionadded:: 0.10
-        """
-        import warnings
-
-        warnings.warn(
-            "'app.json_decoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-
-        if self._json_decoder is None:
-            from . import json
-
-            return json.JSONDecoder
-
-        return self._json_decoder
-
-    @json_decoder.setter
-    def json_decoder(self, value: t.Type[json.JSONDecoder]) -> None:
-        import warnings
-
-        warnings.warn(
-            "'app.json_decoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self._json_decoder = value
-
-    json_provider_class: t.Type[JSONProvider] = DefaultJSONProvider
-    """A subclass of :class:`~flask.json.provider.JSONProvider`. An
-    instance is created and assigned to :attr:`app.json` when creating
-    the app.
-
-    The default, :class:`~flask.json.provider.DefaultJSONProvider`, uses
-    Python's built-in :mod:`json` library. A different provider can use
-    a different JSON library.
-
-    .. versionadded:: 2.2
-    """
-
-    #: Options that are passed to the Jinja environment in
-    #: :meth:`create_jinja_environment`. Changing these options after
-    #: the environment is created (accessing :attr:`jinja_env`) will
-    #: have no effect.
-    #:
-    #: .. versionchanged:: 1.1.0
-    #:     This is a ``dict`` instead of an ``ImmutableDict`` to allow
-    #:     easier configuration.
-    #:
-    jinja_options: dict = {}
-
-    #: Default configuration parameters.
-    default_config = ImmutableDict(
-        {
-            "ENV": None,
-            "DEBUG": None,
-            "TESTING": False,
-            "PROPAGATE_EXCEPTIONS": None,
-            "SECRET_KEY": None,
-            "PERMANENT_SESSION_LIFETIME": timedelta(days=31),
-            "USE_X_SENDFILE": False,
-            "SERVER_NAME": None,
-            "APPLICATION_ROOT": "/",
-            "SESSION_COOKIE_NAME": "session",
-            "SESSION_COOKIE_DOMAIN": None,
-            "SESSION_COOKIE_PATH": None,
-            "SESSION_COOKIE_HTTPONLY": True,
-            "SESSION_COOKIE_SECURE": False,
-            "SESSION_COOKIE_SAMESITE": None,
-            "SESSION_REFRESH_EACH_REQUEST": True,
-            "MAX_CONTENT_LENGTH": None,
-            "SEND_FILE_MAX_AGE_DEFAULT": None,
-            "TRAP_BAD_REQUEST_ERRORS": None,
-            "TRAP_HTTP_EXCEPTIONS": False,
-            "EXPLAIN_TEMPLATE_LOADING": False,
-            "PREFERRED_URL_SCHEME": "http",
-            "JSON_AS_ASCII": None,
-            "JSON_SORT_KEYS": None,
-            "JSONIFY_PRETTYPRINT_REGULAR": None,
-            "JSONIFY_MIMETYPE": None,
-            "TEMPLATES_AUTO_RELOAD": None,
-            "MAX_COOKIE_SIZE": 4093,
-        }
-    )
-
-    #: The rule object to use for URL rules created.  This is used by
-    #: :meth:`add_url_rule`.  Defaults to :class:`werkzeug.routing.Rule`.
-    #:
-    #: .. versionadded:: 0.7
-    url_rule_class = Rule
-
-    #: The map object to use for storing the URL rules and routing
-    #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`.
-    #:
-    #: .. versionadded:: 1.1.0
-    url_map_class = Map
-
-    #: The :meth:`test_client` method creates an instance of this test
-    #: client class. Defaults to :class:`~flask.testing.FlaskClient`.
-    #:
-    #: .. versionadded:: 0.7
-    test_client_class: t.Optional[t.Type["FlaskClient"]] = None
-
-    #: The :class:`~click.testing.CliRunner` subclass, by default
-    #: :class:`~flask.testing.FlaskCliRunner` that is used by
-    #: :meth:`test_cli_runner`. Its ``__init__`` method should take a
-    #: Flask app object as the first argument.
-    #:
-    #: .. versionadded:: 1.0
-    test_cli_runner_class: t.Optional[t.Type["FlaskCliRunner"]] = None
-
-    #: the session interface to use.  By default an instance of
-    #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here.
-    #:
-    #: .. versionadded:: 0.8
-    session_interface: SessionInterface = SecureCookieSessionInterface()
-
-    def __init__(
-        self,
-        import_name: str,
-        static_url_path: t.Optional[str] = None,
-        static_folder: t.Optional[t.Union[str, os.PathLike]] = "static",
-        static_host: t.Optional[str] = None,
-        host_matching: bool = False,
-        subdomain_matching: bool = False,
-        template_folder: t.Optional[str] = "templates",
-        instance_path: t.Optional[str] = None,
-        instance_relative_config: bool = False,
-        root_path: t.Optional[str] = None,
-    ):
-        super().__init__(
-            import_name=import_name,
-            static_folder=static_folder,
-            static_url_path=static_url_path,
-            template_folder=template_folder,
-            root_path=root_path,
-        )
-
-        if instance_path is None:
-            instance_path = self.auto_find_instance_path()
-        elif not os.path.isabs(instance_path):
-            raise ValueError(
-                "If an instance path is provided it must be absolute."
-                " A relative path was given instead."
-            )
-
-        #: Holds the path to the instance folder.
-        #:
-        #: .. versionadded:: 0.8
-        self.instance_path = instance_path
-
-        #: The configuration dictionary as :class:`Config`.  This behaves
-        #: exactly like a regular dictionary but supports additional methods
-        #: to load a config from files.
-        self.config = self.make_config(instance_relative_config)
-
-        #: An instance of :attr:`aborter_class` created by
-        #: :meth:`make_aborter`. This is called by :func:`flask.abort`
-        #: to raise HTTP errors, and can be called directly as well.
-        #:
-        #: .. versionadded:: 2.2
-        #:     Moved from ``flask.abort``, which calls this object.
-        self.aborter = self.make_aborter()
-
-        self.json: JSONProvider = self.json_provider_class(self)
-        """Provides access to JSON methods. Functions in ``flask.json``
-        will call methods on this provider when the application context
-        is active. Used for handling JSON requests and responses.
-
-        An instance of :attr:`json_provider_class`. Can be customized by
-        changing that attribute on a subclass, or by assigning to this
-        attribute afterwards.
-
-        The default, :class:`~flask.json.provider.DefaultJSONProvider`,
-        uses Python's built-in :mod:`json` library. A different provider
-        can use a different JSON library.
-
-        .. versionadded:: 2.2
-        """
-
-        #: A list of functions that are called by
-        #: :meth:`handle_url_build_error` when :meth:`.url_for` raises a
-        #: :exc:`~werkzeug.routing.BuildError`. Each function is called
-        #: with ``error``, ``endpoint`` and ``values``. If a function
-        #: returns ``None`` or raises a ``BuildError``, it is skipped.
-        #: Otherwise, its return value is returned by ``url_for``.
-        #:
-        #: .. versionadded:: 0.9
-        self.url_build_error_handlers: t.List[
-            t.Callable[[Exception, str, t.Dict[str, t.Any]], str]
-        ] = []
-
-        #: A list of functions that will be called at the beginning of the
-        #: first request to this instance. To register a function, use the
-        #: :meth:`before_first_request` decorator.
-        #:
-        #: .. deprecated:: 2.2
-        #:     Will be removed in Flask 2.3. Run setup code when
-        #:     creating the application instead.
-        #:
-        #: .. versionadded:: 0.8
-        self.before_first_request_funcs: t.List[ft.BeforeFirstRequestCallable] = []
-
-        #: A list of functions that are called when the application context
-        #: is destroyed.  Since the application context is also torn down
-        #: if the request ends this is the place to store code that disconnects
-        #: from databases.
-        #:
-        #: .. versionadded:: 0.9
-        self.teardown_appcontext_funcs: t.List[ft.TeardownCallable] = []
-
-        #: A list of shell context processor functions that should be run
-        #: when a shell context is created.
-        #:
-        #: .. versionadded:: 0.11
-        self.shell_context_processors: t.List[ft.ShellContextProcessorCallable] = []
-
-        #: Maps registered blueprint names to blueprint objects. The
-        #: dict retains the order the blueprints were registered in.
-        #: Blueprints can be registered multiple times, this dict does
-        #: not track how often they were attached.
-        #:
-        #: .. versionadded:: 0.7
-        self.blueprints: t.Dict[str, "Blueprint"] = {}
-
-        #: a place where extensions can store application specific state.  For
-        #: example this is where an extension could store database engines and
-        #: similar things.
-        #:
-        #: The key must match the name of the extension module. For example in
-        #: case of a "Flask-Foo" extension in `flask_foo`, the key would be
-        #: ``'foo'``.
-        #:
-        #: .. versionadded:: 0.7
-        self.extensions: dict = {}
-
-        #: The :class:`~werkzeug.routing.Map` for this instance.  You can use
-        #: this to change the routing converters after the class was created
-        #: but before any routes are connected.  Example::
-        #:
-        #:    from werkzeug.routing import BaseConverter
-        #:
-        #:    class ListConverter(BaseConverter):
-        #:        def to_python(self, value):
-        #:            return value.split(',')
-        #:        def to_url(self, values):
-        #:            return ','.join(super(ListConverter, self).to_url(value)
-        #:                            for value in values)
-        #:
-        #:    app = Flask(__name__)
-        #:    app.url_map.converters['list'] = ListConverter
-        self.url_map = self.url_map_class()
-
-        self.url_map.host_matching = host_matching
-        self.subdomain_matching = subdomain_matching
-
-        # tracks internally if the application already handled at least one
-        # request.
-        self._got_first_request = False
-        self._before_request_lock = Lock()
-
-        # Add a static route using the provided static_url_path, static_host,
-        # and static_folder if there is a configured static_folder.
-        # Note we do this without checking if static_folder exists.
-        # For one, it might be created while the server is running (e.g. during
-        # development). Also, Google App Engine stores static files somewhere
-        if self.has_static_folder:
-            assert (
-                bool(static_host) == host_matching
-            ), "Invalid static_host/host_matching combination"
-            # Use a weakref to avoid creating a reference cycle between the app
-            # and the view function (see #3761).
-            self_ref = weakref.ref(self)
-            self.add_url_rule(
-                f"{self.static_url_path}/<path:filename>",
-                endpoint="static",
-                host=static_host,
-                view_func=lambda **kw: self_ref().send_static_file(**kw),  # type: ignore # noqa: B950
-            )
-
-        # Set the name of the Click group in case someone wants to add
-        # the app's commands to another CLI tool.
-        self.cli.name = self.name
-
-    def _check_setup_finished(self, f_name: str) -> None:
-        if self._got_first_request:
-            raise AssertionError(
-                f"The setup method '{f_name}' can no longer be called"
-                " on the application. It has already handled its first"
-                " request, any changes will not be applied"
-                " consistently.\n"
-                "Make sure all imports, decorators, functions, etc."
-                " needed to set up the application are done before"
-                " running it."
-            )
-
-    @locked_cached_property
-    def name(self) -> str:  # type: ignore
-        """The name of the application.  This is usually the import name
-        with the difference that it's guessed from the run file if the
-        import name is main.  This name is used as a display name when
-        Flask needs the name of the application.  It can be set and overridden
-        to change the value.
-
-        .. versionadded:: 0.8
-        """
-        if self.import_name == "__main__":
-            fn = getattr(sys.modules["__main__"], "__file__", None)
-            if fn is None:
-                return "__main__"
-            return os.path.splitext(os.path.basename(fn))[0]
-        return self.import_name
-
-    @property
-    def propagate_exceptions(self) -> bool:
-        """Returns the value of the ``PROPAGATE_EXCEPTIONS`` configuration
-        value in case it's set, otherwise a sensible default is returned.
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3.
-
-        .. versionadded:: 0.7
-        """
-        import warnings
-
-        warnings.warn(
-            "'propagate_exceptions' is deprecated and will be removed in Flask 2.3.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        rv = self.config["PROPAGATE_EXCEPTIONS"]
-        if rv is not None:
-            return rv
-        return self.testing or self.debug
-
-    @locked_cached_property
-    def logger(self) -> logging.Logger:
-        """A standard Python :class:`~logging.Logger` for the app, with
-        the same name as :attr:`name`.
-
-        In debug mode, the logger's :attr:`~logging.Logger.level` will
-        be set to :data:`~logging.DEBUG`.
-
-        If there are no handlers configured, a default handler will be
-        added. See :doc:`/logging` for more information.
-
-        .. versionchanged:: 1.1.0
-            The logger takes the same name as :attr:`name` rather than
-            hard-coding ``"flask.app"``.
-
-        .. versionchanged:: 1.0.0
-            Behavior was simplified. The logger is always named
-            ``"flask.app"``. The level is only set during configuration,
-            it doesn't check ``app.debug`` each time. Only one format is
-            used, not different ones depending on ``app.debug``. No
-            handlers are removed, and a handler is only added if no
-            handlers are already configured.
-
-        .. versionadded:: 0.3
-        """
-        return create_logger(self)
-
-    @locked_cached_property
-    def jinja_env(self) -> Environment:
-        """The Jinja environment used to load templates.
-
-        The environment is created the first time this property is
-        accessed. Changing :attr:`jinja_options` after that will have no
-        effect.
-        """
-        return self.create_jinja_environment()
-
-    @property
-    def got_first_request(self) -> bool:
-        """This attribute is set to ``True`` if the application started
-        handling the first request.
-
-        .. versionadded:: 0.8
-        """
-        return self._got_first_request
-
-    def make_config(self, instance_relative: bool = False) -> Config:
-        """Used to create the config attribute by the Flask constructor.
-        The `instance_relative` parameter is passed in from the constructor
-        of Flask (there named `instance_relative_config`) and indicates if
-        the config should be relative to the instance path or the root path
-        of the application.
-
-        .. versionadded:: 0.8
-        """
-        root_path = self.root_path
-        if instance_relative:
-            root_path = self.instance_path
-        defaults = dict(self.default_config)
-        defaults["ENV"] = os.environ.get("FLASK_ENV") or "production"
-        defaults["DEBUG"] = get_debug_flag()
-        return self.config_class(root_path, defaults)
-
-    def make_aborter(self) -> Aborter:
-        """Create the object to assign to :attr:`aborter`. That object
-        is called by :func:`flask.abort` to raise HTTP errors, and can
-        be called directly as well.
-
-        By default, this creates an instance of :attr:`aborter_class`,
-        which defaults to :class:`werkzeug.exceptions.Aborter`.
-
-        .. versionadded:: 2.2
-        """
-        return self.aborter_class()
-
-    def auto_find_instance_path(self) -> str:
-        """Tries to locate the instance path if it was not provided to the
-        constructor of the application class.  It will basically calculate
-        the path to a folder named ``instance`` next to your main file or
-        the package.
-
-        .. versionadded:: 0.8
-        """
-        prefix, package_path = find_package(self.import_name)
-        if prefix is None:
-            return os.path.join(package_path, "instance")
-        return os.path.join(prefix, "var", f"{self.name}-instance")
-
-    def open_instance_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
-        """Opens a resource from the application's instance folder
-        (:attr:`instance_path`).  Otherwise works like
-        :meth:`open_resource`.  Instance resources can also be opened for
-        writing.
-
-        :param resource: the name of the resource.  To access resources within
-                         subfolders use forward slashes as separator.
-        :param mode: resource file opening mode, default is 'rb'.
-        """
-        return open(os.path.join(self.instance_path, resource), mode)
-
-    @property
-    def templates_auto_reload(self) -> bool:
-        """Reload templates when they are changed. Used by
-        :meth:`create_jinja_environment`. It is enabled by default in debug mode.
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3. Use ``app.config["TEMPLATES_AUTO_RELOAD"]``
-            instead.
-
-        .. versionadded:: 1.0
-            This property was added but the underlying config and behavior
-            already existed.
-        """
-        import warnings
-
-        warnings.warn(
-            "'templates_auto_reload' is deprecated and will be removed in Flask 2.3."
-            " Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        rv = self.config["TEMPLATES_AUTO_RELOAD"]
-        return rv if rv is not None else self.debug
-
-    @templates_auto_reload.setter
-    def templates_auto_reload(self, value: bool) -> None:
-        import warnings
-
-        warnings.warn(
-            "'templates_auto_reload' is deprecated and will be removed in Flask 2.3."
-            " Use 'TEMPLATES_AUTO_RELOAD' in 'app.config' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self.config["TEMPLATES_AUTO_RELOAD"] = value
-
-    def create_jinja_environment(self) -> Environment:
-        """Create the Jinja environment based on :attr:`jinja_options`
-        and the various Jinja-related methods of the app. Changing
-        :attr:`jinja_options` after this will have no effect. Also adds
-        Flask-related globals and filters to the environment.
-
-        .. versionchanged:: 0.11
-           ``Environment.auto_reload`` set in accordance with
-           ``TEMPLATES_AUTO_RELOAD`` configuration option.
-
-        .. versionadded:: 0.5
-        """
-        options = dict(self.jinja_options)
-
-        if "autoescape" not in options:
-            options["autoescape"] = self.select_jinja_autoescape
-
-        if "auto_reload" not in options:
-            auto_reload = self.config["TEMPLATES_AUTO_RELOAD"]
-
-            if auto_reload is None:
-                auto_reload = self.debug
-
-            options["auto_reload"] = auto_reload
-
-        rv = self.jinja_environment(self, **options)
-        rv.globals.update(
-            url_for=self.url_for,
-            get_flashed_messages=get_flashed_messages,
-            config=self.config,
-            # request, session and g are normally added with the
-            # context processor for efficiency reasons but for imported
-            # templates we also want the proxies in there.
-            request=request,
-            session=session,
-            g=g,
-        )
-        rv.policies["json.dumps_function"] = self.json.dumps
-        return rv
-
-    def create_global_jinja_loader(self) -> DispatchingJinjaLoader:
-        """Creates the loader for the Jinja2 environment.  Can be used to
-        override just the loader and keeping the rest unchanged.  It's
-        discouraged to override this function.  Instead one should override
-        the :meth:`jinja_loader` function instead.
-
-        The global loader dispatches between the loaders of the application
-        and the individual blueprints.
-
-        .. versionadded:: 0.7
-        """
-        return DispatchingJinjaLoader(self)
-
-    def select_jinja_autoescape(self, filename: str) -> bool:
-        """Returns ``True`` if autoescaping should be active for the given
-        template name. If no template name is given, returns `True`.
-
-        .. versionadded:: 0.5
-        """
-        if filename is None:
-            return True
-        return filename.endswith((".html", ".htm", ".xml", ".xhtml"))
-
-    def update_template_context(self, context: dict) -> None:
-        """Update the template context with some commonly used variables.
-        This injects request, session, config and g into the template
-        context as well as everything template context processors want
-        to inject.  Note that the as of Flask 0.6, the original values
-        in the context will not be overridden if a context processor
-        decides to return a value with the same key.
-
-        :param context: the context as a dictionary that is updated in place
-                        to add extra variables.
-        """
-        names: t.Iterable[t.Optional[str]] = (None,)
-
-        # A template may be rendered outside a request context.
-        if request:
-            names = chain(names, reversed(request.blueprints))
-
-        # The values passed to render_template take precedence. Keep a
-        # copy to re-apply after all context functions.
-        orig_ctx = context.copy()
-
-        for name in names:
-            if name in self.template_context_processors:
-                for func in self.template_context_processors[name]:
-                    context.update(func())
-
-        context.update(orig_ctx)
-
-    def make_shell_context(self) -> dict:
-        """Returns the shell context for an interactive shell for this
-        application.  This runs all the registered shell context
-        processors.
-
-        .. versionadded:: 0.11
-        """
-        rv = {"app": self, "g": g}
-        for processor in self.shell_context_processors:
-            rv.update(processor())
-        return rv
-
-    @property
-    def env(self) -> str:
-        """What environment the app is running in. This maps to the :data:`ENV` config
-        key.
-
-        **Do not enable development when deploying in production.**
-
-        Default: ``'production'``
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3.
-        """
-        import warnings
-
-        warnings.warn(
-            "'app.env' is deprecated and will be removed in Flask 2.3."
-            " Use 'app.debug' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return self.config["ENV"]
-
-    @env.setter
-    def env(self, value: str) -> None:
-        import warnings
-
-        warnings.warn(
-            "'app.env' is deprecated and will be removed in Flask 2.3."
-            " Use 'app.debug' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self.config["ENV"] = value
-
-    @property
-    def debug(self) -> bool:
-        """Whether debug mode is enabled. When using ``flask run`` to start the
-        development server, an interactive debugger will be shown for unhandled
-        exceptions, and the server will be reloaded when code changes. This maps to the
-        :data:`DEBUG` config key. It may not behave as expected if set late.
-
-        **Do not enable debug mode when deploying in production.**
-
-        Default: ``False``
-        """
-        return self.config["DEBUG"]
-
-    @debug.setter
-    def debug(self, value: bool) -> None:
-        self.config["DEBUG"] = value
-
-        if self.config["TEMPLATES_AUTO_RELOAD"] is None:
-            self.jinja_env.auto_reload = value
-
-    def run(
-        self,
-        host: t.Optional[str] = None,
-        port: t.Optional[int] = None,
-        debug: t.Optional[bool] = None,
-        load_dotenv: bool = True,
-        **options: t.Any,
-    ) -> None:
-        """Runs the application on a local development server.
-
-        Do not use ``run()`` in a production setting. It is not intended to
-        meet security and performance requirements for a production server.
-        Instead, see :doc:`/deploying/index` for WSGI server recommendations.
-
-        If the :attr:`debug` flag is set the server will automatically reload
-        for code changes and show a debugger in case an exception happened.
-
-        If you want to run the application in debug mode, but disable the
-        code execution on the interactive debugger, you can pass
-        ``use_evalex=False`` as parameter.  This will keep the debugger's
-        traceback screen active, but disable code execution.
-
-        It is not recommended to use this function for development with
-        automatic reloading as this is badly supported.  Instead you should
-        be using the :command:`flask` command line script's ``run`` support.
-
-        .. admonition:: Keep in Mind
-
-           Flask will suppress any server error with a generic error page
-           unless it is in debug mode.  As such to enable just the
-           interactive debugger without the code reloading, you have to
-           invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``.
-           Setting ``use_debugger`` to ``True`` without being in debug mode
-           won't catch any exceptions because there won't be any to
-           catch.
-
-        :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to
-            have the server available externally as well. Defaults to
-            ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable
-            if present.
-        :param port: the port of the webserver. Defaults to ``5000`` or the
-            port defined in the ``SERVER_NAME`` config variable if present.
-        :param debug: if given, enable or disable debug mode. See
-            :attr:`debug`.
-        :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
-            files to set environment variables. Will also change the working
-            directory to the directory containing the first file found.
-        :param options: the options to be forwarded to the underlying Werkzeug
-            server. See :func:`werkzeug.serving.run_simple` for more
-            information.
-
-        .. versionchanged:: 1.0
-            If installed, python-dotenv will be used to load environment
-            variables from :file:`.env` and :file:`.flaskenv` files.
-
-            The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`.
-
-            Threaded mode is enabled by default.
-
-        .. versionchanged:: 0.10
-            The default port is now picked from the ``SERVER_NAME``
-            variable.
-        """
-        # Ignore this call so that it doesn't start another server if
-        # the 'flask run' command is used.
-        if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
-            if not is_running_from_reloader():
-                click.secho(
-                    " * Ignoring a call to 'app.run()' that would block"
-                    " the current 'flask' CLI command.\n"
-                    "   Only call 'app.run()' in an 'if __name__ =="
-                    ' "__main__"\' guard.',
-                    fg="red",
-                )
-
-            return
-
-        if get_load_dotenv(load_dotenv):
-            cli.load_dotenv()
-
-            # if set, let env vars override previous values
-            if "FLASK_ENV" in os.environ:
-                print(
-                    "'FLASK_ENV' is deprecated and will not be used in"
-                    " Flask 2.3. Use 'FLASK_DEBUG' instead.",
-                    file=sys.stderr,
-                )
-                self.config["ENV"] = os.environ.get("FLASK_ENV") or "production"
-                self.debug = get_debug_flag()
-            elif "FLASK_DEBUG" in os.environ:
-                self.debug = get_debug_flag()
-
-        # debug passed to method overrides all other sources
-        if debug is not None:
-            self.debug = bool(debug)
-
-        server_name = self.config.get("SERVER_NAME")
-        sn_host = sn_port = None
-
-        if server_name:
-            sn_host, _, sn_port = server_name.partition(":")
-
-        if not host:
-            if sn_host:
-                host = sn_host
-            else:
-                host = "127.0.0.1"
-
-        if port or port == 0:
-            port = int(port)
-        elif sn_port:
-            port = int(sn_port)
-        else:
-            port = 5000
-
-        options.setdefault("use_reloader", self.debug)
-        options.setdefault("use_debugger", self.debug)
-        options.setdefault("threaded", True)
-
-        cli.show_server_banner(self.debug, self.name)
-
-        from werkzeug.serving import run_simple
-
-        try:
-            run_simple(t.cast(str, host), port, self, **options)
-        finally:
-            # reset the first request information if the development server
-            # reset normally.  This makes it possible to restart the server
-            # without reloader and that stuff from an interactive shell.
-            self._got_first_request = False
-
-    def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> "FlaskClient":
-        """Creates a test client for this application.  For information
-        about unit testing head over to :doc:`/testing`.
-
-        Note that if you are testing for assertions or exceptions in your
-        application code, you must set ``app.testing = True`` in order for the
-        exceptions to propagate to the test client.  Otherwise, the exception
-        will be handled by the application (not visible to the test client) and
-        the only indication of an AssertionError or other exception will be a
-        500 status code response to the test client.  See the :attr:`testing`
-        attribute.  For example::
-
-            app.testing = True
-            client = app.test_client()
-
-        The test client can be used in a ``with`` block to defer the closing down
-        of the context until the end of the ``with`` block.  This is useful if
-        you want to access the context locals for testing::
-
-            with app.test_client() as c:
-                rv = c.get('/?vodka=42')
-                assert request.args['vodka'] == '42'
-
-        Additionally, you may pass optional keyword arguments that will then
-        be passed to the application's :attr:`test_client_class` constructor.
-        For example::
-
-            from flask.testing import FlaskClient
-
-            class CustomClient(FlaskClient):
-                def __init__(self, *args, **kwargs):
-                    self._authentication = kwargs.pop("authentication")
-                    super(CustomClient,self).__init__( *args, **kwargs)
-
-            app.test_client_class = CustomClient
-            client = app.test_client(authentication='Basic ....')
-
-        See :class:`~flask.testing.FlaskClient` for more information.
-
-        .. versionchanged:: 0.4
-           added support for ``with`` block usage for the client.
-
-        .. versionadded:: 0.7
-           The `use_cookies` parameter was added as well as the ability
-           to override the client to be used by setting the
-           :attr:`test_client_class` attribute.
-
-        .. versionchanged:: 0.11
-           Added `**kwargs` to support passing additional keyword arguments to
-           the constructor of :attr:`test_client_class`.
-        """
-        cls = self.test_client_class
-        if cls is None:
-            from .testing import FlaskClient as cls  # type: ignore
-        return cls(  # type: ignore
-            self, self.response_class, use_cookies=use_cookies, **kwargs
-        )
-
-    def test_cli_runner(self, **kwargs: t.Any) -> "FlaskCliRunner":
-        """Create a CLI runner for testing CLI commands.
-        See :ref:`testing-cli`.
-
-        Returns an instance of :attr:`test_cli_runner_class`, by default
-        :class:`~flask.testing.FlaskCliRunner`. The Flask app object is
-        passed as the first argument.
-
-        .. versionadded:: 1.0
-        """
-        cls = self.test_cli_runner_class
-
-        if cls is None:
-            from .testing import FlaskCliRunner as cls  # type: ignore
-
-        return cls(self, **kwargs)  # type: ignore
-
-    @setupmethod
-    def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None:
-        """Register a :class:`~flask.Blueprint` on the application. Keyword
-        arguments passed to this method will override the defaults set on the
-        blueprint.
-
-        Calls the blueprint's :meth:`~flask.Blueprint.register` method after
-        recording the blueprint in the application's :attr:`blueprints`.
-
-        :param blueprint: The blueprint to register.
-        :param url_prefix: Blueprint routes will be prefixed with this.
-        :param subdomain: Blueprint routes will match on this subdomain.
-        :param url_defaults: Blueprint routes will use these default values for
-            view arguments.
-        :param options: Additional keyword arguments are passed to
-            :class:`~flask.blueprints.BlueprintSetupState`. They can be
-            accessed in :meth:`~flask.Blueprint.record` callbacks.
-
-        .. versionchanged:: 2.0.1
-            The ``name`` option can be used to change the (pre-dotted)
-            name the blueprint is registered with. This allows the same
-            blueprint to be registered multiple times with unique names
-            for ``url_for``.
-
-        .. versionadded:: 0.7
-        """
-        blueprint.register(self, options)
-
-    def iter_blueprints(self) -> t.ValuesView["Blueprint"]:
-        """Iterates over all blueprints by the order they were registered.
-
-        .. versionadded:: 0.11
-        """
-        return self.blueprints.values()
-
-    @setupmethod
-    def add_url_rule(
-        self,
-        rule: str,
-        endpoint: t.Optional[str] = None,
-        view_func: t.Optional[ft.RouteCallable] = None,
-        provide_automatic_options: t.Optional[bool] = None,
-        **options: t.Any,
-    ) -> None:
-        if endpoint is None:
-            endpoint = _endpoint_from_view_func(view_func)  # type: ignore
-        options["endpoint"] = endpoint
-        methods = options.pop("methods", None)
-
-        # if the methods are not given and the view_func object knows its
-        # methods we can use that instead.  If neither exists, we go with
-        # a tuple of only ``GET`` as default.
-        if methods is None:
-            methods = getattr(view_func, "methods", None) or ("GET",)
-        if isinstance(methods, str):
-            raise TypeError(
-                "Allowed methods must be a list of strings, for"
-                ' example: @app.route(..., methods=["POST"])'
-            )
-        methods = {item.upper() for item in methods}
-
-        # Methods that should always be added
-        required_methods = set(getattr(view_func, "required_methods", ()))
-
-        # starting with Flask 0.8 the view_func object can disable and
-        # force-enable the automatic options handling.
-        if provide_automatic_options is None:
-            provide_automatic_options = getattr(
-                view_func, "provide_automatic_options", None
-            )
-
-        if provide_automatic_options is None:
-            if "OPTIONS" not in methods:
-                provide_automatic_options = True
-                required_methods.add("OPTIONS")
-            else:
-                provide_automatic_options = False
-
-        # Add the required methods now.
-        methods |= required_methods
-
-        rule = self.url_rule_class(rule, methods=methods, **options)
-        rule.provide_automatic_options = provide_automatic_options  # type: ignore
-
-        self.url_map.add(rule)
-        if view_func is not None:
-            old_func = self.view_functions.get(endpoint)
-            if old_func is not None and old_func != view_func:
-                raise AssertionError(
-                    "View function mapping is overwriting an existing"
-                    f" endpoint function: {endpoint}"
-                )
-            self.view_functions[endpoint] = view_func
-
-    @setupmethod
-    def template_filter(
-        self, name: t.Optional[str] = None
-    ) -> t.Callable[[T_template_filter], T_template_filter]:
-        """A decorator that is used to register custom template filter.
-        You can specify a name for the filter, otherwise the function
-        name will be used. Example::
-
-          @app.template_filter()
-          def reverse(s):
-              return s[::-1]
-
-        :param name: the optional name of the filter, otherwise the
-                     function name will be used.
-        """
-
-        def decorator(f: T_template_filter) -> T_template_filter:
-            self.add_template_filter(f, name=name)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def add_template_filter(
-        self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
-    ) -> None:
-        """Register a custom template filter.  Works exactly like the
-        :meth:`template_filter` decorator.
-
-        :param name: the optional name of the filter, otherwise the
-                     function name will be used.
-        """
-        self.jinja_env.filters[name or f.__name__] = f
-
-    @setupmethod
-    def template_test(
-        self, name: t.Optional[str] = None
-    ) -> t.Callable[[T_template_test], T_template_test]:
-        """A decorator that is used to register custom template test.
-        You can specify a name for the test, otherwise the function
-        name will be used. Example::
-
-          @app.template_test()
-          def is_prime(n):
-              if n == 2:
-                  return True
-              for i in range(2, int(math.ceil(math.sqrt(n))) + 1):
-                  if n % i == 0:
-                      return False
-              return True
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the test, otherwise the
-                     function name will be used.
-        """
-
-        def decorator(f: T_template_test) -> T_template_test:
-            self.add_template_test(f, name=name)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def add_template_test(
-        self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
-    ) -> None:
-        """Register a custom template test.  Works exactly like the
-        :meth:`template_test` decorator.
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the test, otherwise the
-                     function name will be used.
-        """
-        self.jinja_env.tests[name or f.__name__] = f
-
-    @setupmethod
-    def template_global(
-        self, name: t.Optional[str] = None
-    ) -> t.Callable[[T_template_global], T_template_global]:
-        """A decorator that is used to register a custom template global function.
-        You can specify a name for the global function, otherwise the function
-        name will be used. Example::
-
-            @app.template_global()
-            def double(n):
-                return 2 * n
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the global function, otherwise the
-                     function name will be used.
-        """
-
-        def decorator(f: T_template_global) -> T_template_global:
-            self.add_template_global(f, name=name)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def add_template_global(
-        self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
-    ) -> None:
-        """Register a custom template global function. Works exactly like the
-        :meth:`template_global` decorator.
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the global function, otherwise the
-                     function name will be used.
-        """
-        self.jinja_env.globals[name or f.__name__] = f
-
-    @setupmethod
-    def before_first_request(self, f: T_before_first_request) -> T_before_first_request:
-        """Registers a function to be run before the first request to this
-        instance of the application.
-
-        The function will be called without any arguments and its return
-        value is ignored.
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3. Run setup code when creating
-            the application instead.
-
-        .. versionadded:: 0.8
-        """
-        import warnings
-
-        warnings.warn(
-            "'before_first_request' is deprecated and will be removed"
-            " in Flask 2.3. Run setup code while creating the"
-            " application instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self.before_first_request_funcs.append(f)
-        return f
-
-    @setupmethod
-    def teardown_appcontext(self, f: T_teardown) -> T_teardown:
-        """Registers a function to be called when the application
-        context is popped. The application context is typically popped
-        after the request context for each request, at the end of CLI
-        commands, or after a manually pushed context ends.
-
-        .. code-block:: python
-
-            with app.app_context():
-                ...
-
-        When the ``with`` block exits (or ``ctx.pop()`` is called), the
-        teardown functions are called just before the app context is
-        made inactive. Since a request context typically also manages an
-        application context it would also be called when you pop a
-        request context.
-
-        When a teardown function was called because of an unhandled
-        exception it will be passed an error object. If an
-        :meth:`errorhandler` is registered, it will handle the exception
-        and the teardown will not receive it.
-
-        Teardown functions must avoid raising exceptions. If they
-        execute code that might fail they must surround that code with a
-        ``try``/``except`` block and log any errors.
-
-        The return values of teardown functions are ignored.
-
-        .. versionadded:: 0.9
-        """
-        self.teardown_appcontext_funcs.append(f)
-        return f
-
-    @setupmethod
-    def shell_context_processor(
-        self, f: T_shell_context_processor
-    ) -> T_shell_context_processor:
-        """Registers a shell context processor function.
-
-        .. versionadded:: 0.11
-        """
-        self.shell_context_processors.append(f)
-        return f
-
-    def _find_error_handler(self, e: Exception) -> t.Optional[ft.ErrorHandlerCallable]:
-        """Return a registered error handler for an exception in this order:
-        blueprint handler for a specific code, app handler for a specific code,
-        blueprint handler for an exception class, app handler for an exception
-        class, or ``None`` if a suitable handler is not found.
-        """
-        exc_class, code = self._get_exc_class_and_code(type(e))
-        names = (*request.blueprints, None)
-
-        for c in (code, None) if code is not None else (None,):
-            for name in names:
-                handler_map = self.error_handler_spec[name][c]
-
-                if not handler_map:
-                    continue
-
-                for cls in exc_class.__mro__:
-                    handler = handler_map.get(cls)
-
-                    if handler is not None:
-                        return handler
-        return None
-
-    def handle_http_exception(
-        self, e: HTTPException
-    ) -> t.Union[HTTPException, ft.ResponseReturnValue]:
-        """Handles an HTTP exception.  By default this will invoke the
-        registered error handlers and fall back to returning the
-        exception as response.
-
-        .. versionchanged:: 1.0.3
-            ``RoutingException``, used internally for actions such as
-             slash redirects during routing, is not passed to error
-             handlers.
-
-        .. versionchanged:: 1.0
-            Exceptions are looked up by code *and* by MRO, so
-            ``HTTPException`` subclasses can be handled with a catch-all
-            handler for the base ``HTTPException``.
-
-        .. versionadded:: 0.3
-        """
-        # Proxy exceptions don't have error codes.  We want to always return
-        # those unchanged as errors
-        if e.code is None:
-            return e
-
-        # RoutingExceptions are used internally to trigger routing
-        # actions, such as slash redirects raising RequestRedirect. They
-        # are not raised or handled in user code.
-        if isinstance(e, RoutingException):
-            return e
-
-        handler = self._find_error_handler(e)
-        if handler is None:
-            return e
-        return self.ensure_sync(handler)(e)
-
-    def trap_http_exception(self, e: Exception) -> bool:
-        """Checks if an HTTP exception should be trapped or not.  By default
-        this will return ``False`` for all exceptions except for a bad request
-        key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``.  It
-        also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``.
-
-        This is called for all HTTP exceptions raised by a view function.
-        If it returns ``True`` for any exception the error handler for this
-        exception is not called and it shows up as regular exception in the
-        traceback.  This is helpful for debugging implicitly raised HTTP
-        exceptions.
-
-        .. versionchanged:: 1.0
-            Bad request errors are not trapped by default in debug mode.
-
-        .. versionadded:: 0.8
-        """
-        if self.config["TRAP_HTTP_EXCEPTIONS"]:
-            return True
-
-        trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"]
-
-        # if unset, trap key errors in debug mode
-        if (
-            trap_bad_request is None
-            and self.debug
-            and isinstance(e, BadRequestKeyError)
-        ):
-            return True
-
-        if trap_bad_request:
-            return isinstance(e, BadRequest)
-
-        return False
-
-    def handle_user_exception(
-        self, e: Exception
-    ) -> t.Union[HTTPException, ft.ResponseReturnValue]:
-        """This method is called whenever an exception occurs that
-        should be handled. A special case is :class:`~werkzeug
-        .exceptions.HTTPException` which is forwarded to the
-        :meth:`handle_http_exception` method. This function will either
-        return a response value or reraise the exception with the same
-        traceback.
-
-        .. versionchanged:: 1.0
-            Key errors raised from request data like ``form`` show the
-            bad key in debug mode rather than a generic bad request
-            message.
-
-        .. versionadded:: 0.7
-        """
-        if isinstance(e, BadRequestKeyError) and (
-            self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]
-        ):
-            e.show_exception = True
-
-        if isinstance(e, HTTPException) and not self.trap_http_exception(e):
-            return self.handle_http_exception(e)
-
-        handler = self._find_error_handler(e)
-
-        if handler is None:
-            raise
-
-        return self.ensure_sync(handler)(e)
-
-    def handle_exception(self, e: Exception) -> Response:
-        """Handle an exception that did not have an error handler
-        associated with it, or that was raised from an error handler.
-        This always causes a 500 ``InternalServerError``.
-
-        Always sends the :data:`got_request_exception` signal.
-
-        If :attr:`propagate_exceptions` is ``True``, such as in debug
-        mode, the error will be re-raised so that the debugger can
-        display it. Otherwise, the original exception is logged, and
-        an :exc:`~werkzeug.exceptions.InternalServerError` is returned.
-
-        If an error handler is registered for ``InternalServerError`` or
-        ``500``, it will be used. For consistency, the handler will
-        always receive the ``InternalServerError``. The original
-        unhandled exception is available as ``e.original_exception``.
-
-        .. versionchanged:: 1.1.0
-            Always passes the ``InternalServerError`` instance to the
-            handler, setting ``original_exception`` to the unhandled
-            error.
-
-        .. versionchanged:: 1.1.0
-            ``after_request`` functions and other finalization is done
-            even for the default 500 response when there is no handler.
-
-        .. versionadded:: 0.3
-        """
-        exc_info = sys.exc_info()
-        got_request_exception.send(self, exception=e)
-        propagate = self.config["PROPAGATE_EXCEPTIONS"]
-
-        if propagate is None:
-            propagate = self.testing or self.debug
-
-        if propagate:
-            # Re-raise if called with an active exception, otherwise
-            # raise the passed in exception.
-            if exc_info[1] is e:
-                raise
-
-            raise e
-
-        self.log_exception(exc_info)
-        server_error: t.Union[InternalServerError, ft.ResponseReturnValue]
-        server_error = InternalServerError(original_exception=e)
-        handler = self._find_error_handler(server_error)
-
-        if handler is not None:
-            server_error = self.ensure_sync(handler)(server_error)
-
-        return self.finalize_request(server_error, from_error_handler=True)
-
-    def log_exception(
-        self,
-        exc_info: t.Union[
-            t.Tuple[type, BaseException, TracebackType], t.Tuple[None, None, None]
-        ],
-    ) -> None:
-        """Logs an exception.  This is called by :meth:`handle_exception`
-        if debugging is disabled and right before the handler is called.
-        The default implementation logs the exception as error on the
-        :attr:`logger`.
-
-        .. versionadded:: 0.8
-        """
-        self.logger.error(
-            f"Exception on {request.path} [{request.method}]", exc_info=exc_info
-        )
-
-    def raise_routing_exception(self, request: Request) -> "te.NoReturn":
-        """Intercept routing exceptions and possibly do something else.
-
-        In debug mode, intercept a routing redirect and replace it with
-        an error if the body will be discarded.
-
-        With modern Werkzeug this shouldn't occur, since it now uses a
-        308 status which tells the browser to resend the method and
-        body.
-
-        .. versionchanged:: 2.1
-            Don't intercept 307 and 308 redirects.
-
-        :meta private:
-        :internal:
-        """
-        if (
-            not self.debug
-            or not isinstance(request.routing_exception, RequestRedirect)
-            or request.routing_exception.code in {307, 308}
-            or request.method in {"GET", "HEAD", "OPTIONS"}
-        ):
-            raise request.routing_exception  # type: ignore
-
-        from .debughelpers import FormDataRoutingRedirect
-
-        raise FormDataRoutingRedirect(request)
-
-    def dispatch_request(self) -> ft.ResponseReturnValue:
-        """Does the request dispatching.  Matches the URL and returns the
-        return value of the view or error handler.  This does not have to
-        be a response object.  In order to convert the return value to a
-        proper response object, call :func:`make_response`.
-
-        .. versionchanged:: 0.7
-           This no longer does the exception handling, this code was
-           moved to the new :meth:`full_dispatch_request`.
-        """
-        req = request_ctx.request
-        if req.routing_exception is not None:
-            self.raise_routing_exception(req)
-        rule: Rule = req.url_rule  # type: ignore[assignment]
-        # if we provide automatic options for this URL and the
-        # request came with the OPTIONS method, reply automatically
-        if (
-            getattr(rule, "provide_automatic_options", False)
-            and req.method == "OPTIONS"
-        ):
-            return self.make_default_options_response()
-        # otherwise dispatch to the handler for that endpoint
-        view_args: t.Dict[str, t.Any] = req.view_args  # type: ignore[assignment]
-        return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
-
-    def full_dispatch_request(self) -> Response:
-        """Dispatches the request and on top of that performs request
-        pre and postprocessing as well as HTTP exception catching and
-        error handling.
-
-        .. versionadded:: 0.7
-        """
-        # Run before_first_request functions if this is the thread's first request.
-        # Inlined to avoid a method call on subsequent requests.
-        # This is deprecated, will be removed in Flask 2.3.
-        if not self._got_first_request:
-            with self._before_request_lock:
-                if not self._got_first_request:
-                    for func in self.before_first_request_funcs:
-                        self.ensure_sync(func)()
-
-                    self._got_first_request = True
-
-        try:
-            request_started.send(self)
-            rv = self.preprocess_request()
-            if rv is None:
-                rv = self.dispatch_request()
-        except Exception as e:
-            rv = self.handle_user_exception(e)
-        return self.finalize_request(rv)
-
-    def finalize_request(
-        self,
-        rv: t.Union[ft.ResponseReturnValue, HTTPException],
-        from_error_handler: bool = False,
-    ) -> Response:
-        """Given the return value from a view function this finalizes
-        the request by converting it into a response and invoking the
-        postprocessing functions.  This is invoked for both normal
-        request dispatching as well as error handlers.
-
-        Because this means that it might be called as a result of a
-        failure a special safe mode is available which can be enabled
-        with the `from_error_handler` flag.  If enabled, failures in
-        response processing will be logged and otherwise ignored.
-
-        :internal:
-        """
-        response = self.make_response(rv)
-        try:
-            response = self.process_response(response)
-            request_finished.send(self, response=response)
-        except Exception:
-            if not from_error_handler:
-                raise
-            self.logger.exception(
-                "Request finalizing failed with an error while handling an error"
-            )
-        return response
-
-    def make_default_options_response(self) -> Response:
-        """This method is called to create the default ``OPTIONS`` response.
-        This can be changed through subclassing to change the default
-        behavior of ``OPTIONS`` responses.
-
-        .. versionadded:: 0.7
-        """
-        adapter = request_ctx.url_adapter
-        methods = adapter.allowed_methods()  # type: ignore[union-attr]
-        rv = self.response_class()
-        rv.allow.update(methods)
-        return rv
-
-    def should_ignore_error(self, error: t.Optional[BaseException]) -> bool:
-        """This is called to figure out if an error should be ignored
-        or not as far as the teardown system is concerned.  If this
-        function returns ``True`` then the teardown handlers will not be
-        passed the error.
-
-        .. versionadded:: 0.10
-        """
-        return False
-
-    def ensure_sync(self, func: t.Callable) -> t.Callable:
-        """Ensure that the function is synchronous for WSGI workers.
-        Plain ``def`` functions are returned as-is. ``async def``
-        functions are wrapped to run and wait for the response.
-
-        Override this method to change how the app runs async views.
-
-        .. versionadded:: 2.0
-        """
-        if iscoroutinefunction(func):
-            return self.async_to_sync(func)
-
-        return func
-
-    def async_to_sync(
-        self, func: t.Callable[..., t.Coroutine]
-    ) -> t.Callable[..., t.Any]:
-        """Return a sync function that will run the coroutine function.
-
-        .. code-block:: python
-
-            result = app.async_to_sync(func)(*args, **kwargs)
-
-        Override this method to change how the app converts async code
-        to be synchronously callable.
-
-        .. versionadded:: 2.0
-        """
-        try:
-            from asgiref.sync import async_to_sync as asgiref_async_to_sync
-        except ImportError:
-            raise RuntimeError(
-                "Install Flask with the 'async' extra in order to use async views."
-            ) from None
-
-        return asgiref_async_to_sync(func)
-
-    def url_for(
-        self,
-        endpoint: str,
-        *,
-        _anchor: t.Optional[str] = None,
-        _method: t.Optional[str] = None,
-        _scheme: t.Optional[str] = None,
-        _external: t.Optional[bool] = None,
-        **values: t.Any,
-    ) -> str:
-        """Generate a URL to the given endpoint with the given values.
-
-        This is called by :func:`flask.url_for`, and can be called
-        directly as well.
-
-        An *endpoint* is the name of a URL rule, usually added with
-        :meth:`@app.route() <route>`, and usually the same name as the
-        view function. A route defined in a :class:`~flask.Blueprint`
-        will prepend the blueprint's name separated by a ``.`` to the
-        endpoint.
-
-        In some cases, such as email messages, you want URLs to include
-        the scheme and domain, like ``https://example.com/hello``. When
-        not in an active request, URLs will be external by default, but
-        this requires setting :data:`SERVER_NAME` so Flask knows what
-        domain to use. :data:`APPLICATION_ROOT` and
-        :data:`PREFERRED_URL_SCHEME` should also be configured as
-        needed. This config is only used when not in an active request.
-
-        Functions can be decorated with :meth:`url_defaults` to modify
-        keyword arguments before the URL is built.
-
-        If building fails for some reason, such as an unknown endpoint
-        or incorrect values, the app's :meth:`handle_url_build_error`
-        method is called. If that returns a string, that is returned,
-        otherwise a :exc:`~werkzeug.routing.BuildError` is raised.
-
-        :param endpoint: The endpoint name associated with the URL to
-            generate. If this starts with a ``.``, the current blueprint
-            name (if any) will be used.
-        :param _anchor: If given, append this as ``#anchor`` to the URL.
-        :param _method: If given, generate the URL associated with this
-            method for the endpoint.
-        :param _scheme: If given, the URL will have this scheme if it
-            is external.
-        :param _external: If given, prefer the URL to be internal
-            (False) or require it to be external (True). External URLs
-            include the scheme and domain. When not in an active
-            request, URLs are external by default.
-        :param values: Values to use for the variable parts of the URL
-            rule. Unknown keys are appended as query string arguments,
-            like ``?a=b&c=d``.
-
-        .. versionadded:: 2.2
-            Moved from ``flask.url_for``, which calls this method.
-        """
-        req_ctx = _cv_request.get(None)
-
-        if req_ctx is not None:
-            url_adapter = req_ctx.url_adapter
-            blueprint_name = req_ctx.request.blueprint
-
-            # If the endpoint starts with "." and the request matches a
-            # blueprint, the endpoint is relative to the blueprint.
-            if endpoint[:1] == ".":
-                if blueprint_name is not None:
-                    endpoint = f"{blueprint_name}{endpoint}"
-                else:
-                    endpoint = endpoint[1:]
-
-            # When in a request, generate a URL without scheme and
-            # domain by default, unless a scheme is given.
-            if _external is None:
-                _external = _scheme is not None
-        else:
-            app_ctx = _cv_app.get(None)
-
-            # If called by helpers.url_for, an app context is active,
-            # use its url_adapter. Otherwise, app.url_for was called
-            # directly, build an adapter.
-            if app_ctx is not None:
-                url_adapter = app_ctx.url_adapter
-            else:
-                url_adapter = self.create_url_adapter(None)
-
-            if url_adapter is None:
-                raise RuntimeError(
-                    "Unable to build URLs outside an active request"
-                    " without 'SERVER_NAME' configured. Also configure"
-                    " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as"
-                    " needed."
-                )
-
-            # When outside a request, generate a URL with scheme and
-            # domain by default.
-            if _external is None:
-                _external = True
-
-        # It is an error to set _scheme when _external=False, in order
-        # to avoid accidental insecure URLs.
-        if _scheme is not None and not _external:
-            raise ValueError("When specifying '_scheme', '_external' must be True.")
-
-        self.inject_url_defaults(endpoint, values)
-
-        try:
-            rv = url_adapter.build(  # type: ignore[union-attr]
-                endpoint,
-                values,
-                method=_method,
-                url_scheme=_scheme,
-                force_external=_external,
-            )
-        except BuildError as error:
-            values.update(
-                _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external
-            )
-            return self.handle_url_build_error(error, endpoint, values)
-
-        if _anchor is not None:
-            rv = f"{rv}#{url_quote(_anchor)}"
-
-        return rv
-
-    def redirect(self, location: str, code: int = 302) -> BaseResponse:
-        """Create a redirect response object.
-
-        This is called by :func:`flask.redirect`, and can be called
-        directly as well.
-
-        :param location: The URL to redirect to.
-        :param code: The status code for the redirect.
-
-        .. versionadded:: 2.2
-            Moved from ``flask.redirect``, which calls this method.
-        """
-        return _wz_redirect(location, code=code, Response=self.response_class)
-
-    def make_response(self, rv: ft.ResponseReturnValue) -> Response:
-        """Convert the return value from a view function to an instance of
-        :attr:`response_class`.
-
-        :param rv: the return value from the view function. The view function
-            must return a response. Returning ``None``, or the view ending
-            without returning, is not allowed. The following types are allowed
-            for ``view_rv``:
-
-            ``str``
-                A response object is created with the string encoded to UTF-8
-                as the body.
-
-            ``bytes``
-                A response object is created with the bytes as the body.
-
-            ``dict``
-                A dictionary that will be jsonify'd before being returned.
-
-            ``list``
-                A list that will be jsonify'd before being returned.
-
-            ``generator`` or ``iterator``
-                A generator that returns ``str`` or ``bytes`` to be
-                streamed as the response.
-
-            ``tuple``
-                Either ``(body, status, headers)``, ``(body, status)``, or
-                ``(body, headers)``, where ``body`` is any of the other types
-                allowed here, ``status`` is a string or an integer, and
-                ``headers`` is a dictionary or a list of ``(key, value)``
-                tuples. If ``body`` is a :attr:`response_class` instance,
-                ``status`` overwrites the exiting value and ``headers`` are
-                extended.
-
-            :attr:`response_class`
-                The object is returned unchanged.
-
-            other :class:`~werkzeug.wrappers.Response` class
-                The object is coerced to :attr:`response_class`.
-
-            :func:`callable`
-                The function is called as a WSGI application. The result is
-                used to create a response object.
-
-        .. versionchanged:: 2.2
-            A generator will be converted to a streaming response.
-            A list will be converted to a JSON response.
-
-        .. versionchanged:: 1.1
-            A dict will be converted to a JSON response.
-
-        .. versionchanged:: 0.9
-           Previously a tuple was interpreted as the arguments for the
-           response object.
-        """
-
-        status = headers = None
-
-        # unpack tuple returns
-        if isinstance(rv, tuple):
-            len_rv = len(rv)
-
-            # a 3-tuple is unpacked directly
-            if len_rv == 3:
-                rv, status, headers = rv  # type: ignore[misc]
-            # decide if a 2-tuple has status or headers
-            elif len_rv == 2:
-                if isinstance(rv[1], (Headers, dict, tuple, list)):
-                    rv, headers = rv
-                else:
-                    rv, status = rv  # type: ignore[assignment,misc]
-            # other sized tuples are not allowed
-            else:
-                raise TypeError(
-                    "The view function did not return a valid response tuple."
-                    " The tuple must have the form (body, status, headers),"
-                    " (body, status), or (body, headers)."
-                )
-
-        # the body must not be None
-        if rv is None:
-            raise TypeError(
-                f"The view function for {request.endpoint!r} did not"
-                " return a valid response. The function either returned"
-                " None or ended without a return statement."
-            )
-
-        # make sure the body is an instance of the response class
-        if not isinstance(rv, self.response_class):
-            if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, _abc_Iterator):
-                # let the response class set the status and headers instead of
-                # waiting to do it manually, so that the class can handle any
-                # special logic
-                rv = self.response_class(
-                    rv,
-                    status=status,
-                    headers=headers,  # type: ignore[arg-type]
-                )
-                status = headers = None
-            elif isinstance(rv, (dict, list)):
-                rv = self.json.response(rv)
-            elif isinstance(rv, BaseResponse) or callable(rv):
-                # evaluate a WSGI callable, or coerce a different response
-                # class to the correct type
-                try:
-                    rv = self.response_class.force_type(
-                        rv, request.environ  # type: ignore[arg-type]
-                    )
-                except TypeError as e:
-                    raise TypeError(
-                        f"{e}\nThe view function did not return a valid"
-                        " response. The return type must be a string,"
-                        " dict, list, tuple with headers or status,"
-                        " Response instance, or WSGI callable, but it"
-                        f" was a {type(rv).__name__}."
-                    ).with_traceback(sys.exc_info()[2]) from None
-            else:
-                raise TypeError(
-                    "The view function did not return a valid"
-                    " response. The return type must be a string,"
-                    " dict, list, tuple with headers or status,"
-                    " Response instance, or WSGI callable, but it was a"
-                    f" {type(rv).__name__}."
-                )
-
-        rv = t.cast(Response, rv)
-        # prefer the status if it was provided
-        if status is not None:
-            if isinstance(status, (str, bytes, bytearray)):
-                rv.status = status
-            else:
-                rv.status_code = status
-
-        # extend existing headers with provided headers
-        if headers:
-            rv.headers.update(headers)  # type: ignore[arg-type]
-
-        return rv
-
-    def create_url_adapter(
-        self, request: t.Optional[Request]
-    ) -> t.Optional[MapAdapter]:
-        """Creates a URL adapter for the given request. The URL adapter
-        is created at a point where the request context is not yet set
-        up so the request is passed explicitly.
-
-        .. versionadded:: 0.6
-
-        .. versionchanged:: 0.9
-           This can now also be called without a request object when the
-           URL adapter is created for the application context.
-
-        .. versionchanged:: 1.0
-            :data:`SERVER_NAME` no longer implicitly enables subdomain
-            matching. Use :attr:`subdomain_matching` instead.
-        """
-        if request is not None:
-            # If subdomain matching is disabled (the default), use the
-            # default subdomain in all cases. This should be the default
-            # in Werkzeug but it currently does not have that feature.
-            if not self.subdomain_matching:
-                subdomain = self.url_map.default_subdomain or None
-            else:
-                subdomain = None
-
-            return self.url_map.bind_to_environ(
-                request.environ,
-                server_name=self.config["SERVER_NAME"],
-                subdomain=subdomain,
-            )
-        # We need at the very least the server name to be set for this
-        # to work.
-        if self.config["SERVER_NAME"] is not None:
-            return self.url_map.bind(
-                self.config["SERVER_NAME"],
-                script_name=self.config["APPLICATION_ROOT"],
-                url_scheme=self.config["PREFERRED_URL_SCHEME"],
-            )
-
-        return None
-
-    def inject_url_defaults(self, endpoint: str, values: dict) -> None:
-        """Injects the URL defaults for the given endpoint directly into
-        the values dictionary passed.  This is used internally and
-        automatically called on URL building.
-
-        .. versionadded:: 0.7
-        """
-        names: t.Iterable[t.Optional[str]] = (None,)
-
-        # url_for may be called outside a request context, parse the
-        # passed endpoint instead of using request.blueprints.
-        if "." in endpoint:
-            names = chain(
-                names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0]))
-            )
-
-        for name in names:
-            if name in self.url_default_functions:
-                for func in self.url_default_functions[name]:
-                    func(endpoint, values)
-
-    def handle_url_build_error(
-        self, error: BuildError, endpoint: str, values: t.Dict[str, t.Any]
-    ) -> str:
-        """Called by :meth:`.url_for` if a
-        :exc:`~werkzeug.routing.BuildError` was raised. If this returns
-        a value, it will be returned by ``url_for``, otherwise the error
-        will be re-raised.
-
-        Each function in :attr:`url_build_error_handlers` is called with
-        ``error``, ``endpoint`` and ``values``. If a function returns
-        ``None`` or raises a ``BuildError``, it is skipped. Otherwise,
-        its return value is returned by ``url_for``.
-
-        :param error: The active ``BuildError`` being handled.
-        :param endpoint: The endpoint being built.
-        :param values: The keyword arguments passed to ``url_for``.
-        """
-        for handler in self.url_build_error_handlers:
-            try:
-                rv = handler(error, endpoint, values)
-            except BuildError as e:
-                # make error available outside except block
-                error = e
-            else:
-                if rv is not None:
-                    return rv
-
-        # Re-raise if called with an active exception, otherwise raise
-        # the passed in exception.
-        if error is sys.exc_info()[1]:
-            raise
-
-        raise error
-
-    def preprocess_request(self) -> t.Optional[ft.ResponseReturnValue]:
-        """Called before the request is dispatched. Calls
-        :attr:`url_value_preprocessors` registered with the app and the
-        current blueprint (if any). Then calls :attr:`before_request_funcs`
-        registered with the app and the blueprint.
-
-        If any :meth:`before_request` handler returns a non-None value, the
-        value is handled as if it was the return value from the view, and
-        further request handling is stopped.
-        """
-        names = (None, *reversed(request.blueprints))
-
-        for name in names:
-            if name in self.url_value_preprocessors:
-                for url_func in self.url_value_preprocessors[name]:
-                    url_func(request.endpoint, request.view_args)
-
-        for name in names:
-            if name in self.before_request_funcs:
-                for before_func in self.before_request_funcs[name]:
-                    rv = self.ensure_sync(before_func)()
-
-                    if rv is not None:
-                        return rv
-
-        return None
-
-    def process_response(self, response: Response) -> Response:
-        """Can be overridden in order to modify the response object
-        before it's sent to the WSGI server.  By default this will
-        call all the :meth:`after_request` decorated functions.
-
-        .. versionchanged:: 0.5
-           As of Flask 0.5 the functions registered for after request
-           execution are called in reverse order of registration.
-
-        :param response: a :attr:`response_class` object.
-        :return: a new response object or the same, has to be an
-                 instance of :attr:`response_class`.
-        """
-        ctx = request_ctx._get_current_object()  # type: ignore[attr-defined]
-
-        for func in ctx._after_request_functions:
-            response = self.ensure_sync(func)(response)
-
-        for name in chain(request.blueprints, (None,)):
-            if name in self.after_request_funcs:
-                for func in reversed(self.after_request_funcs[name]):
-                    response = self.ensure_sync(func)(response)
-
-        if not self.session_interface.is_null_session(ctx.session):
-            self.session_interface.save_session(self, ctx.session, response)
-
-        return response
-
-    def do_teardown_request(
-        self, exc: t.Optional[BaseException] = _sentinel  # type: ignore
-    ) -> None:
-        """Called after the request is dispatched and the response is
-        returned, right before the request context is popped.
-
-        This calls all functions decorated with
-        :meth:`teardown_request`, and :meth:`Blueprint.teardown_request`
-        if a blueprint handled the request. Finally, the
-        :data:`request_tearing_down` signal is sent.
-
-        This is called by
-        :meth:`RequestContext.pop() <flask.ctx.RequestContext.pop>`,
-        which may be delayed during testing to maintain access to
-        resources.
-
-        :param exc: An unhandled exception raised while dispatching the
-            request. Detected from the current exception information if
-            not passed. Passed to each teardown function.
-
-        .. versionchanged:: 0.9
-            Added the ``exc`` argument.
-        """
-        if exc is _sentinel:
-            exc = sys.exc_info()[1]
-
-        for name in chain(request.blueprints, (None,)):
-            if name in self.teardown_request_funcs:
-                for func in reversed(self.teardown_request_funcs[name]):
-                    self.ensure_sync(func)(exc)
-
-        request_tearing_down.send(self, exc=exc)
-
-    def do_teardown_appcontext(
-        self, exc: t.Optional[BaseException] = _sentinel  # type: ignore
-    ) -> None:
-        """Called right before the application context is popped.
-
-        When handling a request, the application context is popped
-        after the request context. See :meth:`do_teardown_request`.
-
-        This calls all functions decorated with
-        :meth:`teardown_appcontext`. Then the
-        :data:`appcontext_tearing_down` signal is sent.
-
-        This is called by
-        :meth:`AppContext.pop() <flask.ctx.AppContext.pop>`.
-
-        .. versionadded:: 0.9
-        """
-        if exc is _sentinel:
-            exc = sys.exc_info()[1]
-
-        for func in reversed(self.teardown_appcontext_funcs):
-            self.ensure_sync(func)(exc)
-
-        appcontext_tearing_down.send(self, exc=exc)
-
-    def app_context(self) -> AppContext:
-        """Create an :class:`~flask.ctx.AppContext`. Use as a ``with``
-        block to push the context, which will make :data:`current_app`
-        point at this application.
-
-        An application context is automatically pushed by
-        :meth:`RequestContext.push() <flask.ctx.RequestContext.push>`
-        when handling a request, and when running a CLI command. Use
-        this to manually create a context outside of these situations.
-
-        ::
-
-            with app.app_context():
-                init_db()
-
-        See :doc:`/appcontext`.
-
-        .. versionadded:: 0.9
-        """
-        return AppContext(self)
-
-    def request_context(self, environ: dict) -> RequestContext:
-        """Create a :class:`~flask.ctx.RequestContext` representing a
-        WSGI environment. Use a ``with`` block to push the context,
-        which will make :data:`request` point at this request.
-
-        See :doc:`/reqcontext`.
-
-        Typically you should not call this from your own code. A request
-        context is automatically pushed by the :meth:`wsgi_app` when
-        handling a request. Use :meth:`test_request_context` to create
-        an environment and context instead of this method.
-
-        :param environ: a WSGI environment
-        """
-        return RequestContext(self, environ)
-
-    def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext:
-        """Create a :class:`~flask.ctx.RequestContext` for a WSGI
-        environment created from the given values. This is mostly useful
-        during testing, where you may want to run a function that uses
-        request data without dispatching a full request.
-
-        See :doc:`/reqcontext`.
-
-        Use a ``with`` block to push the context, which will make
-        :data:`request` point at the request for the created
-        environment. ::
-
-            with test_request_context(...):
-                generate_report()
-
-        When using the shell, it may be easier to push and pop the
-        context manually to avoid indentation. ::
-
-            ctx = app.test_request_context(...)
-            ctx.push()
-            ...
-            ctx.pop()
-
-        Takes the same arguments as Werkzeug's
-        :class:`~werkzeug.test.EnvironBuilder`, with some defaults from
-        the application. See the linked Werkzeug docs for most of the
-        available arguments. Flask-specific behavior is listed here.
-
-        :param path: URL path being requested.
-        :param base_url: Base URL where the app is being served, which
-            ``path`` is relative to. If not given, built from
-            :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
-            :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
-        :param subdomain: Subdomain name to append to
-            :data:`SERVER_NAME`.
-        :param url_scheme: Scheme to use instead of
-            :data:`PREFERRED_URL_SCHEME`.
-        :param data: The request body, either as a string or a dict of
-            form keys and values.
-        :param json: If given, this is serialized as JSON and passed as
-            ``data``. Also defaults ``content_type`` to
-            ``application/json``.
-        :param args: other positional arguments passed to
-            :class:`~werkzeug.test.EnvironBuilder`.
-        :param kwargs: other keyword arguments passed to
-            :class:`~werkzeug.test.EnvironBuilder`.
-        """
-        from .testing import EnvironBuilder
-
-        builder = EnvironBuilder(self, *args, **kwargs)
-
-        try:
-            return self.request_context(builder.get_environ())
-        finally:
-            builder.close()
-
-    def wsgi_app(self, environ: dict, start_response: t.Callable) -> t.Any:
-        """The actual WSGI application. This is not implemented in
-        :meth:`__call__` so that middlewares can be applied without
-        losing a reference to the app object. Instead of doing this::
-
-            app = MyMiddleware(app)
-
-        It's a better idea to do this instead::
-
-            app.wsgi_app = MyMiddleware(app.wsgi_app)
-
-        Then you still have the original application object around and
-        can continue to call methods on it.
-
-        .. versionchanged:: 0.7
-            Teardown events for the request and app contexts are called
-            even if an unhandled error occurs. Other events may not be
-            called depending on when an error occurs during dispatch.
-            See :ref:`callbacks-and-errors`.
-
-        :param environ: A WSGI environment.
-        :param start_response: A callable accepting a status code,
-            a list of headers, and an optional exception context to
-            start the response.
-        """
-        ctx = self.request_context(environ)
-        error: t.Optional[BaseException] = None
-        try:
-            try:
-                ctx.push()
-                response = self.full_dispatch_request()
-            except Exception as e:
-                error = e
-                response = self.handle_exception(e)
-            except:  # noqa: B001
-                error = sys.exc_info()[1]
-                raise
-            return response(environ, start_response)
-        finally:
-            if "werkzeug.debug.preserve_context" in environ:
-                environ["werkzeug.debug.preserve_context"](_cv_app.get())
-                environ["werkzeug.debug.preserve_context"](_cv_request.get())
-
-            if error is not None and self.should_ignore_error(error):
-                error = None
-
-            ctx.pop(error)
-
-    def __call__(self, environ: dict, start_response: t.Callable) -> t.Any:
-        """The WSGI server calls the Flask application object as the
-        WSGI application. This calls :meth:`wsgi_app`, which can be
-        wrapped to apply middleware.
-        """
-        return self.wsgi_app(environ, start_response)

+ 0 - 706
venv/lib/python3.10/site-packages/flask/blueprints.py

@@ -1,706 +0,0 @@
-import json
-import os
-import typing as t
-from collections import defaultdict
-from functools import update_wrapper
-
-from . import typing as ft
-from .scaffold import _endpoint_from_view_func
-from .scaffold import _sentinel
-from .scaffold import Scaffold
-from .scaffold import setupmethod
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from .app import Flask
-
-DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable]
-T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable)
-T_before_first_request = t.TypeVar(
-    "T_before_first_request", bound=ft.BeforeFirstRequestCallable
-)
-T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable)
-T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable)
-T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
-T_template_context_processor = t.TypeVar(
-    "T_template_context_processor", bound=ft.TemplateContextProcessorCallable
-)
-T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable)
-T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable)
-T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable)
-T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable)
-T_url_value_preprocessor = t.TypeVar(
-    "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable
-)
-
-
-class BlueprintSetupState:
-    """Temporary holder object for registering a blueprint with the
-    application.  An instance of this class is created by the
-    :meth:`~flask.Blueprint.make_setup_state` method and later passed
-    to all register callback functions.
-    """
-
-    def __init__(
-        self,
-        blueprint: "Blueprint",
-        app: "Flask",
-        options: t.Any,
-        first_registration: bool,
-    ) -> None:
-        #: a reference to the current application
-        self.app = app
-
-        #: a reference to the blueprint that created this setup state.
-        self.blueprint = blueprint
-
-        #: a dictionary with all options that were passed to the
-        #: :meth:`~flask.Flask.register_blueprint` method.
-        self.options = options
-
-        #: as blueprints can be registered multiple times with the
-        #: application and not everything wants to be registered
-        #: multiple times on it, this attribute can be used to figure
-        #: out if the blueprint was registered in the past already.
-        self.first_registration = first_registration
-
-        subdomain = self.options.get("subdomain")
-        if subdomain is None:
-            subdomain = self.blueprint.subdomain
-
-        #: The subdomain that the blueprint should be active for, ``None``
-        #: otherwise.
-        self.subdomain = subdomain
-
-        url_prefix = self.options.get("url_prefix")
-        if url_prefix is None:
-            url_prefix = self.blueprint.url_prefix
-        #: The prefix that should be used for all URLs defined on the
-        #: blueprint.
-        self.url_prefix = url_prefix
-
-        self.name = self.options.get("name", blueprint.name)
-        self.name_prefix = self.options.get("name_prefix", "")
-
-        #: A dictionary with URL defaults that is added to each and every
-        #: URL that was defined with the blueprint.
-        self.url_defaults = dict(self.blueprint.url_values_defaults)
-        self.url_defaults.update(self.options.get("url_defaults", ()))
-
-    def add_url_rule(
-        self,
-        rule: str,
-        endpoint: t.Optional[str] = None,
-        view_func: t.Optional[t.Callable] = None,
-        **options: t.Any,
-    ) -> None:
-        """A helper method to register a rule (and optionally a view function)
-        to the application.  The endpoint is automatically prefixed with the
-        blueprint's name.
-        """
-        if self.url_prefix is not None:
-            if rule:
-                rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/")))
-            else:
-                rule = self.url_prefix
-        options.setdefault("subdomain", self.subdomain)
-        if endpoint is None:
-            endpoint = _endpoint_from_view_func(view_func)  # type: ignore
-        defaults = self.url_defaults
-        if "defaults" in options:
-            defaults = dict(defaults, **options.pop("defaults"))
-
-        self.app.add_url_rule(
-            rule,
-            f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."),
-            view_func,
-            defaults=defaults,
-            **options,
-        )
-
-
-class Blueprint(Scaffold):
-    """Represents a blueprint, a collection of routes and other
-    app-related functions that can be registered on a real application
-    later.
-
-    A blueprint is an object that allows defining application functions
-    without requiring an application object ahead of time. It uses the
-    same decorators as :class:`~flask.Flask`, but defers the need for an
-    application by recording them for later registration.
-
-    Decorating a function with a blueprint creates a deferred function
-    that is called with :class:`~flask.blueprints.BlueprintSetupState`
-    when the blueprint is registered on an application.
-
-    See :doc:`/blueprints` for more information.
-
-    :param name: The name of the blueprint. Will be prepended to each
-        endpoint name.
-    :param import_name: The name of the blueprint package, usually
-        ``__name__``. This helps locate the ``root_path`` for the
-        blueprint.
-    :param static_folder: A folder with static files that should be
-        served by the blueprint's static route. The path is relative to
-        the blueprint's root path. Blueprint static files are disabled
-        by default.
-    :param static_url_path: The url to serve static files from.
-        Defaults to ``static_folder``. If the blueprint does not have
-        a ``url_prefix``, the app's static route will take precedence,
-        and the blueprint's static files won't be accessible.
-    :param template_folder: A folder with templates that should be added
-        to the app's template search path. The path is relative to the
-        blueprint's root path. Blueprint templates are disabled by
-        default. Blueprint templates have a lower precedence than those
-        in the app's templates folder.
-    :param url_prefix: A path to prepend to all of the blueprint's URLs,
-        to make them distinct from the rest of the app's routes.
-    :param subdomain: A subdomain that blueprint routes will match on by
-        default.
-    :param url_defaults: A dict of default values that blueprint routes
-        will receive by default.
-    :param root_path: By default, the blueprint will automatically set
-        this based on ``import_name``. In certain situations this
-        automatic detection can fail, so the path can be specified
-        manually instead.
-
-    .. versionchanged:: 1.1.0
-        Blueprints have a ``cli`` group to register nested CLI commands.
-        The ``cli_group`` parameter controls the name of the group under
-        the ``flask`` command.
-
-    .. versionadded:: 0.7
-    """
-
-    _got_registered_once = False
-
-    _json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
-    _json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
-
-    @property  # type: ignore[override]
-    def json_encoder(  # type: ignore[override]
-        self,
-    ) -> t.Union[t.Type[json.JSONEncoder], None]:
-        """Blueprint-local JSON encoder class to use. Set to ``None`` to use the app's.
-
-        .. deprecated:: 2.2
-             Will be removed in Flask 2.3. Customize
-             :attr:`json_provider_class` instead.
-
-        .. versionadded:: 0.10
-        """
-        import warnings
-
-        warnings.warn(
-            "'bp.json_encoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return self._json_encoder
-
-    @json_encoder.setter
-    def json_encoder(self, value: t.Union[t.Type[json.JSONEncoder], None]) -> None:
-        import warnings
-
-        warnings.warn(
-            "'bp.json_encoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self._json_encoder = value
-
-    @property  # type: ignore[override]
-    def json_decoder(  # type: ignore[override]
-        self,
-    ) -> t.Union[t.Type[json.JSONDecoder], None]:
-        """Blueprint-local JSON decoder class to use. Set to ``None`` to use the app's.
-
-        .. deprecated:: 2.2
-             Will be removed in Flask 2.3. Customize
-             :attr:`json_provider_class` instead.
-
-        .. versionadded:: 0.10
-        """
-        import warnings
-
-        warnings.warn(
-            "'bp.json_decoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return self._json_decoder
-
-    @json_decoder.setter
-    def json_decoder(self, value: t.Union[t.Type[json.JSONDecoder], None]) -> None:
-        import warnings
-
-        warnings.warn(
-            "'bp.json_decoder' is deprecated and will be removed in Flask 2.3."
-            " Customize 'app.json_provider_class' or 'app.json' instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self._json_decoder = value
-
-    def __init__(
-        self,
-        name: str,
-        import_name: str,
-        static_folder: t.Optional[t.Union[str, os.PathLike]] = None,
-        static_url_path: t.Optional[str] = None,
-        template_folder: t.Optional[str] = None,
-        url_prefix: t.Optional[str] = None,
-        subdomain: t.Optional[str] = None,
-        url_defaults: t.Optional[dict] = None,
-        root_path: t.Optional[str] = None,
-        cli_group: t.Optional[str] = _sentinel,  # type: ignore
-    ):
-        super().__init__(
-            import_name=import_name,
-            static_folder=static_folder,
-            static_url_path=static_url_path,
-            template_folder=template_folder,
-            root_path=root_path,
-        )
-
-        if "." in name:
-            raise ValueError("'name' may not contain a dot '.' character.")
-
-        self.name = name
-        self.url_prefix = url_prefix
-        self.subdomain = subdomain
-        self.deferred_functions: t.List[DeferredSetupFunction] = []
-
-        if url_defaults is None:
-            url_defaults = {}
-
-        self.url_values_defaults = url_defaults
-        self.cli_group = cli_group
-        self._blueprints: t.List[t.Tuple["Blueprint", dict]] = []
-
-    def _check_setup_finished(self, f_name: str) -> None:
-        if self._got_registered_once:
-            import warnings
-
-            warnings.warn(
-                f"The setup method '{f_name}' can no longer be called on"
-                f" the blueprint '{self.name}'. It has already been"
-                " registered at least once, any changes will not be"
-                " applied consistently.\n"
-                "Make sure all imports, decorators, functions, etc."
-                " needed to set up the blueprint are done before"
-                " registering it.\n"
-                "This warning will become an exception in Flask 2.3.",
-                UserWarning,
-                stacklevel=3,
-            )
-
-    @setupmethod
-    def record(self, func: t.Callable) -> None:
-        """Registers a function that is called when the blueprint is
-        registered on the application.  This function is called with the
-        state as argument as returned by the :meth:`make_setup_state`
-        method.
-        """
-        self.deferred_functions.append(func)
-
-    @setupmethod
-    def record_once(self, func: t.Callable) -> None:
-        """Works like :meth:`record` but wraps the function in another
-        function that will ensure the function is only called once.  If the
-        blueprint is registered a second time on the application, the
-        function passed is not called.
-        """
-
-        def wrapper(state: BlueprintSetupState) -> None:
-            if state.first_registration:
-                func(state)
-
-        self.record(update_wrapper(wrapper, func))
-
-    def make_setup_state(
-        self, app: "Flask", options: dict, first_registration: bool = False
-    ) -> BlueprintSetupState:
-        """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState`
-        object that is later passed to the register callback functions.
-        Subclasses can override this to return a subclass of the setup state.
-        """
-        return BlueprintSetupState(self, app, options, first_registration)
-
-    @setupmethod
-    def register_blueprint(self, blueprint: "Blueprint", **options: t.Any) -> None:
-        """Register a :class:`~flask.Blueprint` on this blueprint. Keyword
-        arguments passed to this method will override the defaults set
-        on the blueprint.
-
-        .. versionchanged:: 2.0.1
-            The ``name`` option can be used to change the (pre-dotted)
-            name the blueprint is registered with. This allows the same
-            blueprint to be registered multiple times with unique names
-            for ``url_for``.
-
-        .. versionadded:: 2.0
-        """
-        if blueprint is self:
-            raise ValueError("Cannot register a blueprint on itself")
-        self._blueprints.append((blueprint, options))
-
-    def register(self, app: "Flask", options: dict) -> None:
-        """Called by :meth:`Flask.register_blueprint` to register all
-        views and callbacks registered on the blueprint with the
-        application. Creates a :class:`.BlueprintSetupState` and calls
-        each :meth:`record` callback with it.
-
-        :param app: The application this blueprint is being registered
-            with.
-        :param options: Keyword arguments forwarded from
-            :meth:`~Flask.register_blueprint`.
-
-        .. versionchanged:: 2.0.1
-            Nested blueprints are registered with their dotted name.
-            This allows different blueprints with the same name to be
-            nested at different locations.
-
-        .. versionchanged:: 2.0.1
-            The ``name`` option can be used to change the (pre-dotted)
-            name the blueprint is registered with. This allows the same
-            blueprint to be registered multiple times with unique names
-            for ``url_for``.
-
-        .. versionchanged:: 2.0.1
-            Registering the same blueprint with the same name multiple
-            times is deprecated and will become an error in Flask 2.1.
-        """
-        name_prefix = options.get("name_prefix", "")
-        self_name = options.get("name", self.name)
-        name = f"{name_prefix}.{self_name}".lstrip(".")
-
-        if name in app.blueprints:
-            bp_desc = "this" if app.blueprints[name] is self else "a different"
-            existing_at = f" '{name}'" if self_name != name else ""
-
-            raise ValueError(
-                f"The name '{self_name}' is already registered for"
-                f" {bp_desc} blueprint{existing_at}. Use 'name=' to"
-                f" provide a unique name."
-            )
-
-        first_bp_registration = not any(bp is self for bp in app.blueprints.values())
-        first_name_registration = name not in app.blueprints
-
-        app.blueprints[name] = self
-        self._got_registered_once = True
-        state = self.make_setup_state(app, options, first_bp_registration)
-
-        if self.has_static_folder:
-            state.add_url_rule(
-                f"{self.static_url_path}/<path:filename>",
-                view_func=self.send_static_file,
-                endpoint="static",
-            )
-
-        # Merge blueprint data into parent.
-        if first_bp_registration or first_name_registration:
-
-            def extend(bp_dict, parent_dict):
-                for key, values in bp_dict.items():
-                    key = name if key is None else f"{name}.{key}"
-                    parent_dict[key].extend(values)
-
-            for key, value in self.error_handler_spec.items():
-                key = name if key is None else f"{name}.{key}"
-                value = defaultdict(
-                    dict,
-                    {
-                        code: {
-                            exc_class: func for exc_class, func in code_values.items()
-                        }
-                        for code, code_values in value.items()
-                    },
-                )
-                app.error_handler_spec[key] = value
-
-            for endpoint, func in self.view_functions.items():
-                app.view_functions[endpoint] = func
-
-            extend(self.before_request_funcs, app.before_request_funcs)
-            extend(self.after_request_funcs, app.after_request_funcs)
-            extend(
-                self.teardown_request_funcs,
-                app.teardown_request_funcs,
-            )
-            extend(self.url_default_functions, app.url_default_functions)
-            extend(self.url_value_preprocessors, app.url_value_preprocessors)
-            extend(self.template_context_processors, app.template_context_processors)
-
-        for deferred in self.deferred_functions:
-            deferred(state)
-
-        cli_resolved_group = options.get("cli_group", self.cli_group)
-
-        if self.cli.commands:
-            if cli_resolved_group is None:
-                app.cli.commands.update(self.cli.commands)
-            elif cli_resolved_group is _sentinel:
-                self.cli.name = name
-                app.cli.add_command(self.cli)
-            else:
-                self.cli.name = cli_resolved_group
-                app.cli.add_command(self.cli)
-
-        for blueprint, bp_options in self._blueprints:
-            bp_options = bp_options.copy()
-            bp_url_prefix = bp_options.get("url_prefix")
-
-            if bp_url_prefix is None:
-                bp_url_prefix = blueprint.url_prefix
-
-            if state.url_prefix is not None and bp_url_prefix is not None:
-                bp_options["url_prefix"] = (
-                    state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/")
-                )
-            elif bp_url_prefix is not None:
-                bp_options["url_prefix"] = bp_url_prefix
-            elif state.url_prefix is not None:
-                bp_options["url_prefix"] = state.url_prefix
-
-            bp_options["name_prefix"] = name
-            blueprint.register(app, bp_options)
-
-    @setupmethod
-    def add_url_rule(
-        self,
-        rule: str,
-        endpoint: t.Optional[str] = None,
-        view_func: t.Optional[ft.RouteCallable] = None,
-        provide_automatic_options: t.Optional[bool] = None,
-        **options: t.Any,
-    ) -> None:
-        """Like :meth:`Flask.add_url_rule` but for a blueprint.  The endpoint for
-        the :func:`url_for` function is prefixed with the name of the blueprint.
-        """
-        if endpoint and "." in endpoint:
-            raise ValueError("'endpoint' may not contain a dot '.' character.")
-
-        if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__:
-            raise ValueError("'view_func' name may not contain a dot '.' character.")
-
-        self.record(
-            lambda s: s.add_url_rule(
-                rule,
-                endpoint,
-                view_func,
-                provide_automatic_options=provide_automatic_options,
-                **options,
-            )
-        )
-
-    @setupmethod
-    def app_template_filter(
-        self, name: t.Optional[str] = None
-    ) -> t.Callable[[T_template_filter], T_template_filter]:
-        """Register a custom template filter, available application wide.  Like
-        :meth:`Flask.template_filter` but for a blueprint.
-
-        :param name: the optional name of the filter, otherwise the
-                     function name will be used.
-        """
-
-        def decorator(f: T_template_filter) -> T_template_filter:
-            self.add_app_template_filter(f, name=name)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def add_app_template_filter(
-        self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None
-    ) -> None:
-        """Register a custom template filter, available application wide.  Like
-        :meth:`Flask.add_template_filter` but for a blueprint.  Works exactly
-        like the :meth:`app_template_filter` decorator.
-
-        :param name: the optional name of the filter, otherwise the
-                     function name will be used.
-        """
-
-        def register_template(state: BlueprintSetupState) -> None:
-            state.app.jinja_env.filters[name or f.__name__] = f
-
-        self.record_once(register_template)
-
-    @setupmethod
-    def app_template_test(
-        self, name: t.Optional[str] = None
-    ) -> t.Callable[[T_template_test], T_template_test]:
-        """Register a custom template test, available application wide.  Like
-        :meth:`Flask.template_test` but for a blueprint.
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the test, otherwise the
-                     function name will be used.
-        """
-
-        def decorator(f: T_template_test) -> T_template_test:
-            self.add_app_template_test(f, name=name)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def add_app_template_test(
-        self, f: ft.TemplateTestCallable, name: t.Optional[str] = None
-    ) -> None:
-        """Register a custom template test, available application wide.  Like
-        :meth:`Flask.add_template_test` but for a blueprint.  Works exactly
-        like the :meth:`app_template_test` decorator.
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the test, otherwise the
-                     function name will be used.
-        """
-
-        def register_template(state: BlueprintSetupState) -> None:
-            state.app.jinja_env.tests[name or f.__name__] = f
-
-        self.record_once(register_template)
-
-    @setupmethod
-    def app_template_global(
-        self, name: t.Optional[str] = None
-    ) -> t.Callable[[T_template_global], T_template_global]:
-        """Register a custom template global, available application wide.  Like
-        :meth:`Flask.template_global` but for a blueprint.
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the global, otherwise the
-                     function name will be used.
-        """
-
-        def decorator(f: T_template_global) -> T_template_global:
-            self.add_app_template_global(f, name=name)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def add_app_template_global(
-        self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None
-    ) -> None:
-        """Register a custom template global, available application wide.  Like
-        :meth:`Flask.add_template_global` but for a blueprint.  Works exactly
-        like the :meth:`app_template_global` decorator.
-
-        .. versionadded:: 0.10
-
-        :param name: the optional name of the global, otherwise the
-                     function name will be used.
-        """
-
-        def register_template(state: BlueprintSetupState) -> None:
-            state.app.jinja_env.globals[name or f.__name__] = f
-
-        self.record_once(register_template)
-
-    @setupmethod
-    def before_app_request(self, f: T_before_request) -> T_before_request:
-        """Like :meth:`Flask.before_request`.  Such a function is executed
-        before each request, even if outside of a blueprint.
-        """
-        self.record_once(
-            lambda s: s.app.before_request_funcs.setdefault(None, []).append(f)
-        )
-        return f
-
-    @setupmethod
-    def before_app_first_request(
-        self, f: T_before_first_request
-    ) -> T_before_first_request:
-        """Like :meth:`Flask.before_first_request`.  Such a function is
-        executed before the first request to the application.
-
-        .. deprecated:: 2.2
-            Will be removed in Flask 2.3. Run setup code when creating
-            the application instead.
-        """
-        import warnings
-
-        warnings.warn(
-            "'before_app_first_request' is deprecated and will be"
-            " removed in Flask 2.3. Use 'record_once' instead to run"
-            " setup code when registering the blueprint.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        self.record_once(lambda s: s.app.before_first_request_funcs.append(f))
-        return f
-
-    @setupmethod
-    def after_app_request(self, f: T_after_request) -> T_after_request:
-        """Like :meth:`Flask.after_request` but for a blueprint.  Such a function
-        is executed after each request, even if outside of the blueprint.
-        """
-        self.record_once(
-            lambda s: s.app.after_request_funcs.setdefault(None, []).append(f)
-        )
-        return f
-
-    @setupmethod
-    def teardown_app_request(self, f: T_teardown) -> T_teardown:
-        """Like :meth:`Flask.teardown_request` but for a blueprint.  Such a
-        function is executed when tearing down each request, even if outside of
-        the blueprint.
-        """
-        self.record_once(
-            lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f)
-        )
-        return f
-
-    @setupmethod
-    def app_context_processor(
-        self, f: T_template_context_processor
-    ) -> T_template_context_processor:
-        """Like :meth:`Flask.context_processor` but for a blueprint.  Such a
-        function is executed each request, even if outside of the blueprint.
-        """
-        self.record_once(
-            lambda s: s.app.template_context_processors.setdefault(None, []).append(f)
-        )
-        return f
-
-    @setupmethod
-    def app_errorhandler(
-        self, code: t.Union[t.Type[Exception], int]
-    ) -> t.Callable[[T_error_handler], T_error_handler]:
-        """Like :meth:`Flask.errorhandler` but for a blueprint.  This
-        handler is used for all requests, even if outside of the blueprint.
-        """
-
-        def decorator(f: T_error_handler) -> T_error_handler:
-            self.record_once(lambda s: s.app.errorhandler(code)(f))
-            return f
-
-        return decorator
-
-    @setupmethod
-    def app_url_value_preprocessor(
-        self, f: T_url_value_preprocessor
-    ) -> T_url_value_preprocessor:
-        """Same as :meth:`url_value_preprocessor` but application wide."""
-        self.record_once(
-            lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f)
-        )
-        return f
-
-    @setupmethod
-    def app_url_defaults(self, f: T_url_defaults) -> T_url_defaults:
-        """Same as :meth:`url_defaults` but application wide."""
-        self.record_once(
-            lambda s: s.app.url_default_functions.setdefault(None, []).append(f)
-        )
-        return f

+ 0 - 1051
venv/lib/python3.10/site-packages/flask/cli.py

@@ -1,1051 +0,0 @@
-from __future__ import annotations
-
-import ast
-import inspect
-import os
-import platform
-import re
-import sys
-import traceback
-import typing as t
-from functools import update_wrapper
-from operator import attrgetter
-
-import click
-from click.core import ParameterSource
-from werkzeug import run_simple
-from werkzeug.serving import is_running_from_reloader
-from werkzeug.utils import import_string
-
-from .globals import current_app
-from .helpers import get_debug_flag
-from .helpers import get_load_dotenv
-
-if t.TYPE_CHECKING:
-    from .app import Flask
-
-
-class NoAppException(click.UsageError):
-    """Raised if an application cannot be found or loaded."""
-
-
-def find_best_app(module):
-    """Given a module instance this tries to find the best possible
-    application in the module or raises an exception.
-    """
-    from . import Flask
-
-    # Search for the most common names first.
-    for attr_name in ("app", "application"):
-        app = getattr(module, attr_name, None)
-
-        if isinstance(app, Flask):
-            return app
-
-    # Otherwise find the only object that is a Flask instance.
-    matches = [v for v in module.__dict__.values() if isinstance(v, Flask)]
-
-    if len(matches) == 1:
-        return matches[0]
-    elif len(matches) > 1:
-        raise NoAppException(
-            "Detected multiple Flask applications in module"
-            f" '{module.__name__}'. Use '{module.__name__}:name'"
-            " to specify the correct one."
-        )
-
-    # Search for app factory functions.
-    for attr_name in ("create_app", "make_app"):
-        app_factory = getattr(module, attr_name, None)
-
-        if inspect.isfunction(app_factory):
-            try:
-                app = app_factory()
-
-                if isinstance(app, Flask):
-                    return app
-            except TypeError as e:
-                if not _called_with_wrong_args(app_factory):
-                    raise
-
-                raise NoAppException(
-                    f"Detected factory '{attr_name}' in module '{module.__name__}',"
-                    " but could not call it without arguments. Use"
-                    f" '{module.__name__}:{attr_name}(args)'"
-                    " to specify arguments."
-                ) from e
-
-    raise NoAppException(
-        "Failed to find Flask application or factory in module"
-        f" '{module.__name__}'. Use '{module.__name__}:name'"
-        " to specify one."
-    )
-
-
-def _called_with_wrong_args(f):
-    """Check whether calling a function raised a ``TypeError`` because
-    the call failed or because something in the factory raised the
-    error.
-
-    :param f: The function that was called.
-    :return: ``True`` if the call failed.
-    """
-    tb = sys.exc_info()[2]
-
-    try:
-        while tb is not None:
-            if tb.tb_frame.f_code is f.__code__:
-                # In the function, it was called successfully.
-                return False
-
-            tb = tb.tb_next
-
-        # Didn't reach the function.
-        return True
-    finally:
-        # Delete tb to break a circular reference.
-        # https://docs.python.org/2/library/sys.html#sys.exc_info
-        del tb
-
-
-def find_app_by_string(module, app_name):
-    """Check if the given string is a variable name or a function. Call
-    a function to get the app instance, or return the variable directly.
-    """
-    from . import Flask
-
-    # Parse app_name as a single expression to determine if it's a valid
-    # attribute name or function call.
-    try:
-        expr = ast.parse(app_name.strip(), mode="eval").body
-    except SyntaxError:
-        raise NoAppException(
-            f"Failed to parse {app_name!r} as an attribute name or function call."
-        ) from None
-
-    if isinstance(expr, ast.Name):
-        name = expr.id
-        args = []
-        kwargs = {}
-    elif isinstance(expr, ast.Call):
-        # Ensure the function name is an attribute name only.
-        if not isinstance(expr.func, ast.Name):
-            raise NoAppException(
-                f"Function reference must be a simple name: {app_name!r}."
-            )
-
-        name = expr.func.id
-
-        # Parse the positional and keyword arguments as literals.
-        try:
-            args = [ast.literal_eval(arg) for arg in expr.args]
-            kwargs = {kw.arg: ast.literal_eval(kw.value) for kw in expr.keywords}
-        except ValueError:
-            # literal_eval gives cryptic error messages, show a generic
-            # message with the full expression instead.
-            raise NoAppException(
-                f"Failed to parse arguments as literal values: {app_name!r}."
-            ) from None
-    else:
-        raise NoAppException(
-            f"Failed to parse {app_name!r} as an attribute name or function call."
-        )
-
-    try:
-        attr = getattr(module, name)
-    except AttributeError as e:
-        raise NoAppException(
-            f"Failed to find attribute {name!r} in {module.__name__!r}."
-        ) from e
-
-    # If the attribute is a function, call it with any args and kwargs
-    # to get the real application.
-    if inspect.isfunction(attr):
-        try:
-            app = attr(*args, **kwargs)
-        except TypeError as e:
-            if not _called_with_wrong_args(attr):
-                raise
-
-            raise NoAppException(
-                f"The factory {app_name!r} in module"
-                f" {module.__name__!r} could not be called with the"
-                " specified arguments."
-            ) from e
-    else:
-        app = attr
-
-    if isinstance(app, Flask):
-        return app
-
-    raise NoAppException(
-        "A valid Flask application was not obtained from"
-        f" '{module.__name__}:{app_name}'."
-    )
-
-
-def prepare_import(path):
-    """Given a filename this will try to calculate the python path, add it
-    to the search path and return the actual module name that is expected.
-    """
-    path = os.path.realpath(path)
-
-    fname, ext = os.path.splitext(path)
-    if ext == ".py":
-        path = fname
-
-    if os.path.basename(path) == "__init__":
-        path = os.path.dirname(path)
-
-    module_name = []
-
-    # move up until outside package structure (no __init__.py)
-    while True:
-        path, name = os.path.split(path)
-        module_name.append(name)
-
-        if not os.path.exists(os.path.join(path, "__init__.py")):
-            break
-
-    if sys.path[0] != path:
-        sys.path.insert(0, path)
-
-    return ".".join(module_name[::-1])
-
-
-def locate_app(module_name, app_name, raise_if_not_found=True):
-    try:
-        __import__(module_name)
-    except ImportError:
-        # Reraise the ImportError if it occurred within the imported module.
-        # Determine this by checking whether the trace has a depth > 1.
-        if sys.exc_info()[2].tb_next:
-            raise NoAppException(
-                f"While importing {module_name!r}, an ImportError was"
-                f" raised:\n\n{traceback.format_exc()}"
-            ) from None
-        elif raise_if_not_found:
-            raise NoAppException(f"Could not import {module_name!r}.") from None
-        else:
-            return
-
-    module = sys.modules[module_name]
-
-    if app_name is None:
-        return find_best_app(module)
-    else:
-        return find_app_by_string(module, app_name)
-
-
-def get_version(ctx, param, value):
-    if not value or ctx.resilient_parsing:
-        return
-
-    import werkzeug
-    from . import __version__
-
-    click.echo(
-        f"Python {platform.python_version()}\n"
-        f"Flask {__version__}\n"
-        f"Werkzeug {werkzeug.__version__}",
-        color=ctx.color,
-    )
-    ctx.exit()
-
-
-version_option = click.Option(
-    ["--version"],
-    help="Show the Flask version.",
-    expose_value=False,
-    callback=get_version,
-    is_flag=True,
-    is_eager=True,
-)
-
-
-class ScriptInfo:
-    """Helper object to deal with Flask applications.  This is usually not
-    necessary to interface with as it's used internally in the dispatching
-    to click.  In future versions of Flask this object will most likely play
-    a bigger role.  Typically it's created automatically by the
-    :class:`FlaskGroup` but you can also manually create it and pass it
-    onwards as click object.
-    """
-
-    def __init__(
-        self,
-        app_import_path: str | None = None,
-        create_app: t.Callable[..., Flask] | None = None,
-        set_debug_flag: bool = True,
-    ) -> None:
-        #: Optionally the import path for the Flask application.
-        self.app_import_path = app_import_path
-        #: Optionally a function that is passed the script info to create
-        #: the instance of the application.
-        self.create_app = create_app
-        #: A dictionary with arbitrary data that can be associated with
-        #: this script info.
-        self.data: t.Dict[t.Any, t.Any] = {}
-        self.set_debug_flag = set_debug_flag
-        self._loaded_app: Flask | None = None
-
-    def load_app(self) -> Flask:
-        """Loads the Flask app (if not yet loaded) and returns it.  Calling
-        this multiple times will just result in the already loaded app to
-        be returned.
-        """
-        if self._loaded_app is not None:
-            return self._loaded_app
-
-        if self.create_app is not None:
-            app = self.create_app()
-        else:
-            if self.app_import_path:
-                path, name = (
-                    re.split(r":(?![\\/])", self.app_import_path, 1) + [None]
-                )[:2]
-                import_name = prepare_import(path)
-                app = locate_app(import_name, name)
-            else:
-                for path in ("wsgi.py", "app.py"):
-                    import_name = prepare_import(path)
-                    app = locate_app(import_name, None, raise_if_not_found=False)
-
-                    if app:
-                        break
-
-        if not app:
-            raise NoAppException(
-                "Could not locate a Flask application. Use the"
-                " 'flask --app' option, 'FLASK_APP' environment"
-                " variable, or a 'wsgi.py' or 'app.py' file in the"
-                " current directory."
-            )
-
-        if self.set_debug_flag:
-            # Update the app's debug flag through the descriptor so that
-            # other values repopulate as well.
-            app.debug = get_debug_flag()
-
-        self._loaded_app = app
-        return app
-
-
-pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True)
-
-
-def with_appcontext(f):
-    """Wraps a callback so that it's guaranteed to be executed with the
-    script's application context.
-
-    Custom commands (and their options) registered under ``app.cli`` or
-    ``blueprint.cli`` will always have an app context available, this
-    decorator is not required in that case.
-
-    .. versionchanged:: 2.2
-        The app context is active for subcommands as well as the
-        decorated callback. The app context is always available to
-        ``app.cli`` command and parameter callbacks.
-    """
-
-    @click.pass_context
-    def decorator(__ctx, *args, **kwargs):
-        if not current_app:
-            app = __ctx.ensure_object(ScriptInfo).load_app()
-            __ctx.with_resource(app.app_context())
-
-        return __ctx.invoke(f, *args, **kwargs)
-
-    return update_wrapper(decorator, f)
-
-
-class AppGroup(click.Group):
-    """This works similar to a regular click :class:`~click.Group` but it
-    changes the behavior of the :meth:`command` decorator so that it
-    automatically wraps the functions in :func:`with_appcontext`.
-
-    Not to be confused with :class:`FlaskGroup`.
-    """
-
-    def command(self, *args, **kwargs):
-        """This works exactly like the method of the same name on a regular
-        :class:`click.Group` but it wraps callbacks in :func:`with_appcontext`
-        unless it's disabled by passing ``with_appcontext=False``.
-        """
-        wrap_for_ctx = kwargs.pop("with_appcontext", True)
-
-        def decorator(f):
-            if wrap_for_ctx:
-                f = with_appcontext(f)
-            return click.Group.command(self, *args, **kwargs)(f)
-
-        return decorator
-
-    def group(self, *args, **kwargs):
-        """This works exactly like the method of the same name on a regular
-        :class:`click.Group` but it defaults the group class to
-        :class:`AppGroup`.
-        """
-        kwargs.setdefault("cls", AppGroup)
-        return click.Group.group(self, *args, **kwargs)
-
-
-def _set_app(ctx: click.Context, param: click.Option, value: str | None) -> str | None:
-    if value is None:
-        return None
-
-    info = ctx.ensure_object(ScriptInfo)
-    info.app_import_path = value
-    return value
-
-
-# This option is eager so the app will be available if --help is given.
-# --help is also eager, so --app must be before it in the param list.
-# no_args_is_help bypasses eager processing, so this option must be
-# processed manually in that case to ensure FLASK_APP gets picked up.
-_app_option = click.Option(
-    ["-A", "--app"],
-    metavar="IMPORT",
-    help=(
-        "The Flask application or factory function to load, in the form 'module:name'."
-        " Module can be a dotted import or file path. Name is not required if it is"
-        " 'app', 'application', 'create_app', or 'make_app', and can be 'name(args)' to"
-        " pass arguments."
-    ),
-    is_eager=True,
-    expose_value=False,
-    callback=_set_app,
-)
-
-
-def _set_debug(ctx: click.Context, param: click.Option, value: bool) -> bool | None:
-    # If the flag isn't provided, it will default to False. Don't use
-    # that, let debug be set by env in that case.
-    source = ctx.get_parameter_source(param.name)  # type: ignore[arg-type]
-
-    if source is not None and source in (
-        ParameterSource.DEFAULT,
-        ParameterSource.DEFAULT_MAP,
-    ):
-        return None
-
-    # Set with env var instead of ScriptInfo.load so that it can be
-    # accessed early during a factory function.
-    os.environ["FLASK_DEBUG"] = "1" if value else "0"
-    return value
-
-
-_debug_option = click.Option(
-    ["--debug/--no-debug"],
-    help="Set debug mode.",
-    expose_value=False,
-    callback=_set_debug,
-)
-
-
-def _env_file_callback(
-    ctx: click.Context, param: click.Option, value: str | None
-) -> str | None:
-    if value is None:
-        return None
-
-    import importlib
-
-    try:
-        importlib.import_module("dotenv")
-    except ImportError:
-        raise click.BadParameter(
-            "python-dotenv must be installed to load an env file.",
-            ctx=ctx,
-            param=param,
-        ) from None
-
-    # Don't check FLASK_SKIP_DOTENV, that only disables automatically
-    # loading .env and .flaskenv files.
-    load_dotenv(value)
-    return value
-
-
-# This option is eager so env vars are loaded as early as possible to be
-# used by other options.
-_env_file_option = click.Option(
-    ["-e", "--env-file"],
-    type=click.Path(exists=True, dir_okay=False),
-    help="Load environment variables from this file. python-dotenv must be installed.",
-    is_eager=True,
-    expose_value=False,
-    callback=_env_file_callback,
-)
-
-
-class FlaskGroup(AppGroup):
-    """Special subclass of the :class:`AppGroup` group that supports
-    loading more commands from the configured Flask app.  Normally a
-    developer does not have to interface with this class but there are
-    some very advanced use cases for which it makes sense to create an
-    instance of this. see :ref:`custom-scripts`.
-
-    :param add_default_commands: if this is True then the default run and
-        shell commands will be added.
-    :param add_version_option: adds the ``--version`` option.
-    :param create_app: an optional callback that is passed the script info and
-        returns the loaded app.
-    :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv`
-        files to set environment variables. Will also change the working
-        directory to the directory containing the first file found.
-    :param set_debug_flag: Set the app's debug flag.
-
-    .. versionchanged:: 2.2
-        Added the ``-A/--app``, ``--debug/--no-debug``, ``-e/--env-file`` options.
-
-    .. versionchanged:: 2.2
-        An app context is pushed when running ``app.cli`` commands, so
-        ``@with_appcontext`` is no longer required for those commands.
-
-    .. versionchanged:: 1.0
-        If installed, python-dotenv will be used to load environment variables
-        from :file:`.env` and :file:`.flaskenv` files.
-    """
-
-    def __init__(
-        self,
-        add_default_commands: bool = True,
-        create_app: t.Callable[..., Flask] | None = None,
-        add_version_option: bool = True,
-        load_dotenv: bool = True,
-        set_debug_flag: bool = True,
-        **extra: t.Any,
-    ) -> None:
-        params = list(extra.pop("params", None) or ())
-        # Processing is done with option callbacks instead of a group
-        # callback. This allows users to make a custom group callback
-        # without losing the behavior. --env-file must come first so
-        # that it is eagerly evaluated before --app.
-        params.extend((_env_file_option, _app_option, _debug_option))
-
-        if add_version_option:
-            params.append(version_option)
-
-        if "context_settings" not in extra:
-            extra["context_settings"] = {}
-
-        extra["context_settings"].setdefault("auto_envvar_prefix", "FLASK")
-
-        super().__init__(params=params, **extra)
-
-        self.create_app = create_app
-        self.load_dotenv = load_dotenv
-        self.set_debug_flag = set_debug_flag
-
-        if add_default_commands:
-            self.add_command(run_command)
-            self.add_command(shell_command)
-            self.add_command(routes_command)
-
-        self._loaded_plugin_commands = False
-
-    def _load_plugin_commands(self):
-        if self._loaded_plugin_commands:
-            return
-
-        if sys.version_info >= (3, 10):
-            from importlib import metadata
-        else:
-            # Use a backport on Python < 3.10. We technically have
-            # importlib.metadata on 3.8+, but the API changed in 3.10,
-            # so use the backport for consistency.
-            import importlib_metadata as metadata
-
-        for ep in metadata.entry_points(group="flask.commands"):
-            self.add_command(ep.load(), ep.name)
-
-        self._loaded_plugin_commands = True
-
-    def get_command(self, ctx, name):
-        self._load_plugin_commands()
-        # Look up built-in and plugin commands, which should be
-        # available even if the app fails to load.
-        rv = super().get_command(ctx, name)
-
-        if rv is not None:
-            return rv
-
-        info = ctx.ensure_object(ScriptInfo)
-
-        # Look up commands provided by the app, showing an error and
-        # continuing if the app couldn't be loaded.
-        try:
-            app = info.load_app()
-        except NoAppException as e:
-            click.secho(f"Error: {e.format_message()}\n", err=True, fg="red")
-            return None
-
-        # Push an app context for the loaded app unless it is already
-        # active somehow. This makes the context available to parameter
-        # and command callbacks without needing @with_appcontext.
-        if not current_app or current_app._get_current_object() is not app:
-            ctx.with_resource(app.app_context())
-
-        return app.cli.get_command(ctx, name)
-
-    def list_commands(self, ctx):
-        self._load_plugin_commands()
-        # Start with the built-in and plugin commands.
-        rv = set(super().list_commands(ctx))
-        info = ctx.ensure_object(ScriptInfo)
-
-        # Add commands provided by the app, showing an error and
-        # continuing if the app couldn't be loaded.
-        try:
-            rv.update(info.load_app().cli.list_commands(ctx))
-        except NoAppException as e:
-            # When an app couldn't be loaded, show the error message
-            # without the traceback.
-            click.secho(f"Error: {e.format_message()}\n", err=True, fg="red")
-        except Exception:
-            # When any other errors occurred during loading, show the
-            # full traceback.
-            click.secho(f"{traceback.format_exc()}\n", err=True, fg="red")
-
-        return sorted(rv)
-
-    def make_context(
-        self,
-        info_name: str | None,
-        args: list[str],
-        parent: click.Context | None = None,
-        **extra: t.Any,
-    ) -> click.Context:
-        # Set a flag to tell app.run to become a no-op. If app.run was
-        # not in a __name__ == __main__ guard, it would start the server
-        # when importing, blocking whatever command is being called.
-        os.environ["FLASK_RUN_FROM_CLI"] = "true"
-
-        # Attempt to load .env and .flask env files. The --env-file
-        # option can cause another file to be loaded.
-        if get_load_dotenv(self.load_dotenv):
-            load_dotenv()
-
-        if "obj" not in extra and "obj" not in self.context_settings:
-            extra["obj"] = ScriptInfo(
-                create_app=self.create_app, set_debug_flag=self.set_debug_flag
-            )
-
-        return super().make_context(info_name, args, parent=parent, **extra)
-
-    def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]:
-        if not args and self.no_args_is_help:
-            # Attempt to load --env-file and --app early in case they
-            # were given as env vars. Otherwise no_args_is_help will not
-            # see commands from app.cli.
-            _env_file_option.handle_parse_result(ctx, {}, [])
-            _app_option.handle_parse_result(ctx, {}, [])
-
-        return super().parse_args(ctx, args)
-
-
-def _path_is_ancestor(path, other):
-    """Take ``other`` and remove the length of ``path`` from it. Then join it
-    to ``path``. If it is the original value, ``path`` is an ancestor of
-    ``other``."""
-    return os.path.join(path, other[len(path) :].lstrip(os.sep)) == other
-
-
-def load_dotenv(path: str | os.PathLike | None = None) -> bool:
-    """Load "dotenv" files in order of precedence to set environment variables.
-
-    If an env var is already set it is not overwritten, so earlier files in the
-    list are preferred over later files.
-
-    This is a no-op if `python-dotenv`_ is not installed.
-
-    .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
-
-    :param path: Load the file at this location instead of searching.
-    :return: ``True`` if a file was loaded.
-
-    .. versionchanged:: 2.0
-        The current directory is not changed to the location of the
-        loaded file.
-
-    .. versionchanged:: 2.0
-        When loading the env files, set the default encoding to UTF-8.
-
-    .. versionchanged:: 1.1.0
-        Returns ``False`` when python-dotenv is not installed, or when
-        the given path isn't a file.
-
-    .. versionadded:: 1.0
-    """
-    try:
-        import dotenv
-    except ImportError:
-        if path or os.path.isfile(".env") or os.path.isfile(".flaskenv"):
-            click.secho(
-                " * Tip: There are .env or .flaskenv files present."
-                ' Do "pip install python-dotenv" to use them.',
-                fg="yellow",
-                err=True,
-            )
-
-        return False
-
-    # Always return after attempting to load a given path, don't load
-    # the default files.
-    if path is not None:
-        if os.path.isfile(path):
-            return dotenv.load_dotenv(path, encoding="utf-8")
-
-        return False
-
-    loaded = False
-
-    for name in (".env", ".flaskenv"):
-        path = dotenv.find_dotenv(name, usecwd=True)
-
-        if not path:
-            continue
-
-        dotenv.load_dotenv(path, encoding="utf-8")
-        loaded = True
-
-    return loaded  # True if at least one file was located and loaded.
-
-
-def show_server_banner(debug, app_import_path):
-    """Show extra startup messages the first time the server is run,
-    ignoring the reloader.
-    """
-    if is_running_from_reloader():
-        return
-
-    if app_import_path is not None:
-        click.echo(f" * Serving Flask app '{app_import_path}'")
-
-    if debug is not None:
-        click.echo(f" * Debug mode: {'on' if debug else 'off'}")
-
-
-class CertParamType(click.ParamType):
-    """Click option type for the ``--cert`` option. Allows either an
-    existing file, the string ``'adhoc'``, or an import for a
-    :class:`~ssl.SSLContext` object.
-    """
-
-    name = "path"
-
-    def __init__(self):
-        self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True)
-
-    def convert(self, value, param, ctx):
-        try:
-            import ssl
-        except ImportError:
-            raise click.BadParameter(
-                'Using "--cert" requires Python to be compiled with SSL support.',
-                ctx,
-                param,
-            ) from None
-
-        try:
-            return self.path_type(value, param, ctx)
-        except click.BadParameter:
-            value = click.STRING(value, param, ctx).lower()
-
-            if value == "adhoc":
-                try:
-                    import cryptography  # noqa: F401
-                except ImportError:
-                    raise click.BadParameter(
-                        "Using ad-hoc certificates requires the cryptography library.",
-                        ctx,
-                        param,
-                    ) from None
-
-                return value
-
-            obj = import_string(value, silent=True)
-
-            if isinstance(obj, ssl.SSLContext):
-                return obj
-
-            raise
-
-
-def _validate_key(ctx, param, value):
-    """The ``--key`` option must be specified when ``--cert`` is a file.
-    Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed.
-    """
-    cert = ctx.params.get("cert")
-    is_adhoc = cert == "adhoc"
-
-    try:
-        import ssl
-    except ImportError:
-        is_context = False
-    else:
-        is_context = isinstance(cert, ssl.SSLContext)
-
-    if value is not None:
-        if is_adhoc:
-            raise click.BadParameter(
-                'When "--cert" is "adhoc", "--key" is not used.', ctx, param
-            )
-
-        if is_context:
-            raise click.BadParameter(
-                'When "--cert" is an SSLContext object, "--key is not used.', ctx, param
-            )
-
-        if not cert:
-            raise click.BadParameter('"--cert" must also be specified.', ctx, param)
-
-        ctx.params["cert"] = cert, value
-
-    else:
-        if cert and not (is_adhoc or is_context):
-            raise click.BadParameter('Required when using "--cert".', ctx, param)
-
-    return value
-
-
-class SeparatedPathType(click.Path):
-    """Click option type that accepts a list of values separated by the
-    OS's path separator (``:``, ``;`` on Windows). Each value is
-    validated as a :class:`click.Path` type.
-    """
-
-    def convert(self, value, param, ctx):
-        items = self.split_envvar_value(value)
-        super_convert = super().convert
-        return [super_convert(item, param, ctx) for item in items]
-
-
-@click.command("run", short_help="Run a development server.")
-@click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to.")
-@click.option("--port", "-p", default=5000, help="The port to bind to.")
-@click.option(
-    "--cert",
-    type=CertParamType(),
-    help="Specify a certificate file to use HTTPS.",
-    is_eager=True,
-)
-@click.option(
-    "--key",
-    type=click.Path(exists=True, dir_okay=False, resolve_path=True),
-    callback=_validate_key,
-    expose_value=False,
-    help="The key file to use when specifying a certificate.",
-)
-@click.option(
-    "--reload/--no-reload",
-    default=None,
-    help="Enable or disable the reloader. By default the reloader "
-    "is active if debug is enabled.",
-)
-@click.option(
-    "--debugger/--no-debugger",
-    default=None,
-    help="Enable or disable the debugger. By default the debugger "
-    "is active if debug is enabled.",
-)
-@click.option(
-    "--with-threads/--without-threads",
-    default=True,
-    help="Enable or disable multithreading.",
-)
-@click.option(
-    "--extra-files",
-    default=None,
-    type=SeparatedPathType(),
-    help=(
-        "Extra files that trigger a reload on change. Multiple paths"
-        f" are separated by {os.path.pathsep!r}."
-    ),
-)
-@click.option(
-    "--exclude-patterns",
-    default=None,
-    type=SeparatedPathType(),
-    help=(
-        "Files matching these fnmatch patterns will not trigger a reload"
-        " on change. Multiple patterns are separated by"
-        f" {os.path.pathsep!r}."
-    ),
-)
-@pass_script_info
-def run_command(
-    info,
-    host,
-    port,
-    reload,
-    debugger,
-    with_threads,
-    cert,
-    extra_files,
-    exclude_patterns,
-):
-    """Run a local development server.
-
-    This server is for development purposes only. It does not provide
-    the stability, security, or performance of production WSGI servers.
-
-    The reloader and debugger are enabled by default with the '--debug'
-    option.
-    """
-    try:
-        app = info.load_app()
-    except Exception as e:
-        if is_running_from_reloader():
-            # When reloading, print out the error immediately, but raise
-            # it later so the debugger or server can handle it.
-            traceback.print_exc()
-            err = e
-
-            def app(environ, start_response):
-                raise err from None
-
-        else:
-            # When not reloading, raise the error immediately so the
-            # command fails.
-            raise e from None
-
-    debug = get_debug_flag()
-
-    if reload is None:
-        reload = debug
-
-    if debugger is None:
-        debugger = debug
-
-    show_server_banner(debug, info.app_import_path)
-
-    run_simple(
-        host,
-        port,
-        app,
-        use_reloader=reload,
-        use_debugger=debugger,
-        threaded=with_threads,
-        ssl_context=cert,
-        extra_files=extra_files,
-        exclude_patterns=exclude_patterns,
-    )
-
-
-@click.command("shell", short_help="Run a shell in the app context.")
-@with_appcontext
-def shell_command() -> None:
-    """Run an interactive Python shell in the context of a given
-    Flask application.  The application will populate the default
-    namespace of this shell according to its configuration.
-
-    This is useful for executing small snippets of management code
-    without having to manually configure the application.
-    """
-    import code
-
-    banner = (
-        f"Python {sys.version} on {sys.platform}\n"
-        f"App: {current_app.import_name}\n"
-        f"Instance: {current_app.instance_path}"
-    )
-    ctx: dict = {}
-
-    # Support the regular Python interpreter startup script if someone
-    # is using it.
-    startup = os.environ.get("PYTHONSTARTUP")
-    if startup and os.path.isfile(startup):
-        with open(startup) as f:
-            eval(compile(f.read(), startup, "exec"), ctx)
-
-    ctx.update(current_app.make_shell_context())
-
-    # Site, customize, or startup script can set a hook to call when
-    # entering interactive mode. The default one sets up readline with
-    # tab and history completion.
-    interactive_hook = getattr(sys, "__interactivehook__", None)
-
-    if interactive_hook is not None:
-        try:
-            import readline
-            from rlcompleter import Completer
-        except ImportError:
-            pass
-        else:
-            # rlcompleter uses __main__.__dict__ by default, which is
-            # flask.__main__. Use the shell context instead.
-            readline.set_completer(Completer(ctx).complete)
-
-        interactive_hook()
-
-    code.interact(banner=banner, local=ctx)
-
-
-@click.command("routes", short_help="Show the routes for the app.")
-@click.option(
-    "--sort",
-    "-s",
-    type=click.Choice(("endpoint", "methods", "rule", "match")),
-    default="endpoint",
-    help=(
-        'Method to sort routes by. "match" is the order that Flask will match '
-        "routes when dispatching a request."
-    ),
-)
-@click.option("--all-methods", is_flag=True, help="Show HEAD and OPTIONS methods.")
-@with_appcontext
-def routes_command(sort: str, all_methods: bool) -> None:
-    """Show all registered routes with endpoints and methods."""
-
-    rules = list(current_app.url_map.iter_rules())
-    if not rules:
-        click.echo("No routes were registered.")
-        return
-
-    ignored_methods = set(() if all_methods else ("HEAD", "OPTIONS"))
-
-    if sort in ("endpoint", "rule"):
-        rules = sorted(rules, key=attrgetter(sort))
-    elif sort == "methods":
-        rules = sorted(rules, key=lambda rule: sorted(rule.methods))  # type: ignore
-
-    rule_methods = [
-        ", ".join(sorted(rule.methods - ignored_methods))  # type: ignore
-        for rule in rules
-    ]
-
-    headers = ("Endpoint", "Methods", "Rule")
-    widths = (
-        max(len(rule.endpoint) for rule in rules),
-        max(len(methods) for methods in rule_methods),
-        max(len(rule.rule) for rule in rules),
-    )
-    widths = [max(len(h), w) for h, w in zip(headers, widths)]
-    row = "{{0:<{0}}}  {{1:<{1}}}  {{2:<{2}}}".format(*widths)
-
-    click.echo(row.format(*headers).strip())
-    click.echo(row.format(*("-" * width for width in widths)))
-
-    for rule, methods in zip(rules, rule_methods):
-        click.echo(row.format(rule.endpoint, methods, rule.rule).rstrip())
-
-
-cli = FlaskGroup(
-    name="flask",
-    help="""\
-A general utility script for Flask applications.
-
-An application to load must be given with the '--app' option,
-'FLASK_APP' environment variable, or with a 'wsgi.py' or 'app.py' file
-in the current directory.
-""",
-)
-
-
-def main() -> None:
-    cli.main()
-
-
-if __name__ == "__main__":
-    main()

+ 0 - 337
venv/lib/python3.10/site-packages/flask/config.py

@@ -1,337 +0,0 @@
-import errno
-import json
-import os
-import types
-import typing as t
-
-from werkzeug.utils import import_string
-
-
-class ConfigAttribute:
-    """Makes an attribute forward to the config"""
-
-    def __init__(self, name: str, get_converter: t.Optional[t.Callable] = None) -> None:
-        self.__name__ = name
-        self.get_converter = get_converter
-
-    def __get__(self, obj: t.Any, owner: t.Any = None) -> t.Any:
-        if obj is None:
-            return self
-        rv = obj.config[self.__name__]
-        if self.get_converter is not None:
-            rv = self.get_converter(rv)
-        return rv
-
-    def __set__(self, obj: t.Any, value: t.Any) -> None:
-        obj.config[self.__name__] = value
-
-
-class Config(dict):
-    """Works exactly like a dict but provides ways to fill it from files
-    or special dictionaries.  There are two common patterns to populate the
-    config.
-
-    Either you can fill the config from a config file::
-
-        app.config.from_pyfile('yourconfig.cfg')
-
-    Or alternatively you can define the configuration options in the
-    module that calls :meth:`from_object` or provide an import path to
-    a module that should be loaded.  It is also possible to tell it to
-    use the same module and with that provide the configuration values
-    just before the call::
-
-        DEBUG = True
-        SECRET_KEY = 'development key'
-        app.config.from_object(__name__)
-
-    In both cases (loading from any Python file or loading from modules),
-    only uppercase keys are added to the config.  This makes it possible to use
-    lowercase values in the config file for temporary values that are not added
-    to the config or to define the config keys in the same file that implements
-    the application.
-
-    Probably the most interesting way to load configurations is from an
-    environment variable pointing to a file::
-
-        app.config.from_envvar('YOURAPPLICATION_SETTINGS')
-
-    In this case before launching the application you have to set this
-    environment variable to the file you want to use.  On Linux and OS X
-    use the export statement::
-
-        export YOURAPPLICATION_SETTINGS='/path/to/config/file'
-
-    On windows use `set` instead.
-
-    :param root_path: path to which files are read relative from.  When the
-                      config object is created by the application, this is
-                      the application's :attr:`~flask.Flask.root_path`.
-    :param defaults: an optional dictionary of default values
-    """
-
-    def __init__(self, root_path: str, defaults: t.Optional[dict] = None) -> None:
-        super().__init__(defaults or {})
-        self.root_path = root_path
-
-    def from_envvar(self, variable_name: str, silent: bool = False) -> bool:
-        """Loads a configuration from an environment variable pointing to
-        a configuration file.  This is basically just a shortcut with nicer
-        error messages for this line of code::
-
-            app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS'])
-
-        :param variable_name: name of the environment variable
-        :param silent: set to ``True`` if you want silent failure for missing
-                       files.
-        :return: ``True`` if the file was loaded successfully.
-        """
-        rv = os.environ.get(variable_name)
-        if not rv:
-            if silent:
-                return False
-            raise RuntimeError(
-                f"The environment variable {variable_name!r} is not set"
-                " and as such configuration could not be loaded. Set"
-                " this variable and make it point to a configuration"
-                " file"
-            )
-        return self.from_pyfile(rv, silent=silent)
-
-    def from_prefixed_env(
-        self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads
-    ) -> bool:
-        """Load any environment variables that start with ``FLASK_``,
-        dropping the prefix from the env key for the config key. Values
-        are passed through a loading function to attempt to convert them
-        to more specific types than strings.
-
-        Keys are loaded in :func:`sorted` order.
-
-        The default loading function attempts to parse values as any
-        valid JSON type, including dicts and lists.
-
-        Specific items in nested dicts can be set by separating the
-        keys with double underscores (``__``). If an intermediate key
-        doesn't exist, it will be initialized to an empty dict.
-
-        :param prefix: Load env vars that start with this prefix,
-            separated with an underscore (``_``).
-        :param loads: Pass each string value to this function and use
-            the returned value as the config value. If any error is
-            raised it is ignored and the value remains a string. The
-            default is :func:`json.loads`.
-
-        .. versionadded:: 2.1
-        """
-        prefix = f"{prefix}_"
-        len_prefix = len(prefix)
-
-        for key in sorted(os.environ):
-            if not key.startswith(prefix):
-                continue
-
-            value = os.environ[key]
-
-            try:
-                value = loads(value)
-            except Exception:
-                # Keep the value as a string if loading failed.
-                pass
-
-            # Change to key.removeprefix(prefix) on Python >= 3.9.
-            key = key[len_prefix:]
-
-            if "__" not in key:
-                # A non-nested key, set directly.
-                self[key] = value
-                continue
-
-            # Traverse nested dictionaries with keys separated by "__".
-            current = self
-            *parts, tail = key.split("__")
-
-            for part in parts:
-                # If an intermediate dict does not exist, create it.
-                if part not in current:
-                    current[part] = {}
-
-                current = current[part]
-
-            current[tail] = value
-
-        return True
-
-    def from_pyfile(self, filename: str, silent: bool = False) -> bool:
-        """Updates the values in the config from a Python file.  This function
-        behaves as if the file was imported as module with the
-        :meth:`from_object` function.
-
-        :param filename: the filename of the config.  This can either be an
-                         absolute filename or a filename relative to the
-                         root path.
-        :param silent: set to ``True`` if you want silent failure for missing
-                       files.
-        :return: ``True`` if the file was loaded successfully.
-
-        .. versionadded:: 0.7
-           `silent` parameter.
-        """
-        filename = os.path.join(self.root_path, filename)
-        d = types.ModuleType("config")
-        d.__file__ = filename
-        try:
-            with open(filename, mode="rb") as config_file:
-                exec(compile(config_file.read(), filename, "exec"), d.__dict__)
-        except OSError as e:
-            if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR):
-                return False
-            e.strerror = f"Unable to load configuration file ({e.strerror})"
-            raise
-        self.from_object(d)
-        return True
-
-    def from_object(self, obj: t.Union[object, str]) -> None:
-        """Updates the values from the given object.  An object can be of one
-        of the following two types:
-
-        -   a string: in this case the object with that name will be imported
-        -   an actual object reference: that object is used directly
-
-        Objects are usually either modules or classes. :meth:`from_object`
-        loads only the uppercase attributes of the module/class. A ``dict``
-        object will not work with :meth:`from_object` because the keys of a
-        ``dict`` are not attributes of the ``dict`` class.
-
-        Example of module-based configuration::
-
-            app.config.from_object('yourapplication.default_config')
-            from yourapplication import default_config
-            app.config.from_object(default_config)
-
-        Nothing is done to the object before loading. If the object is a
-        class and has ``@property`` attributes, it needs to be
-        instantiated before being passed to this method.
-
-        You should not use this function to load the actual configuration but
-        rather configuration defaults.  The actual config should be loaded
-        with :meth:`from_pyfile` and ideally from a location not within the
-        package because the package might be installed system wide.
-
-        See :ref:`config-dev-prod` for an example of class-based configuration
-        using :meth:`from_object`.
-
-        :param obj: an import name or object
-        """
-        if isinstance(obj, str):
-            obj = import_string(obj)
-        for key in dir(obj):
-            if key.isupper():
-                self[key] = getattr(obj, key)
-
-    def from_file(
-        self,
-        filename: str,
-        load: t.Callable[[t.IO[t.Any]], t.Mapping],
-        silent: bool = False,
-    ) -> bool:
-        """Update the values in the config from a file that is loaded
-        using the ``load`` parameter. The loaded data is passed to the
-        :meth:`from_mapping` method.
-
-        .. code-block:: python
-
-            import json
-            app.config.from_file("config.json", load=json.load)
-
-            import toml
-            app.config.from_file("config.toml", load=toml.load)
-
-        :param filename: The path to the data file. This can be an
-            absolute path or relative to the config root path.
-        :param load: A callable that takes a file handle and returns a
-            mapping of loaded data from the file.
-        :type load: ``Callable[[Reader], Mapping]`` where ``Reader``
-            implements a ``read`` method.
-        :param silent: Ignore the file if it doesn't exist.
-        :return: ``True`` if the file was loaded successfully.
-
-        .. versionadded:: 2.0
-        """
-        filename = os.path.join(self.root_path, filename)
-
-        try:
-            with open(filename) as f:
-                obj = load(f)
-        except OSError as e:
-            if silent and e.errno in (errno.ENOENT, errno.EISDIR):
-                return False
-
-            e.strerror = f"Unable to load configuration file ({e.strerror})"
-            raise
-
-        return self.from_mapping(obj)
-
-    def from_mapping(
-        self, mapping: t.Optional[t.Mapping[str, t.Any]] = None, **kwargs: t.Any
-    ) -> bool:
-        """Updates the config like :meth:`update` ignoring items with non-upper
-        keys.
-        :return: Always returns ``True``.
-
-        .. versionadded:: 0.11
-        """
-        mappings: t.Dict[str, t.Any] = {}
-        if mapping is not None:
-            mappings.update(mapping)
-        mappings.update(kwargs)
-        for key, value in mappings.items():
-            if key.isupper():
-                self[key] = value
-        return True
-
-    def get_namespace(
-        self, namespace: str, lowercase: bool = True, trim_namespace: bool = True
-    ) -> t.Dict[str, t.Any]:
-        """Returns a dictionary containing a subset of configuration options
-        that match the specified namespace/prefix. Example usage::
-
-            app.config['IMAGE_STORE_TYPE'] = 'fs'
-            app.config['IMAGE_STORE_PATH'] = '/var/app/images'
-            app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com'
-            image_store_config = app.config.get_namespace('IMAGE_STORE_')
-
-        The resulting dictionary `image_store_config` would look like::
-
-            {
-                'type': 'fs',
-                'path': '/var/app/images',
-                'base_url': 'http://img.website.com'
-            }
-
-        This is often useful when configuration options map directly to
-        keyword arguments in functions or class constructors.
-
-        :param namespace: a configuration namespace
-        :param lowercase: a flag indicating if the keys of the resulting
-                          dictionary should be lowercase
-        :param trim_namespace: a flag indicating if the keys of the resulting
-                          dictionary should not include the namespace
-
-        .. versionadded:: 0.11
-        """
-        rv = {}
-        for k, v in self.items():
-            if not k.startswith(namespace):
-                continue
-            if trim_namespace:
-                key = k[len(namespace) :]
-            else:
-                key = k
-            if lowercase:
-                key = key.lower()
-            rv[key] = v
-        return rv
-
-    def __repr__(self) -> str:
-        return f"<{type(self).__name__} {dict.__repr__(self)}>"

+ 0 - 438
venv/lib/python3.10/site-packages/flask/ctx.py

@@ -1,438 +0,0 @@
-import contextvars
-import sys
-import typing as t
-from functools import update_wrapper
-from types import TracebackType
-
-from werkzeug.exceptions import HTTPException
-
-from . import typing as ft
-from .globals import _cv_app
-from .globals import _cv_request
-from .signals import appcontext_popped
-from .signals import appcontext_pushed
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from .app import Flask
-    from .sessions import SessionMixin
-    from .wrappers import Request
-
-
-# a singleton sentinel value for parameter defaults
-_sentinel = object()
-
-
-class _AppCtxGlobals:
-    """A plain object. Used as a namespace for storing data during an
-    application context.
-
-    Creating an app context automatically creates this object, which is
-    made available as the :data:`g` proxy.
-
-    .. describe:: 'key' in g
-
-        Check whether an attribute is present.
-
-        .. versionadded:: 0.10
-
-    .. describe:: iter(g)
-
-        Return an iterator over the attribute names.
-
-        .. versionadded:: 0.10
-    """
-
-    # Define attr methods to let mypy know this is a namespace object
-    # that has arbitrary attributes.
-
-    def __getattr__(self, name: str) -> t.Any:
-        try:
-            return self.__dict__[name]
-        except KeyError:
-            raise AttributeError(name) from None
-
-    def __setattr__(self, name: str, value: t.Any) -> None:
-        self.__dict__[name] = value
-
-    def __delattr__(self, name: str) -> None:
-        try:
-            del self.__dict__[name]
-        except KeyError:
-            raise AttributeError(name) from None
-
-    def get(self, name: str, default: t.Optional[t.Any] = None) -> t.Any:
-        """Get an attribute by name, or a default value. Like
-        :meth:`dict.get`.
-
-        :param name: Name of attribute to get.
-        :param default: Value to return if the attribute is not present.
-
-        .. versionadded:: 0.10
-        """
-        return self.__dict__.get(name, default)
-
-    def pop(self, name: str, default: t.Any = _sentinel) -> t.Any:
-        """Get and remove an attribute by name. Like :meth:`dict.pop`.
-
-        :param name: Name of attribute to pop.
-        :param default: Value to return if the attribute is not present,
-            instead of raising a ``KeyError``.
-
-        .. versionadded:: 0.11
-        """
-        if default is _sentinel:
-            return self.__dict__.pop(name)
-        else:
-            return self.__dict__.pop(name, default)
-
-    def setdefault(self, name: str, default: t.Any = None) -> t.Any:
-        """Get the value of an attribute if it is present, otherwise
-        set and return a default value. Like :meth:`dict.setdefault`.
-
-        :param name: Name of attribute to get.
-        :param default: Value to set and return if the attribute is not
-            present.
-
-        .. versionadded:: 0.11
-        """
-        return self.__dict__.setdefault(name, default)
-
-    def __contains__(self, item: str) -> bool:
-        return item in self.__dict__
-
-    def __iter__(self) -> t.Iterator[str]:
-        return iter(self.__dict__)
-
-    def __repr__(self) -> str:
-        ctx = _cv_app.get(None)
-        if ctx is not None:
-            return f"<flask.g of '{ctx.app.name}'>"
-        return object.__repr__(self)
-
-
-def after_this_request(f: ft.AfterRequestCallable) -> ft.AfterRequestCallable:
-    """Executes a function after this request.  This is useful to modify
-    response objects.  The function is passed the response object and has
-    to return the same or a new one.
-
-    Example::
-
-        @app.route('/')
-        def index():
-            @after_this_request
-            def add_header(response):
-                response.headers['X-Foo'] = 'Parachute'
-                return response
-            return 'Hello World!'
-
-    This is more useful if a function other than the view function wants to
-    modify a response.  For instance think of a decorator that wants to add
-    some headers without converting the return value into a response object.
-
-    .. versionadded:: 0.9
-    """
-    ctx = _cv_request.get(None)
-
-    if ctx is None:
-        raise RuntimeError(
-            "'after_this_request' can only be used when a request"
-            " context is active, such as in a view function."
-        )
-
-    ctx._after_request_functions.append(f)
-    return f
-
-
-def copy_current_request_context(f: t.Callable) -> t.Callable:
-    """A helper function that decorates a function to retain the current
-    request context.  This is useful when working with greenlets.  The moment
-    the function is decorated a copy of the request context is created and
-    then pushed when the function is called.  The current session is also
-    included in the copied request context.
-
-    Example::
-
-        import gevent
-        from flask import copy_current_request_context
-
-        @app.route('/')
-        def index():
-            @copy_current_request_context
-            def do_some_work():
-                # do some work here, it can access flask.request or
-                # flask.session like you would otherwise in the view function.
-                ...
-            gevent.spawn(do_some_work)
-            return 'Regular response'
-
-    .. versionadded:: 0.10
-    """
-    ctx = _cv_request.get(None)
-
-    if ctx is None:
-        raise RuntimeError(
-            "'copy_current_request_context' can only be used when a"
-            " request context is active, such as in a view function."
-        )
-
-    ctx = ctx.copy()
-
-    def wrapper(*args, **kwargs):
-        with ctx:
-            return ctx.app.ensure_sync(f)(*args, **kwargs)
-
-    return update_wrapper(wrapper, f)
-
-
-def has_request_context() -> bool:
-    """If you have code that wants to test if a request context is there or
-    not this function can be used.  For instance, you may want to take advantage
-    of request information if the request object is available, but fail
-    silently if it is unavailable.
-
-    ::
-
-        class User(db.Model):
-
-            def __init__(self, username, remote_addr=None):
-                self.username = username
-                if remote_addr is None and has_request_context():
-                    remote_addr = request.remote_addr
-                self.remote_addr = remote_addr
-
-    Alternatively you can also just test any of the context bound objects
-    (such as :class:`request` or :class:`g`) for truthness::
-
-        class User(db.Model):
-
-            def __init__(self, username, remote_addr=None):
-                self.username = username
-                if remote_addr is None and request:
-                    remote_addr = request.remote_addr
-                self.remote_addr = remote_addr
-
-    .. versionadded:: 0.7
-    """
-    return _cv_request.get(None) is not None
-
-
-def has_app_context() -> bool:
-    """Works like :func:`has_request_context` but for the application
-    context.  You can also just do a boolean check on the
-    :data:`current_app` object instead.
-
-    .. versionadded:: 0.9
-    """
-    return _cv_app.get(None) is not None
-
-
-class AppContext:
-    """The app context contains application-specific information. An app
-    context is created and pushed at the beginning of each request if
-    one is not already active. An app context is also pushed when
-    running CLI commands.
-    """
-
-    def __init__(self, app: "Flask") -> None:
-        self.app = app
-        self.url_adapter = app.create_url_adapter(None)
-        self.g: _AppCtxGlobals = app.app_ctx_globals_class()
-        self._cv_tokens: t.List[contextvars.Token] = []
-
-    def push(self) -> None:
-        """Binds the app context to the current context."""
-        self._cv_tokens.append(_cv_app.set(self))
-        appcontext_pushed.send(self.app)
-
-    def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None:  # type: ignore
-        """Pops the app context."""
-        try:
-            if len(self._cv_tokens) == 1:
-                if exc is _sentinel:
-                    exc = sys.exc_info()[1]
-                self.app.do_teardown_appcontext(exc)
-        finally:
-            ctx = _cv_app.get()
-            _cv_app.reset(self._cv_tokens.pop())
-
-        if ctx is not self:
-            raise AssertionError(
-                f"Popped wrong app context. ({ctx!r} instead of {self!r})"
-            )
-
-        appcontext_popped.send(self.app)
-
-    def __enter__(self) -> "AppContext":
-        self.push()
-        return self
-
-    def __exit__(
-        self,
-        exc_type: t.Optional[type],
-        exc_value: t.Optional[BaseException],
-        tb: t.Optional[TracebackType],
-    ) -> None:
-        self.pop(exc_value)
-
-
-class RequestContext:
-    """The request context contains per-request information. The Flask
-    app creates and pushes it at the beginning of the request, then pops
-    it at the end of the request. It will create the URL adapter and
-    request object for the WSGI environment provided.
-
-    Do not attempt to use this class directly, instead use
-    :meth:`~flask.Flask.test_request_context` and
-    :meth:`~flask.Flask.request_context` to create this object.
-
-    When the request context is popped, it will evaluate all the
-    functions registered on the application for teardown execution
-    (:meth:`~flask.Flask.teardown_request`).
-
-    The request context is automatically popped at the end of the
-    request. When using the interactive debugger, the context will be
-    restored so ``request`` is still accessible. Similarly, the test
-    client can preserve the context after the request ends. However,
-    teardown functions may already have closed some resources such as
-    database connections.
-    """
-
-    def __init__(
-        self,
-        app: "Flask",
-        environ: dict,
-        request: t.Optional["Request"] = None,
-        session: t.Optional["SessionMixin"] = None,
-    ) -> None:
-        self.app = app
-        if request is None:
-            request = app.request_class(environ)
-            request.json_module = app.json  # type: ignore[misc]
-        self.request: Request = request
-        self.url_adapter = None
-        try:
-            self.url_adapter = app.create_url_adapter(self.request)
-        except HTTPException as e:
-            self.request.routing_exception = e
-        self.flashes: t.Optional[t.List[t.Tuple[str, str]]] = None
-        self.session: t.Optional["SessionMixin"] = session
-        # Functions that should be executed after the request on the response
-        # object.  These will be called before the regular "after_request"
-        # functions.
-        self._after_request_functions: t.List[ft.AfterRequestCallable] = []
-
-        self._cv_tokens: t.List[t.Tuple[contextvars.Token, t.Optional[AppContext]]] = []
-
-    def copy(self) -> "RequestContext":
-        """Creates a copy of this request context with the same request object.
-        This can be used to move a request context to a different greenlet.
-        Because the actual request object is the same this cannot be used to
-        move a request context to a different thread unless access to the
-        request object is locked.
-
-        .. versionadded:: 0.10
-
-        .. versionchanged:: 1.1
-           The current session object is used instead of reloading the original
-           data. This prevents `flask.session` pointing to an out-of-date object.
-        """
-        return self.__class__(
-            self.app,
-            environ=self.request.environ,
-            request=self.request,
-            session=self.session,
-        )
-
-    def match_request(self) -> None:
-        """Can be overridden by a subclass to hook into the matching
-        of the request.
-        """
-        try:
-            result = self.url_adapter.match(return_rule=True)  # type: ignore
-            self.request.url_rule, self.request.view_args = result  # type: ignore
-        except HTTPException as e:
-            self.request.routing_exception = e
-
-    def push(self) -> None:
-        # Before we push the request context we have to ensure that there
-        # is an application context.
-        app_ctx = _cv_app.get(None)
-
-        if app_ctx is None or app_ctx.app is not self.app:
-            app_ctx = self.app.app_context()
-            app_ctx.push()
-        else:
-            app_ctx = None
-
-        self._cv_tokens.append((_cv_request.set(self), app_ctx))
-
-        # Open the session at the moment that the request context is available.
-        # This allows a custom open_session method to use the request context.
-        # Only open a new session if this is the first time the request was
-        # pushed, otherwise stream_with_context loses the session.
-        if self.session is None:
-            session_interface = self.app.session_interface
-            self.session = session_interface.open_session(self.app, self.request)
-
-            if self.session is None:
-                self.session = session_interface.make_null_session(self.app)
-
-        # Match the request URL after loading the session, so that the
-        # session is available in custom URL converters.
-        if self.url_adapter is not None:
-            self.match_request()
-
-    def pop(self, exc: t.Optional[BaseException] = _sentinel) -> None:  # type: ignore
-        """Pops the request context and unbinds it by doing that.  This will
-        also trigger the execution of functions registered by the
-        :meth:`~flask.Flask.teardown_request` decorator.
-
-        .. versionchanged:: 0.9
-           Added the `exc` argument.
-        """
-        clear_request = len(self._cv_tokens) == 1
-
-        try:
-            if clear_request:
-                if exc is _sentinel:
-                    exc = sys.exc_info()[1]
-                self.app.do_teardown_request(exc)
-
-                request_close = getattr(self.request, "close", None)
-                if request_close is not None:
-                    request_close()
-        finally:
-            ctx = _cv_request.get()
-            token, app_ctx = self._cv_tokens.pop()
-            _cv_request.reset(token)
-
-            # get rid of circular dependencies at the end of the request
-            # so that we don't require the GC to be active.
-            if clear_request:
-                ctx.request.environ["werkzeug.request"] = None
-
-            if app_ctx is not None:
-                app_ctx.pop(exc)
-
-            if ctx is not self:
-                raise AssertionError(
-                    f"Popped wrong request context. ({ctx!r} instead of {self!r})"
-                )
-
-    def __enter__(self) -> "RequestContext":
-        self.push()
-        return self
-
-    def __exit__(
-        self,
-        exc_type: t.Optional[type],
-        exc_value: t.Optional[BaseException],
-        tb: t.Optional[TracebackType],
-    ) -> None:
-        self.pop(exc_value)
-
-    def __repr__(self) -> str:
-        return (
-            f"<{type(self).__name__} {self.request.url!r}"
-            f" [{self.request.method}] of {self.app.name}>"
-        )

+ 0 - 158
venv/lib/python3.10/site-packages/flask/debughelpers.py

@@ -1,158 +0,0 @@
-import typing as t
-
-from .app import Flask
-from .blueprints import Blueprint
-from .globals import request_ctx
-
-
-class UnexpectedUnicodeError(AssertionError, UnicodeError):
-    """Raised in places where we want some better error reporting for
-    unexpected unicode or binary data.
-    """
-
-
-class DebugFilesKeyError(KeyError, AssertionError):
-    """Raised from request.files during debugging.  The idea is that it can
-    provide a better error message than just a generic KeyError/BadRequest.
-    """
-
-    def __init__(self, request, key):
-        form_matches = request.form.getlist(key)
-        buf = [
-            f"You tried to access the file {key!r} in the request.files"
-            " dictionary but it does not exist. The mimetype for the"
-            f" request is {request.mimetype!r} instead of"
-            " 'multipart/form-data' which means that no file contents"
-            " were transmitted. To fix this error you should provide"
-            ' enctype="multipart/form-data" in your form.'
-        ]
-        if form_matches:
-            names = ", ".join(repr(x) for x in form_matches)
-            buf.append(
-                "\n\nThe browser instead transmitted some file names. "
-                f"This was submitted: {names}"
-            )
-        self.msg = "".join(buf)
-
-    def __str__(self):
-        return self.msg
-
-
-class FormDataRoutingRedirect(AssertionError):
-    """This exception is raised in debug mode if a routing redirect
-    would cause the browser to drop the method or body. This happens
-    when method is not GET, HEAD or OPTIONS and the status code is not
-    307 or 308.
-    """
-
-    def __init__(self, request):
-        exc = request.routing_exception
-        buf = [
-            f"A request was sent to '{request.url}', but routing issued"
-            f" a redirect to the canonical URL '{exc.new_url}'."
-        ]
-
-        if f"{request.base_url}/" == exc.new_url.partition("?")[0]:
-            buf.append(
-                " The URL was defined with a trailing slash. Flask"
-                " will redirect to the URL with a trailing slash if it"
-                " was accessed without one."
-            )
-
-        buf.append(
-            " Send requests to the canonical URL, or use 307 or 308 for"
-            " routing redirects. Otherwise, browsers will drop form"
-            " data.\n\n"
-            "This exception is only raised in debug mode."
-        )
-        super().__init__("".join(buf))
-
-
-def attach_enctype_error_multidict(request):
-    """Patch ``request.files.__getitem__`` to raise a descriptive error
-    about ``enctype=multipart/form-data``.
-
-    :param request: The request to patch.
-    :meta private:
-    """
-    oldcls = request.files.__class__
-
-    class newcls(oldcls):
-        def __getitem__(self, key):
-            try:
-                return super().__getitem__(key)
-            except KeyError as e:
-                if key not in request.form:
-                    raise
-
-                raise DebugFilesKeyError(request, key).with_traceback(
-                    e.__traceback__
-                ) from None
-
-    newcls.__name__ = oldcls.__name__
-    newcls.__module__ = oldcls.__module__
-    request.files.__class__ = newcls
-
-
-def _dump_loader_info(loader) -> t.Generator:
-    yield f"class: {type(loader).__module__}.{type(loader).__name__}"
-    for key, value in sorted(loader.__dict__.items()):
-        if key.startswith("_"):
-            continue
-        if isinstance(value, (tuple, list)):
-            if not all(isinstance(x, str) for x in value):
-                continue
-            yield f"{key}:"
-            for item in value:
-                yield f"  - {item}"
-            continue
-        elif not isinstance(value, (str, int, float, bool)):
-            continue
-        yield f"{key}: {value!r}"
-
-
-def explain_template_loading_attempts(app: Flask, template, attempts) -> None:
-    """This should help developers understand what failed"""
-    info = [f"Locating template {template!r}:"]
-    total_found = 0
-    blueprint = None
-    if request_ctx and request_ctx.request.blueprint is not None:
-        blueprint = request_ctx.request.blueprint
-
-    for idx, (loader, srcobj, triple) in enumerate(attempts):
-        if isinstance(srcobj, Flask):
-            src_info = f"application {srcobj.import_name!r}"
-        elif isinstance(srcobj, Blueprint):
-            src_info = f"blueprint {srcobj.name!r} ({srcobj.import_name})"
-        else:
-            src_info = repr(srcobj)
-
-        info.append(f"{idx + 1:5}: trying loader of {src_info}")
-
-        for line in _dump_loader_info(loader):
-            info.append(f"       {line}")
-
-        if triple is None:
-            detail = "no match"
-        else:
-            detail = f"found ({triple[1] or '<string>'!r})"
-            total_found += 1
-        info.append(f"       -> {detail}")
-
-    seems_fishy = False
-    if total_found == 0:
-        info.append("Error: the template could not be found.")
-        seems_fishy = True
-    elif total_found > 1:
-        info.append("Warning: multiple loaders returned a match for the template.")
-        seems_fishy = True
-
-    if blueprint is not None and seems_fishy:
-        info.append(
-            "  The template was looked up from an endpoint that belongs"
-            f" to the blueprint {blueprint!r}."
-        )
-        info.append("  Maybe you did not place a template in the right folder?")
-        info.append("  See https://flask.palletsprojects.com/blueprints/#templates")
-
-    app.logger.info("\n".join(info))

+ 0 - 107
venv/lib/python3.10/site-packages/flask/globals.py

@@ -1,107 +0,0 @@
-import typing as t
-from contextvars import ContextVar
-
-from werkzeug.local import LocalProxy
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from .app import Flask
-    from .ctx import _AppCtxGlobals
-    from .ctx import AppContext
-    from .ctx import RequestContext
-    from .sessions import SessionMixin
-    from .wrappers import Request
-
-
-class _FakeStack:
-    def __init__(self, name: str, cv: ContextVar[t.Any]) -> None:
-        self.name = name
-        self.cv = cv
-
-    def _warn(self):
-        import warnings
-
-        warnings.warn(
-            f"'_{self.name}_ctx_stack' is deprecated and will be"
-            " removed in Flask 2.3. Use 'g' to store data, or"
-            f" '{self.name}_ctx' to access the current context.",
-            DeprecationWarning,
-            stacklevel=3,
-        )
-
-    def push(self, obj: t.Any) -> None:
-        self._warn()
-        self.cv.set(obj)
-
-    def pop(self) -> t.Any:
-        self._warn()
-        ctx = self.cv.get(None)
-        self.cv.set(None)
-        return ctx
-
-    @property
-    def top(self) -> t.Optional[t.Any]:
-        self._warn()
-        return self.cv.get(None)
-
-
-_no_app_msg = """\
-Working outside of application context.
-
-This typically means that you attempted to use functionality that needed
-the current application. To solve this, set up an application context
-with app.app_context(). See the documentation for more information.\
-"""
-_cv_app: ContextVar["AppContext"] = ContextVar("flask.app_ctx")
-__app_ctx_stack = _FakeStack("app", _cv_app)
-app_ctx: "AppContext" = LocalProxy(  # type: ignore[assignment]
-    _cv_app, unbound_message=_no_app_msg
-)
-current_app: "Flask" = LocalProxy(  # type: ignore[assignment]
-    _cv_app, "app", unbound_message=_no_app_msg
-)
-g: "_AppCtxGlobals" = LocalProxy(  # type: ignore[assignment]
-    _cv_app, "g", unbound_message=_no_app_msg
-)
-
-_no_req_msg = """\
-Working outside of request context.
-
-This typically means that you attempted to use functionality that needed
-an active HTTP request. Consult the documentation on testing for
-information about how to avoid this problem.\
-"""
-_cv_request: ContextVar["RequestContext"] = ContextVar("flask.request_ctx")
-__request_ctx_stack = _FakeStack("request", _cv_request)
-request_ctx: "RequestContext" = LocalProxy(  # type: ignore[assignment]
-    _cv_request, unbound_message=_no_req_msg
-)
-request: "Request" = LocalProxy(  # type: ignore[assignment]
-    _cv_request, "request", unbound_message=_no_req_msg
-)
-session: "SessionMixin" = LocalProxy(  # type: ignore[assignment]
-    _cv_request, "session", unbound_message=_no_req_msg
-)
-
-
-def __getattr__(name: str) -> t.Any:
-    if name == "_app_ctx_stack":
-        import warnings
-
-        warnings.warn(
-            "'_app_ctx_stack' is deprecated and will be remoevd in Flask 2.3.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return __app_ctx_stack
-
-    if name == "_request_ctx_stack":
-        import warnings
-
-        warnings.warn(
-            "'_request_ctx_stack' is deprecated and will be remoevd in Flask 2.3.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-        return __request_ctx_stack
-
-    raise AttributeError(name)

+ 0 - 705
venv/lib/python3.10/site-packages/flask/helpers.py

@@ -1,705 +0,0 @@
-import os
-import pkgutil
-import socket
-import sys
-import typing as t
-from datetime import datetime
-from functools import lru_cache
-from functools import update_wrapper
-from threading import RLock
-
-import werkzeug.utils
-from werkzeug.exceptions import abort as _wz_abort
-from werkzeug.utils import redirect as _wz_redirect
-
-from .globals import _cv_request
-from .globals import current_app
-from .globals import request
-from .globals import request_ctx
-from .globals import session
-from .signals import message_flashed
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from werkzeug.wrappers import Response as BaseResponse
-    from .wrappers import Response
-    import typing_extensions as te
-
-
-def get_env() -> str:
-    """Get the environment the app is running in, indicated by the
-    :envvar:`FLASK_ENV` environment variable. The default is
-    ``'production'``.
-
-    .. deprecated:: 2.2
-        Will be removed in Flask 2.3.
-    """
-    import warnings
-
-    warnings.warn(
-        "'FLASK_ENV' and 'get_env' are deprecated and will be removed"
-        " in Flask 2.3. Use 'FLASK_DEBUG' instead.",
-        DeprecationWarning,
-        stacklevel=2,
-    )
-    return os.environ.get("FLASK_ENV") or "production"
-
-
-def get_debug_flag() -> bool:
-    """Get whether debug mode should be enabled for the app, indicated by the
-    :envvar:`FLASK_DEBUG` environment variable. The default is ``False``.
-    """
-    val = os.environ.get("FLASK_DEBUG")
-
-    if not val:
-        env = os.environ.get("FLASK_ENV")
-
-        if env is not None:
-            print(
-                "'FLASK_ENV' is deprecated and will not be used in"
-                " Flask 2.3. Use 'FLASK_DEBUG' instead.",
-                file=sys.stderr,
-            )
-            return env == "development"
-
-        return False
-
-    return val.lower() not in {"0", "false", "no"}
-
-
-def get_load_dotenv(default: bool = True) -> bool:
-    """Get whether the user has disabled loading default dotenv files by
-    setting :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load
-    the files.
-
-    :param default: What to return if the env var isn't set.
-    """
-    val = os.environ.get("FLASK_SKIP_DOTENV")
-
-    if not val:
-        return default
-
-    return val.lower() in ("0", "false", "no")
-
-
-def stream_with_context(
-    generator_or_function: t.Union[
-        t.Iterator[t.AnyStr], t.Callable[..., t.Iterator[t.AnyStr]]
-    ]
-) -> t.Iterator[t.AnyStr]:
-    """Request contexts disappear when the response is started on the server.
-    This is done for efficiency reasons and to make it less likely to encounter
-    memory leaks with badly written WSGI middlewares.  The downside is that if
-    you are using streamed responses, the generator cannot access request bound
-    information any more.
-
-    This function however can help you keep the context around for longer::
-
-        from flask import stream_with_context, request, Response
-
-        @app.route('/stream')
-        def streamed_response():
-            @stream_with_context
-            def generate():
-                yield 'Hello '
-                yield request.args['name']
-                yield '!'
-            return Response(generate())
-
-    Alternatively it can also be used around a specific generator::
-
-        from flask import stream_with_context, request, Response
-
-        @app.route('/stream')
-        def streamed_response():
-            def generate():
-                yield 'Hello '
-                yield request.args['name']
-                yield '!'
-            return Response(stream_with_context(generate()))
-
-    .. versionadded:: 0.9
-    """
-    try:
-        gen = iter(generator_or_function)  # type: ignore
-    except TypeError:
-
-        def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any:
-            gen = generator_or_function(*args, **kwargs)  # type: ignore
-            return stream_with_context(gen)
-
-        return update_wrapper(decorator, generator_or_function)  # type: ignore
-
-    def generator() -> t.Generator:
-        ctx = _cv_request.get(None)
-        if ctx is None:
-            raise RuntimeError(
-                "'stream_with_context' can only be used when a request"
-                " context is active, such as in a view function."
-            )
-        with ctx:
-            # Dummy sentinel.  Has to be inside the context block or we're
-            # not actually keeping the context around.
-            yield None
-
-            # The try/finally is here so that if someone passes a WSGI level
-            # iterator in we're still running the cleanup logic.  Generators
-            # don't need that because they are closed on their destruction
-            # automatically.
-            try:
-                yield from gen
-            finally:
-                if hasattr(gen, "close"):
-                    gen.close()  # type: ignore
-
-    # The trick is to start the generator.  Then the code execution runs until
-    # the first dummy None is yielded at which point the context was already
-    # pushed.  This item is discarded.  Then when the iteration continues the
-    # real generator is executed.
-    wrapped_g = generator()
-    next(wrapped_g)
-    return wrapped_g
-
-
-def make_response(*args: t.Any) -> "Response":
-    """Sometimes it is necessary to set additional headers in a view.  Because
-    views do not have to return response objects but can return a value that
-    is converted into a response object by Flask itself, it becomes tricky to
-    add headers to it.  This function can be called instead of using a return
-    and you will get a response object which you can use to attach headers.
-
-    If view looked like this and you want to add a new header::
-
-        def index():
-            return render_template('index.html', foo=42)
-
-    You can now do something like this::
-
-        def index():
-            response = make_response(render_template('index.html', foo=42))
-            response.headers['X-Parachutes'] = 'parachutes are cool'
-            return response
-
-    This function accepts the very same arguments you can return from a
-    view function.  This for example creates a response with a 404 error
-    code::
-
-        response = make_response(render_template('not_found.html'), 404)
-
-    The other use case of this function is to force the return value of a
-    view function into a response which is helpful with view
-    decorators::
-
-        response = make_response(view_function())
-        response.headers['X-Parachutes'] = 'parachutes are cool'
-
-    Internally this function does the following things:
-
-    -   if no arguments are passed, it creates a new response argument
-    -   if one argument is passed, :meth:`flask.Flask.make_response`
-        is invoked with it.
-    -   if more than one argument is passed, the arguments are passed
-        to the :meth:`flask.Flask.make_response` function as tuple.
-
-    .. versionadded:: 0.6
-    """
-    if not args:
-        return current_app.response_class()
-    if len(args) == 1:
-        args = args[0]
-    return current_app.make_response(args)  # type: ignore
-
-
-def url_for(
-    endpoint: str,
-    *,
-    _anchor: t.Optional[str] = None,
-    _method: t.Optional[str] = None,
-    _scheme: t.Optional[str] = None,
-    _external: t.Optional[bool] = None,
-    **values: t.Any,
-) -> str:
-    """Generate a URL to the given endpoint with the given values.
-
-    This requires an active request or application context, and calls
-    :meth:`current_app.url_for() <flask.Flask.url_for>`. See that method
-    for full documentation.
-
-    :param endpoint: The endpoint name associated with the URL to
-        generate. If this starts with a ``.``, the current blueprint
-        name (if any) will be used.
-    :param _anchor: If given, append this as ``#anchor`` to the URL.
-    :param _method: If given, generate the URL associated with this
-        method for the endpoint.
-    :param _scheme: If given, the URL will have this scheme if it is
-        external.
-    :param _external: If given, prefer the URL to be internal (False) or
-        require it to be external (True). External URLs include the
-        scheme and domain. When not in an active request, URLs are
-        external by default.
-    :param values: Values to use for the variable parts of the URL rule.
-        Unknown keys are appended as query string arguments, like
-        ``?a=b&c=d``.
-
-    .. versionchanged:: 2.2
-        Calls ``current_app.url_for``, allowing an app to override the
-        behavior.
-
-    .. versionchanged:: 0.10
-       The ``_scheme`` parameter was added.
-
-    .. versionchanged:: 0.9
-       The ``_anchor`` and ``_method`` parameters were added.
-
-    .. versionchanged:: 0.9
-       Calls ``app.handle_url_build_error`` on build errors.
-    """
-    return current_app.url_for(
-        endpoint,
-        _anchor=_anchor,
-        _method=_method,
-        _scheme=_scheme,
-        _external=_external,
-        **values,
-    )
-
-
-def redirect(
-    location: str, code: int = 302, Response: t.Optional[t.Type["BaseResponse"]] = None
-) -> "BaseResponse":
-    """Create a redirect response object.
-
-    If :data:`~flask.current_app` is available, it will use its
-    :meth:`~flask.Flask.redirect` method, otherwise it will use
-    :func:`werkzeug.utils.redirect`.
-
-    :param location: The URL to redirect to.
-    :param code: The status code for the redirect.
-    :param Response: The response class to use. Not used when
-        ``current_app`` is active, which uses ``app.response_class``.
-
-    .. versionadded:: 2.2
-        Calls ``current_app.redirect`` if available instead of always
-        using Werkzeug's default ``redirect``.
-    """
-    if current_app:
-        return current_app.redirect(location, code=code)
-
-    return _wz_redirect(location, code=code, Response=Response)
-
-
-def abort(  # type: ignore[misc]
-    code: t.Union[int, "BaseResponse"], *args: t.Any, **kwargs: t.Any
-) -> "te.NoReturn":
-    """Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given
-    status code.
-
-    If :data:`~flask.current_app` is available, it will call its
-    :attr:`~flask.Flask.aborter` object, otherwise it will use
-    :func:`werkzeug.exceptions.abort`.
-
-    :param code: The status code for the exception, which must be
-        registered in ``app.aborter``.
-    :param args: Passed to the exception.
-    :param kwargs: Passed to the exception.
-
-    .. versionadded:: 2.2
-        Calls ``current_app.aborter`` if available instead of always
-        using Werkzeug's default ``abort``.
-    """
-    if current_app:
-        current_app.aborter(code, *args, **kwargs)
-
-    _wz_abort(code, *args, **kwargs)
-
-
-def get_template_attribute(template_name: str, attribute: str) -> t.Any:
-    """Loads a macro (or variable) a template exports.  This can be used to
-    invoke a macro from within Python code.  If you for example have a
-    template named :file:`_cider.html` with the following contents:
-
-    .. sourcecode:: html+jinja
-
-       {% macro hello(name) %}Hello {{ name }}!{% endmacro %}
-
-    You can access this from Python code like this::
-
-        hello = get_template_attribute('_cider.html', 'hello')
-        return hello('World')
-
-    .. versionadded:: 0.2
-
-    :param template_name: the name of the template
-    :param attribute: the name of the variable of macro to access
-    """
-    return getattr(current_app.jinja_env.get_template(template_name).module, attribute)
-
-
-def flash(message: str, category: str = "message") -> None:
-    """Flashes a message to the next request.  In order to remove the
-    flashed message from the session and to display it to the user,
-    the template has to call :func:`get_flashed_messages`.
-
-    .. versionchanged:: 0.3
-       `category` parameter added.
-
-    :param message: the message to be flashed.
-    :param category: the category for the message.  The following values
-                     are recommended: ``'message'`` for any kind of message,
-                     ``'error'`` for errors, ``'info'`` for information
-                     messages and ``'warning'`` for warnings.  However any
-                     kind of string can be used as category.
-    """
-    # Original implementation:
-    #
-    #     session.setdefault('_flashes', []).append((category, message))
-    #
-    # This assumed that changes made to mutable structures in the session are
-    # always in sync with the session object, which is not true for session
-    # implementations that use external storage for keeping their keys/values.
-    flashes = session.get("_flashes", [])
-    flashes.append((category, message))
-    session["_flashes"] = flashes
-    message_flashed.send(
-        current_app._get_current_object(),  # type: ignore
-        message=message,
-        category=category,
-    )
-
-
-def get_flashed_messages(
-    with_categories: bool = False, category_filter: t.Iterable[str] = ()
-) -> t.Union[t.List[str], t.List[t.Tuple[str, str]]]:
-    """Pulls all flashed messages from the session and returns them.
-    Further calls in the same request to the function will return
-    the same messages.  By default just the messages are returned,
-    but when `with_categories` is set to ``True``, the return value will
-    be a list of tuples in the form ``(category, message)`` instead.
-
-    Filter the flashed messages to one or more categories by providing those
-    categories in `category_filter`.  This allows rendering categories in
-    separate html blocks.  The `with_categories` and `category_filter`
-    arguments are distinct:
-
-    * `with_categories` controls whether categories are returned with message
-      text (``True`` gives a tuple, where ``False`` gives just the message text).
-    * `category_filter` filters the messages down to only those matching the
-      provided categories.
-
-    See :doc:`/patterns/flashing` for examples.
-
-    .. versionchanged:: 0.3
-       `with_categories` parameter added.
-
-    .. versionchanged:: 0.9
-        `category_filter` parameter added.
-
-    :param with_categories: set to ``True`` to also receive categories.
-    :param category_filter: filter of categories to limit return values.  Only
-                            categories in the list will be returned.
-    """
-    flashes = request_ctx.flashes
-    if flashes is None:
-        flashes = session.pop("_flashes") if "_flashes" in session else []
-        request_ctx.flashes = flashes
-    if category_filter:
-        flashes = list(filter(lambda f: f[0] in category_filter, flashes))
-    if not with_categories:
-        return [x[1] for x in flashes]
-    return flashes
-
-
-def _prepare_send_file_kwargs(**kwargs: t.Any) -> t.Dict[str, t.Any]:
-    if kwargs.get("max_age") is None:
-        kwargs["max_age"] = current_app.get_send_file_max_age
-
-    kwargs.update(
-        environ=request.environ,
-        use_x_sendfile=current_app.config["USE_X_SENDFILE"],
-        response_class=current_app.response_class,
-        _root_path=current_app.root_path,  # type: ignore
-    )
-    return kwargs
-
-
-def send_file(
-    path_or_file: t.Union[os.PathLike, str, t.BinaryIO],
-    mimetype: t.Optional[str] = None,
-    as_attachment: bool = False,
-    download_name: t.Optional[str] = None,
-    conditional: bool = True,
-    etag: t.Union[bool, str] = True,
-    last_modified: t.Optional[t.Union[datetime, int, float]] = None,
-    max_age: t.Optional[
-        t.Union[int, t.Callable[[t.Optional[str]], t.Optional[int]]]
-    ] = None,
-) -> "Response":
-    """Send the contents of a file to the client.
-
-    The first argument can be a file path or a file-like object. Paths
-    are preferred in most cases because Werkzeug can manage the file and
-    get extra information from the path. Passing a file-like object
-    requires that the file is opened in binary mode, and is mostly
-    useful when building a file in memory with :class:`io.BytesIO`.
-
-    Never pass file paths provided by a user. The path is assumed to be
-    trusted, so a user could craft a path to access a file you didn't
-    intend. Use :func:`send_from_directory` to safely serve
-    user-requested paths from within a directory.
-
-    If the WSGI server sets a ``file_wrapper`` in ``environ``, it is
-    used, otherwise Werkzeug's built-in wrapper is used. Alternatively,
-    if the HTTP server supports ``X-Sendfile``, configuring Flask with
-    ``USE_X_SENDFILE = True`` will tell the server to send the given
-    path, which is much more efficient than reading it in Python.
-
-    :param path_or_file: The path to the file to send, relative to the
-        current working directory if a relative path is given.
-        Alternatively, a file-like object opened in binary mode. Make
-        sure the file pointer is seeked to the start of the data.
-    :param mimetype: The MIME type to send for the file. If not
-        provided, it will try to detect it from the file name.
-    :param as_attachment: Indicate to a browser that it should offer to
-        save the file instead of displaying it.
-    :param download_name: The default name browsers will use when saving
-        the file. Defaults to the passed file name.
-    :param conditional: Enable conditional and range responses based on
-        request headers. Requires passing a file path and ``environ``.
-    :param etag: Calculate an ETag for the file, which requires passing
-        a file path. Can also be a string to use instead.
-    :param last_modified: The last modified time to send for the file,
-        in seconds. If not provided, it will try to detect it from the
-        file path.
-    :param max_age: How long the client should cache the file, in
-        seconds. If set, ``Cache-Control`` will be ``public``, otherwise
-        it will be ``no-cache`` to prefer conditional caching.
-
-    .. versionchanged:: 2.0
-        ``download_name`` replaces the ``attachment_filename``
-        parameter. If ``as_attachment=False``, it is passed with
-        ``Content-Disposition: inline`` instead.
-
-    .. versionchanged:: 2.0
-        ``max_age`` replaces the ``cache_timeout`` parameter.
-        ``conditional`` is enabled and ``max_age`` is not set by
-        default.
-
-    .. versionchanged:: 2.0
-        ``etag`` replaces the ``add_etags`` parameter. It can be a
-        string to use instead of generating one.
-
-    .. versionchanged:: 2.0
-        Passing a file-like object that inherits from
-        :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather
-        than sending an empty file.
-
-    .. versionadded:: 2.0
-        Moved the implementation to Werkzeug. This is now a wrapper to
-        pass some Flask-specific arguments.
-
-    .. versionchanged:: 1.1
-        ``filename`` may be a :class:`~os.PathLike` object.
-
-    .. versionchanged:: 1.1
-        Passing a :class:`~io.BytesIO` object supports range requests.
-
-    .. versionchanged:: 1.0.3
-        Filenames are encoded with ASCII instead of Latin-1 for broader
-        compatibility with WSGI servers.
-
-    .. versionchanged:: 1.0
-        UTF-8 filenames as specified in :rfc:`2231` are supported.
-
-    .. versionchanged:: 0.12
-        The filename is no longer automatically inferred from file
-        objects. If you want to use automatic MIME and etag support,
-        pass a filename via ``filename_or_fp`` or
-        ``attachment_filename``.
-
-    .. versionchanged:: 0.12
-        ``attachment_filename`` is preferred over ``filename`` for MIME
-        detection.
-
-    .. versionchanged:: 0.9
-        ``cache_timeout`` defaults to
-        :meth:`Flask.get_send_file_max_age`.
-
-    .. versionchanged:: 0.7
-        MIME guessing and etag support for file-like objects was
-        deprecated because it was unreliable. Pass a filename if you are
-        able to, otherwise attach an etag yourself.
-
-    .. versionchanged:: 0.5
-        The ``add_etags``, ``cache_timeout`` and ``conditional``
-        parameters were added. The default behavior is to add etags.
-
-    .. versionadded:: 0.2
-    """
-    return werkzeug.utils.send_file(  # type: ignore[return-value]
-        **_prepare_send_file_kwargs(
-            path_or_file=path_or_file,
-            environ=request.environ,
-            mimetype=mimetype,
-            as_attachment=as_attachment,
-            download_name=download_name,
-            conditional=conditional,
-            etag=etag,
-            last_modified=last_modified,
-            max_age=max_age,
-        )
-    )
-
-
-def send_from_directory(
-    directory: t.Union[os.PathLike, str],
-    path: t.Union[os.PathLike, str],
-    **kwargs: t.Any,
-) -> "Response":
-    """Send a file from within a directory using :func:`send_file`.
-
-    .. code-block:: python
-
-        @app.route("/uploads/<path:name>")
-        def download_file(name):
-            return send_from_directory(
-                app.config['UPLOAD_FOLDER'], name, as_attachment=True
-            )
-
-    This is a secure way to serve files from a folder, such as static
-    files or uploads. Uses :func:`~werkzeug.security.safe_join` to
-    ensure the path coming from the client is not maliciously crafted to
-    point outside the specified directory.
-
-    If the final path does not point to an existing regular file,
-    raises a 404 :exc:`~werkzeug.exceptions.NotFound` error.
-
-    :param directory: The directory that ``path`` must be located under,
-        relative to the current application's root path.
-    :param path: The path to the file to send, relative to
-        ``directory``.
-    :param kwargs: Arguments to pass to :func:`send_file`.
-
-    .. versionchanged:: 2.0
-        ``path`` replaces the ``filename`` parameter.
-
-    .. versionadded:: 2.0
-        Moved the implementation to Werkzeug. This is now a wrapper to
-        pass some Flask-specific arguments.
-
-    .. versionadded:: 0.5
-    """
-    return werkzeug.utils.send_from_directory(  # type: ignore[return-value]
-        directory, path, **_prepare_send_file_kwargs(**kwargs)
-    )
-
-
-def get_root_path(import_name: str) -> str:
-    """Find the root path of a package, or the path that contains a
-    module. If it cannot be found, returns the current working
-    directory.
-
-    Not to be confused with the value returned by :func:`find_package`.
-
-    :meta private:
-    """
-    # Module already imported and has a file attribute. Use that first.
-    mod = sys.modules.get(import_name)
-
-    if mod is not None and hasattr(mod, "__file__") and mod.__file__ is not None:
-        return os.path.dirname(os.path.abspath(mod.__file__))
-
-    # Next attempt: check the loader.
-    loader = pkgutil.get_loader(import_name)
-
-    # Loader does not exist or we're referring to an unloaded main
-    # module or a main module without path (interactive sessions), go
-    # with the current working directory.
-    if loader is None or import_name == "__main__":
-        return os.getcwd()
-
-    if hasattr(loader, "get_filename"):
-        filepath = loader.get_filename(import_name)  # type: ignore
-    else:
-        # Fall back to imports.
-        __import__(import_name)
-        mod = sys.modules[import_name]
-        filepath = getattr(mod, "__file__", None)
-
-        # If we don't have a file path it might be because it is a
-        # namespace package. In this case pick the root path from the
-        # first module that is contained in the package.
-        if filepath is None:
-            raise RuntimeError(
-                "No root path can be found for the provided module"
-                f" {import_name!r}. This can happen because the module"
-                " came from an import hook that does not provide file"
-                " name information or because it's a namespace package."
-                " In this case the root path needs to be explicitly"
-                " provided."
-            )
-
-    # filepath is import_name.py for a module, or __init__.py for a package.
-    return os.path.dirname(os.path.abspath(filepath))
-
-
-class locked_cached_property(werkzeug.utils.cached_property):
-    """A :func:`property` that is only evaluated once. Like
-    :class:`werkzeug.utils.cached_property` except access uses a lock
-    for thread safety.
-
-    .. versionchanged:: 2.0
-        Inherits from Werkzeug's ``cached_property`` (and ``property``).
-    """
-
-    def __init__(
-        self,
-        fget: t.Callable[[t.Any], t.Any],
-        name: t.Optional[str] = None,
-        doc: t.Optional[str] = None,
-    ) -> None:
-        super().__init__(fget, name=name, doc=doc)
-        self.lock = RLock()
-
-    def __get__(self, obj: object, type: type = None) -> t.Any:  # type: ignore
-        if obj is None:
-            return self
-
-        with self.lock:
-            return super().__get__(obj, type=type)
-
-    def __set__(self, obj: object, value: t.Any) -> None:
-        with self.lock:
-            super().__set__(obj, value)
-
-    def __delete__(self, obj: object) -> None:
-        with self.lock:
-            super().__delete__(obj)
-
-
-def is_ip(value: str) -> bool:
-    """Determine if the given string is an IP address.
-
-    :param value: value to check
-    :type value: str
-
-    :return: True if string is an IP address
-    :rtype: bool
-    """
-    for family in (socket.AF_INET, socket.AF_INET6):
-        try:
-            socket.inet_pton(family, value)
-        except OSError:
-            pass
-        else:
-            return True
-
-    return False
-
-
-@lru_cache(maxsize=None)
-def _split_blueprint_path(name: str) -> t.List[str]:
-    out: t.List[str] = [name]
-
-    if "." in name:
-        out.extend(_split_blueprint_path(name.rpartition(".")[0]))
-
-    return out

+ 0 - 342
venv/lib/python3.10/site-packages/flask/json/__init__.py

@@ -1,342 +0,0 @@
-from __future__ import annotations
-
-import json as _json
-import typing as t
-
-from jinja2.utils import htmlsafe_json_dumps as _jinja_htmlsafe_dumps
-
-from ..globals import current_app
-from .provider import _default
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from ..app import Flask
-    from ..wrappers import Response
-
-
-class JSONEncoder(_json.JSONEncoder):
-    """The default JSON encoder. Handles extra types compared to the
-    built-in :class:`json.JSONEncoder`.
-
-    -   :class:`datetime.datetime` and :class:`datetime.date` are
-        serialized to :rfc:`822` strings. This is the same as the HTTP
-        date format.
-    -   :class:`decimal.Decimal` is serialized to a string.
-    -   :class:`uuid.UUID` is serialized to a string.
-    -   :class:`dataclasses.dataclass` is passed to
-        :func:`dataclasses.asdict`.
-    -   :class:`~markupsafe.Markup` (or any object with a ``__html__``
-        method) will call the ``__html__`` method to get a string.
-
-    Assign a subclass of this to :attr:`flask.Flask.json_encoder` or
-    :attr:`flask.Blueprint.json_encoder` to override the default.
-
-    .. deprecated:: 2.2
-        Will be removed in Flask 2.3. Use ``app.json`` instead.
-    """
-
-    def __init__(self, **kwargs) -> None:
-        import warnings
-
-        warnings.warn(
-            "'JSONEncoder' is deprecated and will be removed in"
-            " Flask 2.3. Use 'Flask.json' to provide an alternate"
-            " JSON implementation instead.",
-            DeprecationWarning,
-            stacklevel=3,
-        )
-        super().__init__(**kwargs)
-
-    def default(self, o: t.Any) -> t.Any:
-        """Convert ``o`` to a JSON serializable type. See
-        :meth:`json.JSONEncoder.default`. Python does not support
-        overriding how basic types like ``str`` or ``list`` are
-        serialized, they are handled before this method.
-        """
-        return _default(o)
-
-
-class JSONDecoder(_json.JSONDecoder):
-    """The default JSON decoder.
-
-    This does not change any behavior from the built-in
-    :class:`json.JSONDecoder`.
-
-    Assign a subclass of this to :attr:`flask.Flask.json_decoder` or
-    :attr:`flask.Blueprint.json_decoder` to override the default.
-
-    .. deprecated:: 2.2
-        Will be removed in Flask 2.3. Use ``app.json`` instead.
-    """
-
-    def __init__(self, **kwargs) -> None:
-        import warnings
-
-        warnings.warn(
-            "'JSONDecoder' is deprecated and will be removed in"
-            " Flask 2.3. Use 'Flask.json' to provide an alternate"
-            " JSON implementation instead.",
-            DeprecationWarning,
-            stacklevel=3,
-        )
-        super().__init__(**kwargs)
-
-
-def dumps(obj: t.Any, *, app: Flask | None = None, **kwargs: t.Any) -> str:
-    """Serialize data as JSON.
-
-    If :data:`~flask.current_app` is available, it will use its
-    :meth:`app.json.dumps() <flask.json.provider.JSONProvider.dumps>`
-    method, otherwise it will use :func:`json.dumps`.
-
-    :param obj: The data to serialize.
-    :param kwargs: Arguments passed to the ``dumps`` implementation.
-
-    .. versionchanged:: 2.2
-        Calls ``current_app.json.dumps``, allowing an app to override
-        the behavior.
-
-    .. versionchanged:: 2.2
-        The ``app`` parameter will be removed in Flask 2.3.
-
-    .. versionchanged:: 2.0.2
-        :class:`decimal.Decimal` is supported by converting to a string.
-
-    .. versionchanged:: 2.0
-        ``encoding`` will be removed in Flask 2.1.
-
-    .. versionchanged:: 1.0.3
-        ``app`` can be passed directly, rather than requiring an app
-        context for configuration.
-    """
-    if app is not None:
-        import warnings
-
-        warnings.warn(
-            "The 'app' parameter is deprecated and will be removed in"
-            " Flask 2.3. Call 'app.json.dumps' directly instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-    else:
-        app = current_app
-
-    if app:
-        return app.json.dumps(obj, **kwargs)
-
-    kwargs.setdefault("default", _default)
-    return _json.dumps(obj, **kwargs)
-
-
-def dump(
-    obj: t.Any, fp: t.IO[str], *, app: Flask | None = None, **kwargs: t.Any
-) -> None:
-    """Serialize data as JSON and write to a file.
-
-    If :data:`~flask.current_app` is available, it will use its
-    :meth:`app.json.dump() <flask.json.provider.JSONProvider.dump>`
-    method, otherwise it will use :func:`json.dump`.
-
-    :param obj: The data to serialize.
-    :param fp: A file opened for writing text. Should use the UTF-8
-        encoding to be valid JSON.
-    :param kwargs: Arguments passed to the ``dump`` implementation.
-
-    .. versionchanged:: 2.2
-        Calls ``current_app.json.dump``, allowing an app to override
-        the behavior.
-
-    .. versionchanged:: 2.2
-        The ``app`` parameter will be removed in Flask 2.3.
-
-    .. versionchanged:: 2.0
-        Writing to a binary file, and the ``encoding`` argument, will be
-        removed in Flask 2.1.
-    """
-    if app is not None:
-        import warnings
-
-        warnings.warn(
-            "The 'app' parameter is deprecated and will be removed in"
-            " Flask 2.3. Call 'app.json.dump' directly instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-    else:
-        app = current_app
-
-    if app:
-        app.json.dump(obj, fp, **kwargs)
-    else:
-        kwargs.setdefault("default", _default)
-        _json.dump(obj, fp, **kwargs)
-
-
-def loads(s: str | bytes, *, app: Flask | None = None, **kwargs: t.Any) -> t.Any:
-    """Deserialize data as JSON.
-
-    If :data:`~flask.current_app` is available, it will use its
-    :meth:`app.json.loads() <flask.json.provider.JSONProvider.loads>`
-    method, otherwise it will use :func:`json.loads`.
-
-    :param s: Text or UTF-8 bytes.
-    :param kwargs: Arguments passed to the ``loads`` implementation.
-
-    .. versionchanged:: 2.2
-        Calls ``current_app.json.loads``, allowing an app to override
-        the behavior.
-
-    .. versionchanged:: 2.2
-        The ``app`` parameter will be removed in Flask 2.3.
-
-    .. versionchanged:: 2.0
-        ``encoding`` will be removed in Flask 2.1. The data must be a
-        string or UTF-8 bytes.
-
-    .. versionchanged:: 1.0.3
-        ``app`` can be passed directly, rather than requiring an app
-        context for configuration.
-    """
-    if app is not None:
-        import warnings
-
-        warnings.warn(
-            "The 'app' parameter is deprecated and will be removed in"
-            " Flask 2.3. Call 'app.json.loads' directly instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-    else:
-        app = current_app
-
-    if app:
-        return app.json.loads(s, **kwargs)
-
-    return _json.loads(s, **kwargs)
-
-
-def load(fp: t.IO[t.AnyStr], *, app: Flask | None = None, **kwargs: t.Any) -> t.Any:
-    """Deserialize data as JSON read from a file.
-
-    If :data:`~flask.current_app` is available, it will use its
-    :meth:`app.json.load() <flask.json.provider.JSONProvider.load>`
-    method, otherwise it will use :func:`json.load`.
-
-    :param fp: A file opened for reading text or UTF-8 bytes.
-    :param kwargs: Arguments passed to the ``load`` implementation.
-
-    .. versionchanged:: 2.2
-        Calls ``current_app.json.load``, allowing an app to override
-        the behavior.
-
-    .. versionchanged:: 2.2
-        The ``app`` parameter will be removed in Flask 2.3.
-
-    .. versionchanged:: 2.0
-        ``encoding`` will be removed in Flask 2.1. The file must be text
-        mode, or binary mode with UTF-8 bytes.
-    """
-    if app is not None:
-        import warnings
-
-        warnings.warn(
-            "The 'app' parameter is deprecated and will be removed in"
-            " Flask 2.3. Call 'app.json.load' directly instead.",
-            DeprecationWarning,
-            stacklevel=2,
-        )
-    else:
-        app = current_app
-
-    if app:
-        return app.json.load(fp, **kwargs)
-
-    return _json.load(fp, **kwargs)
-
-
-def htmlsafe_dumps(obj: t.Any, **kwargs: t.Any) -> str:
-    """Serialize an object to a string of JSON with :func:`dumps`, then
-    replace HTML-unsafe characters with Unicode escapes and mark the
-    result safe with :class:`~markupsafe.Markup`.
-
-    This is available in templates as the ``|tojson`` filter.
-
-    The returned string is safe to render in HTML documents and
-    ``<script>`` tags. The exception is in HTML attributes that are
-    double quoted; either use single quotes or the ``|forceescape``
-    filter.
-
-    .. deprecated:: 2.2
-        Will be removed in Flask 2.3. This is built-in to Jinja now.
-
-    .. versionchanged:: 2.0
-        Uses :func:`jinja2.utils.htmlsafe_json_dumps`. The returned
-        value is marked safe by wrapping in :class:`~markupsafe.Markup`.
-
-    .. versionchanged:: 0.10
-        Single quotes are escaped, making this safe to use in HTML,
-        ``<script>`` tags, and single-quoted attributes without further
-        escaping.
-    """
-    import warnings
-
-    warnings.warn(
-        "'htmlsafe_dumps' is deprecated and will be removed in Flask"
-        " 2.3. Use 'jinja2.utils.htmlsafe_json_dumps' instead.",
-        DeprecationWarning,
-        stacklevel=2,
-    )
-    return _jinja_htmlsafe_dumps(obj, dumps=dumps, **kwargs)
-
-
-def htmlsafe_dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None:
-    """Serialize an object to JSON written to a file object, replacing
-    HTML-unsafe characters with Unicode escapes. See
-    :func:`htmlsafe_dumps` and :func:`dumps`.
-
-    .. deprecated:: 2.2
-        Will be removed in Flask 2.3.
-    """
-    import warnings
-
-    warnings.warn(
-        "'htmlsafe_dump' is deprecated and will be removed in Flask"
-        " 2.3. Use 'jinja2.utils.htmlsafe_json_dumps' instead.",
-        DeprecationWarning,
-        stacklevel=2,
-    )
-    fp.write(htmlsafe_dumps(obj, **kwargs))
-
-
-def jsonify(*args: t.Any, **kwargs: t.Any) -> Response:
-    """Serialize the given arguments as JSON, and return a
-    :class:`~flask.Response` object with the ``application/json``
-    mimetype. A dict or list returned from a view will be converted to a
-    JSON response automatically without needing to call this.
-
-    This requires an active request or application context, and calls
-    :meth:`app.json.response() <flask.json.provider.JSONProvider.response>`.
-
-    In debug mode, the output is formatted with indentation to make it
-    easier to read. This may also be controlled by the provider.
-
-    Either positional or keyword arguments can be given, not both.
-    If no arguments are given, ``None`` is serialized.
-
-    :param args: A single value to serialize, or multiple values to
-        treat as a list to serialize.
-    :param kwargs: Treat as a dict to serialize.
-
-    .. versionchanged:: 2.2
-        Calls ``current_app.json.response``, allowing an app to override
-        the behavior.
-
-    .. versionchanged:: 2.0.2
-        :class:`decimal.Decimal` is supported by converting to a string.
-
-    .. versionchanged:: 0.11
-        Added support for serializing top-level arrays. This was a
-        security risk in ancient browsers. See :ref:`security-json`.
-
-    .. versionadded:: 0.2
-    """
-    return current_app.json.response(*args, **kwargs)

+ 0 - 310
venv/lib/python3.10/site-packages/flask/json/provider.py

@@ -1,310 +0,0 @@
-from __future__ import annotations
-
-import dataclasses
-import decimal
-import json
-import typing as t
-import uuid
-import weakref
-from datetime import date
-
-from werkzeug.http import http_date
-
-from ..globals import request
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from ..app import Flask
-    from ..wrappers import Response
-
-
-class JSONProvider:
-    """A standard set of JSON operations for an application. Subclasses
-    of this can be used to customize JSON behavior or use different
-    JSON libraries.
-
-    To implement a provider for a specific library, subclass this base
-    class and implement at least :meth:`dumps` and :meth:`loads`. All
-    other methods have default implementations.
-
-    To use a different provider, either subclass ``Flask`` and set
-    :attr:`~flask.Flask.json_provider_class` to a provider class, or set
-    :attr:`app.json <flask.Flask.json>` to an instance of the class.
-
-    :param app: An application instance. This will be stored as a
-        :class:`weakref.proxy` on the :attr:`_app` attribute.
-
-    .. versionadded:: 2.2
-    """
-
-    def __init__(self, app: Flask) -> None:
-        self._app = weakref.proxy(app)
-
-    def dumps(self, obj: t.Any, **kwargs: t.Any) -> str:
-        """Serialize data as JSON.
-
-        :param obj: The data to serialize.
-        :param kwargs: May be passed to the underlying JSON library.
-        """
-        raise NotImplementedError
-
-    def dump(self, obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None:
-        """Serialize data as JSON and write to a file.
-
-        :param obj: The data to serialize.
-        :param fp: A file opened for writing text. Should use the UTF-8
-            encoding to be valid JSON.
-        :param kwargs: May be passed to the underlying JSON library.
-        """
-        fp.write(self.dumps(obj, **kwargs))
-
-    def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any:
-        """Deserialize data as JSON.
-
-        :param s: Text or UTF-8 bytes.
-        :param kwargs: May be passed to the underlying JSON library.
-        """
-        raise NotImplementedError
-
-    def load(self, fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any:
-        """Deserialize data as JSON read from a file.
-
-        :param fp: A file opened for reading text or UTF-8 bytes.
-        :param kwargs: May be passed to the underlying JSON library.
-        """
-        return self.loads(fp.read(), **kwargs)
-
-    def _prepare_response_obj(
-        self, args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any]
-    ) -> t.Any:
-        if args and kwargs:
-            raise TypeError("app.json.response() takes either args or kwargs, not both")
-
-        if not args and not kwargs:
-            return None
-
-        if len(args) == 1:
-            return args[0]
-
-        return args or kwargs
-
-    def response(self, *args: t.Any, **kwargs: t.Any) -> Response:
-        """Serialize the given arguments as JSON, and return a
-        :class:`~flask.Response` object with the ``application/json``
-        mimetype.
-
-        The :func:`~flask.json.jsonify` function calls this method for
-        the current application.
-
-        Either positional or keyword arguments can be given, not both.
-        If no arguments are given, ``None`` is serialized.
-
-        :param args: A single value to serialize, or multiple values to
-            treat as a list to serialize.
-        :param kwargs: Treat as a dict to serialize.
-        """
-        obj = self._prepare_response_obj(args, kwargs)
-        return self._app.response_class(self.dumps(obj), mimetype="application/json")
-
-
-def _default(o: t.Any) -> t.Any:
-    if isinstance(o, date):
-        return http_date(o)
-
-    if isinstance(o, (decimal.Decimal, uuid.UUID)):
-        return str(o)
-
-    if dataclasses and dataclasses.is_dataclass(o):
-        return dataclasses.asdict(o)
-
-    if hasattr(o, "__html__"):
-        return str(o.__html__())
-
-    raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable")
-
-
-class DefaultJSONProvider(JSONProvider):
-    """Provide JSON operations using Python's built-in :mod:`json`
-    library. Serializes the following additional data types:
-
-    -   :class:`datetime.datetime` and :class:`datetime.date` are
-        serialized to :rfc:`822` strings. This is the same as the HTTP
-        date format.
-    -   :class:`uuid.UUID` is serialized to a string.
-    -   :class:`dataclasses.dataclass` is passed to
-        :func:`dataclasses.asdict`.
-    -   :class:`~markupsafe.Markup` (or any object with a ``__html__``
-        method) will call the ``__html__`` method to get a string.
-    """
-
-    default: t.Callable[[t.Any], t.Any] = staticmethod(
-        _default
-    )  # type: ignore[assignment]
-    """Apply this function to any object that :meth:`json.dumps` does
-    not know how to serialize. It should return a valid JSON type or
-    raise a ``TypeError``.
-    """
-
-    ensure_ascii = True
-    """Replace non-ASCII characters with escape sequences. This may be
-    more compatible with some clients, but can be disabled for better
-    performance and size.
-    """
-
-    sort_keys = True
-    """Sort the keys in any serialized dicts. This may be useful for
-    some caching situations, but can be disabled for better performance.
-    When enabled, keys must all be strings, they are not converted
-    before sorting.
-    """
-
-    compact: bool | None = None
-    """If ``True``, or ``None`` out of debug mode, the :meth:`response`
-    output will not add indentation, newlines, or spaces. If ``False``,
-    or ``None`` in debug mode, it will use a non-compact representation.
-    """
-
-    mimetype = "application/json"
-    """The mimetype set in :meth:`response`."""
-
-    def dumps(self, obj: t.Any, **kwargs: t.Any) -> str:
-        """Serialize data as JSON to a string.
-
-        Keyword arguments are passed to :func:`json.dumps`. Sets some
-        parameter defaults from the :attr:`default`,
-        :attr:`ensure_ascii`, and :attr:`sort_keys` attributes.
-
-        :param obj: The data to serialize.
-        :param kwargs: Passed to :func:`json.dumps`.
-        """
-        cls = self._app._json_encoder
-        bp = self._app.blueprints.get(request.blueprint) if request else None
-
-        if bp is not None and bp._json_encoder is not None:
-            cls = bp._json_encoder
-
-        if cls is not None:
-            import warnings
-
-            warnings.warn(
-                "Setting 'json_encoder' on the app or a blueprint is"
-                " deprecated and will be removed in Flask 2.3."
-                " Customize 'app.json' instead.",
-                DeprecationWarning,
-            )
-            kwargs.setdefault("cls", cls)
-
-            if "default" not in cls.__dict__:
-                kwargs.setdefault("default", self.default)
-        else:
-            kwargs.setdefault("default", self.default)
-
-        ensure_ascii = self._app.config["JSON_AS_ASCII"]
-        sort_keys = self._app.config["JSON_SORT_KEYS"]
-
-        if ensure_ascii is not None:
-            import warnings
-
-            warnings.warn(
-                "The 'JSON_AS_ASCII' config key is deprecated and will"
-                " be removed in Flask 2.3. Set 'app.json.ensure_ascii'"
-                " instead.",
-                DeprecationWarning,
-            )
-        else:
-            ensure_ascii = self.ensure_ascii
-
-        if sort_keys is not None:
-            import warnings
-
-            warnings.warn(
-                "The 'JSON_SORT_KEYS' config key is deprecated and will"
-                " be removed in Flask 2.3. Set 'app.json.sort_keys'"
-                " instead.",
-                DeprecationWarning,
-            )
-        else:
-            sort_keys = self.sort_keys
-
-        kwargs.setdefault("ensure_ascii", ensure_ascii)
-        kwargs.setdefault("sort_keys", sort_keys)
-        return json.dumps(obj, **kwargs)
-
-    def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any:
-        """Deserialize data as JSON from a string or bytes.
-
-        :param s: Text or UTF-8 bytes.
-        :param kwargs: Passed to :func:`json.loads`.
-        """
-        cls = self._app._json_decoder
-        bp = self._app.blueprints.get(request.blueprint) if request else None
-
-        if bp is not None and bp._json_decoder is not None:
-            cls = bp._json_decoder
-
-        if cls is not None:
-            import warnings
-
-            warnings.warn(
-                "Setting 'json_decoder' on the app or a blueprint is"
-                " deprecated and will be removed in Flask 2.3."
-                " Customize 'app.json' instead.",
-                DeprecationWarning,
-            )
-            kwargs.setdefault("cls", cls)
-
-        return json.loads(s, **kwargs)
-
-    def response(self, *args: t.Any, **kwargs: t.Any) -> Response:
-        """Serialize the given arguments as JSON, and return a
-        :class:`~flask.Response` object with it. The response mimetype
-        will be "application/json" and can be changed with
-        :attr:`mimetype`.
-
-        If :attr:`compact` is ``False`` or debug mode is enabled, the
-        output will be formatted to be easier to read.
-
-        Either positional or keyword arguments can be given, not both.
-        If no arguments are given, ``None`` is serialized.
-
-        :param args: A single value to serialize, or multiple values to
-            treat as a list to serialize.
-        :param kwargs: Treat as a dict to serialize.
-        """
-        obj = self._prepare_response_obj(args, kwargs)
-        dump_args: t.Dict[str, t.Any] = {}
-        pretty = self._app.config["JSONIFY_PRETTYPRINT_REGULAR"]
-        mimetype = self._app.config["JSONIFY_MIMETYPE"]
-
-        if pretty is not None:
-            import warnings
-
-            warnings.warn(
-                "The 'JSONIFY_PRETTYPRINT_REGULAR' config key is"
-                " deprecated and will be removed in Flask 2.3. Set"
-                " 'app.json.compact' instead.",
-                DeprecationWarning,
-            )
-            compact: bool | None = not pretty
-        else:
-            compact = self.compact
-
-        if (compact is None and self._app.debug) or compact is False:
-            dump_args.setdefault("indent", 2)
-        else:
-            dump_args.setdefault("separators", (",", ":"))
-
-        if mimetype is not None:
-            import warnings
-
-            warnings.warn(
-                "The 'JSONIFY_MIMETYPE' config key is deprecated and"
-                " will be removed in Flask 2.3. Set 'app.json.mimetype'"
-                " instead.",
-                DeprecationWarning,
-            )
-        else:
-            mimetype = self.mimetype
-
-        return self._app.response_class(
-            f"{self.dumps(obj, **dump_args)}\n", mimetype=mimetype
-        )

+ 0 - 312
venv/lib/python3.10/site-packages/flask/json/tag.py

@@ -1,312 +0,0 @@
-"""
-Tagged JSON
-~~~~~~~~~~~
-
-A compact representation for lossless serialization of non-standard JSON
-types. :class:`~flask.sessions.SecureCookieSessionInterface` uses this
-to serialize the session data, but it may be useful in other places. It
-can be extended to support other types.
-
-.. autoclass:: TaggedJSONSerializer
-    :members:
-
-.. autoclass:: JSONTag
-    :members:
-
-Let's see an example that adds support for
-:class:`~collections.OrderedDict`. Dicts don't have an order in JSON, so
-to handle this we will dump the items as a list of ``[key, value]``
-pairs. Subclass :class:`JSONTag` and give it the new key ``' od'`` to
-identify the type. The session serializer processes dicts first, so
-insert the new tag at the front of the order since ``OrderedDict`` must
-be processed before ``dict``.
-
-.. code-block:: python
-
-    from flask.json.tag import JSONTag
-
-    class TagOrderedDict(JSONTag):
-        __slots__ = ('serializer',)
-        key = ' od'
-
-        def check(self, value):
-            return isinstance(value, OrderedDict)
-
-        def to_json(self, value):
-            return [[k, self.serializer.tag(v)] for k, v in iteritems(value)]
-
-        def to_python(self, value):
-            return OrderedDict(value)
-
-    app.session_interface.serializer.register(TagOrderedDict, index=0)
-"""
-import typing as t
-from base64 import b64decode
-from base64 import b64encode
-from datetime import datetime
-from uuid import UUID
-
-from markupsafe import Markup
-from werkzeug.http import http_date
-from werkzeug.http import parse_date
-
-from ..json import dumps
-from ..json import loads
-
-
-class JSONTag:
-    """Base class for defining type tags for :class:`TaggedJSONSerializer`."""
-
-    __slots__ = ("serializer",)
-
-    #: The tag to mark the serialized object with. If ``None``, this tag is
-    #: only used as an intermediate step during tagging.
-    key: t.Optional[str] = None
-
-    def __init__(self, serializer: "TaggedJSONSerializer") -> None:
-        """Create a tagger for the given serializer."""
-        self.serializer = serializer
-
-    def check(self, value: t.Any) -> bool:
-        """Check if the given value should be tagged by this tag."""
-        raise NotImplementedError
-
-    def to_json(self, value: t.Any) -> t.Any:
-        """Convert the Python object to an object that is a valid JSON type.
-        The tag will be added later."""
-        raise NotImplementedError
-
-    def to_python(self, value: t.Any) -> t.Any:
-        """Convert the JSON representation back to the correct type. The tag
-        will already be removed."""
-        raise NotImplementedError
-
-    def tag(self, value: t.Any) -> t.Any:
-        """Convert the value to a valid JSON type and add the tag structure
-        around it."""
-        return {self.key: self.to_json(value)}
-
-
-class TagDict(JSONTag):
-    """Tag for 1-item dicts whose only key matches a registered tag.
-
-    Internally, the dict key is suffixed with `__`, and the suffix is removed
-    when deserializing.
-    """
-
-    __slots__ = ()
-    key = " di"
-
-    def check(self, value: t.Any) -> bool:
-        return (
-            isinstance(value, dict)
-            and len(value) == 1
-            and next(iter(value)) in self.serializer.tags
-        )
-
-    def to_json(self, value: t.Any) -> t.Any:
-        key = next(iter(value))
-        return {f"{key}__": self.serializer.tag(value[key])}
-
-    def to_python(self, value: t.Any) -> t.Any:
-        key = next(iter(value))
-        return {key[:-2]: value[key]}
-
-
-class PassDict(JSONTag):
-    __slots__ = ()
-
-    def check(self, value: t.Any) -> bool:
-        return isinstance(value, dict)
-
-    def to_json(self, value: t.Any) -> t.Any:
-        # JSON objects may only have string keys, so don't bother tagging the
-        # key here.
-        return {k: self.serializer.tag(v) for k, v in value.items()}
-
-    tag = to_json
-
-
-class TagTuple(JSONTag):
-    __slots__ = ()
-    key = " t"
-
-    def check(self, value: t.Any) -> bool:
-        return isinstance(value, tuple)
-
-    def to_json(self, value: t.Any) -> t.Any:
-        return [self.serializer.tag(item) for item in value]
-
-    def to_python(self, value: t.Any) -> t.Any:
-        return tuple(value)
-
-
-class PassList(JSONTag):
-    __slots__ = ()
-
-    def check(self, value: t.Any) -> bool:
-        return isinstance(value, list)
-
-    def to_json(self, value: t.Any) -> t.Any:
-        return [self.serializer.tag(item) for item in value]
-
-    tag = to_json
-
-
-class TagBytes(JSONTag):
-    __slots__ = ()
-    key = " b"
-
-    def check(self, value: t.Any) -> bool:
-        return isinstance(value, bytes)
-
-    def to_json(self, value: t.Any) -> t.Any:
-        return b64encode(value).decode("ascii")
-
-    def to_python(self, value: t.Any) -> t.Any:
-        return b64decode(value)
-
-
-class TagMarkup(JSONTag):
-    """Serialize anything matching the :class:`~markupsafe.Markup` API by
-    having a ``__html__`` method to the result of that method. Always
-    deserializes to an instance of :class:`~markupsafe.Markup`."""
-
-    __slots__ = ()
-    key = " m"
-
-    def check(self, value: t.Any) -> bool:
-        return callable(getattr(value, "__html__", None))
-
-    def to_json(self, value: t.Any) -> t.Any:
-        return str(value.__html__())
-
-    def to_python(self, value: t.Any) -> t.Any:
-        return Markup(value)
-
-
-class TagUUID(JSONTag):
-    __slots__ = ()
-    key = " u"
-
-    def check(self, value: t.Any) -> bool:
-        return isinstance(value, UUID)
-
-    def to_json(self, value: t.Any) -> t.Any:
-        return value.hex
-
-    def to_python(self, value: t.Any) -> t.Any:
-        return UUID(value)
-
-
-class TagDateTime(JSONTag):
-    __slots__ = ()
-    key = " d"
-
-    def check(self, value: t.Any) -> bool:
-        return isinstance(value, datetime)
-
-    def to_json(self, value: t.Any) -> t.Any:
-        return http_date(value)
-
-    def to_python(self, value: t.Any) -> t.Any:
-        return parse_date(value)
-
-
-class TaggedJSONSerializer:
-    """Serializer that uses a tag system to compactly represent objects that
-    are not JSON types. Passed as the intermediate serializer to
-    :class:`itsdangerous.Serializer`.
-
-    The following extra types are supported:
-
-    * :class:`dict`
-    * :class:`tuple`
-    * :class:`bytes`
-    * :class:`~markupsafe.Markup`
-    * :class:`~uuid.UUID`
-    * :class:`~datetime.datetime`
-    """
-
-    __slots__ = ("tags", "order")
-
-    #: Tag classes to bind when creating the serializer. Other tags can be
-    #: added later using :meth:`~register`.
-    default_tags = [
-        TagDict,
-        PassDict,
-        TagTuple,
-        PassList,
-        TagBytes,
-        TagMarkup,
-        TagUUID,
-        TagDateTime,
-    ]
-
-    def __init__(self) -> None:
-        self.tags: t.Dict[str, JSONTag] = {}
-        self.order: t.List[JSONTag] = []
-
-        for cls in self.default_tags:
-            self.register(cls)
-
-    def register(
-        self,
-        tag_class: t.Type[JSONTag],
-        force: bool = False,
-        index: t.Optional[int] = None,
-    ) -> None:
-        """Register a new tag with this serializer.
-
-        :param tag_class: tag class to register. Will be instantiated with this
-            serializer instance.
-        :param force: overwrite an existing tag. If false (default), a
-            :exc:`KeyError` is raised.
-        :param index: index to insert the new tag in the tag order. Useful when
-            the new tag is a special case of an existing tag. If ``None``
-            (default), the tag is appended to the end of the order.
-
-        :raise KeyError: if the tag key is already registered and ``force`` is
-            not true.
-        """
-        tag = tag_class(self)
-        key = tag.key
-
-        if key is not None:
-            if not force and key in self.tags:
-                raise KeyError(f"Tag '{key}' is already registered.")
-
-            self.tags[key] = tag
-
-        if index is None:
-            self.order.append(tag)
-        else:
-            self.order.insert(index, tag)
-
-    def tag(self, value: t.Any) -> t.Dict[str, t.Any]:
-        """Convert a value to a tagged representation if necessary."""
-        for tag in self.order:
-            if tag.check(value):
-                return tag.tag(value)
-
-        return value
-
-    def untag(self, value: t.Dict[str, t.Any]) -> t.Any:
-        """Convert a tagged representation back to the original type."""
-        if len(value) != 1:
-            return value
-
-        key = next(iter(value))
-
-        if key not in self.tags:
-            return value
-
-        return self.tags[key].to_python(value[key])
-
-    def dumps(self, value: t.Any) -> str:
-        """Tag the value and dump it to a compact JSON string."""
-        return dumps(self.tag(value), separators=(",", ":"))
-
-    def loads(self, value: str) -> t.Any:
-        """Load data from a JSON string and deserialized any tagged objects."""
-        return loads(value, object_hook=self.untag)

+ 0 - 74
venv/lib/python3.10/site-packages/flask/logging.py

@@ -1,74 +0,0 @@
-import logging
-import sys
-import typing as t
-
-from werkzeug.local import LocalProxy
-
-from .globals import request
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from .app import Flask
-
-
-@LocalProxy
-def wsgi_errors_stream() -> t.TextIO:
-    """Find the most appropriate error stream for the application. If a request
-    is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``.
-
-    If you configure your own :class:`logging.StreamHandler`, you may want to
-    use this for the stream. If you are using file or dict configuration and
-    can't import this directly, you can refer to it as
-    ``ext://flask.logging.wsgi_errors_stream``.
-    """
-    return request.environ["wsgi.errors"] if request else sys.stderr
-
-
-def has_level_handler(logger: logging.Logger) -> bool:
-    """Check if there is a handler in the logging chain that will handle the
-    given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`.
-    """
-    level = logger.getEffectiveLevel()
-    current = logger
-
-    while current:
-        if any(handler.level <= level for handler in current.handlers):
-            return True
-
-        if not current.propagate:
-            break
-
-        current = current.parent  # type: ignore
-
-    return False
-
-
-#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format
-#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``.
-default_handler = logging.StreamHandler(wsgi_errors_stream)  # type: ignore
-default_handler.setFormatter(
-    logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")
-)
-
-
-def create_logger(app: "Flask") -> logging.Logger:
-    """Get the Flask app's logger and configure it if needed.
-
-    The logger name will be the same as
-    :attr:`app.import_name <flask.Flask.name>`.
-
-    When :attr:`~flask.Flask.debug` is enabled, set the logger level to
-    :data:`logging.DEBUG` if it is not set.
-
-    If there is no handler for the logger's effective level, add a
-    :class:`~logging.StreamHandler` for
-    :func:`~flask.logging.wsgi_errors_stream` with a basic format.
-    """
-    logger = logging.getLogger(app.name)
-
-    if app.debug and not logger.level:
-        logger.setLevel(logging.DEBUG)
-
-    if not has_level_handler(logger):
-        logger.addHandler(default_handler)
-
-    return logger

+ 0 - 0
venv/lib/python3.10/site-packages/flask/py.typed


+ 0 - 898
venv/lib/python3.10/site-packages/flask/scaffold.py

@@ -1,898 +0,0 @@
-import importlib.util
-import json
-import os
-import pathlib
-import pkgutil
-import sys
-import typing as t
-from collections import defaultdict
-from datetime import timedelta
-from functools import update_wrapper
-
-from jinja2 import FileSystemLoader
-from werkzeug.exceptions import default_exceptions
-from werkzeug.exceptions import HTTPException
-
-from . import typing as ft
-from .cli import AppGroup
-from .globals import current_app
-from .helpers import get_root_path
-from .helpers import locked_cached_property
-from .helpers import send_from_directory
-from .templating import _default_template_ctx_processor
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from .wrappers import Response
-
-# a singleton sentinel value for parameter defaults
-_sentinel = object()
-
-F = t.TypeVar("F", bound=t.Callable[..., t.Any])
-T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable)
-T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable)
-T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable)
-T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable)
-T_template_context_processor = t.TypeVar(
-    "T_template_context_processor", bound=ft.TemplateContextProcessorCallable
-)
-T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable)
-T_url_value_preprocessor = t.TypeVar(
-    "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable
-)
-T_route = t.TypeVar("T_route", bound=ft.RouteCallable)
-
-
-def setupmethod(f: F) -> F:
-    f_name = f.__name__
-
-    def wrapper_func(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
-        self._check_setup_finished(f_name)
-        return f(self, *args, **kwargs)
-
-    return t.cast(F, update_wrapper(wrapper_func, f))
-
-
-class Scaffold:
-    """Common behavior shared between :class:`~flask.Flask` and
-    :class:`~flask.blueprints.Blueprint`.
-
-    :param import_name: The import name of the module where this object
-        is defined. Usually :attr:`__name__` should be used.
-    :param static_folder: Path to a folder of static files to serve.
-        If this is set, a static route will be added.
-    :param static_url_path: URL prefix for the static route.
-    :param template_folder: Path to a folder containing template files.
-        for rendering. If this is set, a Jinja loader will be added.
-    :param root_path: The path that static, template, and resource files
-        are relative to. Typically not set, it is discovered based on
-        the ``import_name``.
-
-    .. versionadded:: 2.0
-    """
-
-    name: str
-    _static_folder: t.Optional[str] = None
-    _static_url_path: t.Optional[str] = None
-
-    #: JSON encoder class used by :func:`flask.json.dumps`. If a
-    #: blueprint sets this, it will be used instead of the app's value.
-    #:
-    #: .. deprecated:: 2.2
-    #:      Will be removed in Flask 2.3.
-    json_encoder: t.Union[t.Type[json.JSONEncoder], None] = None
-
-    #: JSON decoder class used by :func:`flask.json.loads`. If a
-    #: blueprint sets this, it will be used instead of the app's value.
-    #:
-    #: .. deprecated:: 2.2
-    #:      Will be removed in Flask 2.3.
-    json_decoder: t.Union[t.Type[json.JSONDecoder], None] = None
-
-    def __init__(
-        self,
-        import_name: str,
-        static_folder: t.Optional[t.Union[str, os.PathLike]] = None,
-        static_url_path: t.Optional[str] = None,
-        template_folder: t.Optional[str] = None,
-        root_path: t.Optional[str] = None,
-    ):
-        #: The name of the package or module that this object belongs
-        #: to. Do not change this once it is set by the constructor.
-        self.import_name = import_name
-
-        self.static_folder = static_folder  # type: ignore
-        self.static_url_path = static_url_path
-
-        #: The path to the templates folder, relative to
-        #: :attr:`root_path`, to add to the template loader. ``None`` if
-        #: templates should not be added.
-        self.template_folder = template_folder
-
-        if root_path is None:
-            root_path = get_root_path(self.import_name)
-
-        #: Absolute path to the package on the filesystem. Used to look
-        #: up resources contained in the package.
-        self.root_path = root_path
-
-        #: The Click command group for registering CLI commands for this
-        #: object. The commands are available from the ``flask`` command
-        #: once the application has been discovered and blueprints have
-        #: been registered.
-        self.cli = AppGroup()
-
-        #: A dictionary mapping endpoint names to view functions.
-        #:
-        #: To register a view function, use the :meth:`route` decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.view_functions: t.Dict[str, t.Callable] = {}
-
-        #: A data structure of registered error handlers, in the format
-        #: ``{scope: {code: {class: handler}}}``. The ``scope`` key is
-        #: the name of a blueprint the handlers are active for, or
-        #: ``None`` for all requests. The ``code`` key is the HTTP
-        #: status code for ``HTTPException``, or ``None`` for
-        #: other exceptions. The innermost dictionary maps exception
-        #: classes to handler functions.
-        #:
-        #: To register an error handler, use the :meth:`errorhandler`
-        #: decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.error_handler_spec: t.Dict[
-            ft.AppOrBlueprintKey,
-            t.Dict[t.Optional[int], t.Dict[t.Type[Exception], ft.ErrorHandlerCallable]],
-        ] = defaultdict(lambda: defaultdict(dict))
-
-        #: A data structure of functions to call at the beginning of
-        #: each request, in the format ``{scope: [functions]}``. The
-        #: ``scope`` key is the name of a blueprint the functions are
-        #: active for, or ``None`` for all requests.
-        #:
-        #: To register a function, use the :meth:`before_request`
-        #: decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.before_request_funcs: t.Dict[
-            ft.AppOrBlueprintKey, t.List[ft.BeforeRequestCallable]
-        ] = defaultdict(list)
-
-        #: A data structure of functions to call at the end of each
-        #: request, in the format ``{scope: [functions]}``. The
-        #: ``scope`` key is the name of a blueprint the functions are
-        #: active for, or ``None`` for all requests.
-        #:
-        #: To register a function, use the :meth:`after_request`
-        #: decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.after_request_funcs: t.Dict[
-            ft.AppOrBlueprintKey, t.List[ft.AfterRequestCallable]
-        ] = defaultdict(list)
-
-        #: A data structure of functions to call at the end of each
-        #: request even if an exception is raised, in the format
-        #: ``{scope: [functions]}``. The ``scope`` key is the name of a
-        #: blueprint the functions are active for, or ``None`` for all
-        #: requests.
-        #:
-        #: To register a function, use the :meth:`teardown_request`
-        #: decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.teardown_request_funcs: t.Dict[
-            ft.AppOrBlueprintKey, t.List[ft.TeardownCallable]
-        ] = defaultdict(list)
-
-        #: A data structure of functions to call to pass extra context
-        #: values when rendering templates, in the format
-        #: ``{scope: [functions]}``. The ``scope`` key is the name of a
-        #: blueprint the functions are active for, or ``None`` for all
-        #: requests.
-        #:
-        #: To register a function, use the :meth:`context_processor`
-        #: decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.template_context_processors: t.Dict[
-            ft.AppOrBlueprintKey, t.List[ft.TemplateContextProcessorCallable]
-        ] = defaultdict(list, {None: [_default_template_ctx_processor]})
-
-        #: A data structure of functions to call to modify the keyword
-        #: arguments passed to the view function, in the format
-        #: ``{scope: [functions]}``. The ``scope`` key is the name of a
-        #: blueprint the functions are active for, or ``None`` for all
-        #: requests.
-        #:
-        #: To register a function, use the
-        #: :meth:`url_value_preprocessor` decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.url_value_preprocessors: t.Dict[
-            ft.AppOrBlueprintKey,
-            t.List[ft.URLValuePreprocessorCallable],
-        ] = defaultdict(list)
-
-        #: A data structure of functions to call to modify the keyword
-        #: arguments when generating URLs, in the format
-        #: ``{scope: [functions]}``. The ``scope`` key is the name of a
-        #: blueprint the functions are active for, or ``None`` for all
-        #: requests.
-        #:
-        #: To register a function, use the :meth:`url_defaults`
-        #: decorator.
-        #:
-        #: This data structure is internal. It should not be modified
-        #: directly and its format may change at any time.
-        self.url_default_functions: t.Dict[
-            ft.AppOrBlueprintKey, t.List[ft.URLDefaultCallable]
-        ] = defaultdict(list)
-
-    def __repr__(self) -> str:
-        return f"<{type(self).__name__} {self.name!r}>"
-
-    def _check_setup_finished(self, f_name: str) -> None:
-        raise NotImplementedError
-
-    @property
-    def static_folder(self) -> t.Optional[str]:
-        """The absolute path to the configured static folder. ``None``
-        if no static folder is set.
-        """
-        if self._static_folder is not None:
-            return os.path.join(self.root_path, self._static_folder)
-        else:
-            return None
-
-    @static_folder.setter
-    def static_folder(self, value: t.Optional[t.Union[str, os.PathLike]]) -> None:
-        if value is not None:
-            value = os.fspath(value).rstrip(r"\/")
-
-        self._static_folder = value
-
-    @property
-    def has_static_folder(self) -> bool:
-        """``True`` if :attr:`static_folder` is set.
-
-        .. versionadded:: 0.5
-        """
-        return self.static_folder is not None
-
-    @property
-    def static_url_path(self) -> t.Optional[str]:
-        """The URL prefix that the static route will be accessible from.
-
-        If it was not configured during init, it is derived from
-        :attr:`static_folder`.
-        """
-        if self._static_url_path is not None:
-            return self._static_url_path
-
-        if self.static_folder is not None:
-            basename = os.path.basename(self.static_folder)
-            return f"/{basename}".rstrip("/")
-
-        return None
-
-    @static_url_path.setter
-    def static_url_path(self, value: t.Optional[str]) -> None:
-        if value is not None:
-            value = value.rstrip("/")
-
-        self._static_url_path = value
-
-    def get_send_file_max_age(self, filename: t.Optional[str]) -> t.Optional[int]:
-        """Used by :func:`send_file` to determine the ``max_age`` cache
-        value for a given file path if it wasn't passed.
-
-        By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from
-        the configuration of :data:`~flask.current_app`. This defaults
-        to ``None``, which tells the browser to use conditional requests
-        instead of a timed cache, which is usually preferable.
-
-        .. versionchanged:: 2.0
-            The default configuration is ``None`` instead of 12 hours.
-
-        .. versionadded:: 0.9
-        """
-        value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"]
-
-        if value is None:
-            return None
-
-        if isinstance(value, timedelta):
-            return int(value.total_seconds())
-
-        return value
-
-    def send_static_file(self, filename: str) -> "Response":
-        """The view function used to serve files from
-        :attr:`static_folder`. A route is automatically registered for
-        this view at :attr:`static_url_path` if :attr:`static_folder` is
-        set.
-
-        .. versionadded:: 0.5
-        """
-        if not self.has_static_folder:
-            raise RuntimeError("'static_folder' must be set to serve static_files.")
-
-        # send_file only knows to call get_send_file_max_age on the app,
-        # call it here so it works for blueprints too.
-        max_age = self.get_send_file_max_age(filename)
-        return send_from_directory(
-            t.cast(str, self.static_folder), filename, max_age=max_age
-        )
-
-    @locked_cached_property
-    def jinja_loader(self) -> t.Optional[FileSystemLoader]:
-        """The Jinja loader for this object's templates. By default this
-        is a class :class:`jinja2.loaders.FileSystemLoader` to
-        :attr:`template_folder` if it is set.
-
-        .. versionadded:: 0.5
-        """
-        if self.template_folder is not None:
-            return FileSystemLoader(os.path.join(self.root_path, self.template_folder))
-        else:
-            return None
-
-    def open_resource(self, resource: str, mode: str = "rb") -> t.IO[t.AnyStr]:
-        """Open a resource file relative to :attr:`root_path` for
-        reading.
-
-        For example, if the file ``schema.sql`` is next to the file
-        ``app.py`` where the ``Flask`` app is defined, it can be opened
-        with:
-
-        .. code-block:: python
-
-            with app.open_resource("schema.sql") as f:
-                conn.executescript(f.read())
-
-        :param resource: Path to the resource relative to
-            :attr:`root_path`.
-        :param mode: Open the file in this mode. Only reading is
-            supported, valid values are "r" (or "rt") and "rb".
-        """
-        if mode not in {"r", "rt", "rb"}:
-            raise ValueError("Resources can only be opened for reading.")
-
-        return open(os.path.join(self.root_path, resource), mode)
-
-    def _method_route(
-        self,
-        method: str,
-        rule: str,
-        options: dict,
-    ) -> t.Callable[[T_route], T_route]:
-        if "methods" in options:
-            raise TypeError("Use the 'route' decorator to use the 'methods' argument.")
-
-        return self.route(rule, methods=[method], **options)
-
-    @setupmethod
-    def get(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
-        """Shortcut for :meth:`route` with ``methods=["GET"]``.
-
-        .. versionadded:: 2.0
-        """
-        return self._method_route("GET", rule, options)
-
-    @setupmethod
-    def post(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
-        """Shortcut for :meth:`route` with ``methods=["POST"]``.
-
-        .. versionadded:: 2.0
-        """
-        return self._method_route("POST", rule, options)
-
-    @setupmethod
-    def put(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
-        """Shortcut for :meth:`route` with ``methods=["PUT"]``.
-
-        .. versionadded:: 2.0
-        """
-        return self._method_route("PUT", rule, options)
-
-    @setupmethod
-    def delete(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
-        """Shortcut for :meth:`route` with ``methods=["DELETE"]``.
-
-        .. versionadded:: 2.0
-        """
-        return self._method_route("DELETE", rule, options)
-
-    @setupmethod
-    def patch(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
-        """Shortcut for :meth:`route` with ``methods=["PATCH"]``.
-
-        .. versionadded:: 2.0
-        """
-        return self._method_route("PATCH", rule, options)
-
-    @setupmethod
-    def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]:
-        """Decorate a view function to register it with the given URL
-        rule and options. Calls :meth:`add_url_rule`, which has more
-        details about the implementation.
-
-        .. code-block:: python
-
-            @app.route("/")
-            def index():
-                return "Hello, World!"
-
-        See :ref:`url-route-registrations`.
-
-        The endpoint name for the route defaults to the name of the view
-        function if the ``endpoint`` parameter isn't passed.
-
-        The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` and
-        ``OPTIONS`` are added automatically.
-
-        :param rule: The URL rule string.
-        :param options: Extra options passed to the
-            :class:`~werkzeug.routing.Rule` object.
-        """
-
-        def decorator(f: T_route) -> T_route:
-            endpoint = options.pop("endpoint", None)
-            self.add_url_rule(rule, endpoint, f, **options)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def add_url_rule(
-        self,
-        rule: str,
-        endpoint: t.Optional[str] = None,
-        view_func: t.Optional[ft.RouteCallable] = None,
-        provide_automatic_options: t.Optional[bool] = None,
-        **options: t.Any,
-    ) -> None:
-        """Register a rule for routing incoming requests and building
-        URLs. The :meth:`route` decorator is a shortcut to call this
-        with the ``view_func`` argument. These are equivalent:
-
-        .. code-block:: python
-
-            @app.route("/")
-            def index():
-                ...
-
-        .. code-block:: python
-
-            def index():
-                ...
-
-            app.add_url_rule("/", view_func=index)
-
-        See :ref:`url-route-registrations`.
-
-        The endpoint name for the route defaults to the name of the view
-        function if the ``endpoint`` parameter isn't passed. An error
-        will be raised if a function has already been registered for the
-        endpoint.
-
-        The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` is
-        always added automatically, and ``OPTIONS`` is added
-        automatically by default.
-
-        ``view_func`` does not necessarily need to be passed, but if the
-        rule should participate in routing an endpoint name must be
-        associated with a view function at some point with the
-        :meth:`endpoint` decorator.
-
-        .. code-block:: python
-
-            app.add_url_rule("/", endpoint="index")
-
-            @app.endpoint("index")
-            def index():
-                ...
-
-        If ``view_func`` has a ``required_methods`` attribute, those
-        methods are added to the passed and automatic methods. If it
-        has a ``provide_automatic_methods`` attribute, it is used as the
-        default if the parameter is not passed.
-
-        :param rule: The URL rule string.
-        :param endpoint: The endpoint name to associate with the rule
-            and view function. Used when routing and building URLs.
-            Defaults to ``view_func.__name__``.
-        :param view_func: The view function to associate with the
-            endpoint name.
-        :param provide_automatic_options: Add the ``OPTIONS`` method and
-            respond to ``OPTIONS`` requests automatically.
-        :param options: Extra options passed to the
-            :class:`~werkzeug.routing.Rule` object.
-        """
-        raise NotImplementedError
-
-    @setupmethod
-    def endpoint(self, endpoint: str) -> t.Callable[[F], F]:
-        """Decorate a view function to register it for the given
-        endpoint. Used if a rule is added without a ``view_func`` with
-        :meth:`add_url_rule`.
-
-        .. code-block:: python
-
-            app.add_url_rule("/ex", endpoint="example")
-
-            @app.endpoint("example")
-            def example():
-                ...
-
-        :param endpoint: The endpoint name to associate with the view
-            function.
-        """
-
-        def decorator(f: F) -> F:
-            self.view_functions[endpoint] = f
-            return f
-
-        return decorator
-
-    @setupmethod
-    def before_request(self, f: T_before_request) -> T_before_request:
-        """Register a function to run before each request.
-
-        For example, this can be used to open a database connection, or
-        to load the logged in user from the session.
-
-        .. code-block:: python
-
-            @app.before_request
-            def load_user():
-                if "user_id" in session:
-                    g.user = db.session.get(session["user_id"])
-
-        The function will be called without any arguments. If it returns
-        a non-``None`` value, the value is handled as if it was the
-        return value from the view, and further request handling is
-        stopped.
-        """
-        self.before_request_funcs.setdefault(None, []).append(f)
-        return f
-
-    @setupmethod
-    def after_request(self, f: T_after_request) -> T_after_request:
-        """Register a function to run after each request to this object.
-
-        The function is called with the response object, and must return
-        a response object. This allows the functions to modify or
-        replace the response before it is sent.
-
-        If a function raises an exception, any remaining
-        ``after_request`` functions will not be called. Therefore, this
-        should not be used for actions that must execute, such as to
-        close resources. Use :meth:`teardown_request` for that.
-        """
-        self.after_request_funcs.setdefault(None, []).append(f)
-        return f
-
-    @setupmethod
-    def teardown_request(self, f: T_teardown) -> T_teardown:
-        """Register a function to be called when the request context is
-        popped. Typically this happens at the end of each request, but
-        contexts may be pushed manually as well during testing.
-
-        .. code-block:: python
-
-            with app.test_request_context():
-                ...
-
-        When the ``with`` block exits (or ``ctx.pop()`` is called), the
-        teardown functions are called just before the request context is
-        made inactive.
-
-        When a teardown function was called because of an unhandled
-        exception it will be passed an error object. If an
-        :meth:`errorhandler` is registered, it will handle the exception
-        and the teardown will not receive it.
-
-        Teardown functions must avoid raising exceptions. If they
-        execute code that might fail they must surround that code with a
-        ``try``/``except`` block and log any errors.
-
-        The return values of teardown functions are ignored.
-        """
-        self.teardown_request_funcs.setdefault(None, []).append(f)
-        return f
-
-    @setupmethod
-    def context_processor(
-        self,
-        f: T_template_context_processor,
-    ) -> T_template_context_processor:
-        """Registers a template context processor function."""
-        self.template_context_processors[None].append(f)
-        return f
-
-    @setupmethod
-    def url_value_preprocessor(
-        self,
-        f: T_url_value_preprocessor,
-    ) -> T_url_value_preprocessor:
-        """Register a URL value preprocessor function for all view
-        functions in the application. These functions will be called before the
-        :meth:`before_request` functions.
-
-        The function can modify the values captured from the matched url before
-        they are passed to the view. For example, this can be used to pop a
-        common language code value and place it in ``g`` rather than pass it to
-        every view.
-
-        The function is passed the endpoint name and values dict. The return
-        value is ignored.
-        """
-        self.url_value_preprocessors[None].append(f)
-        return f
-
-    @setupmethod
-    def url_defaults(self, f: T_url_defaults) -> T_url_defaults:
-        """Callback function for URL defaults for all view functions of the
-        application.  It's called with the endpoint and values and should
-        update the values passed in place.
-        """
-        self.url_default_functions[None].append(f)
-        return f
-
-    @setupmethod
-    def errorhandler(
-        self, code_or_exception: t.Union[t.Type[Exception], int]
-    ) -> t.Callable[[T_error_handler], T_error_handler]:
-        """Register a function to handle errors by code or exception class.
-
-        A decorator that is used to register a function given an
-        error code.  Example::
-
-            @app.errorhandler(404)
-            def page_not_found(error):
-                return 'This page does not exist', 404
-
-        You can also register handlers for arbitrary exceptions::
-
-            @app.errorhandler(DatabaseError)
-            def special_exception_handler(error):
-                return 'Database connection failed', 500
-
-        .. versionadded:: 0.7
-            Use :meth:`register_error_handler` instead of modifying
-            :attr:`error_handler_spec` directly, for application wide error
-            handlers.
-
-        .. versionadded:: 0.7
-           One can now additionally also register custom exception types
-           that do not necessarily have to be a subclass of the
-           :class:`~werkzeug.exceptions.HTTPException` class.
-
-        :param code_or_exception: the code as integer for the handler, or
-                                  an arbitrary exception
-        """
-
-        def decorator(f: T_error_handler) -> T_error_handler:
-            self.register_error_handler(code_or_exception, f)
-            return f
-
-        return decorator
-
-    @setupmethod
-    def register_error_handler(
-        self,
-        code_or_exception: t.Union[t.Type[Exception], int],
-        f: ft.ErrorHandlerCallable,
-    ) -> None:
-        """Alternative error attach function to the :meth:`errorhandler`
-        decorator that is more straightforward to use for non decorator
-        usage.
-
-        .. versionadded:: 0.7
-        """
-        exc_class, code = self._get_exc_class_and_code(code_or_exception)
-        self.error_handler_spec[None][code][exc_class] = f
-
-    @staticmethod
-    def _get_exc_class_and_code(
-        exc_class_or_code: t.Union[t.Type[Exception], int]
-    ) -> t.Tuple[t.Type[Exception], t.Optional[int]]:
-        """Get the exception class being handled. For HTTP status codes
-        or ``HTTPException`` subclasses, return both the exception and
-        status code.
-
-        :param exc_class_or_code: Any exception class, or an HTTP status
-            code as an integer.
-        """
-        exc_class: t.Type[Exception]
-
-        if isinstance(exc_class_or_code, int):
-            try:
-                exc_class = default_exceptions[exc_class_or_code]
-            except KeyError:
-                raise ValueError(
-                    f"'{exc_class_or_code}' is not a recognized HTTP"
-                    " error code. Use a subclass of HTTPException with"
-                    " that code instead."
-                ) from None
-        else:
-            exc_class = exc_class_or_code
-
-        if isinstance(exc_class, Exception):
-            raise TypeError(
-                f"{exc_class!r} is an instance, not a class. Handlers"
-                " can only be registered for Exception classes or HTTP"
-                " error codes."
-            )
-
-        if not issubclass(exc_class, Exception):
-            raise ValueError(
-                f"'{exc_class.__name__}' is not a subclass of Exception."
-                " Handlers can only be registered for Exception classes"
-                " or HTTP error codes."
-            )
-
-        if issubclass(exc_class, HTTPException):
-            return exc_class, exc_class.code
-        else:
-            return exc_class, None
-
-
-def _endpoint_from_view_func(view_func: t.Callable) -> str:
-    """Internal helper that returns the default endpoint for a given
-    function.  This always is the function name.
-    """
-    assert view_func is not None, "expected view func if endpoint is not provided."
-    return view_func.__name__
-
-
-def _matching_loader_thinks_module_is_package(loader, mod_name):
-    """Attempt to figure out if the given name is a package or a module.
-
-    :param: loader: The loader that handled the name.
-    :param mod_name: The name of the package or module.
-    """
-    # Use loader.is_package if it's available.
-    if hasattr(loader, "is_package"):
-        return loader.is_package(mod_name)
-
-    cls = type(loader)
-
-    # NamespaceLoader doesn't implement is_package, but all names it
-    # loads must be packages.
-    if cls.__module__ == "_frozen_importlib" and cls.__name__ == "NamespaceLoader":
-        return True
-
-    # Otherwise we need to fail with an error that explains what went
-    # wrong.
-    raise AttributeError(
-        f"'{cls.__name__}.is_package()' must be implemented for PEP 302"
-        f" import hooks."
-    )
-
-
-def _path_is_relative_to(path: pathlib.PurePath, base: str) -> bool:
-    # Path.is_relative_to doesn't exist until Python 3.9
-    try:
-        path.relative_to(base)
-        return True
-    except ValueError:
-        return False
-
-
-def _find_package_path(import_name):
-    """Find the path that contains the package or module."""
-    root_mod_name, _, _ = import_name.partition(".")
-
-    try:
-        root_spec = importlib.util.find_spec(root_mod_name)
-
-        if root_spec is None:
-            raise ValueError("not found")
-    # ImportError: the machinery told us it does not exist
-    # ValueError:
-    #    - the module name was invalid
-    #    - the module name is __main__
-    #    - *we* raised `ValueError` due to `root_spec` being `None`
-    except (ImportError, ValueError):
-        pass  # handled below
-    else:
-        # namespace package
-        if root_spec.origin in {"namespace", None}:
-            package_spec = importlib.util.find_spec(import_name)
-            if package_spec is not None and package_spec.submodule_search_locations:
-                # Pick the path in the namespace that contains the submodule.
-                package_path = pathlib.Path(
-                    os.path.commonpath(package_spec.submodule_search_locations)
-                )
-                search_locations = (
-                    location
-                    for location in root_spec.submodule_search_locations
-                    if _path_is_relative_to(package_path, location)
-                )
-            else:
-                # Pick the first path.
-                search_locations = iter(root_spec.submodule_search_locations)
-            return os.path.dirname(next(search_locations))
-        # a package (with __init__.py)
-        elif root_spec.submodule_search_locations:
-            return os.path.dirname(os.path.dirname(root_spec.origin))
-        # just a normal module
-        else:
-            return os.path.dirname(root_spec.origin)
-
-    # we were unable to find the `package_path` using PEP 451 loaders
-    loader = pkgutil.get_loader(root_mod_name)
-
-    if loader is None or root_mod_name == "__main__":
-        # import name is not found, or interactive/main module
-        return os.getcwd()
-
-    if hasattr(loader, "get_filename"):
-        filename = loader.get_filename(root_mod_name)
-    elif hasattr(loader, "archive"):
-        # zipimporter's loader.archive points to the .egg or .zip file.
-        filename = loader.archive
-    else:
-        # At least one loader is missing both get_filename and archive:
-        # Google App Engine's HardenedModulesHook, use __file__.
-        filename = importlib.import_module(root_mod_name).__file__
-
-    package_path = os.path.abspath(os.path.dirname(filename))
-
-    # If the imported name is a package, filename is currently pointing
-    # to the root of the package, need to get the current directory.
-    if _matching_loader_thinks_module_is_package(loader, root_mod_name):
-        package_path = os.path.dirname(package_path)
-
-    return package_path
-
-
-def find_package(import_name: str):
-    """Find the prefix that a package is installed under, and the path
-    that it would be imported from.
-
-    The prefix is the directory containing the standard directory
-    hierarchy (lib, bin, etc.). If the package is not installed to the
-    system (:attr:`sys.prefix`) or a virtualenv (``site-packages``),
-    ``None`` is returned.
-
-    The path is the entry in :attr:`sys.path` that contains the package
-    for import. If the package is not installed, it's assumed that the
-    package was imported from the current working directory.
-    """
-    package_path = _find_package_path(import_name)
-    py_prefix = os.path.abspath(sys.prefix)
-
-    # installed to the system
-    if _path_is_relative_to(pathlib.PurePath(package_path), py_prefix):
-        return py_prefix, package_path
-
-    site_parent, site_folder = os.path.split(package_path)
-
-    # installed to a virtualenv
-    if site_folder.lower() == "site-packages":
-        parent, folder = os.path.split(site_parent)
-
-        # Windows (prefix/lib/site-packages)
-        if folder.lower() == "lib":
-            return parent, package_path
-
-        # Unix (prefix/lib/pythonX.Y/site-packages)
-        if os.path.basename(parent).lower() == "lib":
-            return os.path.dirname(parent), package_path
-
-        # something else (prefix/site-packages)
-        return site_parent, package_path
-
-    # not installed
-    return None, package_path

+ 0 - 419
venv/lib/python3.10/site-packages/flask/sessions.py

@@ -1,419 +0,0 @@
-import hashlib
-import typing as t
-import warnings
-from collections.abc import MutableMapping
-from datetime import datetime
-from datetime import timezone
-
-from itsdangerous import BadSignature
-from itsdangerous import URLSafeTimedSerializer
-from werkzeug.datastructures import CallbackDict
-
-from .helpers import is_ip
-from .json.tag import TaggedJSONSerializer
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    import typing_extensions as te
-    from .app import Flask
-    from .wrappers import Request, Response
-
-
-class SessionMixin(MutableMapping):
-    """Expands a basic dictionary with session attributes."""
-
-    @property
-    def permanent(self) -> bool:
-        """This reflects the ``'_permanent'`` key in the dict."""
-        return self.get("_permanent", False)
-
-    @permanent.setter
-    def permanent(self, value: bool) -> None:
-        self["_permanent"] = bool(value)
-
-    #: Some implementations can detect whether a session is newly
-    #: created, but that is not guaranteed. Use with caution. The mixin
-    # default is hard-coded ``False``.
-    new = False
-
-    #: Some implementations can detect changes to the session and set
-    #: this when that happens. The mixin default is hard coded to
-    #: ``True``.
-    modified = True
-
-    #: Some implementations can detect when session data is read or
-    #: written and set this when that happens. The mixin default is hard
-    #: coded to ``True``.
-    accessed = True
-
-
-class SecureCookieSession(CallbackDict, SessionMixin):
-    """Base class for sessions based on signed cookies.
-
-    This session backend will set the :attr:`modified` and
-    :attr:`accessed` attributes. It cannot reliably track whether a
-    session is new (vs. empty), so :attr:`new` remains hard coded to
-    ``False``.
-    """
-
-    #: When data is changed, this is set to ``True``. Only the session
-    #: dictionary itself is tracked; if the session contains mutable
-    #: data (for example a nested dict) then this must be set to
-    #: ``True`` manually when modifying that data. The session cookie
-    #: will only be written to the response if this is ``True``.
-    modified = False
-
-    #: When data is read or written, this is set to ``True``. Used by
-    # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie``
-    #: header, which allows caching proxies to cache different pages for
-    #: different users.
-    accessed = False
-
-    def __init__(self, initial: t.Any = None) -> None:
-        def on_update(self) -> None:
-            self.modified = True
-            self.accessed = True
-
-        super().__init__(initial, on_update)
-
-    def __getitem__(self, key: str) -> t.Any:
-        self.accessed = True
-        return super().__getitem__(key)
-
-    def get(self, key: str, default: t.Any = None) -> t.Any:
-        self.accessed = True
-        return super().get(key, default)
-
-    def setdefault(self, key: str, default: t.Any = None) -> t.Any:
-        self.accessed = True
-        return super().setdefault(key, default)
-
-
-class NullSession(SecureCookieSession):
-    """Class used to generate nicer error messages if sessions are not
-    available.  Will still allow read-only access to the empty session
-    but fail on setting.
-    """
-
-    def _fail(self, *args: t.Any, **kwargs: t.Any) -> "te.NoReturn":
-        raise RuntimeError(
-            "The session is unavailable because no secret "
-            "key was set.  Set the secret_key on the "
-            "application to something unique and secret."
-        )
-
-    __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail  # type: ignore # noqa: B950
-    del _fail
-
-
-class SessionInterface:
-    """The basic interface you have to implement in order to replace the
-    default session interface which uses werkzeug's securecookie
-    implementation.  The only methods you have to implement are
-    :meth:`open_session` and :meth:`save_session`, the others have
-    useful defaults which you don't need to change.
-
-    The session object returned by the :meth:`open_session` method has to
-    provide a dictionary like interface plus the properties and methods
-    from the :class:`SessionMixin`.  We recommend just subclassing a dict
-    and adding that mixin::
-
-        class Session(dict, SessionMixin):
-            pass
-
-    If :meth:`open_session` returns ``None`` Flask will call into
-    :meth:`make_null_session` to create a session that acts as replacement
-    if the session support cannot work because some requirement is not
-    fulfilled.  The default :class:`NullSession` class that is created
-    will complain that the secret key was not set.
-
-    To replace the session interface on an application all you have to do
-    is to assign :attr:`flask.Flask.session_interface`::
-
-        app = Flask(__name__)
-        app.session_interface = MySessionInterface()
-
-    Multiple requests with the same session may be sent and handled
-    concurrently. When implementing a new session interface, consider
-    whether reads or writes to the backing store must be synchronized.
-    There is no guarantee on the order in which the session for each
-    request is opened or saved, it will occur in the order that requests
-    begin and end processing.
-
-    .. versionadded:: 0.8
-    """
-
-    #: :meth:`make_null_session` will look here for the class that should
-    #: be created when a null session is requested.  Likewise the
-    #: :meth:`is_null_session` method will perform a typecheck against
-    #: this type.
-    null_session_class = NullSession
-
-    #: A flag that indicates if the session interface is pickle based.
-    #: This can be used by Flask extensions to make a decision in regards
-    #: to how to deal with the session object.
-    #:
-    #: .. versionadded:: 0.10
-    pickle_based = False
-
-    def make_null_session(self, app: "Flask") -> NullSession:
-        """Creates a null session which acts as a replacement object if the
-        real session support could not be loaded due to a configuration
-        error.  This mainly aids the user experience because the job of the
-        null session is to still support lookup without complaining but
-        modifications are answered with a helpful error message of what
-        failed.
-
-        This creates an instance of :attr:`null_session_class` by default.
-        """
-        return self.null_session_class()
-
-    def is_null_session(self, obj: object) -> bool:
-        """Checks if a given object is a null session.  Null sessions are
-        not asked to be saved.
-
-        This checks if the object is an instance of :attr:`null_session_class`
-        by default.
-        """
-        return isinstance(obj, self.null_session_class)
-
-    def get_cookie_name(self, app: "Flask") -> str:
-        """The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``."""
-        return app.config["SESSION_COOKIE_NAME"]
-
-    def get_cookie_domain(self, app: "Flask") -> t.Optional[str]:
-        """Returns the domain that should be set for the session cookie.
-
-        Uses ``SESSION_COOKIE_DOMAIN`` if it is configured, otherwise
-        falls back to detecting the domain based on ``SERVER_NAME``.
-
-        Once detected (or if not set at all), ``SESSION_COOKIE_DOMAIN`` is
-        updated to avoid re-running the logic.
-        """
-
-        rv = app.config["SESSION_COOKIE_DOMAIN"]
-
-        # set explicitly, or cached from SERVER_NAME detection
-        # if False, return None
-        if rv is not None:
-            return rv if rv else None
-
-        rv = app.config["SERVER_NAME"]
-
-        # server name not set, cache False to return none next time
-        if not rv:
-            app.config["SESSION_COOKIE_DOMAIN"] = False
-            return None
-
-        # chop off the port which is usually not supported by browsers
-        # remove any leading '.' since we'll add that later
-        rv = rv.rsplit(":", 1)[0].lstrip(".")
-
-        if "." not in rv:
-            # Chrome doesn't allow names without a '.'. This should only
-            # come up with localhost. Hack around this by not setting
-            # the name, and show a warning.
-            warnings.warn(
-                f"{rv!r} is not a valid cookie domain, it must contain"
-                " a '.'. Add an entry to your hosts file, for example"
-                f" '{rv}.localdomain', and use that instead."
-            )
-            app.config["SESSION_COOKIE_DOMAIN"] = False
-            return None
-
-        ip = is_ip(rv)
-
-        if ip:
-            warnings.warn(
-                "The session cookie domain is an IP address. This may not work"
-                " as intended in some browsers. Add an entry to your hosts"
-                ' file, for example "localhost.localdomain", and use that'
-                " instead."
-            )
-
-        # if this is not an ip and app is mounted at the root, allow subdomain
-        # matching by adding a '.' prefix
-        if self.get_cookie_path(app) == "/" and not ip:
-            rv = f".{rv}"
-
-        app.config["SESSION_COOKIE_DOMAIN"] = rv
-        return rv
-
-    def get_cookie_path(self, app: "Flask") -> str:
-        """Returns the path for which the cookie should be valid.  The
-        default implementation uses the value from the ``SESSION_COOKIE_PATH``
-        config var if it's set, and falls back to ``APPLICATION_ROOT`` or
-        uses ``/`` if it's ``None``.
-        """
-        return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"]
-
-    def get_cookie_httponly(self, app: "Flask") -> bool:
-        """Returns True if the session cookie should be httponly.  This
-        currently just returns the value of the ``SESSION_COOKIE_HTTPONLY``
-        config var.
-        """
-        return app.config["SESSION_COOKIE_HTTPONLY"]
-
-    def get_cookie_secure(self, app: "Flask") -> bool:
-        """Returns True if the cookie should be secure.  This currently
-        just returns the value of the ``SESSION_COOKIE_SECURE`` setting.
-        """
-        return app.config["SESSION_COOKIE_SECURE"]
-
-    def get_cookie_samesite(self, app: "Flask") -> str:
-        """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the
-        ``SameSite`` attribute. This currently just returns the value of
-        the :data:`SESSION_COOKIE_SAMESITE` setting.
-        """
-        return app.config["SESSION_COOKIE_SAMESITE"]
-
-    def get_expiration_time(
-        self, app: "Flask", session: SessionMixin
-    ) -> t.Optional[datetime]:
-        """A helper method that returns an expiration date for the session
-        or ``None`` if the session is linked to the browser session.  The
-        default implementation returns now + the permanent session
-        lifetime configured on the application.
-        """
-        if session.permanent:
-            return datetime.now(timezone.utc) + app.permanent_session_lifetime
-        return None
-
-    def should_set_cookie(self, app: "Flask", session: SessionMixin) -> bool:
-        """Used by session backends to determine if a ``Set-Cookie`` header
-        should be set for this session cookie for this response. If the session
-        has been modified, the cookie is set. If the session is permanent and
-        the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is
-        always set.
-
-        This check is usually skipped if the session was deleted.
-
-        .. versionadded:: 0.11
-        """
-
-        return session.modified or (
-            session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"]
-        )
-
-    def open_session(
-        self, app: "Flask", request: "Request"
-    ) -> t.Optional[SessionMixin]:
-        """This is called at the beginning of each request, after
-        pushing the request context, before matching the URL.
-
-        This must return an object which implements a dictionary-like
-        interface as well as the :class:`SessionMixin` interface.
-
-        This will return ``None`` to indicate that loading failed in
-        some way that is not immediately an error. The request
-        context will fall back to using :meth:`make_null_session`
-        in this case.
-        """
-        raise NotImplementedError()
-
-    def save_session(
-        self, app: "Flask", session: SessionMixin, response: "Response"
-    ) -> None:
-        """This is called at the end of each request, after generating
-        a response, before removing the request context. It is skipped
-        if :meth:`is_null_session` returns ``True``.
-        """
-        raise NotImplementedError()
-
-
-session_json_serializer = TaggedJSONSerializer()
-
-
-class SecureCookieSessionInterface(SessionInterface):
-    """The default session interface that stores sessions in signed cookies
-    through the :mod:`itsdangerous` module.
-    """
-
-    #: the salt that should be applied on top of the secret key for the
-    #: signing of cookie based sessions.
-    salt = "cookie-session"
-    #: the hash function to use for the signature.  The default is sha1
-    digest_method = staticmethod(hashlib.sha1)
-    #: the name of the itsdangerous supported key derivation.  The default
-    #: is hmac.
-    key_derivation = "hmac"
-    #: A python serializer for the payload.  The default is a compact
-    #: JSON derived serializer with support for some extra Python types
-    #: such as datetime objects or tuples.
-    serializer = session_json_serializer
-    session_class = SecureCookieSession
-
-    def get_signing_serializer(
-        self, app: "Flask"
-    ) -> t.Optional[URLSafeTimedSerializer]:
-        if not app.secret_key:
-            return None
-        signer_kwargs = dict(
-            key_derivation=self.key_derivation, digest_method=self.digest_method
-        )
-        return URLSafeTimedSerializer(
-            app.secret_key,
-            salt=self.salt,
-            serializer=self.serializer,
-            signer_kwargs=signer_kwargs,
-        )
-
-    def open_session(
-        self, app: "Flask", request: "Request"
-    ) -> t.Optional[SecureCookieSession]:
-        s = self.get_signing_serializer(app)
-        if s is None:
-            return None
-        val = request.cookies.get(self.get_cookie_name(app))
-        if not val:
-            return self.session_class()
-        max_age = int(app.permanent_session_lifetime.total_seconds())
-        try:
-            data = s.loads(val, max_age=max_age)
-            return self.session_class(data)
-        except BadSignature:
-            return self.session_class()
-
-    def save_session(
-        self, app: "Flask", session: SessionMixin, response: "Response"
-    ) -> None:
-        name = self.get_cookie_name(app)
-        domain = self.get_cookie_domain(app)
-        path = self.get_cookie_path(app)
-        secure = self.get_cookie_secure(app)
-        samesite = self.get_cookie_samesite(app)
-        httponly = self.get_cookie_httponly(app)
-
-        # If the session is modified to be empty, remove the cookie.
-        # If the session is empty, return without setting the cookie.
-        if not session:
-            if session.modified:
-                response.delete_cookie(
-                    name,
-                    domain=domain,
-                    path=path,
-                    secure=secure,
-                    samesite=samesite,
-                    httponly=httponly,
-                )
-
-            return
-
-        # Add a "Vary: Cookie" header if the session was accessed at all.
-        if session.accessed:
-            response.vary.add("Cookie")
-
-        if not self.should_set_cookie(app, session):
-            return
-
-        expires = self.get_expiration_time(app, session)
-        val = self.get_signing_serializer(app).dumps(dict(session))  # type: ignore
-        response.set_cookie(
-            name,
-            val,  # type: ignore
-            expires=expires,
-            httponly=httponly,
-            domain=domain,
-            path=path,
-            secure=secure,
-            samesite=samesite,
-        )

+ 0 - 56
venv/lib/python3.10/site-packages/flask/signals.py

@@ -1,56 +0,0 @@
-import typing as t
-
-try:
-    from blinker import Namespace
-
-    signals_available = True
-except ImportError:
-    signals_available = False
-
-    class Namespace:  # type: ignore
-        def signal(self, name: str, doc: t.Optional[str] = None) -> "_FakeSignal":
-            return _FakeSignal(name, doc)
-
-    class _FakeSignal:
-        """If blinker is unavailable, create a fake class with the same
-        interface that allows sending of signals but will fail with an
-        error on anything else.  Instead of doing anything on send, it
-        will just ignore the arguments and do nothing instead.
-        """
-
-        def __init__(self, name: str, doc: t.Optional[str] = None) -> None:
-            self.name = name
-            self.__doc__ = doc
-
-        def send(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
-            pass
-
-        def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
-            raise RuntimeError(
-                "Signalling support is unavailable because the blinker"
-                " library is not installed."
-            ) from None
-
-        connect = connect_via = connected_to = temporarily_connected_to = _fail
-        disconnect = _fail
-        has_receivers_for = receivers_for = _fail
-        del _fail
-
-
-# The namespace for code signals.  If you are not Flask code, do
-# not put signals in here.  Create your own namespace instead.
-_signals = Namespace()
-
-
-# Core signals.  For usage examples grep the source code or consult
-# the API documentation in docs/api.rst as well as docs/signals.rst
-template_rendered = _signals.signal("template-rendered")
-before_render_template = _signals.signal("before-render-template")
-request_started = _signals.signal("request-started")
-request_finished = _signals.signal("request-finished")
-request_tearing_down = _signals.signal("request-tearing-down")
-got_request_exception = _signals.signal("got-request-exception")
-appcontext_tearing_down = _signals.signal("appcontext-tearing-down")
-appcontext_pushed = _signals.signal("appcontext-pushed")
-appcontext_popped = _signals.signal("appcontext-popped")
-message_flashed = _signals.signal("message-flashed")

+ 0 - 212
venv/lib/python3.10/site-packages/flask/templating.py

@@ -1,212 +0,0 @@
-import typing as t
-
-from jinja2 import BaseLoader
-from jinja2 import Environment as BaseEnvironment
-from jinja2 import Template
-from jinja2 import TemplateNotFound
-
-from .globals import _cv_app
-from .globals import _cv_request
-from .globals import current_app
-from .globals import request
-from .helpers import stream_with_context
-from .signals import before_render_template
-from .signals import template_rendered
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from .app import Flask
-    from .scaffold import Scaffold
-
-
-def _default_template_ctx_processor() -> t.Dict[str, t.Any]:
-    """Default template context processor.  Injects `request`,
-    `session` and `g`.
-    """
-    appctx = _cv_app.get(None)
-    reqctx = _cv_request.get(None)
-    rv: t.Dict[str, t.Any] = {}
-    if appctx is not None:
-        rv["g"] = appctx.g
-    if reqctx is not None:
-        rv["request"] = reqctx.request
-        rv["session"] = reqctx.session
-    return rv
-
-
-class Environment(BaseEnvironment):
-    """Works like a regular Jinja2 environment but has some additional
-    knowledge of how Flask's blueprint works so that it can prepend the
-    name of the blueprint to referenced templates if necessary.
-    """
-
-    def __init__(self, app: "Flask", **options: t.Any) -> None:
-        if "loader" not in options:
-            options["loader"] = app.create_global_jinja_loader()
-        BaseEnvironment.__init__(self, **options)
-        self.app = app
-
-
-class DispatchingJinjaLoader(BaseLoader):
-    """A loader that looks for templates in the application and all
-    the blueprint folders.
-    """
-
-    def __init__(self, app: "Flask") -> None:
-        self.app = app
-
-    def get_source(  # type: ignore
-        self, environment: Environment, template: str
-    ) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable]]:
-        if self.app.config["EXPLAIN_TEMPLATE_LOADING"]:
-            return self._get_source_explained(environment, template)
-        return self._get_source_fast(environment, template)
-
-    def _get_source_explained(
-        self, environment: Environment, template: str
-    ) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable]]:
-        attempts = []
-        rv: t.Optional[t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]]
-        trv: t.Optional[
-            t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]
-        ] = None
-
-        for srcobj, loader in self._iter_loaders(template):
-            try:
-                rv = loader.get_source(environment, template)
-                if trv is None:
-                    trv = rv
-            except TemplateNotFound:
-                rv = None
-            attempts.append((loader, srcobj, rv))
-
-        from .debughelpers import explain_template_loading_attempts
-
-        explain_template_loading_attempts(self.app, template, attempts)
-
-        if trv is not None:
-            return trv
-        raise TemplateNotFound(template)
-
-    def _get_source_fast(
-        self, environment: Environment, template: str
-    ) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable]]:
-        for _srcobj, loader in self._iter_loaders(template):
-            try:
-                return loader.get_source(environment, template)
-            except TemplateNotFound:
-                continue
-        raise TemplateNotFound(template)
-
-    def _iter_loaders(
-        self, template: str
-    ) -> t.Generator[t.Tuple["Scaffold", BaseLoader], None, None]:
-        loader = self.app.jinja_loader
-        if loader is not None:
-            yield self.app, loader
-
-        for blueprint in self.app.iter_blueprints():
-            loader = blueprint.jinja_loader
-            if loader is not None:
-                yield blueprint, loader
-
-    def list_templates(self) -> t.List[str]:
-        result = set()
-        loader = self.app.jinja_loader
-        if loader is not None:
-            result.update(loader.list_templates())
-
-        for blueprint in self.app.iter_blueprints():
-            loader = blueprint.jinja_loader
-            if loader is not None:
-                for template in loader.list_templates():
-                    result.add(template)
-
-        return list(result)
-
-
-def _render(app: "Flask", template: Template, context: t.Dict[str, t.Any]) -> str:
-    app.update_template_context(context)
-    before_render_template.send(app, template=template, context=context)
-    rv = template.render(context)
-    template_rendered.send(app, template=template, context=context)
-    return rv
-
-
-def render_template(
-    template_name_or_list: t.Union[str, Template, t.List[t.Union[str, Template]]],
-    **context: t.Any
-) -> str:
-    """Render a template by name with the given context.
-
-    :param template_name_or_list: The name of the template to render. If
-        a list is given, the first name to exist will be rendered.
-    :param context: The variables to make available in the template.
-    """
-    app = current_app._get_current_object()  # type: ignore[attr-defined]
-    template = app.jinja_env.get_or_select_template(template_name_or_list)
-    return _render(app, template, context)
-
-
-def render_template_string(source: str, **context: t.Any) -> str:
-    """Render a template from the given source string with the given
-    context.
-
-    :param source: The source code of the template to render.
-    :param context: The variables to make available in the template.
-    """
-    app = current_app._get_current_object()  # type: ignore[attr-defined]
-    template = app.jinja_env.from_string(source)
-    return _render(app, template, context)
-
-
-def _stream(
-    app: "Flask", template: Template, context: t.Dict[str, t.Any]
-) -> t.Iterator[str]:
-    app.update_template_context(context)
-    before_render_template.send(app, template=template, context=context)
-
-    def generate() -> t.Iterator[str]:
-        yield from template.generate(context)
-        template_rendered.send(app, template=template, context=context)
-
-    rv = generate()
-
-    # If a request context is active, keep it while generating.
-    if request:
-        rv = stream_with_context(rv)
-
-    return rv
-
-
-def stream_template(
-    template_name_or_list: t.Union[str, Template, t.List[t.Union[str, Template]]],
-    **context: t.Any
-) -> t.Iterator[str]:
-    """Render a template by name with the given context as a stream.
-    This returns an iterator of strings, which can be used as a
-    streaming response from a view.
-
-    :param template_name_or_list: The name of the template to render. If
-        a list is given, the first name to exist will be rendered.
-    :param context: The variables to make available in the template.
-
-    .. versionadded:: 2.2
-    """
-    app = current_app._get_current_object()  # type: ignore[attr-defined]
-    template = app.jinja_env.get_or_select_template(template_name_or_list)
-    return _stream(app, template, context)
-
-
-def stream_template_string(source: str, **context: t.Any) -> t.Iterator[str]:
-    """Render a template from the given source string with the given
-    context as a stream. This returns an iterator of strings, which can
-    be used as a streaming response from a view.
-
-    :param source: The source code of the template to render.
-    :param context: The variables to make available in the template.
-
-    .. versionadded:: 2.2
-    """
-    app = current_app._get_current_object()  # type: ignore[attr-defined]
-    template = app.jinja_env.from_string(source)
-    return _stream(app, template, context)

+ 0 - 286
venv/lib/python3.10/site-packages/flask/testing.py

@@ -1,286 +0,0 @@
-import typing as t
-from contextlib import contextmanager
-from contextlib import ExitStack
-from copy import copy
-from types import TracebackType
-
-import werkzeug.test
-from click.testing import CliRunner
-from werkzeug.test import Client
-from werkzeug.urls import url_parse
-from werkzeug.wrappers import Request as BaseRequest
-
-from .cli import ScriptInfo
-from .globals import _cv_request
-from .sessions import SessionMixin
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from werkzeug.test import TestResponse
-
-    from .app import Flask
-
-
-class EnvironBuilder(werkzeug.test.EnvironBuilder):
-    """An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the
-    application.
-
-    :param app: The Flask application to configure the environment from.
-    :param path: URL path being requested.
-    :param base_url: Base URL where the app is being served, which
-        ``path`` is relative to. If not given, built from
-        :data:`PREFERRED_URL_SCHEME`, ``subdomain``,
-        :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`.
-    :param subdomain: Subdomain name to append to :data:`SERVER_NAME`.
-    :param url_scheme: Scheme to use instead of
-        :data:`PREFERRED_URL_SCHEME`.
-    :param json: If given, this is serialized as JSON and passed as
-        ``data``. Also defaults ``content_type`` to
-        ``application/json``.
-    :param args: other positional arguments passed to
-        :class:`~werkzeug.test.EnvironBuilder`.
-    :param kwargs: other keyword arguments passed to
-        :class:`~werkzeug.test.EnvironBuilder`.
-    """
-
-    def __init__(
-        self,
-        app: "Flask",
-        path: str = "/",
-        base_url: t.Optional[str] = None,
-        subdomain: t.Optional[str] = None,
-        url_scheme: t.Optional[str] = None,
-        *args: t.Any,
-        **kwargs: t.Any,
-    ) -> None:
-        assert not (base_url or subdomain or url_scheme) or (
-            base_url is not None
-        ) != bool(
-            subdomain or url_scheme
-        ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".'
-
-        if base_url is None:
-            http_host = app.config.get("SERVER_NAME") or "localhost"
-            app_root = app.config["APPLICATION_ROOT"]
-
-            if subdomain:
-                http_host = f"{subdomain}.{http_host}"
-
-            if url_scheme is None:
-                url_scheme = app.config["PREFERRED_URL_SCHEME"]
-
-            url = url_parse(path)
-            base_url = (
-                f"{url.scheme or url_scheme}://{url.netloc or http_host}"
-                f"/{app_root.lstrip('/')}"
-            )
-            path = url.path
-
-            if url.query:
-                sep = b"?" if isinstance(url.query, bytes) else "?"
-                path += sep + url.query
-
-        self.app = app
-        super().__init__(path, base_url, *args, **kwargs)
-
-    def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str:  # type: ignore
-        """Serialize ``obj`` to a JSON-formatted string.
-
-        The serialization will be configured according to the config associated
-        with this EnvironBuilder's ``app``.
-        """
-        return self.app.json.dumps(obj, **kwargs)
-
-
-class FlaskClient(Client):
-    """Works like a regular Werkzeug test client but has knowledge about
-    Flask's contexts to defer the cleanup of the request context until
-    the end of a ``with`` block. For general information about how to
-    use this class refer to :class:`werkzeug.test.Client`.
-
-    .. versionchanged:: 0.12
-       `app.test_client()` includes preset default environment, which can be
-       set after instantiation of the `app.test_client()` object in
-       `client.environ_base`.
-
-    Basic usage is outlined in the :doc:`/testing` chapter.
-    """
-
-    application: "Flask"
-
-    def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
-        super().__init__(*args, **kwargs)
-        self.preserve_context = False
-        self._new_contexts: t.List[t.ContextManager[t.Any]] = []
-        self._context_stack = ExitStack()
-        self.environ_base = {
-            "REMOTE_ADDR": "127.0.0.1",
-            "HTTP_USER_AGENT": f"werkzeug/{werkzeug.__version__}",
-        }
-
-    @contextmanager
-    def session_transaction(
-        self, *args: t.Any, **kwargs: t.Any
-    ) -> t.Generator[SessionMixin, None, None]:
-        """When used in combination with a ``with`` statement this opens a
-        session transaction.  This can be used to modify the session that
-        the test client uses.  Once the ``with`` block is left the session is
-        stored back.
-
-        ::
-
-            with client.session_transaction() as session:
-                session['value'] = 42
-
-        Internally this is implemented by going through a temporary test
-        request context and since session handling could depend on
-        request variables this function accepts the same arguments as
-        :meth:`~flask.Flask.test_request_context` which are directly
-        passed through.
-        """
-        if self.cookie_jar is None:
-            raise RuntimeError(
-                "Session transactions only make sense with cookies enabled."
-            )
-        app = self.application
-        environ_overrides = kwargs.setdefault("environ_overrides", {})
-        self.cookie_jar.inject_wsgi(environ_overrides)
-        outer_reqctx = _cv_request.get(None)
-        with app.test_request_context(*args, **kwargs) as c:
-            session_interface = app.session_interface
-            sess = session_interface.open_session(app, c.request)
-            if sess is None:
-                raise RuntimeError(
-                    "Session backend did not open a session. Check the configuration"
-                )
-
-            # Since we have to open a new request context for the session
-            # handling we want to make sure that we hide out own context
-            # from the caller.  By pushing the original request context
-            # (or None) on top of this and popping it we get exactly that
-            # behavior.  It's important to not use the push and pop
-            # methods of the actual request context object since that would
-            # mean that cleanup handlers are called
-            token = _cv_request.set(outer_reqctx)  # type: ignore[arg-type]
-            try:
-                yield sess
-            finally:
-                _cv_request.reset(token)
-
-            resp = app.response_class()
-            if not session_interface.is_null_session(sess):
-                session_interface.save_session(app, sess, resp)
-            headers = resp.get_wsgi_headers(c.request.environ)
-            self.cookie_jar.extract_wsgi(c.request.environ, headers)
-
-    def _copy_environ(self, other):
-        out = {**self.environ_base, **other}
-
-        if self.preserve_context:
-            out["werkzeug.debug.preserve_context"] = self._new_contexts.append
-
-        return out
-
-    def _request_from_builder_args(self, args, kwargs):
-        kwargs["environ_base"] = self._copy_environ(kwargs.get("environ_base", {}))
-        builder = EnvironBuilder(self.application, *args, **kwargs)
-
-        try:
-            return builder.get_request()
-        finally:
-            builder.close()
-
-    def open(
-        self,
-        *args: t.Any,
-        buffered: bool = False,
-        follow_redirects: bool = False,
-        **kwargs: t.Any,
-    ) -> "TestResponse":
-        if args and isinstance(
-            args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest)
-        ):
-            if isinstance(args[0], werkzeug.test.EnvironBuilder):
-                builder = copy(args[0])
-                builder.environ_base = self._copy_environ(builder.environ_base or {})
-                request = builder.get_request()
-            elif isinstance(args[0], dict):
-                request = EnvironBuilder.from_environ(
-                    args[0], app=self.application, environ_base=self._copy_environ({})
-                ).get_request()
-            else:
-                # isinstance(args[0], BaseRequest)
-                request = copy(args[0])
-                request.environ = self._copy_environ(request.environ)
-        else:
-            # request is None
-            request = self._request_from_builder_args(args, kwargs)
-
-        # Pop any previously preserved contexts. This prevents contexts
-        # from being preserved across redirects or multiple requests
-        # within a single block.
-        self._context_stack.close()
-
-        response = super().open(
-            request,
-            buffered=buffered,
-            follow_redirects=follow_redirects,
-        )
-        response.json_module = self.application.json  # type: ignore[misc]
-
-        # Re-push contexts that were preserved during the request.
-        while self._new_contexts:
-            cm = self._new_contexts.pop()
-            self._context_stack.enter_context(cm)
-
-        return response
-
-    def __enter__(self) -> "FlaskClient":
-        if self.preserve_context:
-            raise RuntimeError("Cannot nest client invocations")
-        self.preserve_context = True
-        return self
-
-    def __exit__(
-        self,
-        exc_type: t.Optional[type],
-        exc_value: t.Optional[BaseException],
-        tb: t.Optional[TracebackType],
-    ) -> None:
-        self.preserve_context = False
-        self._context_stack.close()
-
-
-class FlaskCliRunner(CliRunner):
-    """A :class:`~click.testing.CliRunner` for testing a Flask app's
-    CLI commands. Typically created using
-    :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`.
-    """
-
-    def __init__(self, app: "Flask", **kwargs: t.Any) -> None:
-        self.app = app
-        super().__init__(**kwargs)
-
-    def invoke(  # type: ignore
-        self, cli: t.Any = None, args: t.Any = None, **kwargs: t.Any
-    ) -> t.Any:
-        """Invokes a CLI command in an isolated environment. See
-        :meth:`CliRunner.invoke <click.testing.CliRunner.invoke>` for
-        full method documentation. See :ref:`testing-cli` for examples.
-
-        If the ``obj`` argument is not given, passes an instance of
-        :class:`~flask.cli.ScriptInfo` that knows how to load the Flask
-        app being tested.
-
-        :param cli: Command object to invoke. Default is the app's
-            :attr:`~flask.app.Flask.cli` group.
-        :param args: List of strings to invoke the command with.
-
-        :return: a :class:`~click.testing.Result` object.
-        """
-        if cli is None:
-            cli = self.app.cli  # type: ignore
-
-        if "obj" not in kwargs:
-            kwargs["obj"] = ScriptInfo(create_app=lambda: self.app)
-
-        return super().invoke(cli, args, **kwargs)

+ 0 - 80
venv/lib/python3.10/site-packages/flask/typing.py

@@ -1,80 +0,0 @@
-import typing as t
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from _typeshed.wsgi import WSGIApplication  # noqa: F401
-    from werkzeug.datastructures import Headers  # noqa: F401
-    from werkzeug.wrappers import Response  # noqa: F401
-
-# The possible types that are directly convertible or are a Response object.
-ResponseValue = t.Union[
-    "Response",
-    str,
-    bytes,
-    t.List[t.Any],
-    # Only dict is actually accepted, but Mapping allows for TypedDict.
-    t.Mapping[str, t.Any],
-    t.Iterator[str],
-    t.Iterator[bytes],
-]
-
-# the possible types for an individual HTTP header
-# This should be a Union, but mypy doesn't pass unless it's a TypeVar.
-HeaderValue = t.Union[str, t.List[str], t.Tuple[str, ...]]
-
-# the possible types for HTTP headers
-HeadersValue = t.Union[
-    "Headers",
-    t.Mapping[str, HeaderValue],
-    t.Sequence[t.Tuple[str, HeaderValue]],
-]
-
-# The possible types returned by a route function.
-ResponseReturnValue = t.Union[
-    ResponseValue,
-    t.Tuple[ResponseValue, HeadersValue],
-    t.Tuple[ResponseValue, int],
-    t.Tuple[ResponseValue, int, HeadersValue],
-    "WSGIApplication",
-]
-
-# Allow any subclass of werkzeug.Response, such as the one from Flask,
-# as a callback argument. Using werkzeug.Response directly makes a
-# callback annotated with flask.Response fail type checking.
-ResponseClass = t.TypeVar("ResponseClass", bound="Response")
-
-AppOrBlueprintKey = t.Optional[str]  # The App key is None, whereas blueprints are named
-AfterRequestCallable = t.Union[
-    t.Callable[[ResponseClass], ResponseClass],
-    t.Callable[[ResponseClass], t.Awaitable[ResponseClass]],
-]
-BeforeFirstRequestCallable = t.Union[
-    t.Callable[[], None], t.Callable[[], t.Awaitable[None]]
-]
-BeforeRequestCallable = t.Union[
-    t.Callable[[], t.Optional[ResponseReturnValue]],
-    t.Callable[[], t.Awaitable[t.Optional[ResponseReturnValue]]],
-]
-ShellContextProcessorCallable = t.Callable[[], t.Dict[str, t.Any]]
-TeardownCallable = t.Union[
-    t.Callable[[t.Optional[BaseException]], None],
-    t.Callable[[t.Optional[BaseException]], t.Awaitable[None]],
-]
-TemplateContextProcessorCallable = t.Callable[[], t.Dict[str, t.Any]]
-TemplateFilterCallable = t.Callable[..., t.Any]
-TemplateGlobalCallable = t.Callable[..., t.Any]
-TemplateTestCallable = t.Callable[..., bool]
-URLDefaultCallable = t.Callable[[str, dict], None]
-URLValuePreprocessorCallable = t.Callable[[t.Optional[str], t.Optional[dict]], None]
-
-# This should take Exception, but that either breaks typing the argument
-# with a specific exception, or decorating multiple times with different
-# exceptions (and using a union type on the argument).
-# https://github.com/pallets/flask/issues/4095
-# https://github.com/pallets/flask/issues/4295
-# https://github.com/pallets/flask/issues/4297
-ErrorHandlerCallable = t.Callable[[t.Any], ResponseReturnValue]
-
-RouteCallable = t.Union[
-    t.Callable[..., ResponseReturnValue],
-    t.Callable[..., t.Awaitable[ResponseReturnValue]],
-]

+ 0 - 188
venv/lib/python3.10/site-packages/flask/views.py

@@ -1,188 +0,0 @@
-import typing as t
-
-from . import typing as ft
-from .globals import current_app
-from .globals import request
-
-
-http_method_funcs = frozenset(
-    ["get", "post", "head", "options", "delete", "put", "trace", "patch"]
-)
-
-
-class View:
-    """Subclass this class and override :meth:`dispatch_request` to
-    create a generic class-based view. Call :meth:`as_view` to create a
-    view function that creates an instance of the class with the given
-    arguments and calls its ``dispatch_request`` method with any URL
-    variables.
-
-    See :doc:`views` for a detailed guide.
-
-    .. code-block:: python
-
-        class Hello(View):
-            init_every_request = False
-
-            def dispatch_request(self, name):
-                return f"Hello, {name}!"
-
-        app.add_url_rule(
-            "/hello/<name>", view_func=Hello.as_view("hello")
-        )
-
-    Set :attr:`methods` on the class to change what methods the view
-    accepts.
-
-    Set :attr:`decorators` on the class to apply a list of decorators to
-    the generated view function. Decorators applied to the class itself
-    will not be applied to the generated view function!
-
-    Set :attr:`init_every_request` to ``False`` for efficiency, unless
-    you need to store request-global data on ``self``.
-    """
-
-    #: The methods this view is registered for. Uses the same default
-    #: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and
-    #: ``add_url_rule`` by default.
-    methods: t.ClassVar[t.Optional[t.Collection[str]]] = None
-
-    #: Control whether the ``OPTIONS`` method is handled automatically.
-    #: Uses the same default (``True``) as ``route`` and
-    #: ``add_url_rule`` by default.
-    provide_automatic_options: t.ClassVar[t.Optional[bool]] = None
-
-    #: A list of decorators to apply, in order, to the generated view
-    #: function. Remember that ``@decorator`` syntax is applied bottom
-    #: to top, so the first decorator in the list would be the bottom
-    #: decorator.
-    #:
-    #: .. versionadded:: 0.8
-    decorators: t.ClassVar[t.List[t.Callable]] = []
-
-    #: Create a new instance of this view class for every request by
-    #: default. If a view subclass sets this to ``False``, the same
-    #: instance is used for every request.
-    #:
-    #: A single instance is more efficient, especially if complex setup
-    #: is done during init. However, storing data on ``self`` is no
-    #: longer safe across requests, and :data:`~flask.g` should be used
-    #: instead.
-    #:
-    #: .. versionadded:: 2.2
-    init_every_request: t.ClassVar[bool] = True
-
-    def dispatch_request(self) -> ft.ResponseReturnValue:
-        """The actual view function behavior. Subclasses must override
-        this and return a valid response. Any variables from the URL
-        rule are passed as keyword arguments.
-        """
-        raise NotImplementedError()
-
-    @classmethod
-    def as_view(
-        cls, name: str, *class_args: t.Any, **class_kwargs: t.Any
-    ) -> ft.RouteCallable:
-        """Convert the class into a view function that can be registered
-        for a route.
-
-        By default, the generated view will create a new instance of the
-        view class for every request and call its
-        :meth:`dispatch_request` method. If the view class sets
-        :attr:`init_every_request` to ``False``, the same instance will
-        be used for every request.
-
-        The arguments passed to this method are forwarded to the view
-        class ``__init__`` method.
-
-        .. versionchanged:: 2.2
-            Added the ``init_every_request`` class attribute.
-        """
-        if cls.init_every_request:
-
-            def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
-                self = view.view_class(  # type: ignore[attr-defined]
-                    *class_args, **class_kwargs
-                )
-                return current_app.ensure_sync(self.dispatch_request)(**kwargs)
-
-        else:
-            self = cls(*class_args, **class_kwargs)
-
-            def view(**kwargs: t.Any) -> ft.ResponseReturnValue:
-                return current_app.ensure_sync(self.dispatch_request)(**kwargs)
-
-        if cls.decorators:
-            view.__name__ = name
-            view.__module__ = cls.__module__
-            for decorator in cls.decorators:
-                view = decorator(view)
-
-        # We attach the view class to the view function for two reasons:
-        # first of all it allows us to easily figure out what class-based
-        # view this thing came from, secondly it's also used for instantiating
-        # the view class so you can actually replace it with something else
-        # for testing purposes and debugging.
-        view.view_class = cls  # type: ignore
-        view.__name__ = name
-        view.__doc__ = cls.__doc__
-        view.__module__ = cls.__module__
-        view.methods = cls.methods  # type: ignore
-        view.provide_automatic_options = cls.provide_automatic_options  # type: ignore
-        return view
-
-
-class MethodView(View):
-    """Dispatches request methods to the corresponding instance methods.
-    For example, if you implement a ``get`` method, it will be used to
-    handle ``GET`` requests.
-
-    This can be useful for defining a REST API.
-
-    :attr:`methods` is automatically set based on the methods defined on
-    the class.
-
-    See :doc:`views` for a detailed guide.
-
-    .. code-block:: python
-
-        class CounterAPI(MethodView):
-            def get(self):
-                return str(session.get("counter", 0))
-
-            def post(self):
-                session["counter"] = session.get("counter", 0) + 1
-                return redirect(url_for("counter"))
-
-        app.add_url_rule(
-            "/counter", view_func=CounterAPI.as_view("counter")
-        )
-    """
-
-    def __init_subclass__(cls, **kwargs: t.Any) -> None:
-        super().__init_subclass__(**kwargs)
-
-        if "methods" not in cls.__dict__:
-            methods = set()
-
-            for base in cls.__bases__:
-                if getattr(base, "methods", None):
-                    methods.update(base.methods)  # type: ignore[attr-defined]
-
-            for key in http_method_funcs:
-                if hasattr(cls, key):
-                    methods.add(key.upper())
-
-            if methods:
-                cls.methods = methods
-
-    def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue:
-        meth = getattr(self, request.method.lower(), None)
-
-        # If the request method is HEAD and we don't have a handler for it
-        # retry with GET.
-        if meth is None and request.method == "HEAD":
-            meth = getattr(self, "get", None)
-
-        assert meth is not None, f"Unimplemented method {request.method!r}"
-        return current_app.ensure_sync(meth)(**kwargs)

+ 0 - 171
venv/lib/python3.10/site-packages/flask/wrappers.py

@@ -1,171 +0,0 @@
-import typing as t
-
-from werkzeug.exceptions import BadRequest
-from werkzeug.wrappers import Request as RequestBase
-from werkzeug.wrappers import Response as ResponseBase
-
-from . import json
-from .globals import current_app
-from .helpers import _split_blueprint_path
-
-if t.TYPE_CHECKING:  # pragma: no cover
-    from werkzeug.routing import Rule
-
-
-class Request(RequestBase):
-    """The request object used by default in Flask.  Remembers the
-    matched endpoint and view arguments.
-
-    It is what ends up as :class:`~flask.request`.  If you want to replace
-    the request object used you can subclass this and set
-    :attr:`~flask.Flask.request_class` to your subclass.
-
-    The request object is a :class:`~werkzeug.wrappers.Request` subclass and
-    provides all of the attributes Werkzeug defines plus a few Flask
-    specific ones.
-    """
-
-    json_module = json
-
-    #: The internal URL rule that matched the request.  This can be
-    #: useful to inspect which methods are allowed for the URL from
-    #: a before/after handler (``request.url_rule.methods``) etc.
-    #: Though if the request's method was invalid for the URL rule,
-    #: the valid list is available in ``routing_exception.valid_methods``
-    #: instead (an attribute of the Werkzeug exception
-    #: :exc:`~werkzeug.exceptions.MethodNotAllowed`)
-    #: because the request was never internally bound.
-    #:
-    #: .. versionadded:: 0.6
-    url_rule: t.Optional["Rule"] = None
-
-    #: A dict of view arguments that matched the request.  If an exception
-    #: happened when matching, this will be ``None``.
-    view_args: t.Optional[t.Dict[str, t.Any]] = None
-
-    #: If matching the URL failed, this is the exception that will be
-    #: raised / was raised as part of the request handling.  This is
-    #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or
-    #: something similar.
-    routing_exception: t.Optional[Exception] = None
-
-    @property
-    def max_content_length(self) -> t.Optional[int]:  # type: ignore
-        """Read-only view of the ``MAX_CONTENT_LENGTH`` config key."""
-        if current_app:
-            return current_app.config["MAX_CONTENT_LENGTH"]
-        else:
-            return None
-
-    @property
-    def endpoint(self) -> t.Optional[str]:
-        """The endpoint that matched the request URL.
-
-        This will be ``None`` if matching failed or has not been
-        performed yet.
-
-        This in combination with :attr:`view_args` can be used to
-        reconstruct the same URL or a modified URL.
-        """
-        if self.url_rule is not None:
-            return self.url_rule.endpoint
-
-        return None
-
-    @property
-    def blueprint(self) -> t.Optional[str]:
-        """The registered name of the current blueprint.
-
-        This will be ``None`` if the endpoint is not part of a
-        blueprint, or if URL matching failed or has not been performed
-        yet.
-
-        This does not necessarily match the name the blueprint was
-        created with. It may have been nested, or registered with a
-        different name.
-        """
-        endpoint = self.endpoint
-
-        if endpoint is not None and "." in endpoint:
-            return endpoint.rpartition(".")[0]
-
-        return None
-
-    @property
-    def blueprints(self) -> t.List[str]:
-        """The registered names of the current blueprint upwards through
-        parent blueprints.
-
-        This will be an empty list if there is no current blueprint, or
-        if URL matching failed.
-
-        .. versionadded:: 2.0.1
-        """
-        name = self.blueprint
-
-        if name is None:
-            return []
-
-        return _split_blueprint_path(name)
-
-    def _load_form_data(self) -> None:
-        super()._load_form_data()
-
-        # In debug mode we're replacing the files multidict with an ad-hoc
-        # subclass that raises a different error for key errors.
-        if (
-            current_app
-            and current_app.debug
-            and self.mimetype != "multipart/form-data"
-            and not self.files
-        ):
-            from .debughelpers import attach_enctype_error_multidict
-
-            attach_enctype_error_multidict(self)
-
-    def on_json_loading_failed(self, e: t.Optional[ValueError]) -> t.Any:
-        try:
-            return super().on_json_loading_failed(e)
-        except BadRequest as e:
-            if current_app and current_app.debug:
-                raise
-
-            raise BadRequest() from e
-
-
-class Response(ResponseBase):
-    """The response object that is used by default in Flask.  Works like the
-    response object from Werkzeug but is set to have an HTML mimetype by
-    default.  Quite often you don't have to create this object yourself because
-    :meth:`~flask.Flask.make_response` will take care of that for you.
-
-    If you want to replace the response object used you can subclass this and
-    set :attr:`~flask.Flask.response_class` to your subclass.
-
-    .. versionchanged:: 1.0
-        JSON support is added to the response, like the request. This is useful
-        when testing to get the test client response data as JSON.
-
-    .. versionchanged:: 1.0
-
-        Added :attr:`max_cookie_size`.
-    """
-
-    default_mimetype = "text/html"
-
-    json_module = json
-
-    autocorrect_location_header = False
-
-    @property
-    def max_cookie_size(self) -> int:  # type: ignore
-        """Read-only view of the :data:`MAX_COOKIE_SIZE` config key.
-
-        See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in
-        Werkzeug's docs.
-        """
-        if current_app:
-            return current_app.config["MAX_COOKIE_SIZE"]
-
-        # return Werkzeug's default when not in an app context
-        return super().max_cookie_size

+ 0 - 1
venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/INSTALLER

@@ -1 +0,0 @@
-pip

+ 0 - 28
venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/LICENSE.rst

@@ -1,28 +0,0 @@
-Copyright 2011 Pallets
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1.  Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-2.  Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in the
-    documentation and/or other materials provided with the distribution.
-
-3.  Neither the name of the copyright holder nor the names of its
-    contributors may be used to endorse or promote products derived from
-    this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 97
venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/METADATA

@@ -1,97 +0,0 @@
-Metadata-Version: 2.1
-Name: itsdangerous
-Version: 2.1.2
-Summary: Safely pass data to untrusted environments and back.
-Home-page: https://palletsprojects.com/p/itsdangerous/
-Author: Armin Ronacher
-Author-email: armin.ronacher@active-4.com
-Maintainer: Pallets
-Maintainer-email: contact@palletsprojects.com
-License: BSD-3-Clause
-Project-URL: Donate, https://palletsprojects.com/donate
-Project-URL: Documentation, https://itsdangerous.palletsprojects.com/
-Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/
-Project-URL: Source Code, https://github.com/pallets/itsdangerous/
-Project-URL: Issue Tracker, https://github.com/pallets/itsdangerous/issues/
-Project-URL: Twitter, https://twitter.com/PalletsTeam
-Project-URL: Chat, https://discord.gg/pallets
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: BSD License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Requires-Python: >=3.7
-Description-Content-Type: text/x-rst
-License-File: LICENSE.rst
-
-ItsDangerous
-============
-
-... so better sign this
-
-Various helpers to pass data to untrusted environments and to get it
-back safe and sound. Data is cryptographically signed to ensure that a
-token has not been tampered with.
-
-It's possible to customize how data is serialized. Data is compressed as
-needed. A timestamp can be added and verified automatically while
-loading a token.
-
-
-Installing
-----------
-
-Install and update using `pip`_:
-
-.. code-block:: text
-
-    pip install -U itsdangerous
-
-.. _pip: https://pip.pypa.io/en/stable/getting-started/
-
-
-A Simple Example
-----------------
-
-Here's how you could generate a token for transmitting a user's id and
-name between web requests.
-
-.. code-block:: python
-
-    from itsdangerous import URLSafeSerializer
-    auth_s = URLSafeSerializer("secret key", "auth")
-    token = auth_s.dumps({"id": 5, "name": "itsdangerous"})
-
-    print(token)
-    # eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg
-
-    data = auth_s.loads(token)
-    print(data["name"])
-    # itsdangerous
-
-
-Donate
-------
-
-The Pallets organization develops and supports ItsDangerous and other
-popular packages. In order to grow the community of contributors and
-users, and allow the maintainers to devote more time to the projects,
-`please donate today`_.
-
-.. _please donate today: https://palletsprojects.com/donate
-
-
-Links
------
-
--   Documentation: https://itsdangerous.palletsprojects.com/
--   Changes: https://itsdangerous.palletsprojects.com/changes/
--   PyPI Releases: https://pypi.org/project/ItsDangerous/
--   Source Code: https://github.com/pallets/itsdangerous/
--   Issue Tracker: https://github.com/pallets/itsdangerous/issues/
--   Website: https://palletsprojects.com/p/itsdangerous/
--   Twitter: https://twitter.com/PalletsTeam
--   Chat: https://discord.gg/pallets
-
-

+ 0 - 23
venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/RECORD

@@ -1,23 +0,0 @@
-itsdangerous-2.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
-itsdangerous-2.1.2.dist-info/LICENSE.rst,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475
-itsdangerous-2.1.2.dist-info/METADATA,sha256=ThrHIJQ_6XlfbDMCAVe_hawT7IXiIxnTBIDrwxxtucQ,2928
-itsdangerous-2.1.2.dist-info/RECORD,,
-itsdangerous-2.1.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
-itsdangerous-2.1.2.dist-info/top_level.txt,sha256=gKN1OKLk81i7fbWWildJA88EQ9NhnGMSvZqhfz9ICjk,13
-itsdangerous/__init__.py,sha256=n4mkyjlIVn23pgsgCIw0MJKPdcHIetyeRpe5Fwsn8qg,876
-itsdangerous/__pycache__/__init__.cpython-310.pyc,,
-itsdangerous/__pycache__/_json.cpython-310.pyc,,
-itsdangerous/__pycache__/encoding.cpython-310.pyc,,
-itsdangerous/__pycache__/exc.cpython-310.pyc,,
-itsdangerous/__pycache__/serializer.cpython-310.pyc,,
-itsdangerous/__pycache__/signer.cpython-310.pyc,,
-itsdangerous/__pycache__/timed.cpython-310.pyc,,
-itsdangerous/__pycache__/url_safe.cpython-310.pyc,,
-itsdangerous/_json.py,sha256=wIhs_7-_XZolmyr-JvKNiy_LgAcfevYR0qhCVdlIhg8,450
-itsdangerous/encoding.py,sha256=pgh86snHC76dPLNCnPlrjR5SaYL_M8H-gWRiiLNbhCU,1419
-itsdangerous/exc.py,sha256=VFxmP2lMoSJFqxNMzWonqs35ROII4-fvCBfG0v1Tkbs,3206
-itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
-itsdangerous/serializer.py,sha256=zgZ1-U705jHDpt62x_pmLJdryEKDNAbt5UkJtnkcCSw,11144
-itsdangerous/signer.py,sha256=QUH0iX0in-OTptMAXKU5zWMwmOCXn1fsDsubXiGdFN4,9367
-itsdangerous/timed.py,sha256=5CBWLds4Nm8-3bFVC8RxNzFjx6PSwjch8wuZ5cwcHFI,8174
-itsdangerous/url_safe.py,sha256=5bC4jSKOjWNRkWrFseifWVXUnHnPgwOLROjiOwb-eeo,2402

+ 0 - 5
venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/WHEEL

@@ -1,5 +0,0 @@
-Wheel-Version: 1.0
-Generator: bdist_wheel (0.37.1)
-Root-Is-Purelib: true
-Tag: py3-none-any
-

+ 0 - 1
venv/lib/python3.10/site-packages/itsdangerous-2.1.2.dist-info/top_level.txt

@@ -1 +0,0 @@
-itsdangerous

+ 0 - 19
venv/lib/python3.10/site-packages/itsdangerous/__init__.py

@@ -1,19 +0,0 @@
-from .encoding import base64_decode as base64_decode
-from .encoding import base64_encode as base64_encode
-from .encoding import want_bytes as want_bytes
-from .exc import BadData as BadData
-from .exc import BadHeader as BadHeader
-from .exc import BadPayload as BadPayload
-from .exc import BadSignature as BadSignature
-from .exc import BadTimeSignature as BadTimeSignature
-from .exc import SignatureExpired as SignatureExpired
-from .serializer import Serializer as Serializer
-from .signer import HMACAlgorithm as HMACAlgorithm
-from .signer import NoneAlgorithm as NoneAlgorithm
-from .signer import Signer as Signer
-from .timed import TimedSerializer as TimedSerializer
-from .timed import TimestampSigner as TimestampSigner
-from .url_safe import URLSafeSerializer as URLSafeSerializer
-from .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer
-
-__version__ = "2.1.2"

Some files were not shown because too many files changed in this diff