koichi12 commited on
Commit
be6050f
·
verified ·
1 Parent(s): bf8f71c

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .venv/lib/python3.11/site-packages/pip/_vendor/certifi/__init__.py +4 -0
  2. .venv/lib/python3.11/site-packages/pip/_vendor/certifi/__main__.py +12 -0
  3. .venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-311.pyc +0 -0
  4. .venv/lib/python3.11/site-packages/pip/_vendor/certifi/cacert.pem +0 -0
  5. .venv/lib/python3.11/site-packages/pip/_vendor/certifi/core.py +108 -0
  6. .venv/lib/python3.11/site-packages/pip/_vendor/certifi/py.typed +0 -0
  7. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__init__.py +182 -0
  8. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-311.pyc +0 -0
  9. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-311.pyc +0 -0
  10. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-311.pyc +0 -0
  11. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-311.pyc +0 -0
  12. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/api.cpython-311.pyc +0 -0
  13. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-311.pyc +0 -0
  14. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-311.pyc +0 -0
  15. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-311.pyc +0 -0
  16. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-311.pyc +0 -0
  17. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-311.pyc +0 -0
  18. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/help.cpython-311.pyc +0 -0
  19. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-311.pyc +0 -0
  20. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/models.cpython-311.pyc +0 -0
  21. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-311.pyc +0 -0
  22. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-311.pyc +0 -0
  23. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-311.pyc +0 -0
  24. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-311.pyc +0 -0
  25. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-311.pyc +0 -0
  26. .venv/lib/python3.11/site-packages/pip/_vendor/requests/__version__.py +14 -0
  27. .venv/lib/python3.11/site-packages/pip/_vendor/requests/_internal_utils.py +50 -0
  28. .venv/lib/python3.11/site-packages/pip/_vendor/requests/adapters.py +538 -0
  29. .venv/lib/python3.11/site-packages/pip/_vendor/requests/api.py +157 -0
  30. .venv/lib/python3.11/site-packages/pip/_vendor/requests/auth.py +315 -0
  31. .venv/lib/python3.11/site-packages/pip/_vendor/requests/certs.py +24 -0
  32. .venv/lib/python3.11/site-packages/pip/_vendor/requests/compat.py +67 -0
  33. .venv/lib/python3.11/site-packages/pip/_vendor/requests/cookies.py +561 -0
  34. .venv/lib/python3.11/site-packages/pip/_vendor/requests/exceptions.py +141 -0
  35. .venv/lib/python3.11/site-packages/pip/_vendor/requests/help.py +131 -0
  36. .venv/lib/python3.11/site-packages/pip/_vendor/requests/hooks.py +33 -0
  37. .venv/lib/python3.11/site-packages/pip/_vendor/requests/models.py +1034 -0
  38. .venv/lib/python3.11/site-packages/pip/_vendor/requests/packages.py +16 -0
  39. .venv/lib/python3.11/site-packages/pip/_vendor/requests/sessions.py +833 -0
  40. .venv/lib/python3.11/site-packages/pip/_vendor/requests/status_codes.py +128 -0
  41. .venv/lib/python3.11/site-packages/pip/_vendor/requests/structures.py +99 -0
  42. .venv/lib/python3.11/site-packages/pip/_vendor/requests/utils.py +1094 -0
  43. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-311.pyc +0 -0
  44. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-311.pyc +0 -0
  45. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-311.pyc +0 -0
  46. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-311.pyc +0 -0
  47. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-311.pyc +0 -0
  48. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-311.pyc +0 -0
  49. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-311.pyc +0 -0
  50. .venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-311.pyc +0 -0
.venv/lib/python3.11/site-packages/pip/_vendor/certifi/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from .core import contents, where
2
+
3
+ __all__ = ["contents", "where"]
4
+ __version__ = "2023.07.22"
.venv/lib/python3.11/site-packages/pip/_vendor/certifi/__main__.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import argparse
2
+
3
+ from pip._vendor.certifi import contents, where
4
+
5
+ parser = argparse.ArgumentParser()
6
+ parser.add_argument("-c", "--contents", action="store_true")
7
+ args = parser.parse_args()
8
+
9
+ if args.contents:
10
+ print(contents())
11
+ else:
12
+ print(where())
.venv/lib/python3.11/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-311.pyc ADDED
Binary file (735 Bytes). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/certifi/cacert.pem ADDED
The diff for this file is too large to render. See raw diff
 
.venv/lib/python3.11/site-packages/pip/_vendor/certifi/core.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ certifi.py
3
+ ~~~~~~~~~~
4
+
5
+ This module returns the installation location of cacert.pem or its contents.
6
+ """
7
+ import sys
8
+
9
+
10
+ if sys.version_info >= (3, 11):
11
+
12
+ from importlib.resources import as_file, files
13
+
14
+ _CACERT_CTX = None
15
+ _CACERT_PATH = None
16
+
17
+ def where() -> str:
18
+ # This is slightly terrible, but we want to delay extracting the file
19
+ # in cases where we're inside of a zipimport situation until someone
20
+ # actually calls where(), but we don't want to re-extract the file
21
+ # on every call of where(), so we'll do it once then store it in a
22
+ # global variable.
23
+ global _CACERT_CTX
24
+ global _CACERT_PATH
25
+ if _CACERT_PATH is None:
26
+ # This is slightly janky, the importlib.resources API wants you to
27
+ # manage the cleanup of this file, so it doesn't actually return a
28
+ # path, it returns a context manager that will give you the path
29
+ # when you enter it and will do any cleanup when you leave it. In
30
+ # the common case of not needing a temporary file, it will just
31
+ # return the file system location and the __exit__() is a no-op.
32
+ #
33
+ # We also have to hold onto the actual context manager, because
34
+ # it will do the cleanup whenever it gets garbage collected, so
35
+ # we will also store that at the global level as well.
36
+ _CACERT_CTX = as_file(files("pip._vendor.certifi").joinpath("cacert.pem"))
37
+ _CACERT_PATH = str(_CACERT_CTX.__enter__())
38
+
39
+ return _CACERT_PATH
40
+
41
+ def contents() -> str:
42
+ return files("pip._vendor.certifi").joinpath("cacert.pem").read_text(encoding="ascii")
43
+
44
+ elif sys.version_info >= (3, 7):
45
+
46
+ from importlib.resources import path as get_path, read_text
47
+
48
+ _CACERT_CTX = None
49
+ _CACERT_PATH = None
50
+
51
+ def where() -> str:
52
+ # This is slightly terrible, but we want to delay extracting the
53
+ # file in cases where we're inside of a zipimport situation until
54
+ # someone actually calls where(), but we don't want to re-extract
55
+ # the file on every call of where(), so we'll do it once then store
56
+ # it in a global variable.
57
+ global _CACERT_CTX
58
+ global _CACERT_PATH
59
+ if _CACERT_PATH is None:
60
+ # This is slightly janky, the importlib.resources API wants you
61
+ # to manage the cleanup of this file, so it doesn't actually
62
+ # return a path, it returns a context manager that will give
63
+ # you the path when you enter it and will do any cleanup when
64
+ # you leave it. In the common case of not needing a temporary
65
+ # file, it will just return the file system location and the
66
+ # __exit__() is a no-op.
67
+ #
68
+ # We also have to hold onto the actual context manager, because
69
+ # it will do the cleanup whenever it gets garbage collected, so
70
+ # we will also store that at the global level as well.
71
+ _CACERT_CTX = get_path("pip._vendor.certifi", "cacert.pem")
72
+ _CACERT_PATH = str(_CACERT_CTX.__enter__())
73
+
74
+ return _CACERT_PATH
75
+
76
+ def contents() -> str:
77
+ return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii")
78
+
79
+ else:
80
+ import os
81
+ import types
82
+ from typing import Union
83
+
84
+ Package = Union[types.ModuleType, str]
85
+ Resource = Union[str, "os.PathLike"]
86
+
87
+ # This fallback will work for Python versions prior to 3.7 that lack the
88
+ # importlib.resources module but relies on the existing `where` function
89
+ # so won't address issues with environments like PyOxidizer that don't set
90
+ # __file__ on modules.
91
+ def read_text(
92
+ package: Package,
93
+ resource: Resource,
94
+ encoding: str = 'utf-8',
95
+ errors: str = 'strict'
96
+ ) -> str:
97
+ with open(where(), encoding=encoding) as data:
98
+ return data.read()
99
+
100
+ # If we don't have importlib.resources, then we will just do the old logic
101
+ # of assuming we're on the filesystem and munge the path directly.
102
+ def where() -> str:
103
+ f = os.path.dirname(__file__)
104
+
105
+ return os.path.join(f, "cacert.pem")
106
+
107
+ def contents() -> str:
108
+ return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii")
.venv/lib/python3.11/site-packages/pip/_vendor/certifi/py.typed ADDED
File without changes
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__init__.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # __
2
+ # /__) _ _ _ _ _/ _
3
+ # / ( (- (/ (/ (- _) / _)
4
+ # /
5
+
6
+ """
7
+ Requests HTTP Library
8
+ ~~~~~~~~~~~~~~~~~~~~~
9
+
10
+ Requests is an HTTP library, written in Python, for human beings.
11
+ Basic GET usage:
12
+
13
+ >>> import requests
14
+ >>> r = requests.get('https://www.python.org')
15
+ >>> r.status_code
16
+ 200
17
+ >>> b'Python is a programming language' in r.content
18
+ True
19
+
20
+ ... or POST:
21
+
22
+ >>> payload = dict(key1='value1', key2='value2')
23
+ >>> r = requests.post('https://httpbin.org/post', data=payload)
24
+ >>> print(r.text)
25
+ {
26
+ ...
27
+ "form": {
28
+ "key1": "value1",
29
+ "key2": "value2"
30
+ },
31
+ ...
32
+ }
33
+
34
+ The other HTTP methods are supported - see `requests.api`. Full documentation
35
+ is at <https://requests.readthedocs.io>.
36
+
37
+ :copyright: (c) 2017 by Kenneth Reitz.
38
+ :license: Apache 2.0, see LICENSE for more details.
39
+ """
40
+
41
+ import warnings
42
+
43
+ from pip._vendor import urllib3
44
+
45
+ from .exceptions import RequestsDependencyWarning
46
+
47
+ charset_normalizer_version = None
48
+
49
+ try:
50
+ from pip._vendor.chardet import __version__ as chardet_version
51
+ except ImportError:
52
+ chardet_version = None
53
+
54
+
55
+ def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version):
56
+ urllib3_version = urllib3_version.split(".")
57
+ assert urllib3_version != ["dev"] # Verify urllib3 isn't installed from git.
58
+
59
+ # Sometimes, urllib3 only reports its version as 16.1.
60
+ if len(urllib3_version) == 2:
61
+ urllib3_version.append("0")
62
+
63
+ # Check urllib3 for compatibility.
64
+ major, minor, patch = urllib3_version # noqa: F811
65
+ major, minor, patch = int(major), int(minor), int(patch)
66
+ # urllib3 >= 1.21.1
67
+ assert major >= 1
68
+ if major == 1:
69
+ assert minor >= 21
70
+
71
+ # Check charset_normalizer for compatibility.
72
+ if chardet_version:
73
+ major, minor, patch = chardet_version.split(".")[:3]
74
+ major, minor, patch = int(major), int(minor), int(patch)
75
+ # chardet_version >= 3.0.2, < 6.0.0
76
+ assert (3, 0, 2) <= (major, minor, patch) < (6, 0, 0)
77
+ elif charset_normalizer_version:
78
+ major, minor, patch = charset_normalizer_version.split(".")[:3]
79
+ major, minor, patch = int(major), int(minor), int(patch)
80
+ # charset_normalizer >= 2.0.0 < 4.0.0
81
+ assert (2, 0, 0) <= (major, minor, patch) < (4, 0, 0)
82
+ else:
83
+ raise Exception("You need either charset_normalizer or chardet installed")
84
+
85
+
86
+ def _check_cryptography(cryptography_version):
87
+ # cryptography < 1.3.4
88
+ try:
89
+ cryptography_version = list(map(int, cryptography_version.split(".")))
90
+ except ValueError:
91
+ return
92
+
93
+ if cryptography_version < [1, 3, 4]:
94
+ warning = "Old version of cryptography ({}) may cause slowdown.".format(
95
+ cryptography_version
96
+ )
97
+ warnings.warn(warning, RequestsDependencyWarning)
98
+
99
+
100
+ # Check imported dependencies for compatibility.
101
+ try:
102
+ check_compatibility(
103
+ urllib3.__version__, chardet_version, charset_normalizer_version
104
+ )
105
+ except (AssertionError, ValueError):
106
+ warnings.warn(
107
+ "urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
108
+ "version!".format(
109
+ urllib3.__version__, chardet_version, charset_normalizer_version
110
+ ),
111
+ RequestsDependencyWarning,
112
+ )
113
+
114
+ # Attempt to enable urllib3's fallback for SNI support
115
+ # if the standard library doesn't support SNI or the
116
+ # 'ssl' library isn't available.
117
+ try:
118
+ # Note: This logic prevents upgrading cryptography on Windows, if imported
119
+ # as part of pip.
120
+ from pip._internal.utils.compat import WINDOWS
121
+ if not WINDOWS:
122
+ raise ImportError("pip internals: don't import cryptography on Windows")
123
+ try:
124
+ import ssl
125
+ except ImportError:
126
+ ssl = None
127
+
128
+ if not getattr(ssl, "HAS_SNI", False):
129
+ from pip._vendor.urllib3.contrib import pyopenssl
130
+
131
+ pyopenssl.inject_into_urllib3()
132
+
133
+ # Check cryptography version
134
+ from cryptography import __version__ as cryptography_version
135
+
136
+ _check_cryptography(cryptography_version)
137
+ except ImportError:
138
+ pass
139
+
140
+ # urllib3's DependencyWarnings should be silenced.
141
+ from pip._vendor.urllib3.exceptions import DependencyWarning
142
+
143
+ warnings.simplefilter("ignore", DependencyWarning)
144
+
145
+ # Set default logging handler to avoid "No handler found" warnings.
146
+ import logging
147
+ from logging import NullHandler
148
+
149
+ from . import packages, utils
150
+ from .__version__ import (
151
+ __author__,
152
+ __author_email__,
153
+ __build__,
154
+ __cake__,
155
+ __copyright__,
156
+ __description__,
157
+ __license__,
158
+ __title__,
159
+ __url__,
160
+ __version__,
161
+ )
162
+ from .api import delete, get, head, options, patch, post, put, request
163
+ from .exceptions import (
164
+ ConnectionError,
165
+ ConnectTimeout,
166
+ FileModeWarning,
167
+ HTTPError,
168
+ JSONDecodeError,
169
+ ReadTimeout,
170
+ RequestException,
171
+ Timeout,
172
+ TooManyRedirects,
173
+ URLRequired,
174
+ )
175
+ from .models import PreparedRequest, Request, Response
176
+ from .sessions import Session, session
177
+ from .status_codes import codes
178
+
179
+ logging.getLogger(__name__).addHandler(NullHandler())
180
+
181
+ # FileModeWarnings go off per the default.
182
+ warnings.simplefilter("default", FileModeWarning, append=True)
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (6.43 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-311.pyc ADDED
Binary file (580 Bytes). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-311.pyc ADDED
Binary file (2.14 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-311.pyc ADDED
Binary file (23.2 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/api.cpython-311.pyc ADDED
Binary file (7.5 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-311.pyc ADDED
Binary file (14.6 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-311.pyc ADDED
Binary file (976 Bytes). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-311.pyc ADDED
Binary file (1.8 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-311.pyc ADDED
Binary file (27.1 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-311.pyc ADDED
Binary file (8.52 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/help.cpython-311.pyc ADDED
Binary file (4.51 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-311.pyc ADDED
Binary file (1.24 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/models.cpython-311.pyc ADDED
Binary file (38.8 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-311.pyc ADDED
Binary file (824 Bytes). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-311.pyc ADDED
Binary file (29.7 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-311.pyc ADDED
Binary file (6.23 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-311.pyc ADDED
Binary file (6.22 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-311.pyc ADDED
Binary file (40.3 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/requests/__version__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # .-. .-. .-. . . .-. .-. .-. .-.
2
+ # |( |- |.| | | |- `-. | `-.
3
+ # ' ' `-' `-`.`-' `-' `-' ' `-'
4
+
5
+ __title__ = "requests"
6
+ __description__ = "Python HTTP for Humans."
7
+ __url__ = "https://requests.readthedocs.io"
8
+ __version__ = "2.31.0"
9
+ __build__ = 0x023100
10
+ __author__ = "Kenneth Reitz"
11
+ __author_email__ = "me@kennethreitz.org"
12
+ __license__ = "Apache 2.0"
13
+ __copyright__ = "Copyright Kenneth Reitz"
14
+ __cake__ = "\u2728 \U0001f370 \u2728"
.venv/lib/python3.11/site-packages/pip/_vendor/requests/_internal_utils.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests._internal_utils
3
+ ~~~~~~~~~~~~~~
4
+
5
+ Provides utility functions that are consumed internally by Requests
6
+ which depend on extremely few external helpers (such as compat)
7
+ """
8
+ import re
9
+
10
+ from .compat import builtin_str
11
+
12
+ _VALID_HEADER_NAME_RE_BYTE = re.compile(rb"^[^:\s][^:\r\n]*$")
13
+ _VALID_HEADER_NAME_RE_STR = re.compile(r"^[^:\s][^:\r\n]*$")
14
+ _VALID_HEADER_VALUE_RE_BYTE = re.compile(rb"^\S[^\r\n]*$|^$")
15
+ _VALID_HEADER_VALUE_RE_STR = re.compile(r"^\S[^\r\n]*$|^$")
16
+
17
+ _HEADER_VALIDATORS_STR = (_VALID_HEADER_NAME_RE_STR, _VALID_HEADER_VALUE_RE_STR)
18
+ _HEADER_VALIDATORS_BYTE = (_VALID_HEADER_NAME_RE_BYTE, _VALID_HEADER_VALUE_RE_BYTE)
19
+ HEADER_VALIDATORS = {
20
+ bytes: _HEADER_VALIDATORS_BYTE,
21
+ str: _HEADER_VALIDATORS_STR,
22
+ }
23
+
24
+
25
+ def to_native_string(string, encoding="ascii"):
26
+ """Given a string object, regardless of type, returns a representation of
27
+ that string in the native string type, encoding and decoding where
28
+ necessary. This assumes ASCII unless told otherwise.
29
+ """
30
+ if isinstance(string, builtin_str):
31
+ out = string
32
+ else:
33
+ out = string.decode(encoding)
34
+
35
+ return out
36
+
37
+
38
+ def unicode_is_ascii(u_string):
39
+ """Determine if unicode string only contains ASCII characters.
40
+
41
+ :param str u_string: unicode string to check. Must be unicode
42
+ and not Python 2 `str`.
43
+ :rtype: bool
44
+ """
45
+ assert isinstance(u_string, str)
46
+ try:
47
+ u_string.encode("ascii")
48
+ return True
49
+ except UnicodeEncodeError:
50
+ return False
.venv/lib/python3.11/site-packages/pip/_vendor/requests/adapters.py ADDED
@@ -0,0 +1,538 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.adapters
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ This module contains the transport adapters that Requests uses to define
6
+ and maintain connections.
7
+ """
8
+
9
+ import os.path
10
+ import socket # noqa: F401
11
+
12
+ from pip._vendor.urllib3.exceptions import ClosedPoolError, ConnectTimeoutError
13
+ from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError
14
+ from pip._vendor.urllib3.exceptions import InvalidHeader as _InvalidHeader
15
+ from pip._vendor.urllib3.exceptions import (
16
+ LocationValueError,
17
+ MaxRetryError,
18
+ NewConnectionError,
19
+ ProtocolError,
20
+ )
21
+ from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError
22
+ from pip._vendor.urllib3.exceptions import ReadTimeoutError, ResponseError
23
+ from pip._vendor.urllib3.exceptions import SSLError as _SSLError
24
+ from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url
25
+ from pip._vendor.urllib3.util import Timeout as TimeoutSauce
26
+ from pip._vendor.urllib3.util import parse_url
27
+ from pip._vendor.urllib3.util.retry import Retry
28
+
29
+ from .auth import _basic_auth_str
30
+ from .compat import basestring, urlparse
31
+ from .cookies import extract_cookies_to_jar
32
+ from .exceptions import (
33
+ ConnectionError,
34
+ ConnectTimeout,
35
+ InvalidHeader,
36
+ InvalidProxyURL,
37
+ InvalidSchema,
38
+ InvalidURL,
39
+ ProxyError,
40
+ ReadTimeout,
41
+ RetryError,
42
+ SSLError,
43
+ )
44
+ from .models import Response
45
+ from .structures import CaseInsensitiveDict
46
+ from .utils import (
47
+ DEFAULT_CA_BUNDLE_PATH,
48
+ extract_zipped_paths,
49
+ get_auth_from_url,
50
+ get_encoding_from_headers,
51
+ prepend_scheme_if_needed,
52
+ select_proxy,
53
+ urldefragauth,
54
+ )
55
+
56
+ try:
57
+ from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager
58
+ except ImportError:
59
+
60
+ def SOCKSProxyManager(*args, **kwargs):
61
+ raise InvalidSchema("Missing dependencies for SOCKS support.")
62
+
63
+
64
+ DEFAULT_POOLBLOCK = False
65
+ DEFAULT_POOLSIZE = 10
66
+ DEFAULT_RETRIES = 0
67
+ DEFAULT_POOL_TIMEOUT = None
68
+
69
+
70
+ class BaseAdapter:
71
+ """The Base Transport Adapter"""
72
+
73
+ def __init__(self):
74
+ super().__init__()
75
+
76
+ def send(
77
+ self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
78
+ ):
79
+ """Sends PreparedRequest object. Returns Response object.
80
+
81
+ :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
82
+ :param stream: (optional) Whether to stream the request content.
83
+ :param timeout: (optional) How long to wait for the server to send
84
+ data before giving up, as a float, or a :ref:`(connect timeout,
85
+ read timeout) <timeouts>` tuple.
86
+ :type timeout: float or tuple
87
+ :param verify: (optional) Either a boolean, in which case it controls whether we verify
88
+ the server's TLS certificate, or a string, in which case it must be a path
89
+ to a CA bundle to use
90
+ :param cert: (optional) Any user-provided SSL certificate to be trusted.
91
+ :param proxies: (optional) The proxies dictionary to apply to the request.
92
+ """
93
+ raise NotImplementedError
94
+
95
+ def close(self):
96
+ """Cleans up adapter specific items."""
97
+ raise NotImplementedError
98
+
99
+
100
+ class HTTPAdapter(BaseAdapter):
101
+ """The built-in HTTP Adapter for urllib3.
102
+
103
+ Provides a general-case interface for Requests sessions to contact HTTP and
104
+ HTTPS urls by implementing the Transport Adapter interface. This class will
105
+ usually be created by the :class:`Session <Session>` class under the
106
+ covers.
107
+
108
+ :param pool_connections: The number of urllib3 connection pools to cache.
109
+ :param pool_maxsize: The maximum number of connections to save in the pool.
110
+ :param max_retries: The maximum number of retries each connection
111
+ should attempt. Note, this applies only to failed DNS lookups, socket
112
+ connections and connection timeouts, never to requests where data has
113
+ made it to the server. By default, Requests does not retry failed
114
+ connections. If you need granular control over the conditions under
115
+ which we retry a request, import urllib3's ``Retry`` class and pass
116
+ that instead.
117
+ :param pool_block: Whether the connection pool should block for connections.
118
+
119
+ Usage::
120
+
121
+ >>> import requests
122
+ >>> s = requests.Session()
123
+ >>> a = requests.adapters.HTTPAdapter(max_retries=3)
124
+ >>> s.mount('http://', a)
125
+ """
126
+
127
+ __attrs__ = [
128
+ "max_retries",
129
+ "config",
130
+ "_pool_connections",
131
+ "_pool_maxsize",
132
+ "_pool_block",
133
+ ]
134
+
135
+ def __init__(
136
+ self,
137
+ pool_connections=DEFAULT_POOLSIZE,
138
+ pool_maxsize=DEFAULT_POOLSIZE,
139
+ max_retries=DEFAULT_RETRIES,
140
+ pool_block=DEFAULT_POOLBLOCK,
141
+ ):
142
+ if max_retries == DEFAULT_RETRIES:
143
+ self.max_retries = Retry(0, read=False)
144
+ else:
145
+ self.max_retries = Retry.from_int(max_retries)
146
+ self.config = {}
147
+ self.proxy_manager = {}
148
+
149
+ super().__init__()
150
+
151
+ self._pool_connections = pool_connections
152
+ self._pool_maxsize = pool_maxsize
153
+ self._pool_block = pool_block
154
+
155
+ self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block)
156
+
157
+ def __getstate__(self):
158
+ return {attr: getattr(self, attr, None) for attr in self.__attrs__}
159
+
160
+ def __setstate__(self, state):
161
+ # Can't handle by adding 'proxy_manager' to self.__attrs__ because
162
+ # self.poolmanager uses a lambda function, which isn't pickleable.
163
+ self.proxy_manager = {}
164
+ self.config = {}
165
+
166
+ for attr, value in state.items():
167
+ setattr(self, attr, value)
168
+
169
+ self.init_poolmanager(
170
+ self._pool_connections, self._pool_maxsize, block=self._pool_block
171
+ )
172
+
173
+ def init_poolmanager(
174
+ self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs
175
+ ):
176
+ """Initializes a urllib3 PoolManager.
177
+
178
+ This method should not be called from user code, and is only
179
+ exposed for use when subclassing the
180
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
181
+
182
+ :param connections: The number of urllib3 connection pools to cache.
183
+ :param maxsize: The maximum number of connections to save in the pool.
184
+ :param block: Block when no free connections are available.
185
+ :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager.
186
+ """
187
+ # save these values for pickling
188
+ self._pool_connections = connections
189
+ self._pool_maxsize = maxsize
190
+ self._pool_block = block
191
+
192
+ self.poolmanager = PoolManager(
193
+ num_pools=connections,
194
+ maxsize=maxsize,
195
+ block=block,
196
+ **pool_kwargs,
197
+ )
198
+
199
+ def proxy_manager_for(self, proxy, **proxy_kwargs):
200
+ """Return urllib3 ProxyManager for the given proxy.
201
+
202
+ This method should not be called from user code, and is only
203
+ exposed for use when subclassing the
204
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
205
+
206
+ :param proxy: The proxy to return a urllib3 ProxyManager for.
207
+ :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager.
208
+ :returns: ProxyManager
209
+ :rtype: urllib3.ProxyManager
210
+ """
211
+ if proxy in self.proxy_manager:
212
+ manager = self.proxy_manager[proxy]
213
+ elif proxy.lower().startswith("socks"):
214
+ username, password = get_auth_from_url(proxy)
215
+ manager = self.proxy_manager[proxy] = SOCKSProxyManager(
216
+ proxy,
217
+ username=username,
218
+ password=password,
219
+ num_pools=self._pool_connections,
220
+ maxsize=self._pool_maxsize,
221
+ block=self._pool_block,
222
+ **proxy_kwargs,
223
+ )
224
+ else:
225
+ proxy_headers = self.proxy_headers(proxy)
226
+ manager = self.proxy_manager[proxy] = proxy_from_url(
227
+ proxy,
228
+ proxy_headers=proxy_headers,
229
+ num_pools=self._pool_connections,
230
+ maxsize=self._pool_maxsize,
231
+ block=self._pool_block,
232
+ **proxy_kwargs,
233
+ )
234
+
235
+ return manager
236
+
237
+ def cert_verify(self, conn, url, verify, cert):
238
+ """Verify a SSL certificate. This method should not be called from user
239
+ code, and is only exposed for use when subclassing the
240
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
241
+
242
+ :param conn: The urllib3 connection object associated with the cert.
243
+ :param url: The requested URL.
244
+ :param verify: Either a boolean, in which case it controls whether we verify
245
+ the server's TLS certificate, or a string, in which case it must be a path
246
+ to a CA bundle to use
247
+ :param cert: The SSL certificate to verify.
248
+ """
249
+ if url.lower().startswith("https") and verify:
250
+
251
+ cert_loc = None
252
+
253
+ # Allow self-specified cert location.
254
+ if verify is not True:
255
+ cert_loc = verify
256
+
257
+ if not cert_loc:
258
+ cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH)
259
+
260
+ if not cert_loc or not os.path.exists(cert_loc):
261
+ raise OSError(
262
+ f"Could not find a suitable TLS CA certificate bundle, "
263
+ f"invalid path: {cert_loc}"
264
+ )
265
+
266
+ conn.cert_reqs = "CERT_REQUIRED"
267
+
268
+ if not os.path.isdir(cert_loc):
269
+ conn.ca_certs = cert_loc
270
+ else:
271
+ conn.ca_cert_dir = cert_loc
272
+ else:
273
+ conn.cert_reqs = "CERT_NONE"
274
+ conn.ca_certs = None
275
+ conn.ca_cert_dir = None
276
+
277
+ if cert:
278
+ if not isinstance(cert, basestring):
279
+ conn.cert_file = cert[0]
280
+ conn.key_file = cert[1]
281
+ else:
282
+ conn.cert_file = cert
283
+ conn.key_file = None
284
+ if conn.cert_file and not os.path.exists(conn.cert_file):
285
+ raise OSError(
286
+ f"Could not find the TLS certificate file, "
287
+ f"invalid path: {conn.cert_file}"
288
+ )
289
+ if conn.key_file and not os.path.exists(conn.key_file):
290
+ raise OSError(
291
+ f"Could not find the TLS key file, invalid path: {conn.key_file}"
292
+ )
293
+
294
+ def build_response(self, req, resp):
295
+ """Builds a :class:`Response <requests.Response>` object from a urllib3
296
+ response. This should not be called from user code, and is only exposed
297
+ for use when subclassing the
298
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`
299
+
300
+ :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response.
301
+ :param resp: The urllib3 response object.
302
+ :rtype: requests.Response
303
+ """
304
+ response = Response()
305
+
306
+ # Fallback to None if there's no status_code, for whatever reason.
307
+ response.status_code = getattr(resp, "status", None)
308
+
309
+ # Make headers case-insensitive.
310
+ response.headers = CaseInsensitiveDict(getattr(resp, "headers", {}))
311
+
312
+ # Set encoding.
313
+ response.encoding = get_encoding_from_headers(response.headers)
314
+ response.raw = resp
315
+ response.reason = response.raw.reason
316
+
317
+ if isinstance(req.url, bytes):
318
+ response.url = req.url.decode("utf-8")
319
+ else:
320
+ response.url = req.url
321
+
322
+ # Add new cookies from the server.
323
+ extract_cookies_to_jar(response.cookies, req, resp)
324
+
325
+ # Give the Response some context.
326
+ response.request = req
327
+ response.connection = self
328
+
329
+ return response
330
+
331
+ def get_connection(self, url, proxies=None):
332
+ """Returns a urllib3 connection for the given URL. This should not be
333
+ called from user code, and is only exposed for use when subclassing the
334
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
335
+
336
+ :param url: The URL to connect to.
337
+ :param proxies: (optional) A Requests-style dictionary of proxies used on this request.
338
+ :rtype: urllib3.ConnectionPool
339
+ """
340
+ proxy = select_proxy(url, proxies)
341
+
342
+ if proxy:
343
+ proxy = prepend_scheme_if_needed(proxy, "http")
344
+ proxy_url = parse_url(proxy)
345
+ if not proxy_url.host:
346
+ raise InvalidProxyURL(
347
+ "Please check proxy URL. It is malformed "
348
+ "and could be missing the host."
349
+ )
350
+ proxy_manager = self.proxy_manager_for(proxy)
351
+ conn = proxy_manager.connection_from_url(url)
352
+ else:
353
+ # Only scheme should be lower case
354
+ parsed = urlparse(url)
355
+ url = parsed.geturl()
356
+ conn = self.poolmanager.connection_from_url(url)
357
+
358
+ return conn
359
+
360
+ def close(self):
361
+ """Disposes of any internal state.
362
+
363
+ Currently, this closes the PoolManager and any active ProxyManager,
364
+ which closes any pooled connections.
365
+ """
366
+ self.poolmanager.clear()
367
+ for proxy in self.proxy_manager.values():
368
+ proxy.clear()
369
+
370
+ def request_url(self, request, proxies):
371
+ """Obtain the url to use when making the final request.
372
+
373
+ If the message is being sent through a HTTP proxy, the full URL has to
374
+ be used. Otherwise, we should only use the path portion of the URL.
375
+
376
+ This should not be called from user code, and is only exposed for use
377
+ when subclassing the
378
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
379
+
380
+ :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
381
+ :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs.
382
+ :rtype: str
383
+ """
384
+ proxy = select_proxy(request.url, proxies)
385
+ scheme = urlparse(request.url).scheme
386
+
387
+ is_proxied_http_request = proxy and scheme != "https"
388
+ using_socks_proxy = False
389
+ if proxy:
390
+ proxy_scheme = urlparse(proxy).scheme.lower()
391
+ using_socks_proxy = proxy_scheme.startswith("socks")
392
+
393
+ url = request.path_url
394
+ if is_proxied_http_request and not using_socks_proxy:
395
+ url = urldefragauth(request.url)
396
+
397
+ return url
398
+
399
+ def add_headers(self, request, **kwargs):
400
+ """Add any headers needed by the connection. As of v2.0 this does
401
+ nothing by default, but is left for overriding by users that subclass
402
+ the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
403
+
404
+ This should not be called from user code, and is only exposed for use
405
+ when subclassing the
406
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
407
+
408
+ :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to.
409
+ :param kwargs: The keyword arguments from the call to send().
410
+ """
411
+ pass
412
+
413
+ def proxy_headers(self, proxy):
414
+ """Returns a dictionary of the headers to add to any request sent
415
+ through a proxy. This works with urllib3 magic to ensure that they are
416
+ correctly sent to the proxy, rather than in a tunnelled request if
417
+ CONNECT is being used.
418
+
419
+ This should not be called from user code, and is only exposed for use
420
+ when subclassing the
421
+ :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`.
422
+
423
+ :param proxy: The url of the proxy being used for this request.
424
+ :rtype: dict
425
+ """
426
+ headers = {}
427
+ username, password = get_auth_from_url(proxy)
428
+
429
+ if username:
430
+ headers["Proxy-Authorization"] = _basic_auth_str(username, password)
431
+
432
+ return headers
433
+
434
+ def send(
435
+ self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None
436
+ ):
437
+ """Sends PreparedRequest object. Returns Response object.
438
+
439
+ :param request: The :class:`PreparedRequest <PreparedRequest>` being sent.
440
+ :param stream: (optional) Whether to stream the request content.
441
+ :param timeout: (optional) How long to wait for the server to send
442
+ data before giving up, as a float, or a :ref:`(connect timeout,
443
+ read timeout) <timeouts>` tuple.
444
+ :type timeout: float or tuple or urllib3 Timeout object
445
+ :param verify: (optional) Either a boolean, in which case it controls whether
446
+ we verify the server's TLS certificate, or a string, in which case it
447
+ must be a path to a CA bundle to use
448
+ :param cert: (optional) Any user-provided SSL certificate to be trusted.
449
+ :param proxies: (optional) The proxies dictionary to apply to the request.
450
+ :rtype: requests.Response
451
+ """
452
+
453
+ try:
454
+ conn = self.get_connection(request.url, proxies)
455
+ except LocationValueError as e:
456
+ raise InvalidURL(e, request=request)
457
+
458
+ self.cert_verify(conn, request.url, verify, cert)
459
+ url = self.request_url(request, proxies)
460
+ self.add_headers(
461
+ request,
462
+ stream=stream,
463
+ timeout=timeout,
464
+ verify=verify,
465
+ cert=cert,
466
+ proxies=proxies,
467
+ )
468
+
469
+ chunked = not (request.body is None or "Content-Length" in request.headers)
470
+
471
+ if isinstance(timeout, tuple):
472
+ try:
473
+ connect, read = timeout
474
+ timeout = TimeoutSauce(connect=connect, read=read)
475
+ except ValueError:
476
+ raise ValueError(
477
+ f"Invalid timeout {timeout}. Pass a (connect, read) timeout tuple, "
478
+ f"or a single float to set both timeouts to the same value."
479
+ )
480
+ elif isinstance(timeout, TimeoutSauce):
481
+ pass
482
+ else:
483
+ timeout = TimeoutSauce(connect=timeout, read=timeout)
484
+
485
+ try:
486
+ resp = conn.urlopen(
487
+ method=request.method,
488
+ url=url,
489
+ body=request.body,
490
+ headers=request.headers,
491
+ redirect=False,
492
+ assert_same_host=False,
493
+ preload_content=False,
494
+ decode_content=False,
495
+ retries=self.max_retries,
496
+ timeout=timeout,
497
+ chunked=chunked,
498
+ )
499
+
500
+ except (ProtocolError, OSError) as err:
501
+ raise ConnectionError(err, request=request)
502
+
503
+ except MaxRetryError as e:
504
+ if isinstance(e.reason, ConnectTimeoutError):
505
+ # TODO: Remove this in 3.0.0: see #2811
506
+ if not isinstance(e.reason, NewConnectionError):
507
+ raise ConnectTimeout(e, request=request)
508
+
509
+ if isinstance(e.reason, ResponseError):
510
+ raise RetryError(e, request=request)
511
+
512
+ if isinstance(e.reason, _ProxyError):
513
+ raise ProxyError(e, request=request)
514
+
515
+ if isinstance(e.reason, _SSLError):
516
+ # This branch is for urllib3 v1.22 and later.
517
+ raise SSLError(e, request=request)
518
+
519
+ raise ConnectionError(e, request=request)
520
+
521
+ except ClosedPoolError as e:
522
+ raise ConnectionError(e, request=request)
523
+
524
+ except _ProxyError as e:
525
+ raise ProxyError(e)
526
+
527
+ except (_SSLError, _HTTPError) as e:
528
+ if isinstance(e, _SSLError):
529
+ # This branch is for urllib3 versions earlier than v1.22
530
+ raise SSLError(e, request=request)
531
+ elif isinstance(e, ReadTimeoutError):
532
+ raise ReadTimeout(e, request=request)
533
+ elif isinstance(e, _InvalidHeader):
534
+ raise InvalidHeader(e, request=request)
535
+ else:
536
+ raise
537
+
538
+ return self.build_response(request, resp)
.venv/lib/python3.11/site-packages/pip/_vendor/requests/api.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.api
3
+ ~~~~~~~~~~~~
4
+
5
+ This module implements the Requests API.
6
+
7
+ :copyright: (c) 2012 by Kenneth Reitz.
8
+ :license: Apache2, see LICENSE for more details.
9
+ """
10
+
11
+ from . import sessions
12
+
13
+
14
+ def request(method, url, **kwargs):
15
+ """Constructs and sends a :class:`Request <Request>`.
16
+
17
+ :param method: method for the new :class:`Request` object: ``GET``, ``OPTIONS``, ``HEAD``, ``POST``, ``PUT``, ``PATCH``, or ``DELETE``.
18
+ :param url: URL for the new :class:`Request` object.
19
+ :param params: (optional) Dictionary, list of tuples or bytes to send
20
+ in the query string for the :class:`Request`.
21
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
22
+ object to send in the body of the :class:`Request`.
23
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
24
+ :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`.
25
+ :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`.
26
+ :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload.
27
+ ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')``
28
+ or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string
29
+ defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers
30
+ to add for the file.
31
+ :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth.
32
+ :param timeout: (optional) How many seconds to wait for the server to send data
33
+ before giving up, as a float, or a :ref:`(connect timeout, read
34
+ timeout) <timeouts>` tuple.
35
+ :type timeout: float or tuple
36
+ :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``.
37
+ :type allow_redirects: bool
38
+ :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy.
39
+ :param verify: (optional) Either a boolean, in which case it controls whether we verify
40
+ the server's TLS certificate, or a string, in which case it must be a path
41
+ to a CA bundle to use. Defaults to ``True``.
42
+ :param stream: (optional) if ``False``, the response content will be immediately downloaded.
43
+ :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair.
44
+ :return: :class:`Response <Response>` object
45
+ :rtype: requests.Response
46
+
47
+ Usage::
48
+
49
+ >>> import requests
50
+ >>> req = requests.request('GET', 'https://httpbin.org/get')
51
+ >>> req
52
+ <Response [200]>
53
+ """
54
+
55
+ # By using the 'with' statement we are sure the session is closed, thus we
56
+ # avoid leaving sockets open which can trigger a ResourceWarning in some
57
+ # cases, and look like a memory leak in others.
58
+ with sessions.Session() as session:
59
+ return session.request(method=method, url=url, **kwargs)
60
+
61
+
62
+ def get(url, params=None, **kwargs):
63
+ r"""Sends a GET request.
64
+
65
+ :param url: URL for the new :class:`Request` object.
66
+ :param params: (optional) Dictionary, list of tuples or bytes to send
67
+ in the query string for the :class:`Request`.
68
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
69
+ :return: :class:`Response <Response>` object
70
+ :rtype: requests.Response
71
+ """
72
+
73
+ return request("get", url, params=params, **kwargs)
74
+
75
+
76
+ def options(url, **kwargs):
77
+ r"""Sends an OPTIONS request.
78
+
79
+ :param url: URL for the new :class:`Request` object.
80
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
81
+ :return: :class:`Response <Response>` object
82
+ :rtype: requests.Response
83
+ """
84
+
85
+ return request("options", url, **kwargs)
86
+
87
+
88
+ def head(url, **kwargs):
89
+ r"""Sends a HEAD request.
90
+
91
+ :param url: URL for the new :class:`Request` object.
92
+ :param \*\*kwargs: Optional arguments that ``request`` takes. If
93
+ `allow_redirects` is not provided, it will be set to `False` (as
94
+ opposed to the default :meth:`request` behavior).
95
+ :return: :class:`Response <Response>` object
96
+ :rtype: requests.Response
97
+ """
98
+
99
+ kwargs.setdefault("allow_redirects", False)
100
+ return request("head", url, **kwargs)
101
+
102
+
103
+ def post(url, data=None, json=None, **kwargs):
104
+ r"""Sends a POST request.
105
+
106
+ :param url: URL for the new :class:`Request` object.
107
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
108
+ object to send in the body of the :class:`Request`.
109
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
110
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
111
+ :return: :class:`Response <Response>` object
112
+ :rtype: requests.Response
113
+ """
114
+
115
+ return request("post", url, data=data, json=json, **kwargs)
116
+
117
+
118
+ def put(url, data=None, **kwargs):
119
+ r"""Sends a PUT request.
120
+
121
+ :param url: URL for the new :class:`Request` object.
122
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
123
+ object to send in the body of the :class:`Request`.
124
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
125
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
126
+ :return: :class:`Response <Response>` object
127
+ :rtype: requests.Response
128
+ """
129
+
130
+ return request("put", url, data=data, **kwargs)
131
+
132
+
133
+ def patch(url, data=None, **kwargs):
134
+ r"""Sends a PATCH request.
135
+
136
+ :param url: URL for the new :class:`Request` object.
137
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
138
+ object to send in the body of the :class:`Request`.
139
+ :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`.
140
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
141
+ :return: :class:`Response <Response>` object
142
+ :rtype: requests.Response
143
+ """
144
+
145
+ return request("patch", url, data=data, **kwargs)
146
+
147
+
148
+ def delete(url, **kwargs):
149
+ r"""Sends a DELETE request.
150
+
151
+ :param url: URL for the new :class:`Request` object.
152
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
153
+ :return: :class:`Response <Response>` object
154
+ :rtype: requests.Response
155
+ """
156
+
157
+ return request("delete", url, **kwargs)
.venv/lib/python3.11/site-packages/pip/_vendor/requests/auth.py ADDED
@@ -0,0 +1,315 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.auth
3
+ ~~~~~~~~~~~~~
4
+
5
+ This module contains the authentication handlers for Requests.
6
+ """
7
+
8
+ import hashlib
9
+ import os
10
+ import re
11
+ import threading
12
+ import time
13
+ import warnings
14
+ from base64 import b64encode
15
+
16
+ from ._internal_utils import to_native_string
17
+ from .compat import basestring, str, urlparse
18
+ from .cookies import extract_cookies_to_jar
19
+ from .utils import parse_dict_header
20
+
21
+ CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"
22
+ CONTENT_TYPE_MULTI_PART = "multipart/form-data"
23
+
24
+
25
+ def _basic_auth_str(username, password):
26
+ """Returns a Basic Auth string."""
27
+
28
+ # "I want us to put a big-ol' comment on top of it that
29
+ # says that this behaviour is dumb but we need to preserve
30
+ # it because people are relying on it."
31
+ # - Lukasa
32
+ #
33
+ # These are here solely to maintain backwards compatibility
34
+ # for things like ints. This will be removed in 3.0.0.
35
+ if not isinstance(username, basestring):
36
+ warnings.warn(
37
+ "Non-string usernames will no longer be supported in Requests "
38
+ "3.0.0. Please convert the object you've passed in ({!r}) to "
39
+ "a string or bytes object in the near future to avoid "
40
+ "problems.".format(username),
41
+ category=DeprecationWarning,
42
+ )
43
+ username = str(username)
44
+
45
+ if not isinstance(password, basestring):
46
+ warnings.warn(
47
+ "Non-string passwords will no longer be supported in Requests "
48
+ "3.0.0. Please convert the object you've passed in ({!r}) to "
49
+ "a string or bytes object in the near future to avoid "
50
+ "problems.".format(type(password)),
51
+ category=DeprecationWarning,
52
+ )
53
+ password = str(password)
54
+ # -- End Removal --
55
+
56
+ if isinstance(username, str):
57
+ username = username.encode("latin1")
58
+
59
+ if isinstance(password, str):
60
+ password = password.encode("latin1")
61
+
62
+ authstr = "Basic " + to_native_string(
63
+ b64encode(b":".join((username, password))).strip()
64
+ )
65
+
66
+ return authstr
67
+
68
+
69
+ class AuthBase:
70
+ """Base class that all auth implementations derive from"""
71
+
72
+ def __call__(self, r):
73
+ raise NotImplementedError("Auth hooks must be callable.")
74
+
75
+
76
+ class HTTPBasicAuth(AuthBase):
77
+ """Attaches HTTP Basic Authentication to the given Request object."""
78
+
79
+ def __init__(self, username, password):
80
+ self.username = username
81
+ self.password = password
82
+
83
+ def __eq__(self, other):
84
+ return all(
85
+ [
86
+ self.username == getattr(other, "username", None),
87
+ self.password == getattr(other, "password", None),
88
+ ]
89
+ )
90
+
91
+ def __ne__(self, other):
92
+ return not self == other
93
+
94
+ def __call__(self, r):
95
+ r.headers["Authorization"] = _basic_auth_str(self.username, self.password)
96
+ return r
97
+
98
+
99
+ class HTTPProxyAuth(HTTPBasicAuth):
100
+ """Attaches HTTP Proxy Authentication to a given Request object."""
101
+
102
+ def __call__(self, r):
103
+ r.headers["Proxy-Authorization"] = _basic_auth_str(self.username, self.password)
104
+ return r
105
+
106
+
107
+ class HTTPDigestAuth(AuthBase):
108
+ """Attaches HTTP Digest Authentication to the given Request object."""
109
+
110
+ def __init__(self, username, password):
111
+ self.username = username
112
+ self.password = password
113
+ # Keep state in per-thread local storage
114
+ self._thread_local = threading.local()
115
+
116
+ def init_per_thread_state(self):
117
+ # Ensure state is initialized just once per-thread
118
+ if not hasattr(self._thread_local, "init"):
119
+ self._thread_local.init = True
120
+ self._thread_local.last_nonce = ""
121
+ self._thread_local.nonce_count = 0
122
+ self._thread_local.chal = {}
123
+ self._thread_local.pos = None
124
+ self._thread_local.num_401_calls = None
125
+
126
+ def build_digest_header(self, method, url):
127
+ """
128
+ :rtype: str
129
+ """
130
+
131
+ realm = self._thread_local.chal["realm"]
132
+ nonce = self._thread_local.chal["nonce"]
133
+ qop = self._thread_local.chal.get("qop")
134
+ algorithm = self._thread_local.chal.get("algorithm")
135
+ opaque = self._thread_local.chal.get("opaque")
136
+ hash_utf8 = None
137
+
138
+ if algorithm is None:
139
+ _algorithm = "MD5"
140
+ else:
141
+ _algorithm = algorithm.upper()
142
+ # lambdas assume digest modules are imported at the top level
143
+ if _algorithm == "MD5" or _algorithm == "MD5-SESS":
144
+
145
+ def md5_utf8(x):
146
+ if isinstance(x, str):
147
+ x = x.encode("utf-8")
148
+ return hashlib.md5(x).hexdigest()
149
+
150
+ hash_utf8 = md5_utf8
151
+ elif _algorithm == "SHA":
152
+
153
+ def sha_utf8(x):
154
+ if isinstance(x, str):
155
+ x = x.encode("utf-8")
156
+ return hashlib.sha1(x).hexdigest()
157
+
158
+ hash_utf8 = sha_utf8
159
+ elif _algorithm == "SHA-256":
160
+
161
+ def sha256_utf8(x):
162
+ if isinstance(x, str):
163
+ x = x.encode("utf-8")
164
+ return hashlib.sha256(x).hexdigest()
165
+
166
+ hash_utf8 = sha256_utf8
167
+ elif _algorithm == "SHA-512":
168
+
169
+ def sha512_utf8(x):
170
+ if isinstance(x, str):
171
+ x = x.encode("utf-8")
172
+ return hashlib.sha512(x).hexdigest()
173
+
174
+ hash_utf8 = sha512_utf8
175
+
176
+ KD = lambda s, d: hash_utf8(f"{s}:{d}") # noqa:E731
177
+
178
+ if hash_utf8 is None:
179
+ return None
180
+
181
+ # XXX not implemented yet
182
+ entdig = None
183
+ p_parsed = urlparse(url)
184
+ #: path is request-uri defined in RFC 2616 which should not be empty
185
+ path = p_parsed.path or "/"
186
+ if p_parsed.query:
187
+ path += f"?{p_parsed.query}"
188
+
189
+ A1 = f"{self.username}:{realm}:{self.password}"
190
+ A2 = f"{method}:{path}"
191
+
192
+ HA1 = hash_utf8(A1)
193
+ HA2 = hash_utf8(A2)
194
+
195
+ if nonce == self._thread_local.last_nonce:
196
+ self._thread_local.nonce_count += 1
197
+ else:
198
+ self._thread_local.nonce_count = 1
199
+ ncvalue = f"{self._thread_local.nonce_count:08x}"
200
+ s = str(self._thread_local.nonce_count).encode("utf-8")
201
+ s += nonce.encode("utf-8")
202
+ s += time.ctime().encode("utf-8")
203
+ s += os.urandom(8)
204
+
205
+ cnonce = hashlib.sha1(s).hexdigest()[:16]
206
+ if _algorithm == "MD5-SESS":
207
+ HA1 = hash_utf8(f"{HA1}:{nonce}:{cnonce}")
208
+
209
+ if not qop:
210
+ respdig = KD(HA1, f"{nonce}:{HA2}")
211
+ elif qop == "auth" or "auth" in qop.split(","):
212
+ noncebit = f"{nonce}:{ncvalue}:{cnonce}:auth:{HA2}"
213
+ respdig = KD(HA1, noncebit)
214
+ else:
215
+ # XXX handle auth-int.
216
+ return None
217
+
218
+ self._thread_local.last_nonce = nonce
219
+
220
+ # XXX should the partial digests be encoded too?
221
+ base = (
222
+ f'username="{self.username}", realm="{realm}", nonce="{nonce}", '
223
+ f'uri="{path}", response="{respdig}"'
224
+ )
225
+ if opaque:
226
+ base += f', opaque="{opaque}"'
227
+ if algorithm:
228
+ base += f', algorithm="{algorithm}"'
229
+ if entdig:
230
+ base += f', digest="{entdig}"'
231
+ if qop:
232
+ base += f', qop="auth", nc={ncvalue}, cnonce="{cnonce}"'
233
+
234
+ return f"Digest {base}"
235
+
236
+ def handle_redirect(self, r, **kwargs):
237
+ """Reset num_401_calls counter on redirects."""
238
+ if r.is_redirect:
239
+ self._thread_local.num_401_calls = 1
240
+
241
+ def handle_401(self, r, **kwargs):
242
+ """
243
+ Takes the given response and tries digest-auth, if needed.
244
+
245
+ :rtype: requests.Response
246
+ """
247
+
248
+ # If response is not 4xx, do not auth
249
+ # See https://github.com/psf/requests/issues/3772
250
+ if not 400 <= r.status_code < 500:
251
+ self._thread_local.num_401_calls = 1
252
+ return r
253
+
254
+ if self._thread_local.pos is not None:
255
+ # Rewind the file position indicator of the body to where
256
+ # it was to resend the request.
257
+ r.request.body.seek(self._thread_local.pos)
258
+ s_auth = r.headers.get("www-authenticate", "")
259
+
260
+ if "digest" in s_auth.lower() and self._thread_local.num_401_calls < 2:
261
+
262
+ self._thread_local.num_401_calls += 1
263
+ pat = re.compile(r"digest ", flags=re.IGNORECASE)
264
+ self._thread_local.chal = parse_dict_header(pat.sub("", s_auth, count=1))
265
+
266
+ # Consume content and release the original connection
267
+ # to allow our new request to reuse the same one.
268
+ r.content
269
+ r.close()
270
+ prep = r.request.copy()
271
+ extract_cookies_to_jar(prep._cookies, r.request, r.raw)
272
+ prep.prepare_cookies(prep._cookies)
273
+
274
+ prep.headers["Authorization"] = self.build_digest_header(
275
+ prep.method, prep.url
276
+ )
277
+ _r = r.connection.send(prep, **kwargs)
278
+ _r.history.append(r)
279
+ _r.request = prep
280
+
281
+ return _r
282
+
283
+ self._thread_local.num_401_calls = 1
284
+ return r
285
+
286
+ def __call__(self, r):
287
+ # Initialize per-thread state, if needed
288
+ self.init_per_thread_state()
289
+ # If we have a saved nonce, skip the 401
290
+ if self._thread_local.last_nonce:
291
+ r.headers["Authorization"] = self.build_digest_header(r.method, r.url)
292
+ try:
293
+ self._thread_local.pos = r.body.tell()
294
+ except AttributeError:
295
+ # In the case of HTTPDigestAuth being reused and the body of
296
+ # the previous request was a file-like object, pos has the
297
+ # file position of the previous body. Ensure it's set to
298
+ # None.
299
+ self._thread_local.pos = None
300
+ r.register_hook("response", self.handle_401)
301
+ r.register_hook("response", self.handle_redirect)
302
+ self._thread_local.num_401_calls = 1
303
+
304
+ return r
305
+
306
+ def __eq__(self, other):
307
+ return all(
308
+ [
309
+ self.username == getattr(other, "username", None),
310
+ self.password == getattr(other, "password", None),
311
+ ]
312
+ )
313
+
314
+ def __ne__(self, other):
315
+ return not self == other
.venv/lib/python3.11/site-packages/pip/_vendor/requests/certs.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+
3
+ """
4
+ requests.certs
5
+ ~~~~~~~~~~~~~~
6
+
7
+ This module returns the preferred default CA certificate bundle. There is
8
+ only one — the one from the certifi package.
9
+
10
+ If you are packaging Requests, e.g., for a Linux distribution or a managed
11
+ environment, you can change the definition of where() to return a separately
12
+ packaged CA bundle.
13
+ """
14
+
15
+ import os
16
+
17
+ if "_PIP_STANDALONE_CERT" not in os.environ:
18
+ from pip._vendor.certifi import where
19
+ else:
20
+ def where():
21
+ return os.environ["_PIP_STANDALONE_CERT"]
22
+
23
+ if __name__ == "__main__":
24
+ print(where())
.venv/lib/python3.11/site-packages/pip/_vendor/requests/compat.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.compat
3
+ ~~~~~~~~~~~~~~~
4
+
5
+ This module previously handled import compatibility issues
6
+ between Python 2 and Python 3. It remains for backwards
7
+ compatibility until the next major version.
8
+ """
9
+
10
+ from pip._vendor import chardet
11
+
12
+ import sys
13
+
14
+ # -------
15
+ # Pythons
16
+ # -------
17
+
18
+ # Syntax sugar.
19
+ _ver = sys.version_info
20
+
21
+ #: Python 2.x?
22
+ is_py2 = _ver[0] == 2
23
+
24
+ #: Python 3.x?
25
+ is_py3 = _ver[0] == 3
26
+
27
+ # Note: We've patched out simplejson support in pip because it prevents
28
+ # upgrading simplejson on Windows.
29
+ import json
30
+ from json import JSONDecodeError
31
+
32
+ # Keep OrderedDict for backwards compatibility.
33
+ from collections import OrderedDict
34
+ from collections.abc import Callable, Mapping, MutableMapping
35
+ from http import cookiejar as cookielib
36
+ from http.cookies import Morsel
37
+ from io import StringIO
38
+
39
+ # --------------
40
+ # Legacy Imports
41
+ # --------------
42
+ from urllib.parse import (
43
+ quote,
44
+ quote_plus,
45
+ unquote,
46
+ unquote_plus,
47
+ urldefrag,
48
+ urlencode,
49
+ urljoin,
50
+ urlparse,
51
+ urlsplit,
52
+ urlunparse,
53
+ )
54
+ from urllib.request import (
55
+ getproxies,
56
+ getproxies_environment,
57
+ parse_http_list,
58
+ proxy_bypass,
59
+ proxy_bypass_environment,
60
+ )
61
+
62
+ builtin_str = str
63
+ str = str
64
+ bytes = bytes
65
+ basestring = (str, bytes)
66
+ numeric_types = (int, float)
67
+ integer_types = (int,)
.venv/lib/python3.11/site-packages/pip/_vendor/requests/cookies.py ADDED
@@ -0,0 +1,561 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.cookies
3
+ ~~~~~~~~~~~~~~~~
4
+
5
+ Compatibility code to be able to use `cookielib.CookieJar` with requests.
6
+
7
+ requests.utils imports from here, so be careful with imports.
8
+ """
9
+
10
+ import calendar
11
+ import copy
12
+ import time
13
+
14
+ from ._internal_utils import to_native_string
15
+ from .compat import Morsel, MutableMapping, cookielib, urlparse, urlunparse
16
+
17
+ try:
18
+ import threading
19
+ except ImportError:
20
+ import dummy_threading as threading
21
+
22
+
23
+ class MockRequest:
24
+ """Wraps a `requests.Request` to mimic a `urllib2.Request`.
25
+
26
+ The code in `cookielib.CookieJar` expects this interface in order to correctly
27
+ manage cookie policies, i.e., determine whether a cookie can be set, given the
28
+ domains of the request and the cookie.
29
+
30
+ The original request object is read-only. The client is responsible for collecting
31
+ the new headers via `get_new_headers()` and interpreting them appropriately. You
32
+ probably want `get_cookie_header`, defined below.
33
+ """
34
+
35
+ def __init__(self, request):
36
+ self._r = request
37
+ self._new_headers = {}
38
+ self.type = urlparse(self._r.url).scheme
39
+
40
+ def get_type(self):
41
+ return self.type
42
+
43
+ def get_host(self):
44
+ return urlparse(self._r.url).netloc
45
+
46
+ def get_origin_req_host(self):
47
+ return self.get_host()
48
+
49
+ def get_full_url(self):
50
+ # Only return the response's URL if the user hadn't set the Host
51
+ # header
52
+ if not self._r.headers.get("Host"):
53
+ return self._r.url
54
+ # If they did set it, retrieve it and reconstruct the expected domain
55
+ host = to_native_string(self._r.headers["Host"], encoding="utf-8")
56
+ parsed = urlparse(self._r.url)
57
+ # Reconstruct the URL as we expect it
58
+ return urlunparse(
59
+ [
60
+ parsed.scheme,
61
+ host,
62
+ parsed.path,
63
+ parsed.params,
64
+ parsed.query,
65
+ parsed.fragment,
66
+ ]
67
+ )
68
+
69
+ def is_unverifiable(self):
70
+ return True
71
+
72
+ def has_header(self, name):
73
+ return name in self._r.headers or name in self._new_headers
74
+
75
+ def get_header(self, name, default=None):
76
+ return self._r.headers.get(name, self._new_headers.get(name, default))
77
+
78
+ def add_header(self, key, val):
79
+ """cookielib has no legitimate use for this method; add it back if you find one."""
80
+ raise NotImplementedError(
81
+ "Cookie headers should be added with add_unredirected_header()"
82
+ )
83
+
84
+ def add_unredirected_header(self, name, value):
85
+ self._new_headers[name] = value
86
+
87
+ def get_new_headers(self):
88
+ return self._new_headers
89
+
90
+ @property
91
+ def unverifiable(self):
92
+ return self.is_unverifiable()
93
+
94
+ @property
95
+ def origin_req_host(self):
96
+ return self.get_origin_req_host()
97
+
98
+ @property
99
+ def host(self):
100
+ return self.get_host()
101
+
102
+
103
+ class MockResponse:
104
+ """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`.
105
+
106
+ ...what? Basically, expose the parsed HTTP headers from the server response
107
+ the way `cookielib` expects to see them.
108
+ """
109
+
110
+ def __init__(self, headers):
111
+ """Make a MockResponse for `cookielib` to read.
112
+
113
+ :param headers: a httplib.HTTPMessage or analogous carrying the headers
114
+ """
115
+ self._headers = headers
116
+
117
+ def info(self):
118
+ return self._headers
119
+
120
+ def getheaders(self, name):
121
+ self._headers.getheaders(name)
122
+
123
+
124
+ def extract_cookies_to_jar(jar, request, response):
125
+ """Extract the cookies from the response into a CookieJar.
126
+
127
+ :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar)
128
+ :param request: our own requests.Request object
129
+ :param response: urllib3.HTTPResponse object
130
+ """
131
+ if not (hasattr(response, "_original_response") and response._original_response):
132
+ return
133
+ # the _original_response field is the wrapped httplib.HTTPResponse object,
134
+ req = MockRequest(request)
135
+ # pull out the HTTPMessage with the headers and put it in the mock:
136
+ res = MockResponse(response._original_response.msg)
137
+ jar.extract_cookies(res, req)
138
+
139
+
140
+ def get_cookie_header(jar, request):
141
+ """
142
+ Produce an appropriate Cookie header string to be sent with `request`, or None.
143
+
144
+ :rtype: str
145
+ """
146
+ r = MockRequest(request)
147
+ jar.add_cookie_header(r)
148
+ return r.get_new_headers().get("Cookie")
149
+
150
+
151
+ def remove_cookie_by_name(cookiejar, name, domain=None, path=None):
152
+ """Unsets a cookie by name, by default over all domains and paths.
153
+
154
+ Wraps CookieJar.clear(), is O(n).
155
+ """
156
+ clearables = []
157
+ for cookie in cookiejar:
158
+ if cookie.name != name:
159
+ continue
160
+ if domain is not None and domain != cookie.domain:
161
+ continue
162
+ if path is not None and path != cookie.path:
163
+ continue
164
+ clearables.append((cookie.domain, cookie.path, cookie.name))
165
+
166
+ for domain, path, name in clearables:
167
+ cookiejar.clear(domain, path, name)
168
+
169
+
170
+ class CookieConflictError(RuntimeError):
171
+ """There are two cookies that meet the criteria specified in the cookie jar.
172
+ Use .get and .set and include domain and path args in order to be more specific.
173
+ """
174
+
175
+
176
+ class RequestsCookieJar(cookielib.CookieJar, MutableMapping):
177
+ """Compatibility class; is a cookielib.CookieJar, but exposes a dict
178
+ interface.
179
+
180
+ This is the CookieJar we create by default for requests and sessions that
181
+ don't specify one, since some clients may expect response.cookies and
182
+ session.cookies to support dict operations.
183
+
184
+ Requests does not use the dict interface internally; it's just for
185
+ compatibility with external client code. All requests code should work
186
+ out of the box with externally provided instances of ``CookieJar``, e.g.
187
+ ``LWPCookieJar`` and ``FileCookieJar``.
188
+
189
+ Unlike a regular CookieJar, this class is pickleable.
190
+
191
+ .. warning:: dictionary operations that are normally O(1) may be O(n).
192
+ """
193
+
194
+ def get(self, name, default=None, domain=None, path=None):
195
+ """Dict-like get() that also supports optional domain and path args in
196
+ order to resolve naming collisions from using one cookie jar over
197
+ multiple domains.
198
+
199
+ .. warning:: operation is O(n), not O(1).
200
+ """
201
+ try:
202
+ return self._find_no_duplicates(name, domain, path)
203
+ except KeyError:
204
+ return default
205
+
206
+ def set(self, name, value, **kwargs):
207
+ """Dict-like set() that also supports optional domain and path args in
208
+ order to resolve naming collisions from using one cookie jar over
209
+ multiple domains.
210
+ """
211
+ # support client code that unsets cookies by assignment of a None value:
212
+ if value is None:
213
+ remove_cookie_by_name(
214
+ self, name, domain=kwargs.get("domain"), path=kwargs.get("path")
215
+ )
216
+ return
217
+
218
+ if isinstance(value, Morsel):
219
+ c = morsel_to_cookie(value)
220
+ else:
221
+ c = create_cookie(name, value, **kwargs)
222
+ self.set_cookie(c)
223
+ return c
224
+
225
+ def iterkeys(self):
226
+ """Dict-like iterkeys() that returns an iterator of names of cookies
227
+ from the jar.
228
+
229
+ .. seealso:: itervalues() and iteritems().
230
+ """
231
+ for cookie in iter(self):
232
+ yield cookie.name
233
+
234
+ def keys(self):
235
+ """Dict-like keys() that returns a list of names of cookies from the
236
+ jar.
237
+
238
+ .. seealso:: values() and items().
239
+ """
240
+ return list(self.iterkeys())
241
+
242
+ def itervalues(self):
243
+ """Dict-like itervalues() that returns an iterator of values of cookies
244
+ from the jar.
245
+
246
+ .. seealso:: iterkeys() and iteritems().
247
+ """
248
+ for cookie in iter(self):
249
+ yield cookie.value
250
+
251
+ def values(self):
252
+ """Dict-like values() that returns a list of values of cookies from the
253
+ jar.
254
+
255
+ .. seealso:: keys() and items().
256
+ """
257
+ return list(self.itervalues())
258
+
259
+ def iteritems(self):
260
+ """Dict-like iteritems() that returns an iterator of name-value tuples
261
+ from the jar.
262
+
263
+ .. seealso:: iterkeys() and itervalues().
264
+ """
265
+ for cookie in iter(self):
266
+ yield cookie.name, cookie.value
267
+
268
+ def items(self):
269
+ """Dict-like items() that returns a list of name-value tuples from the
270
+ jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a
271
+ vanilla python dict of key value pairs.
272
+
273
+ .. seealso:: keys() and values().
274
+ """
275
+ return list(self.iteritems())
276
+
277
+ def list_domains(self):
278
+ """Utility method to list all the domains in the jar."""
279
+ domains = []
280
+ for cookie in iter(self):
281
+ if cookie.domain not in domains:
282
+ domains.append(cookie.domain)
283
+ return domains
284
+
285
+ def list_paths(self):
286
+ """Utility method to list all the paths in the jar."""
287
+ paths = []
288
+ for cookie in iter(self):
289
+ if cookie.path not in paths:
290
+ paths.append(cookie.path)
291
+ return paths
292
+
293
+ def multiple_domains(self):
294
+ """Returns True if there are multiple domains in the jar.
295
+ Returns False otherwise.
296
+
297
+ :rtype: bool
298
+ """
299
+ domains = []
300
+ for cookie in iter(self):
301
+ if cookie.domain is not None and cookie.domain in domains:
302
+ return True
303
+ domains.append(cookie.domain)
304
+ return False # there is only one domain in jar
305
+
306
+ def get_dict(self, domain=None, path=None):
307
+ """Takes as an argument an optional domain and path and returns a plain
308
+ old Python dict of name-value pairs of cookies that meet the
309
+ requirements.
310
+
311
+ :rtype: dict
312
+ """
313
+ dictionary = {}
314
+ for cookie in iter(self):
315
+ if (domain is None or cookie.domain == domain) and (
316
+ path is None or cookie.path == path
317
+ ):
318
+ dictionary[cookie.name] = cookie.value
319
+ return dictionary
320
+
321
+ def __contains__(self, name):
322
+ try:
323
+ return super().__contains__(name)
324
+ except CookieConflictError:
325
+ return True
326
+
327
+ def __getitem__(self, name):
328
+ """Dict-like __getitem__() for compatibility with client code. Throws
329
+ exception if there are more than one cookie with name. In that case,
330
+ use the more explicit get() method instead.
331
+
332
+ .. warning:: operation is O(n), not O(1).
333
+ """
334
+ return self._find_no_duplicates(name)
335
+
336
+ def __setitem__(self, name, value):
337
+ """Dict-like __setitem__ for compatibility with client code. Throws
338
+ exception if there is already a cookie of that name in the jar. In that
339
+ case, use the more explicit set() method instead.
340
+ """
341
+ self.set(name, value)
342
+
343
+ def __delitem__(self, name):
344
+ """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s
345
+ ``remove_cookie_by_name()``.
346
+ """
347
+ remove_cookie_by_name(self, name)
348
+
349
+ def set_cookie(self, cookie, *args, **kwargs):
350
+ if (
351
+ hasattr(cookie.value, "startswith")
352
+ and cookie.value.startswith('"')
353
+ and cookie.value.endswith('"')
354
+ ):
355
+ cookie.value = cookie.value.replace('\\"', "")
356
+ return super().set_cookie(cookie, *args, **kwargs)
357
+
358
+ def update(self, other):
359
+ """Updates this jar with cookies from another CookieJar or dict-like"""
360
+ if isinstance(other, cookielib.CookieJar):
361
+ for cookie in other:
362
+ self.set_cookie(copy.copy(cookie))
363
+ else:
364
+ super().update(other)
365
+
366
+ def _find(self, name, domain=None, path=None):
367
+ """Requests uses this method internally to get cookie values.
368
+
369
+ If there are conflicting cookies, _find arbitrarily chooses one.
370
+ See _find_no_duplicates if you want an exception thrown if there are
371
+ conflicting cookies.
372
+
373
+ :param name: a string containing name of cookie
374
+ :param domain: (optional) string containing domain of cookie
375
+ :param path: (optional) string containing path of cookie
376
+ :return: cookie.value
377
+ """
378
+ for cookie in iter(self):
379
+ if cookie.name == name:
380
+ if domain is None or cookie.domain == domain:
381
+ if path is None or cookie.path == path:
382
+ return cookie.value
383
+
384
+ raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
385
+
386
+ def _find_no_duplicates(self, name, domain=None, path=None):
387
+ """Both ``__get_item__`` and ``get`` call this function: it's never
388
+ used elsewhere in Requests.
389
+
390
+ :param name: a string containing name of cookie
391
+ :param domain: (optional) string containing domain of cookie
392
+ :param path: (optional) string containing path of cookie
393
+ :raises KeyError: if cookie is not found
394
+ :raises CookieConflictError: if there are multiple cookies
395
+ that match name and optionally domain and path
396
+ :return: cookie.value
397
+ """
398
+ toReturn = None
399
+ for cookie in iter(self):
400
+ if cookie.name == name:
401
+ if domain is None or cookie.domain == domain:
402
+ if path is None or cookie.path == path:
403
+ if toReturn is not None:
404
+ # if there are multiple cookies that meet passed in criteria
405
+ raise CookieConflictError(
406
+ f"There are multiple cookies with name, {name!r}"
407
+ )
408
+ # we will eventually return this as long as no cookie conflict
409
+ toReturn = cookie.value
410
+
411
+ if toReturn:
412
+ return toReturn
413
+ raise KeyError(f"name={name!r}, domain={domain!r}, path={path!r}")
414
+
415
+ def __getstate__(self):
416
+ """Unlike a normal CookieJar, this class is pickleable."""
417
+ state = self.__dict__.copy()
418
+ # remove the unpickleable RLock object
419
+ state.pop("_cookies_lock")
420
+ return state
421
+
422
+ def __setstate__(self, state):
423
+ """Unlike a normal CookieJar, this class is pickleable."""
424
+ self.__dict__.update(state)
425
+ if "_cookies_lock" not in self.__dict__:
426
+ self._cookies_lock = threading.RLock()
427
+
428
+ def copy(self):
429
+ """Return a copy of this RequestsCookieJar."""
430
+ new_cj = RequestsCookieJar()
431
+ new_cj.set_policy(self.get_policy())
432
+ new_cj.update(self)
433
+ return new_cj
434
+
435
+ def get_policy(self):
436
+ """Return the CookiePolicy instance used."""
437
+ return self._policy
438
+
439
+
440
+ def _copy_cookie_jar(jar):
441
+ if jar is None:
442
+ return None
443
+
444
+ if hasattr(jar, "copy"):
445
+ # We're dealing with an instance of RequestsCookieJar
446
+ return jar.copy()
447
+ # We're dealing with a generic CookieJar instance
448
+ new_jar = copy.copy(jar)
449
+ new_jar.clear()
450
+ for cookie in jar:
451
+ new_jar.set_cookie(copy.copy(cookie))
452
+ return new_jar
453
+
454
+
455
+ def create_cookie(name, value, **kwargs):
456
+ """Make a cookie from underspecified parameters.
457
+
458
+ By default, the pair of `name` and `value` will be set for the domain ''
459
+ and sent on every request (this is sometimes called a "supercookie").
460
+ """
461
+ result = {
462
+ "version": 0,
463
+ "name": name,
464
+ "value": value,
465
+ "port": None,
466
+ "domain": "",
467
+ "path": "/",
468
+ "secure": False,
469
+ "expires": None,
470
+ "discard": True,
471
+ "comment": None,
472
+ "comment_url": None,
473
+ "rest": {"HttpOnly": None},
474
+ "rfc2109": False,
475
+ }
476
+
477
+ badargs = set(kwargs) - set(result)
478
+ if badargs:
479
+ raise TypeError(
480
+ f"create_cookie() got unexpected keyword arguments: {list(badargs)}"
481
+ )
482
+
483
+ result.update(kwargs)
484
+ result["port_specified"] = bool(result["port"])
485
+ result["domain_specified"] = bool(result["domain"])
486
+ result["domain_initial_dot"] = result["domain"].startswith(".")
487
+ result["path_specified"] = bool(result["path"])
488
+
489
+ return cookielib.Cookie(**result)
490
+
491
+
492
+ def morsel_to_cookie(morsel):
493
+ """Convert a Morsel object into a Cookie containing the one k/v pair."""
494
+
495
+ expires = None
496
+ if morsel["max-age"]:
497
+ try:
498
+ expires = int(time.time() + int(morsel["max-age"]))
499
+ except ValueError:
500
+ raise TypeError(f"max-age: {morsel['max-age']} must be integer")
501
+ elif morsel["expires"]:
502
+ time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
503
+ expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
504
+ return create_cookie(
505
+ comment=morsel["comment"],
506
+ comment_url=bool(morsel["comment"]),
507
+ discard=False,
508
+ domain=morsel["domain"],
509
+ expires=expires,
510
+ name=morsel.key,
511
+ path=morsel["path"],
512
+ port=None,
513
+ rest={"HttpOnly": morsel["httponly"]},
514
+ rfc2109=False,
515
+ secure=bool(morsel["secure"]),
516
+ value=morsel.value,
517
+ version=morsel["version"] or 0,
518
+ )
519
+
520
+
521
+ def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True):
522
+ """Returns a CookieJar from a key/value dictionary.
523
+
524
+ :param cookie_dict: Dict of key/values to insert into CookieJar.
525
+ :param cookiejar: (optional) A cookiejar to add the cookies to.
526
+ :param overwrite: (optional) If False, will not replace cookies
527
+ already in the jar with new ones.
528
+ :rtype: CookieJar
529
+ """
530
+ if cookiejar is None:
531
+ cookiejar = RequestsCookieJar()
532
+
533
+ if cookie_dict is not None:
534
+ names_from_jar = [cookie.name for cookie in cookiejar]
535
+ for name in cookie_dict:
536
+ if overwrite or (name not in names_from_jar):
537
+ cookiejar.set_cookie(create_cookie(name, cookie_dict[name]))
538
+
539
+ return cookiejar
540
+
541
+
542
+ def merge_cookies(cookiejar, cookies):
543
+ """Add cookies to cookiejar and returns a merged CookieJar.
544
+
545
+ :param cookiejar: CookieJar object to add the cookies to.
546
+ :param cookies: Dictionary or CookieJar object to be added.
547
+ :rtype: CookieJar
548
+ """
549
+ if not isinstance(cookiejar, cookielib.CookieJar):
550
+ raise ValueError("You can only merge into CookieJar")
551
+
552
+ if isinstance(cookies, dict):
553
+ cookiejar = cookiejar_from_dict(cookies, cookiejar=cookiejar, overwrite=False)
554
+ elif isinstance(cookies, cookielib.CookieJar):
555
+ try:
556
+ cookiejar.update(cookies)
557
+ except AttributeError:
558
+ for cookie_in_jar in cookies:
559
+ cookiejar.set_cookie(cookie_in_jar)
560
+
561
+ return cookiejar
.venv/lib/python3.11/site-packages/pip/_vendor/requests/exceptions.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.exceptions
3
+ ~~~~~~~~~~~~~~~~~~~
4
+
5
+ This module contains the set of Requests' exceptions.
6
+ """
7
+ from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError
8
+
9
+ from .compat import JSONDecodeError as CompatJSONDecodeError
10
+
11
+
12
+ class RequestException(IOError):
13
+ """There was an ambiguous exception that occurred while handling your
14
+ request.
15
+ """
16
+
17
+ def __init__(self, *args, **kwargs):
18
+ """Initialize RequestException with `request` and `response` objects."""
19
+ response = kwargs.pop("response", None)
20
+ self.response = response
21
+ self.request = kwargs.pop("request", None)
22
+ if response is not None and not self.request and hasattr(response, "request"):
23
+ self.request = self.response.request
24
+ super().__init__(*args, **kwargs)
25
+
26
+
27
+ class InvalidJSONError(RequestException):
28
+ """A JSON error occurred."""
29
+
30
+
31
+ class JSONDecodeError(InvalidJSONError, CompatJSONDecodeError):
32
+ """Couldn't decode the text into json"""
33
+
34
+ def __init__(self, *args, **kwargs):
35
+ """
36
+ Construct the JSONDecodeError instance first with all
37
+ args. Then use it's args to construct the IOError so that
38
+ the json specific args aren't used as IOError specific args
39
+ and the error message from JSONDecodeError is preserved.
40
+ """
41
+ CompatJSONDecodeError.__init__(self, *args)
42
+ InvalidJSONError.__init__(self, *self.args, **kwargs)
43
+
44
+
45
+ class HTTPError(RequestException):
46
+ """An HTTP error occurred."""
47
+
48
+
49
+ class ConnectionError(RequestException):
50
+ """A Connection error occurred."""
51
+
52
+
53
+ class ProxyError(ConnectionError):
54
+ """A proxy error occurred."""
55
+
56
+
57
+ class SSLError(ConnectionError):
58
+ """An SSL error occurred."""
59
+
60
+
61
+ class Timeout(RequestException):
62
+ """The request timed out.
63
+
64
+ Catching this error will catch both
65
+ :exc:`~requests.exceptions.ConnectTimeout` and
66
+ :exc:`~requests.exceptions.ReadTimeout` errors.
67
+ """
68
+
69
+
70
+ class ConnectTimeout(ConnectionError, Timeout):
71
+ """The request timed out while trying to connect to the remote server.
72
+
73
+ Requests that produced this error are safe to retry.
74
+ """
75
+
76
+
77
+ class ReadTimeout(Timeout):
78
+ """The server did not send any data in the allotted amount of time."""
79
+
80
+
81
+ class URLRequired(RequestException):
82
+ """A valid URL is required to make a request."""
83
+
84
+
85
+ class TooManyRedirects(RequestException):
86
+ """Too many redirects."""
87
+
88
+
89
+ class MissingSchema(RequestException, ValueError):
90
+ """The URL scheme (e.g. http or https) is missing."""
91
+
92
+
93
+ class InvalidSchema(RequestException, ValueError):
94
+ """The URL scheme provided is either invalid or unsupported."""
95
+
96
+
97
+ class InvalidURL(RequestException, ValueError):
98
+ """The URL provided was somehow invalid."""
99
+
100
+
101
+ class InvalidHeader(RequestException, ValueError):
102
+ """The header value provided was somehow invalid."""
103
+
104
+
105
+ class InvalidProxyURL(InvalidURL):
106
+ """The proxy URL provided is invalid."""
107
+
108
+
109
+ class ChunkedEncodingError(RequestException):
110
+ """The server declared chunked encoding but sent an invalid chunk."""
111
+
112
+
113
+ class ContentDecodingError(RequestException, BaseHTTPError):
114
+ """Failed to decode response content."""
115
+
116
+
117
+ class StreamConsumedError(RequestException, TypeError):
118
+ """The content for this response was already consumed."""
119
+
120
+
121
+ class RetryError(RequestException):
122
+ """Custom retries logic failed"""
123
+
124
+
125
+ class UnrewindableBodyError(RequestException):
126
+ """Requests encountered an error when trying to rewind a body."""
127
+
128
+
129
+ # Warnings
130
+
131
+
132
+ class RequestsWarning(Warning):
133
+ """Base warning for Requests."""
134
+
135
+
136
+ class FileModeWarning(RequestsWarning, DeprecationWarning):
137
+ """A file was opened in text mode, but Requests determined its binary length."""
138
+
139
+
140
+ class RequestsDependencyWarning(RequestsWarning):
141
+ """An imported dependency doesn't match the expected version range."""
.venv/lib/python3.11/site-packages/pip/_vendor/requests/help.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Module containing bug report helper(s)."""
2
+
3
+ import json
4
+ import platform
5
+ import ssl
6
+ import sys
7
+
8
+ from pip._vendor import idna
9
+ from pip._vendor import urllib3
10
+
11
+ from . import __version__ as requests_version
12
+
13
+ charset_normalizer = None
14
+
15
+ try:
16
+ from pip._vendor import chardet
17
+ except ImportError:
18
+ chardet = None
19
+
20
+ try:
21
+ from pip._vendor.urllib3.contrib import pyopenssl
22
+ except ImportError:
23
+ pyopenssl = None
24
+ OpenSSL = None
25
+ cryptography = None
26
+ else:
27
+ import cryptography
28
+ import OpenSSL
29
+
30
+
31
+ def _implementation():
32
+ """Return a dict with the Python implementation and version.
33
+
34
+ Provide both the name and the version of the Python implementation
35
+ currently running. For example, on CPython 3.10.3 it will return
36
+ {'name': 'CPython', 'version': '3.10.3'}.
37
+
38
+ This function works best on CPython and PyPy: in particular, it probably
39
+ doesn't work for Jython or IronPython. Future investigation should be done
40
+ to work out the correct shape of the code for those platforms.
41
+ """
42
+ implementation = platform.python_implementation()
43
+
44
+ if implementation == "CPython":
45
+ implementation_version = platform.python_version()
46
+ elif implementation == "PyPy":
47
+ implementation_version = "{}.{}.{}".format(
48
+ sys.pypy_version_info.major,
49
+ sys.pypy_version_info.minor,
50
+ sys.pypy_version_info.micro,
51
+ )
52
+ if sys.pypy_version_info.releaselevel != "final":
53
+ implementation_version = "".join(
54
+ [implementation_version, sys.pypy_version_info.releaselevel]
55
+ )
56
+ elif implementation == "Jython":
57
+ implementation_version = platform.python_version() # Complete Guess
58
+ elif implementation == "IronPython":
59
+ implementation_version = platform.python_version() # Complete Guess
60
+ else:
61
+ implementation_version = "Unknown"
62
+
63
+ return {"name": implementation, "version": implementation_version}
64
+
65
+
66
+ def info():
67
+ """Generate information for a bug report."""
68
+ try:
69
+ platform_info = {
70
+ "system": platform.system(),
71
+ "release": platform.release(),
72
+ }
73
+ except OSError:
74
+ platform_info = {
75
+ "system": "Unknown",
76
+ "release": "Unknown",
77
+ }
78
+
79
+ implementation_info = _implementation()
80
+ urllib3_info = {"version": urllib3.__version__}
81
+ charset_normalizer_info = {"version": None}
82
+ chardet_info = {"version": None}
83
+ if charset_normalizer:
84
+ charset_normalizer_info = {"version": charset_normalizer.__version__}
85
+ if chardet:
86
+ chardet_info = {"version": chardet.__version__}
87
+
88
+ pyopenssl_info = {
89
+ "version": None,
90
+ "openssl_version": "",
91
+ }
92
+ if OpenSSL:
93
+ pyopenssl_info = {
94
+ "version": OpenSSL.__version__,
95
+ "openssl_version": f"{OpenSSL.SSL.OPENSSL_VERSION_NUMBER:x}",
96
+ }
97
+ cryptography_info = {
98
+ "version": getattr(cryptography, "__version__", ""),
99
+ }
100
+ idna_info = {
101
+ "version": getattr(idna, "__version__", ""),
102
+ }
103
+
104
+ system_ssl = ssl.OPENSSL_VERSION_NUMBER
105
+ system_ssl_info = {"version": f"{system_ssl:x}" if system_ssl is not None else ""}
106
+
107
+ return {
108
+ "platform": platform_info,
109
+ "implementation": implementation_info,
110
+ "system_ssl": system_ssl_info,
111
+ "using_pyopenssl": pyopenssl is not None,
112
+ "using_charset_normalizer": chardet is None,
113
+ "pyOpenSSL": pyopenssl_info,
114
+ "urllib3": urllib3_info,
115
+ "chardet": chardet_info,
116
+ "charset_normalizer": charset_normalizer_info,
117
+ "cryptography": cryptography_info,
118
+ "idna": idna_info,
119
+ "requests": {
120
+ "version": requests_version,
121
+ },
122
+ }
123
+
124
+
125
+ def main():
126
+ """Pretty-print the bug information as JSON."""
127
+ print(json.dumps(info(), sort_keys=True, indent=2))
128
+
129
+
130
+ if __name__ == "__main__":
131
+ main()
.venv/lib/python3.11/site-packages/pip/_vendor/requests/hooks.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.hooks
3
+ ~~~~~~~~~~~~~~
4
+
5
+ This module provides the capabilities for the Requests hooks system.
6
+
7
+ Available hooks:
8
+
9
+ ``response``:
10
+ The response generated from a Request.
11
+ """
12
+ HOOKS = ["response"]
13
+
14
+
15
+ def default_hooks():
16
+ return {event: [] for event in HOOKS}
17
+
18
+
19
+ # TODO: response is the only one
20
+
21
+
22
+ def dispatch_hook(key, hooks, hook_data, **kwargs):
23
+ """Dispatches a hook dictionary on a given piece of data."""
24
+ hooks = hooks or {}
25
+ hooks = hooks.get(key)
26
+ if hooks:
27
+ if hasattr(hooks, "__call__"):
28
+ hooks = [hooks]
29
+ for hook in hooks:
30
+ _hook_data = hook(hook_data, **kwargs)
31
+ if _hook_data is not None:
32
+ hook_data = _hook_data
33
+ return hook_data
.venv/lib/python3.11/site-packages/pip/_vendor/requests/models.py ADDED
@@ -0,0 +1,1034 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.models
3
+ ~~~~~~~~~~~~~~~
4
+
5
+ This module contains the primary objects that power Requests.
6
+ """
7
+
8
+ import datetime
9
+
10
+ # Import encoding now, to avoid implicit import later.
11
+ # Implicit import within threads may cause LookupError when standard library is in a ZIP,
12
+ # such as in Embedded Python. See https://github.com/psf/requests/issues/3578.
13
+ import encodings.idna # noqa: F401
14
+ from io import UnsupportedOperation
15
+
16
+ from pip._vendor.urllib3.exceptions import (
17
+ DecodeError,
18
+ LocationParseError,
19
+ ProtocolError,
20
+ ReadTimeoutError,
21
+ SSLError,
22
+ )
23
+ from pip._vendor.urllib3.fields import RequestField
24
+ from pip._vendor.urllib3.filepost import encode_multipart_formdata
25
+ from pip._vendor.urllib3.util import parse_url
26
+
27
+ from ._internal_utils import to_native_string, unicode_is_ascii
28
+ from .auth import HTTPBasicAuth
29
+ from .compat import (
30
+ Callable,
31
+ JSONDecodeError,
32
+ Mapping,
33
+ basestring,
34
+ builtin_str,
35
+ chardet,
36
+ cookielib,
37
+ )
38
+ from .compat import json as complexjson
39
+ from .compat import urlencode, urlsplit, urlunparse
40
+ from .cookies import _copy_cookie_jar, cookiejar_from_dict, get_cookie_header
41
+ from .exceptions import (
42
+ ChunkedEncodingError,
43
+ ConnectionError,
44
+ ContentDecodingError,
45
+ HTTPError,
46
+ InvalidJSONError,
47
+ InvalidURL,
48
+ )
49
+ from .exceptions import JSONDecodeError as RequestsJSONDecodeError
50
+ from .exceptions import MissingSchema
51
+ from .exceptions import SSLError as RequestsSSLError
52
+ from .exceptions import StreamConsumedError
53
+ from .hooks import default_hooks
54
+ from .status_codes import codes
55
+ from .structures import CaseInsensitiveDict
56
+ from .utils import (
57
+ check_header_validity,
58
+ get_auth_from_url,
59
+ guess_filename,
60
+ guess_json_utf,
61
+ iter_slices,
62
+ parse_header_links,
63
+ requote_uri,
64
+ stream_decode_response_unicode,
65
+ super_len,
66
+ to_key_val_list,
67
+ )
68
+
69
+ #: The set of HTTP status codes that indicate an automatically
70
+ #: processable redirect.
71
+ REDIRECT_STATI = (
72
+ codes.moved, # 301
73
+ codes.found, # 302
74
+ codes.other, # 303
75
+ codes.temporary_redirect, # 307
76
+ codes.permanent_redirect, # 308
77
+ )
78
+
79
+ DEFAULT_REDIRECT_LIMIT = 30
80
+ CONTENT_CHUNK_SIZE = 10 * 1024
81
+ ITER_CHUNK_SIZE = 512
82
+
83
+
84
+ class RequestEncodingMixin:
85
+ @property
86
+ def path_url(self):
87
+ """Build the path URL to use."""
88
+
89
+ url = []
90
+
91
+ p = urlsplit(self.url)
92
+
93
+ path = p.path
94
+ if not path:
95
+ path = "/"
96
+
97
+ url.append(path)
98
+
99
+ query = p.query
100
+ if query:
101
+ url.append("?")
102
+ url.append(query)
103
+
104
+ return "".join(url)
105
+
106
+ @staticmethod
107
+ def _encode_params(data):
108
+ """Encode parameters in a piece of data.
109
+
110
+ Will successfully encode parameters when passed as a dict or a list of
111
+ 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary
112
+ if parameters are supplied as a dict.
113
+ """
114
+
115
+ if isinstance(data, (str, bytes)):
116
+ return data
117
+ elif hasattr(data, "read"):
118
+ return data
119
+ elif hasattr(data, "__iter__"):
120
+ result = []
121
+ for k, vs in to_key_val_list(data):
122
+ if isinstance(vs, basestring) or not hasattr(vs, "__iter__"):
123
+ vs = [vs]
124
+ for v in vs:
125
+ if v is not None:
126
+ result.append(
127
+ (
128
+ k.encode("utf-8") if isinstance(k, str) else k,
129
+ v.encode("utf-8") if isinstance(v, str) else v,
130
+ )
131
+ )
132
+ return urlencode(result, doseq=True)
133
+ else:
134
+ return data
135
+
136
+ @staticmethod
137
+ def _encode_files(files, data):
138
+ """Build the body for a multipart/form-data request.
139
+
140
+ Will successfully encode files when passed as a dict or a list of
141
+ tuples. Order is retained if data is a list of tuples but arbitrary
142
+ if parameters are supplied as a dict.
143
+ The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype)
144
+ or 4-tuples (filename, fileobj, contentype, custom_headers).
145
+ """
146
+ if not files:
147
+ raise ValueError("Files must be provided.")
148
+ elif isinstance(data, basestring):
149
+ raise ValueError("Data must not be a string.")
150
+
151
+ new_fields = []
152
+ fields = to_key_val_list(data or {})
153
+ files = to_key_val_list(files or {})
154
+
155
+ for field, val in fields:
156
+ if isinstance(val, basestring) or not hasattr(val, "__iter__"):
157
+ val = [val]
158
+ for v in val:
159
+ if v is not None:
160
+ # Don't call str() on bytestrings: in Py3 it all goes wrong.
161
+ if not isinstance(v, bytes):
162
+ v = str(v)
163
+
164
+ new_fields.append(
165
+ (
166
+ field.decode("utf-8")
167
+ if isinstance(field, bytes)
168
+ else field,
169
+ v.encode("utf-8") if isinstance(v, str) else v,
170
+ )
171
+ )
172
+
173
+ for (k, v) in files:
174
+ # support for explicit filename
175
+ ft = None
176
+ fh = None
177
+ if isinstance(v, (tuple, list)):
178
+ if len(v) == 2:
179
+ fn, fp = v
180
+ elif len(v) == 3:
181
+ fn, fp, ft = v
182
+ else:
183
+ fn, fp, ft, fh = v
184
+ else:
185
+ fn = guess_filename(v) or k
186
+ fp = v
187
+
188
+ if isinstance(fp, (str, bytes, bytearray)):
189
+ fdata = fp
190
+ elif hasattr(fp, "read"):
191
+ fdata = fp.read()
192
+ elif fp is None:
193
+ continue
194
+ else:
195
+ fdata = fp
196
+
197
+ rf = RequestField(name=k, data=fdata, filename=fn, headers=fh)
198
+ rf.make_multipart(content_type=ft)
199
+ new_fields.append(rf)
200
+
201
+ body, content_type = encode_multipart_formdata(new_fields)
202
+
203
+ return body, content_type
204
+
205
+
206
+ class RequestHooksMixin:
207
+ def register_hook(self, event, hook):
208
+ """Properly register a hook."""
209
+
210
+ if event not in self.hooks:
211
+ raise ValueError(f'Unsupported event specified, with event name "{event}"')
212
+
213
+ if isinstance(hook, Callable):
214
+ self.hooks[event].append(hook)
215
+ elif hasattr(hook, "__iter__"):
216
+ self.hooks[event].extend(h for h in hook if isinstance(h, Callable))
217
+
218
+ def deregister_hook(self, event, hook):
219
+ """Deregister a previously registered hook.
220
+ Returns True if the hook existed, False if not.
221
+ """
222
+
223
+ try:
224
+ self.hooks[event].remove(hook)
225
+ return True
226
+ except ValueError:
227
+ return False
228
+
229
+
230
+ class Request(RequestHooksMixin):
231
+ """A user-created :class:`Request <Request>` object.
232
+
233
+ Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server.
234
+
235
+ :param method: HTTP method to use.
236
+ :param url: URL to send.
237
+ :param headers: dictionary of headers to send.
238
+ :param files: dictionary of {filename: fileobject} files to multipart upload.
239
+ :param data: the body to attach to the request. If a dictionary or
240
+ list of tuples ``[(key, value)]`` is provided, form-encoding will
241
+ take place.
242
+ :param json: json for the body to attach to the request (if files or data is not specified).
243
+ :param params: URL parameters to append to the URL. If a dictionary or
244
+ list of tuples ``[(key, value)]`` is provided, form-encoding will
245
+ take place.
246
+ :param auth: Auth handler or (user, pass) tuple.
247
+ :param cookies: dictionary or CookieJar of cookies to attach to this request.
248
+ :param hooks: dictionary of callback hooks, for internal usage.
249
+
250
+ Usage::
251
+
252
+ >>> import requests
253
+ >>> req = requests.Request('GET', 'https://httpbin.org/get')
254
+ >>> req.prepare()
255
+ <PreparedRequest [GET]>
256
+ """
257
+
258
+ def __init__(
259
+ self,
260
+ method=None,
261
+ url=None,
262
+ headers=None,
263
+ files=None,
264
+ data=None,
265
+ params=None,
266
+ auth=None,
267
+ cookies=None,
268
+ hooks=None,
269
+ json=None,
270
+ ):
271
+
272
+ # Default empty dicts for dict params.
273
+ data = [] if data is None else data
274
+ files = [] if files is None else files
275
+ headers = {} if headers is None else headers
276
+ params = {} if params is None else params
277
+ hooks = {} if hooks is None else hooks
278
+
279
+ self.hooks = default_hooks()
280
+ for (k, v) in list(hooks.items()):
281
+ self.register_hook(event=k, hook=v)
282
+
283
+ self.method = method
284
+ self.url = url
285
+ self.headers = headers
286
+ self.files = files
287
+ self.data = data
288
+ self.json = json
289
+ self.params = params
290
+ self.auth = auth
291
+ self.cookies = cookies
292
+
293
+ def __repr__(self):
294
+ return f"<Request [{self.method}]>"
295
+
296
+ def prepare(self):
297
+ """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it."""
298
+ p = PreparedRequest()
299
+ p.prepare(
300
+ method=self.method,
301
+ url=self.url,
302
+ headers=self.headers,
303
+ files=self.files,
304
+ data=self.data,
305
+ json=self.json,
306
+ params=self.params,
307
+ auth=self.auth,
308
+ cookies=self.cookies,
309
+ hooks=self.hooks,
310
+ )
311
+ return p
312
+
313
+
314
+ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
315
+ """The fully mutable :class:`PreparedRequest <PreparedRequest>` object,
316
+ containing the exact bytes that will be sent to the server.
317
+
318
+ Instances are generated from a :class:`Request <Request>` object, and
319
+ should not be instantiated manually; doing so may produce undesirable
320
+ effects.
321
+
322
+ Usage::
323
+
324
+ >>> import requests
325
+ >>> req = requests.Request('GET', 'https://httpbin.org/get')
326
+ >>> r = req.prepare()
327
+ >>> r
328
+ <PreparedRequest [GET]>
329
+
330
+ >>> s = requests.Session()
331
+ >>> s.send(r)
332
+ <Response [200]>
333
+ """
334
+
335
+ def __init__(self):
336
+ #: HTTP verb to send to the server.
337
+ self.method = None
338
+ #: HTTP URL to send the request to.
339
+ self.url = None
340
+ #: dictionary of HTTP headers.
341
+ self.headers = None
342
+ # The `CookieJar` used to create the Cookie header will be stored here
343
+ # after prepare_cookies is called
344
+ self._cookies = None
345
+ #: request body to send to the server.
346
+ self.body = None
347
+ #: dictionary of callback hooks, for internal usage.
348
+ self.hooks = default_hooks()
349
+ #: integer denoting starting position of a readable file-like body.
350
+ self._body_position = None
351
+
352
+ def prepare(
353
+ self,
354
+ method=None,
355
+ url=None,
356
+ headers=None,
357
+ files=None,
358
+ data=None,
359
+ params=None,
360
+ auth=None,
361
+ cookies=None,
362
+ hooks=None,
363
+ json=None,
364
+ ):
365
+ """Prepares the entire request with the given parameters."""
366
+
367
+ self.prepare_method(method)
368
+ self.prepare_url(url, params)
369
+ self.prepare_headers(headers)
370
+ self.prepare_cookies(cookies)
371
+ self.prepare_body(data, files, json)
372
+ self.prepare_auth(auth, url)
373
+
374
+ # Note that prepare_auth must be last to enable authentication schemes
375
+ # such as OAuth to work on a fully prepared request.
376
+
377
+ # This MUST go after prepare_auth. Authenticators could add a hook
378
+ self.prepare_hooks(hooks)
379
+
380
+ def __repr__(self):
381
+ return f"<PreparedRequest [{self.method}]>"
382
+
383
+ def copy(self):
384
+ p = PreparedRequest()
385
+ p.method = self.method
386
+ p.url = self.url
387
+ p.headers = self.headers.copy() if self.headers is not None else None
388
+ p._cookies = _copy_cookie_jar(self._cookies)
389
+ p.body = self.body
390
+ p.hooks = self.hooks
391
+ p._body_position = self._body_position
392
+ return p
393
+
394
+ def prepare_method(self, method):
395
+ """Prepares the given HTTP method."""
396
+ self.method = method
397
+ if self.method is not None:
398
+ self.method = to_native_string(self.method.upper())
399
+
400
+ @staticmethod
401
+ def _get_idna_encoded_host(host):
402
+ from pip._vendor import idna
403
+
404
+ try:
405
+ host = idna.encode(host, uts46=True).decode("utf-8")
406
+ except idna.IDNAError:
407
+ raise UnicodeError
408
+ return host
409
+
410
+ def prepare_url(self, url, params):
411
+ """Prepares the given HTTP URL."""
412
+ #: Accept objects that have string representations.
413
+ #: We're unable to blindly call unicode/str functions
414
+ #: as this will include the bytestring indicator (b'')
415
+ #: on python 3.x.
416
+ #: https://github.com/psf/requests/pull/2238
417
+ if isinstance(url, bytes):
418
+ url = url.decode("utf8")
419
+ else:
420
+ url = str(url)
421
+
422
+ # Remove leading whitespaces from url
423
+ url = url.lstrip()
424
+
425
+ # Don't do any URL preparation for non-HTTP schemes like `mailto`,
426
+ # `data` etc to work around exceptions from `url_parse`, which
427
+ # handles RFC 3986 only.
428
+ if ":" in url and not url.lower().startswith("http"):
429
+ self.url = url
430
+ return
431
+
432
+ # Support for unicode domain names and paths.
433
+ try:
434
+ scheme, auth, host, port, path, query, fragment = parse_url(url)
435
+ except LocationParseError as e:
436
+ raise InvalidURL(*e.args)
437
+
438
+ if not scheme:
439
+ raise MissingSchema(
440
+ f"Invalid URL {url!r}: No scheme supplied. "
441
+ f"Perhaps you meant https://{url}?"
442
+ )
443
+
444
+ if not host:
445
+ raise InvalidURL(f"Invalid URL {url!r}: No host supplied")
446
+
447
+ # In general, we want to try IDNA encoding the hostname if the string contains
448
+ # non-ASCII characters. This allows users to automatically get the correct IDNA
449
+ # behaviour. For strings containing only ASCII characters, we need to also verify
450
+ # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
451
+ if not unicode_is_ascii(host):
452
+ try:
453
+ host = self._get_idna_encoded_host(host)
454
+ except UnicodeError:
455
+ raise InvalidURL("URL has an invalid label.")
456
+ elif host.startswith(("*", ".")):
457
+ raise InvalidURL("URL has an invalid label.")
458
+
459
+ # Carefully reconstruct the network location
460
+ netloc = auth or ""
461
+ if netloc:
462
+ netloc += "@"
463
+ netloc += host
464
+ if port:
465
+ netloc += f":{port}"
466
+
467
+ # Bare domains aren't valid URLs.
468
+ if not path:
469
+ path = "/"
470
+
471
+ if isinstance(params, (str, bytes)):
472
+ params = to_native_string(params)
473
+
474
+ enc_params = self._encode_params(params)
475
+ if enc_params:
476
+ if query:
477
+ query = f"{query}&{enc_params}"
478
+ else:
479
+ query = enc_params
480
+
481
+ url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment]))
482
+ self.url = url
483
+
484
+ def prepare_headers(self, headers):
485
+ """Prepares the given HTTP headers."""
486
+
487
+ self.headers = CaseInsensitiveDict()
488
+ if headers:
489
+ for header in headers.items():
490
+ # Raise exception on invalid header value.
491
+ check_header_validity(header)
492
+ name, value = header
493
+ self.headers[to_native_string(name)] = value
494
+
495
+ def prepare_body(self, data, files, json=None):
496
+ """Prepares the given HTTP body data."""
497
+
498
+ # Check if file, fo, generator, iterator.
499
+ # If not, run through normal process.
500
+
501
+ # Nottin' on you.
502
+ body = None
503
+ content_type = None
504
+
505
+ if not data and json is not None:
506
+ # urllib3 requires a bytes-like body. Python 2's json.dumps
507
+ # provides this natively, but Python 3 gives a Unicode string.
508
+ content_type = "application/json"
509
+
510
+ try:
511
+ body = complexjson.dumps(json, allow_nan=False)
512
+ except ValueError as ve:
513
+ raise InvalidJSONError(ve, request=self)
514
+
515
+ if not isinstance(body, bytes):
516
+ body = body.encode("utf-8")
517
+
518
+ is_stream = all(
519
+ [
520
+ hasattr(data, "__iter__"),
521
+ not isinstance(data, (basestring, list, tuple, Mapping)),
522
+ ]
523
+ )
524
+
525
+ if is_stream:
526
+ try:
527
+ length = super_len(data)
528
+ except (TypeError, AttributeError, UnsupportedOperation):
529
+ length = None
530
+
531
+ body = data
532
+
533
+ if getattr(body, "tell", None) is not None:
534
+ # Record the current file position before reading.
535
+ # This will allow us to rewind a file in the event
536
+ # of a redirect.
537
+ try:
538
+ self._body_position = body.tell()
539
+ except OSError:
540
+ # This differentiates from None, allowing us to catch
541
+ # a failed `tell()` later when trying to rewind the body
542
+ self._body_position = object()
543
+
544
+ if files:
545
+ raise NotImplementedError(
546
+ "Streamed bodies and files are mutually exclusive."
547
+ )
548
+
549
+ if length:
550
+ self.headers["Content-Length"] = builtin_str(length)
551
+ else:
552
+ self.headers["Transfer-Encoding"] = "chunked"
553
+ else:
554
+ # Multi-part file uploads.
555
+ if files:
556
+ (body, content_type) = self._encode_files(files, data)
557
+ else:
558
+ if data:
559
+ body = self._encode_params(data)
560
+ if isinstance(data, basestring) or hasattr(data, "read"):
561
+ content_type = None
562
+ else:
563
+ content_type = "application/x-www-form-urlencoded"
564
+
565
+ self.prepare_content_length(body)
566
+
567
+ # Add content-type if it wasn't explicitly provided.
568
+ if content_type and ("content-type" not in self.headers):
569
+ self.headers["Content-Type"] = content_type
570
+
571
+ self.body = body
572
+
573
+ def prepare_content_length(self, body):
574
+ """Prepare Content-Length header based on request method and body"""
575
+ if body is not None:
576
+ length = super_len(body)
577
+ if length:
578
+ # If length exists, set it. Otherwise, we fallback
579
+ # to Transfer-Encoding: chunked.
580
+ self.headers["Content-Length"] = builtin_str(length)
581
+ elif (
582
+ self.method not in ("GET", "HEAD")
583
+ and self.headers.get("Content-Length") is None
584
+ ):
585
+ # Set Content-Length to 0 for methods that can have a body
586
+ # but don't provide one. (i.e. not GET or HEAD)
587
+ self.headers["Content-Length"] = "0"
588
+
589
+ def prepare_auth(self, auth, url=""):
590
+ """Prepares the given HTTP auth data."""
591
+
592
+ # If no Auth is explicitly provided, extract it from the URL first.
593
+ if auth is None:
594
+ url_auth = get_auth_from_url(self.url)
595
+ auth = url_auth if any(url_auth) else None
596
+
597
+ if auth:
598
+ if isinstance(auth, tuple) and len(auth) == 2:
599
+ # special-case basic HTTP auth
600
+ auth = HTTPBasicAuth(*auth)
601
+
602
+ # Allow auth to make its changes.
603
+ r = auth(self)
604
+
605
+ # Update self to reflect the auth changes.
606
+ self.__dict__.update(r.__dict__)
607
+
608
+ # Recompute Content-Length
609
+ self.prepare_content_length(self.body)
610
+
611
+ def prepare_cookies(self, cookies):
612
+ """Prepares the given HTTP cookie data.
613
+
614
+ This function eventually generates a ``Cookie`` header from the
615
+ given cookies using cookielib. Due to cookielib's design, the header
616
+ will not be regenerated if it already exists, meaning this function
617
+ can only be called once for the life of the
618
+ :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls
619
+ to ``prepare_cookies`` will have no actual effect, unless the "Cookie"
620
+ header is removed beforehand.
621
+ """
622
+ if isinstance(cookies, cookielib.CookieJar):
623
+ self._cookies = cookies
624
+ else:
625
+ self._cookies = cookiejar_from_dict(cookies)
626
+
627
+ cookie_header = get_cookie_header(self._cookies, self)
628
+ if cookie_header is not None:
629
+ self.headers["Cookie"] = cookie_header
630
+
631
+ def prepare_hooks(self, hooks):
632
+ """Prepares the given hooks."""
633
+ # hooks can be passed as None to the prepare method and to this
634
+ # method. To prevent iterating over None, simply use an empty list
635
+ # if hooks is False-y
636
+ hooks = hooks or []
637
+ for event in hooks:
638
+ self.register_hook(event, hooks[event])
639
+
640
+
641
+ class Response:
642
+ """The :class:`Response <Response>` object, which contains a
643
+ server's response to an HTTP request.
644
+ """
645
+
646
+ __attrs__ = [
647
+ "_content",
648
+ "status_code",
649
+ "headers",
650
+ "url",
651
+ "history",
652
+ "encoding",
653
+ "reason",
654
+ "cookies",
655
+ "elapsed",
656
+ "request",
657
+ ]
658
+
659
+ def __init__(self):
660
+ self._content = False
661
+ self._content_consumed = False
662
+ self._next = None
663
+
664
+ #: Integer Code of responded HTTP Status, e.g. 404 or 200.
665
+ self.status_code = None
666
+
667
+ #: Case-insensitive Dictionary of Response Headers.
668
+ #: For example, ``headers['content-encoding']`` will return the
669
+ #: value of a ``'Content-Encoding'`` response header.
670
+ self.headers = CaseInsensitiveDict()
671
+
672
+ #: File-like object representation of response (for advanced usage).
673
+ #: Use of ``raw`` requires that ``stream=True`` be set on the request.
674
+ #: This requirement does not apply for use internally to Requests.
675
+ self.raw = None
676
+
677
+ #: Final URL location of Response.
678
+ self.url = None
679
+
680
+ #: Encoding to decode with when accessing r.text.
681
+ self.encoding = None
682
+
683
+ #: A list of :class:`Response <Response>` objects from
684
+ #: the history of the Request. Any redirect responses will end
685
+ #: up here. The list is sorted from the oldest to the most recent request.
686
+ self.history = []
687
+
688
+ #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK".
689
+ self.reason = None
690
+
691
+ #: A CookieJar of Cookies the server sent back.
692
+ self.cookies = cookiejar_from_dict({})
693
+
694
+ #: The amount of time elapsed between sending the request
695
+ #: and the arrival of the response (as a timedelta).
696
+ #: This property specifically measures the time taken between sending
697
+ #: the first byte of the request and finishing parsing the headers. It
698
+ #: is therefore unaffected by consuming the response content or the
699
+ #: value of the ``stream`` keyword argument.
700
+ self.elapsed = datetime.timedelta(0)
701
+
702
+ #: The :class:`PreparedRequest <PreparedRequest>` object to which this
703
+ #: is a response.
704
+ self.request = None
705
+
706
+ def __enter__(self):
707
+ return self
708
+
709
+ def __exit__(self, *args):
710
+ self.close()
711
+
712
+ def __getstate__(self):
713
+ # Consume everything; accessing the content attribute makes
714
+ # sure the content has been fully read.
715
+ if not self._content_consumed:
716
+ self.content
717
+
718
+ return {attr: getattr(self, attr, None) for attr in self.__attrs__}
719
+
720
+ def __setstate__(self, state):
721
+ for name, value in state.items():
722
+ setattr(self, name, value)
723
+
724
+ # pickled objects do not have .raw
725
+ setattr(self, "_content_consumed", True)
726
+ setattr(self, "raw", None)
727
+
728
+ def __repr__(self):
729
+ return f"<Response [{self.status_code}]>"
730
+
731
+ def __bool__(self):
732
+ """Returns True if :attr:`status_code` is less than 400.
733
+
734
+ This attribute checks if the status code of the response is between
735
+ 400 and 600 to see if there was a client error or a server error. If
736
+ the status code, is between 200 and 400, this will return True. This
737
+ is **not** a check to see if the response code is ``200 OK``.
738
+ """
739
+ return self.ok
740
+
741
+ def __nonzero__(self):
742
+ """Returns True if :attr:`status_code` is less than 400.
743
+
744
+ This attribute checks if the status code of the response is between
745
+ 400 and 600 to see if there was a client error or a server error. If
746
+ the status code, is between 200 and 400, this will return True. This
747
+ is **not** a check to see if the response code is ``200 OK``.
748
+ """
749
+ return self.ok
750
+
751
+ def __iter__(self):
752
+ """Allows you to use a response as an iterator."""
753
+ return self.iter_content(128)
754
+
755
+ @property
756
+ def ok(self):
757
+ """Returns True if :attr:`status_code` is less than 400, False if not.
758
+
759
+ This attribute checks if the status code of the response is between
760
+ 400 and 600 to see if there was a client error or a server error. If
761
+ the status code is between 200 and 400, this will return True. This
762
+ is **not** a check to see if the response code is ``200 OK``.
763
+ """
764
+ try:
765
+ self.raise_for_status()
766
+ except HTTPError:
767
+ return False
768
+ return True
769
+
770
+ @property
771
+ def is_redirect(self):
772
+ """True if this Response is a well-formed HTTP redirect that could have
773
+ been processed automatically (by :meth:`Session.resolve_redirects`).
774
+ """
775
+ return "location" in self.headers and self.status_code in REDIRECT_STATI
776
+
777
+ @property
778
+ def is_permanent_redirect(self):
779
+ """True if this Response one of the permanent versions of redirect."""
780
+ return "location" in self.headers and self.status_code in (
781
+ codes.moved_permanently,
782
+ codes.permanent_redirect,
783
+ )
784
+
785
+ @property
786
+ def next(self):
787
+ """Returns a PreparedRequest for the next request in a redirect chain, if there is one."""
788
+ return self._next
789
+
790
+ @property
791
+ def apparent_encoding(self):
792
+ """The apparent encoding, provided by the charset_normalizer or chardet libraries."""
793
+ return chardet.detect(self.content)["encoding"]
794
+
795
+ def iter_content(self, chunk_size=1, decode_unicode=False):
796
+ """Iterates over the response data. When stream=True is set on the
797
+ request, this avoids reading the content at once into memory for
798
+ large responses. The chunk size is the number of bytes it should
799
+ read into memory. This is not necessarily the length of each item
800
+ returned as decoding can take place.
801
+
802
+ chunk_size must be of type int or None. A value of None will
803
+ function differently depending on the value of `stream`.
804
+ stream=True will read data as it arrives in whatever size the
805
+ chunks are received. If stream=False, data is returned as
806
+ a single chunk.
807
+
808
+ If decode_unicode is True, content will be decoded using the best
809
+ available encoding based on the response.
810
+ """
811
+
812
+ def generate():
813
+ # Special case for urllib3.
814
+ if hasattr(self.raw, "stream"):
815
+ try:
816
+ yield from self.raw.stream(chunk_size, decode_content=True)
817
+ except ProtocolError as e:
818
+ raise ChunkedEncodingError(e)
819
+ except DecodeError as e:
820
+ raise ContentDecodingError(e)
821
+ except ReadTimeoutError as e:
822
+ raise ConnectionError(e)
823
+ except SSLError as e:
824
+ raise RequestsSSLError(e)
825
+ else:
826
+ # Standard file-like object.
827
+ while True:
828
+ chunk = self.raw.read(chunk_size)
829
+ if not chunk:
830
+ break
831
+ yield chunk
832
+
833
+ self._content_consumed = True
834
+
835
+ if self._content_consumed and isinstance(self._content, bool):
836
+ raise StreamConsumedError()
837
+ elif chunk_size is not None and not isinstance(chunk_size, int):
838
+ raise TypeError(
839
+ f"chunk_size must be an int, it is instead a {type(chunk_size)}."
840
+ )
841
+ # simulate reading small chunks of the content
842
+ reused_chunks = iter_slices(self._content, chunk_size)
843
+
844
+ stream_chunks = generate()
845
+
846
+ chunks = reused_chunks if self._content_consumed else stream_chunks
847
+
848
+ if decode_unicode:
849
+ chunks = stream_decode_response_unicode(chunks, self)
850
+
851
+ return chunks
852
+
853
+ def iter_lines(
854
+ self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None
855
+ ):
856
+ """Iterates over the response data, one line at a time. When
857
+ stream=True is set on the request, this avoids reading the
858
+ content at once into memory for large responses.
859
+
860
+ .. note:: This method is not reentrant safe.
861
+ """
862
+
863
+ pending = None
864
+
865
+ for chunk in self.iter_content(
866
+ chunk_size=chunk_size, decode_unicode=decode_unicode
867
+ ):
868
+
869
+ if pending is not None:
870
+ chunk = pending + chunk
871
+
872
+ if delimiter:
873
+ lines = chunk.split(delimiter)
874
+ else:
875
+ lines = chunk.splitlines()
876
+
877
+ if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
878
+ pending = lines.pop()
879
+ else:
880
+ pending = None
881
+
882
+ yield from lines
883
+
884
+ if pending is not None:
885
+ yield pending
886
+
887
+ @property
888
+ def content(self):
889
+ """Content of the response, in bytes."""
890
+
891
+ if self._content is False:
892
+ # Read the contents.
893
+ if self._content_consumed:
894
+ raise RuntimeError("The content for this response was already consumed")
895
+
896
+ if self.status_code == 0 or self.raw is None:
897
+ self._content = None
898
+ else:
899
+ self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
900
+
901
+ self._content_consumed = True
902
+ # don't need to release the connection; that's been handled by urllib3
903
+ # since we exhausted the data.
904
+ return self._content
905
+
906
+ @property
907
+ def text(self):
908
+ """Content of the response, in unicode.
909
+
910
+ If Response.encoding is None, encoding will be guessed using
911
+ ``charset_normalizer`` or ``chardet``.
912
+
913
+ The encoding of the response content is determined based solely on HTTP
914
+ headers, following RFC 2616 to the letter. If you can take advantage of
915
+ non-HTTP knowledge to make a better guess at the encoding, you should
916
+ set ``r.encoding`` appropriately before accessing this property.
917
+ """
918
+
919
+ # Try charset from content-type
920
+ content = None
921
+ encoding = self.encoding
922
+
923
+ if not self.content:
924
+ return ""
925
+
926
+ # Fallback to auto-detected encoding.
927
+ if self.encoding is None:
928
+ encoding = self.apparent_encoding
929
+
930
+ # Decode unicode from given encoding.
931
+ try:
932
+ content = str(self.content, encoding, errors="replace")
933
+ except (LookupError, TypeError):
934
+ # A LookupError is raised if the encoding was not found which could
935
+ # indicate a misspelling or similar mistake.
936
+ #
937
+ # A TypeError can be raised if encoding is None
938
+ #
939
+ # So we try blindly encoding.
940
+ content = str(self.content, errors="replace")
941
+
942
+ return content
943
+
944
+ def json(self, **kwargs):
945
+ r"""Returns the json-encoded content of a response, if any.
946
+
947
+ :param \*\*kwargs: Optional arguments that ``json.loads`` takes.
948
+ :raises requests.exceptions.JSONDecodeError: If the response body does not
949
+ contain valid json.
950
+ """
951
+
952
+ if not self.encoding and self.content and len(self.content) > 3:
953
+ # No encoding set. JSON RFC 4627 section 3 states we should expect
954
+ # UTF-8, -16 or -32. Detect which one to use; If the detection or
955
+ # decoding fails, fall back to `self.text` (using charset_normalizer to make
956
+ # a best guess).
957
+ encoding = guess_json_utf(self.content)
958
+ if encoding is not None:
959
+ try:
960
+ return complexjson.loads(self.content.decode(encoding), **kwargs)
961
+ except UnicodeDecodeError:
962
+ # Wrong UTF codec detected; usually because it's not UTF-8
963
+ # but some other 8-bit codec. This is an RFC violation,
964
+ # and the server didn't bother to tell us what codec *was*
965
+ # used.
966
+ pass
967
+ except JSONDecodeError as e:
968
+ raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
969
+
970
+ try:
971
+ return complexjson.loads(self.text, **kwargs)
972
+ except JSONDecodeError as e:
973
+ # Catch JSON-related errors and raise as requests.JSONDecodeError
974
+ # This aliases json.JSONDecodeError and simplejson.JSONDecodeError
975
+ raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
976
+
977
+ @property
978
+ def links(self):
979
+ """Returns the parsed header links of the response, if any."""
980
+
981
+ header = self.headers.get("link")
982
+
983
+ resolved_links = {}
984
+
985
+ if header:
986
+ links = parse_header_links(header)
987
+
988
+ for link in links:
989
+ key = link.get("rel") or link.get("url")
990
+ resolved_links[key] = link
991
+
992
+ return resolved_links
993
+
994
+ def raise_for_status(self):
995
+ """Raises :class:`HTTPError`, if one occurred."""
996
+
997
+ http_error_msg = ""
998
+ if isinstance(self.reason, bytes):
999
+ # We attempt to decode utf-8 first because some servers
1000
+ # choose to localize their reason strings. If the string
1001
+ # isn't utf-8, we fall back to iso-8859-1 for all other
1002
+ # encodings. (See PR #3538)
1003
+ try:
1004
+ reason = self.reason.decode("utf-8")
1005
+ except UnicodeDecodeError:
1006
+ reason = self.reason.decode("iso-8859-1")
1007
+ else:
1008
+ reason = self.reason
1009
+
1010
+ if 400 <= self.status_code < 500:
1011
+ http_error_msg = (
1012
+ f"{self.status_code} Client Error: {reason} for url: {self.url}"
1013
+ )
1014
+
1015
+ elif 500 <= self.status_code < 600:
1016
+ http_error_msg = (
1017
+ f"{self.status_code} Server Error: {reason} for url: {self.url}"
1018
+ )
1019
+
1020
+ if http_error_msg:
1021
+ raise HTTPError(http_error_msg, response=self)
1022
+
1023
+ def close(self):
1024
+ """Releases the connection back to the pool. Once this method has been
1025
+ called the underlying ``raw`` object must not be accessed again.
1026
+
1027
+ *Note: Should not normally need to be called explicitly.*
1028
+ """
1029
+ if not self._content_consumed:
1030
+ self.raw.close()
1031
+
1032
+ release_conn = getattr(self.raw, "release_conn", None)
1033
+ if release_conn is not None:
1034
+ release_conn()
.venv/lib/python3.11/site-packages/pip/_vendor/requests/packages.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ # This code exists for backwards compatibility reasons.
4
+ # I don't like it either. Just look the other way. :)
5
+
6
+ for package in ('urllib3', 'idna', 'chardet'):
7
+ vendored_package = "pip._vendor." + package
8
+ locals()[package] = __import__(vendored_package)
9
+ # This traversal is apparently necessary such that the identities are
10
+ # preserved (requests.packages.urllib3.* is urllib3.*)
11
+ for mod in list(sys.modules):
12
+ if mod == vendored_package or mod.startswith(vendored_package + '.'):
13
+ unprefixed_mod = mod[len("pip._vendor."):]
14
+ sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod]
15
+
16
+ # Kinda cool, though, right?
.venv/lib/python3.11/site-packages/pip/_vendor/requests/sessions.py ADDED
@@ -0,0 +1,833 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.sessions
3
+ ~~~~~~~~~~~~~~~~~
4
+
5
+ This module provides a Session object to manage and persist settings across
6
+ requests (cookies, auth, proxies).
7
+ """
8
+ import os
9
+ import sys
10
+ import time
11
+ from collections import OrderedDict
12
+ from datetime import timedelta
13
+
14
+ from ._internal_utils import to_native_string
15
+ from .adapters import HTTPAdapter
16
+ from .auth import _basic_auth_str
17
+ from .compat import Mapping, cookielib, urljoin, urlparse
18
+ from .cookies import (
19
+ RequestsCookieJar,
20
+ cookiejar_from_dict,
21
+ extract_cookies_to_jar,
22
+ merge_cookies,
23
+ )
24
+ from .exceptions import (
25
+ ChunkedEncodingError,
26
+ ContentDecodingError,
27
+ InvalidSchema,
28
+ TooManyRedirects,
29
+ )
30
+ from .hooks import default_hooks, dispatch_hook
31
+
32
+ # formerly defined here, reexposed here for backward compatibility
33
+ from .models import ( # noqa: F401
34
+ DEFAULT_REDIRECT_LIMIT,
35
+ REDIRECT_STATI,
36
+ PreparedRequest,
37
+ Request,
38
+ )
39
+ from .status_codes import codes
40
+ from .structures import CaseInsensitiveDict
41
+ from .utils import ( # noqa: F401
42
+ DEFAULT_PORTS,
43
+ default_headers,
44
+ get_auth_from_url,
45
+ get_environ_proxies,
46
+ get_netrc_auth,
47
+ requote_uri,
48
+ resolve_proxies,
49
+ rewind_body,
50
+ should_bypass_proxies,
51
+ to_key_val_list,
52
+ )
53
+
54
+ # Preferred clock, based on which one is more accurate on a given system.
55
+ if sys.platform == "win32":
56
+ preferred_clock = time.perf_counter
57
+ else:
58
+ preferred_clock = time.time
59
+
60
+
61
+ def merge_setting(request_setting, session_setting, dict_class=OrderedDict):
62
+ """Determines appropriate setting for a given request, taking into account
63
+ the explicit setting on that request, and the setting in the session. If a
64
+ setting is a dictionary, they will be merged together using `dict_class`
65
+ """
66
+
67
+ if session_setting is None:
68
+ return request_setting
69
+
70
+ if request_setting is None:
71
+ return session_setting
72
+
73
+ # Bypass if not a dictionary (e.g. verify)
74
+ if not (
75
+ isinstance(session_setting, Mapping) and isinstance(request_setting, Mapping)
76
+ ):
77
+ return request_setting
78
+
79
+ merged_setting = dict_class(to_key_val_list(session_setting))
80
+ merged_setting.update(to_key_val_list(request_setting))
81
+
82
+ # Remove keys that are set to None. Extract keys first to avoid altering
83
+ # the dictionary during iteration.
84
+ none_keys = [k for (k, v) in merged_setting.items() if v is None]
85
+ for key in none_keys:
86
+ del merged_setting[key]
87
+
88
+ return merged_setting
89
+
90
+
91
+ def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict):
92
+ """Properly merges both requests and session hooks.
93
+
94
+ This is necessary because when request_hooks == {'response': []}, the
95
+ merge breaks Session hooks entirely.
96
+ """
97
+ if session_hooks is None or session_hooks.get("response") == []:
98
+ return request_hooks
99
+
100
+ if request_hooks is None or request_hooks.get("response") == []:
101
+ return session_hooks
102
+
103
+ return merge_setting(request_hooks, session_hooks, dict_class)
104
+
105
+
106
+ class SessionRedirectMixin:
107
+ def get_redirect_target(self, resp):
108
+ """Receives a Response. Returns a redirect URI or ``None``"""
109
+ # Due to the nature of how requests processes redirects this method will
110
+ # be called at least once upon the original response and at least twice
111
+ # on each subsequent redirect response (if any).
112
+ # If a custom mixin is used to handle this logic, it may be advantageous
113
+ # to cache the redirect location onto the response object as a private
114
+ # attribute.
115
+ if resp.is_redirect:
116
+ location = resp.headers["location"]
117
+ # Currently the underlying http module on py3 decode headers
118
+ # in latin1, but empirical evidence suggests that latin1 is very
119
+ # rarely used with non-ASCII characters in HTTP headers.
120
+ # It is more likely to get UTF8 header rather than latin1.
121
+ # This causes incorrect handling of UTF8 encoded location headers.
122
+ # To solve this, we re-encode the location in latin1.
123
+ location = location.encode("latin1")
124
+ return to_native_string(location, "utf8")
125
+ return None
126
+
127
+ def should_strip_auth(self, old_url, new_url):
128
+ """Decide whether Authorization header should be removed when redirecting"""
129
+ old_parsed = urlparse(old_url)
130
+ new_parsed = urlparse(new_url)
131
+ if old_parsed.hostname != new_parsed.hostname:
132
+ return True
133
+ # Special case: allow http -> https redirect when using the standard
134
+ # ports. This isn't specified by RFC 7235, but is kept to avoid
135
+ # breaking backwards compatibility with older versions of requests
136
+ # that allowed any redirects on the same host.
137
+ if (
138
+ old_parsed.scheme == "http"
139
+ and old_parsed.port in (80, None)
140
+ and new_parsed.scheme == "https"
141
+ and new_parsed.port in (443, None)
142
+ ):
143
+ return False
144
+
145
+ # Handle default port usage corresponding to scheme.
146
+ changed_port = old_parsed.port != new_parsed.port
147
+ changed_scheme = old_parsed.scheme != new_parsed.scheme
148
+ default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None)
149
+ if (
150
+ not changed_scheme
151
+ and old_parsed.port in default_port
152
+ and new_parsed.port in default_port
153
+ ):
154
+ return False
155
+
156
+ # Standard case: root URI must match
157
+ return changed_port or changed_scheme
158
+
159
+ def resolve_redirects(
160
+ self,
161
+ resp,
162
+ req,
163
+ stream=False,
164
+ timeout=None,
165
+ verify=True,
166
+ cert=None,
167
+ proxies=None,
168
+ yield_requests=False,
169
+ **adapter_kwargs,
170
+ ):
171
+ """Receives a Response. Returns a generator of Responses or Requests."""
172
+
173
+ hist = [] # keep track of history
174
+
175
+ url = self.get_redirect_target(resp)
176
+ previous_fragment = urlparse(req.url).fragment
177
+ while url:
178
+ prepared_request = req.copy()
179
+
180
+ # Update history and keep track of redirects.
181
+ # resp.history must ignore the original request in this loop
182
+ hist.append(resp)
183
+ resp.history = hist[1:]
184
+
185
+ try:
186
+ resp.content # Consume socket so it can be released
187
+ except (ChunkedEncodingError, ContentDecodingError, RuntimeError):
188
+ resp.raw.read(decode_content=False)
189
+
190
+ if len(resp.history) >= self.max_redirects:
191
+ raise TooManyRedirects(
192
+ f"Exceeded {self.max_redirects} redirects.", response=resp
193
+ )
194
+
195
+ # Release the connection back into the pool.
196
+ resp.close()
197
+
198
+ # Handle redirection without scheme (see: RFC 1808 Section 4)
199
+ if url.startswith("//"):
200
+ parsed_rurl = urlparse(resp.url)
201
+ url = ":".join([to_native_string(parsed_rurl.scheme), url])
202
+
203
+ # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2)
204
+ parsed = urlparse(url)
205
+ if parsed.fragment == "" and previous_fragment:
206
+ parsed = parsed._replace(fragment=previous_fragment)
207
+ elif parsed.fragment:
208
+ previous_fragment = parsed.fragment
209
+ url = parsed.geturl()
210
+
211
+ # Facilitate relative 'location' headers, as allowed by RFC 7231.
212
+ # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource')
213
+ # Compliant with RFC3986, we percent encode the url.
214
+ if not parsed.netloc:
215
+ url = urljoin(resp.url, requote_uri(url))
216
+ else:
217
+ url = requote_uri(url)
218
+
219
+ prepared_request.url = to_native_string(url)
220
+
221
+ self.rebuild_method(prepared_request, resp)
222
+
223
+ # https://github.com/psf/requests/issues/1084
224
+ if resp.status_code not in (
225
+ codes.temporary_redirect,
226
+ codes.permanent_redirect,
227
+ ):
228
+ # https://github.com/psf/requests/issues/3490
229
+ purged_headers = ("Content-Length", "Content-Type", "Transfer-Encoding")
230
+ for header in purged_headers:
231
+ prepared_request.headers.pop(header, None)
232
+ prepared_request.body = None
233
+
234
+ headers = prepared_request.headers
235
+ headers.pop("Cookie", None)
236
+
237
+ # Extract any cookies sent on the response to the cookiejar
238
+ # in the new request. Because we've mutated our copied prepared
239
+ # request, use the old one that we haven't yet touched.
240
+ extract_cookies_to_jar(prepared_request._cookies, req, resp.raw)
241
+ merge_cookies(prepared_request._cookies, self.cookies)
242
+ prepared_request.prepare_cookies(prepared_request._cookies)
243
+
244
+ # Rebuild auth and proxy information.
245
+ proxies = self.rebuild_proxies(prepared_request, proxies)
246
+ self.rebuild_auth(prepared_request, resp)
247
+
248
+ # A failed tell() sets `_body_position` to `object()`. This non-None
249
+ # value ensures `rewindable` will be True, allowing us to raise an
250
+ # UnrewindableBodyError, instead of hanging the connection.
251
+ rewindable = prepared_request._body_position is not None and (
252
+ "Content-Length" in headers or "Transfer-Encoding" in headers
253
+ )
254
+
255
+ # Attempt to rewind consumed file-like object.
256
+ if rewindable:
257
+ rewind_body(prepared_request)
258
+
259
+ # Override the original request.
260
+ req = prepared_request
261
+
262
+ if yield_requests:
263
+ yield req
264
+ else:
265
+
266
+ resp = self.send(
267
+ req,
268
+ stream=stream,
269
+ timeout=timeout,
270
+ verify=verify,
271
+ cert=cert,
272
+ proxies=proxies,
273
+ allow_redirects=False,
274
+ **adapter_kwargs,
275
+ )
276
+
277
+ extract_cookies_to_jar(self.cookies, prepared_request, resp.raw)
278
+
279
+ # extract redirect url, if any, for the next loop
280
+ url = self.get_redirect_target(resp)
281
+ yield resp
282
+
283
+ def rebuild_auth(self, prepared_request, response):
284
+ """When being redirected we may want to strip authentication from the
285
+ request to avoid leaking credentials. This method intelligently removes
286
+ and reapplies authentication where possible to avoid credential loss.
287
+ """
288
+ headers = prepared_request.headers
289
+ url = prepared_request.url
290
+
291
+ if "Authorization" in headers and self.should_strip_auth(
292
+ response.request.url, url
293
+ ):
294
+ # If we get redirected to a new host, we should strip out any
295
+ # authentication headers.
296
+ del headers["Authorization"]
297
+
298
+ # .netrc might have more auth for us on our new host.
299
+ new_auth = get_netrc_auth(url) if self.trust_env else None
300
+ if new_auth is not None:
301
+ prepared_request.prepare_auth(new_auth)
302
+
303
+ def rebuild_proxies(self, prepared_request, proxies):
304
+ """This method re-evaluates the proxy configuration by considering the
305
+ environment variables. If we are redirected to a URL covered by
306
+ NO_PROXY, we strip the proxy configuration. Otherwise, we set missing
307
+ proxy keys for this URL (in case they were stripped by a previous
308
+ redirect).
309
+
310
+ This method also replaces the Proxy-Authorization header where
311
+ necessary.
312
+
313
+ :rtype: dict
314
+ """
315
+ headers = prepared_request.headers
316
+ scheme = urlparse(prepared_request.url).scheme
317
+ new_proxies = resolve_proxies(prepared_request, proxies, self.trust_env)
318
+
319
+ if "Proxy-Authorization" in headers:
320
+ del headers["Proxy-Authorization"]
321
+
322
+ try:
323
+ username, password = get_auth_from_url(new_proxies[scheme])
324
+ except KeyError:
325
+ username, password = None, None
326
+
327
+ # urllib3 handles proxy authorization for us in the standard adapter.
328
+ # Avoid appending this to TLS tunneled requests where it may be leaked.
329
+ if not scheme.startswith('https') and username and password:
330
+ headers["Proxy-Authorization"] = _basic_auth_str(username, password)
331
+
332
+ return new_proxies
333
+
334
+ def rebuild_method(self, prepared_request, response):
335
+ """When being redirected we may want to change the method of the request
336
+ based on certain specs or browser behavior.
337
+ """
338
+ method = prepared_request.method
339
+
340
+ # https://tools.ietf.org/html/rfc7231#section-6.4.4
341
+ if response.status_code == codes.see_other and method != "HEAD":
342
+ method = "GET"
343
+
344
+ # Do what the browsers do, despite standards...
345
+ # First, turn 302s into GETs.
346
+ if response.status_code == codes.found and method != "HEAD":
347
+ method = "GET"
348
+
349
+ # Second, if a POST is responded to with a 301, turn it into a GET.
350
+ # This bizarre behaviour is explained in Issue 1704.
351
+ if response.status_code == codes.moved and method == "POST":
352
+ method = "GET"
353
+
354
+ prepared_request.method = method
355
+
356
+
357
+ class Session(SessionRedirectMixin):
358
+ """A Requests session.
359
+
360
+ Provides cookie persistence, connection-pooling, and configuration.
361
+
362
+ Basic Usage::
363
+
364
+ >>> import requests
365
+ >>> s = requests.Session()
366
+ >>> s.get('https://httpbin.org/get')
367
+ <Response [200]>
368
+
369
+ Or as a context manager::
370
+
371
+ >>> with requests.Session() as s:
372
+ ... s.get('https://httpbin.org/get')
373
+ <Response [200]>
374
+ """
375
+
376
+ __attrs__ = [
377
+ "headers",
378
+ "cookies",
379
+ "auth",
380
+ "proxies",
381
+ "hooks",
382
+ "params",
383
+ "verify",
384
+ "cert",
385
+ "adapters",
386
+ "stream",
387
+ "trust_env",
388
+ "max_redirects",
389
+ ]
390
+
391
+ def __init__(self):
392
+
393
+ #: A case-insensitive dictionary of headers to be sent on each
394
+ #: :class:`Request <Request>` sent from this
395
+ #: :class:`Session <Session>`.
396
+ self.headers = default_headers()
397
+
398
+ #: Default Authentication tuple or object to attach to
399
+ #: :class:`Request <Request>`.
400
+ self.auth = None
401
+
402
+ #: Dictionary mapping protocol or protocol and host to the URL of the proxy
403
+ #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to
404
+ #: be used on each :class:`Request <Request>`.
405
+ self.proxies = {}
406
+
407
+ #: Event-handling hooks.
408
+ self.hooks = default_hooks()
409
+
410
+ #: Dictionary of querystring data to attach to each
411
+ #: :class:`Request <Request>`. The dictionary values may be lists for
412
+ #: representing multivalued query parameters.
413
+ self.params = {}
414
+
415
+ #: Stream response content default.
416
+ self.stream = False
417
+
418
+ #: SSL Verification default.
419
+ #: Defaults to `True`, requiring requests to verify the TLS certificate at the
420
+ #: remote end.
421
+ #: If verify is set to `False`, requests will accept any TLS certificate
422
+ #: presented by the server, and will ignore hostname mismatches and/or
423
+ #: expired certificates, which will make your application vulnerable to
424
+ #: man-in-the-middle (MitM) attacks.
425
+ #: Only set this to `False` for testing.
426
+ self.verify = True
427
+
428
+ #: SSL client certificate default, if String, path to ssl client
429
+ #: cert file (.pem). If Tuple, ('cert', 'key') pair.
430
+ self.cert = None
431
+
432
+ #: Maximum number of redirects allowed. If the request exceeds this
433
+ #: limit, a :class:`TooManyRedirects` exception is raised.
434
+ #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is
435
+ #: 30.
436
+ self.max_redirects = DEFAULT_REDIRECT_LIMIT
437
+
438
+ #: Trust environment settings for proxy configuration, default
439
+ #: authentication and similar.
440
+ self.trust_env = True
441
+
442
+ #: A CookieJar containing all currently outstanding cookies set on this
443
+ #: session. By default it is a
444
+ #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but
445
+ #: may be any other ``cookielib.CookieJar`` compatible object.
446
+ self.cookies = cookiejar_from_dict({})
447
+
448
+ # Default connection adapters.
449
+ self.adapters = OrderedDict()
450
+ self.mount("https://", HTTPAdapter())
451
+ self.mount("http://", HTTPAdapter())
452
+
453
+ def __enter__(self):
454
+ return self
455
+
456
+ def __exit__(self, *args):
457
+ self.close()
458
+
459
+ def prepare_request(self, request):
460
+ """Constructs a :class:`PreparedRequest <PreparedRequest>` for
461
+ transmission and returns it. The :class:`PreparedRequest` has settings
462
+ merged from the :class:`Request <Request>` instance and those of the
463
+ :class:`Session`.
464
+
465
+ :param request: :class:`Request` instance to prepare with this
466
+ session's settings.
467
+ :rtype: requests.PreparedRequest
468
+ """
469
+ cookies = request.cookies or {}
470
+
471
+ # Bootstrap CookieJar.
472
+ if not isinstance(cookies, cookielib.CookieJar):
473
+ cookies = cookiejar_from_dict(cookies)
474
+
475
+ # Merge with session cookies
476
+ merged_cookies = merge_cookies(
477
+ merge_cookies(RequestsCookieJar(), self.cookies), cookies
478
+ )
479
+
480
+ # Set environment's basic authentication if not explicitly set.
481
+ auth = request.auth
482
+ if self.trust_env and not auth and not self.auth:
483
+ auth = get_netrc_auth(request.url)
484
+
485
+ p = PreparedRequest()
486
+ p.prepare(
487
+ method=request.method.upper(),
488
+ url=request.url,
489
+ files=request.files,
490
+ data=request.data,
491
+ json=request.json,
492
+ headers=merge_setting(
493
+ request.headers, self.headers, dict_class=CaseInsensitiveDict
494
+ ),
495
+ params=merge_setting(request.params, self.params),
496
+ auth=merge_setting(auth, self.auth),
497
+ cookies=merged_cookies,
498
+ hooks=merge_hooks(request.hooks, self.hooks),
499
+ )
500
+ return p
501
+
502
+ def request(
503
+ self,
504
+ method,
505
+ url,
506
+ params=None,
507
+ data=None,
508
+ headers=None,
509
+ cookies=None,
510
+ files=None,
511
+ auth=None,
512
+ timeout=None,
513
+ allow_redirects=True,
514
+ proxies=None,
515
+ hooks=None,
516
+ stream=None,
517
+ verify=None,
518
+ cert=None,
519
+ json=None,
520
+ ):
521
+ """Constructs a :class:`Request <Request>`, prepares it and sends it.
522
+ Returns :class:`Response <Response>` object.
523
+
524
+ :param method: method for the new :class:`Request` object.
525
+ :param url: URL for the new :class:`Request` object.
526
+ :param params: (optional) Dictionary or bytes to be sent in the query
527
+ string for the :class:`Request`.
528
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
529
+ object to send in the body of the :class:`Request`.
530
+ :param json: (optional) json to send in the body of the
531
+ :class:`Request`.
532
+ :param headers: (optional) Dictionary of HTTP Headers to send with the
533
+ :class:`Request`.
534
+ :param cookies: (optional) Dict or CookieJar object to send with the
535
+ :class:`Request`.
536
+ :param files: (optional) Dictionary of ``'filename': file-like-objects``
537
+ for multipart encoding upload.
538
+ :param auth: (optional) Auth tuple or callable to enable
539
+ Basic/Digest/Custom HTTP Auth.
540
+ :param timeout: (optional) How long to wait for the server to send
541
+ data before giving up, as a float, or a :ref:`(connect timeout,
542
+ read timeout) <timeouts>` tuple.
543
+ :type timeout: float or tuple
544
+ :param allow_redirects: (optional) Set to True by default.
545
+ :type allow_redirects: bool
546
+ :param proxies: (optional) Dictionary mapping protocol or protocol and
547
+ hostname to the URL of the proxy.
548
+ :param stream: (optional) whether to immediately download the response
549
+ content. Defaults to ``False``.
550
+ :param verify: (optional) Either a boolean, in which case it controls whether we verify
551
+ the server's TLS certificate, or a string, in which case it must be a path
552
+ to a CA bundle to use. Defaults to ``True``. When set to
553
+ ``False``, requests will accept any TLS certificate presented by
554
+ the server, and will ignore hostname mismatches and/or expired
555
+ certificates, which will make your application vulnerable to
556
+ man-in-the-middle (MitM) attacks. Setting verify to ``False``
557
+ may be useful during local development or testing.
558
+ :param cert: (optional) if String, path to ssl client cert file (.pem).
559
+ If Tuple, ('cert', 'key') pair.
560
+ :rtype: requests.Response
561
+ """
562
+ # Create the Request.
563
+ req = Request(
564
+ method=method.upper(),
565
+ url=url,
566
+ headers=headers,
567
+ files=files,
568
+ data=data or {},
569
+ json=json,
570
+ params=params or {},
571
+ auth=auth,
572
+ cookies=cookies,
573
+ hooks=hooks,
574
+ )
575
+ prep = self.prepare_request(req)
576
+
577
+ proxies = proxies or {}
578
+
579
+ settings = self.merge_environment_settings(
580
+ prep.url, proxies, stream, verify, cert
581
+ )
582
+
583
+ # Send the request.
584
+ send_kwargs = {
585
+ "timeout": timeout,
586
+ "allow_redirects": allow_redirects,
587
+ }
588
+ send_kwargs.update(settings)
589
+ resp = self.send(prep, **send_kwargs)
590
+
591
+ return resp
592
+
593
+ def get(self, url, **kwargs):
594
+ r"""Sends a GET request. Returns :class:`Response` object.
595
+
596
+ :param url: URL for the new :class:`Request` object.
597
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
598
+ :rtype: requests.Response
599
+ """
600
+
601
+ kwargs.setdefault("allow_redirects", True)
602
+ return self.request("GET", url, **kwargs)
603
+
604
+ def options(self, url, **kwargs):
605
+ r"""Sends a OPTIONS request. Returns :class:`Response` object.
606
+
607
+ :param url: URL for the new :class:`Request` object.
608
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
609
+ :rtype: requests.Response
610
+ """
611
+
612
+ kwargs.setdefault("allow_redirects", True)
613
+ return self.request("OPTIONS", url, **kwargs)
614
+
615
+ def head(self, url, **kwargs):
616
+ r"""Sends a HEAD request. Returns :class:`Response` object.
617
+
618
+ :param url: URL for the new :class:`Request` object.
619
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
620
+ :rtype: requests.Response
621
+ """
622
+
623
+ kwargs.setdefault("allow_redirects", False)
624
+ return self.request("HEAD", url, **kwargs)
625
+
626
+ def post(self, url, data=None, json=None, **kwargs):
627
+ r"""Sends a POST request. Returns :class:`Response` object.
628
+
629
+ :param url: URL for the new :class:`Request` object.
630
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
631
+ object to send in the body of the :class:`Request`.
632
+ :param json: (optional) json to send in the body of the :class:`Request`.
633
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
634
+ :rtype: requests.Response
635
+ """
636
+
637
+ return self.request("POST", url, data=data, json=json, **kwargs)
638
+
639
+ def put(self, url, data=None, **kwargs):
640
+ r"""Sends a PUT request. Returns :class:`Response` object.
641
+
642
+ :param url: URL for the new :class:`Request` object.
643
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
644
+ object to send in the body of the :class:`Request`.
645
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
646
+ :rtype: requests.Response
647
+ """
648
+
649
+ return self.request("PUT", url, data=data, **kwargs)
650
+
651
+ def patch(self, url, data=None, **kwargs):
652
+ r"""Sends a PATCH request. Returns :class:`Response` object.
653
+
654
+ :param url: URL for the new :class:`Request` object.
655
+ :param data: (optional) Dictionary, list of tuples, bytes, or file-like
656
+ object to send in the body of the :class:`Request`.
657
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
658
+ :rtype: requests.Response
659
+ """
660
+
661
+ return self.request("PATCH", url, data=data, **kwargs)
662
+
663
+ def delete(self, url, **kwargs):
664
+ r"""Sends a DELETE request. Returns :class:`Response` object.
665
+
666
+ :param url: URL for the new :class:`Request` object.
667
+ :param \*\*kwargs: Optional arguments that ``request`` takes.
668
+ :rtype: requests.Response
669
+ """
670
+
671
+ return self.request("DELETE", url, **kwargs)
672
+
673
+ def send(self, request, **kwargs):
674
+ """Send a given PreparedRequest.
675
+
676
+ :rtype: requests.Response
677
+ """
678
+ # Set defaults that the hooks can utilize to ensure they always have
679
+ # the correct parameters to reproduce the previous request.
680
+ kwargs.setdefault("stream", self.stream)
681
+ kwargs.setdefault("verify", self.verify)
682
+ kwargs.setdefault("cert", self.cert)
683
+ if "proxies" not in kwargs:
684
+ kwargs["proxies"] = resolve_proxies(request, self.proxies, self.trust_env)
685
+
686
+ # It's possible that users might accidentally send a Request object.
687
+ # Guard against that specific failure case.
688
+ if isinstance(request, Request):
689
+ raise ValueError("You can only send PreparedRequests.")
690
+
691
+ # Set up variables needed for resolve_redirects and dispatching of hooks
692
+ allow_redirects = kwargs.pop("allow_redirects", True)
693
+ stream = kwargs.get("stream")
694
+ hooks = request.hooks
695
+
696
+ # Get the appropriate adapter to use
697
+ adapter = self.get_adapter(url=request.url)
698
+
699
+ # Start time (approximately) of the request
700
+ start = preferred_clock()
701
+
702
+ # Send the request
703
+ r = adapter.send(request, **kwargs)
704
+
705
+ # Total elapsed time of the request (approximately)
706
+ elapsed = preferred_clock() - start
707
+ r.elapsed = timedelta(seconds=elapsed)
708
+
709
+ # Response manipulation hooks
710
+ r = dispatch_hook("response", hooks, r, **kwargs)
711
+
712
+ # Persist cookies
713
+ if r.history:
714
+
715
+ # If the hooks create history then we want those cookies too
716
+ for resp in r.history:
717
+ extract_cookies_to_jar(self.cookies, resp.request, resp.raw)
718
+
719
+ extract_cookies_to_jar(self.cookies, request, r.raw)
720
+
721
+ # Resolve redirects if allowed.
722
+ if allow_redirects:
723
+ # Redirect resolving generator.
724
+ gen = self.resolve_redirects(r, request, **kwargs)
725
+ history = [resp for resp in gen]
726
+ else:
727
+ history = []
728
+
729
+ # Shuffle things around if there's history.
730
+ if history:
731
+ # Insert the first (original) request at the start
732
+ history.insert(0, r)
733
+ # Get the last request made
734
+ r = history.pop()
735
+ r.history = history
736
+
737
+ # If redirects aren't being followed, store the response on the Request for Response.next().
738
+ if not allow_redirects:
739
+ try:
740
+ r._next = next(
741
+ self.resolve_redirects(r, request, yield_requests=True, **kwargs)
742
+ )
743
+ except StopIteration:
744
+ pass
745
+
746
+ if not stream:
747
+ r.content
748
+
749
+ return r
750
+
751
+ def merge_environment_settings(self, url, proxies, stream, verify, cert):
752
+ """
753
+ Check the environment and merge it with some settings.
754
+
755
+ :rtype: dict
756
+ """
757
+ # Gather clues from the surrounding environment.
758
+ if self.trust_env:
759
+ # Set environment's proxies.
760
+ no_proxy = proxies.get("no_proxy") if proxies is not None else None
761
+ env_proxies = get_environ_proxies(url, no_proxy=no_proxy)
762
+ for (k, v) in env_proxies.items():
763
+ proxies.setdefault(k, v)
764
+
765
+ # Look for requests environment configuration
766
+ # and be compatible with cURL.
767
+ if verify is True or verify is None:
768
+ verify = (
769
+ os.environ.get("REQUESTS_CA_BUNDLE")
770
+ or os.environ.get("CURL_CA_BUNDLE")
771
+ or verify
772
+ )
773
+
774
+ # Merge all the kwargs.
775
+ proxies = merge_setting(proxies, self.proxies)
776
+ stream = merge_setting(stream, self.stream)
777
+ verify = merge_setting(verify, self.verify)
778
+ cert = merge_setting(cert, self.cert)
779
+
780
+ return {"proxies": proxies, "stream": stream, "verify": verify, "cert": cert}
781
+
782
+ def get_adapter(self, url):
783
+ """
784
+ Returns the appropriate connection adapter for the given URL.
785
+
786
+ :rtype: requests.adapters.BaseAdapter
787
+ """
788
+ for (prefix, adapter) in self.adapters.items():
789
+
790
+ if url.lower().startswith(prefix.lower()):
791
+ return adapter
792
+
793
+ # Nothing matches :-/
794
+ raise InvalidSchema(f"No connection adapters were found for {url!r}")
795
+
796
+ def close(self):
797
+ """Closes all adapters and as such the session"""
798
+ for v in self.adapters.values():
799
+ v.close()
800
+
801
+ def mount(self, prefix, adapter):
802
+ """Registers a connection adapter to a prefix.
803
+
804
+ Adapters are sorted in descending order by prefix length.
805
+ """
806
+ self.adapters[prefix] = adapter
807
+ keys_to_move = [k for k in self.adapters if len(k) < len(prefix)]
808
+
809
+ for key in keys_to_move:
810
+ self.adapters[key] = self.adapters.pop(key)
811
+
812
+ def __getstate__(self):
813
+ state = {attr: getattr(self, attr, None) for attr in self.__attrs__}
814
+ return state
815
+
816
+ def __setstate__(self, state):
817
+ for attr, value in state.items():
818
+ setattr(self, attr, value)
819
+
820
+
821
+ def session():
822
+ """
823
+ Returns a :class:`Session` for context-management.
824
+
825
+ .. deprecated:: 1.0.0
826
+
827
+ This method has been deprecated since version 1.0.0 and is only kept for
828
+ backwards compatibility. New code should use :class:`~requests.sessions.Session`
829
+ to create a session. This may be removed at a future date.
830
+
831
+ :rtype: Session
832
+ """
833
+ return Session()
.venv/lib/python3.11/site-packages/pip/_vendor/requests/status_codes.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ r"""
2
+ The ``codes`` object defines a mapping from common names for HTTP statuses
3
+ to their numerical codes, accessible either as attributes or as dictionary
4
+ items.
5
+
6
+ Example::
7
+
8
+ >>> import requests
9
+ >>> requests.codes['temporary_redirect']
10
+ 307
11
+ >>> requests.codes.teapot
12
+ 418
13
+ >>> requests.codes['\o/']
14
+ 200
15
+
16
+ Some codes have multiple names, and both upper- and lower-case versions of
17
+ the names are allowed. For example, ``codes.ok``, ``codes.OK``, and
18
+ ``codes.okay`` all correspond to the HTTP status code 200.
19
+ """
20
+
21
+ from .structures import LookupDict
22
+
23
+ _codes = {
24
+ # Informational.
25
+ 100: ("continue",),
26
+ 101: ("switching_protocols",),
27
+ 102: ("processing",),
28
+ 103: ("checkpoint",),
29
+ 122: ("uri_too_long", "request_uri_too_long"),
30
+ 200: ("ok", "okay", "all_ok", "all_okay", "all_good", "\\o/", "✓"),
31
+ 201: ("created",),
32
+ 202: ("accepted",),
33
+ 203: ("non_authoritative_info", "non_authoritative_information"),
34
+ 204: ("no_content",),
35
+ 205: ("reset_content", "reset"),
36
+ 206: ("partial_content", "partial"),
37
+ 207: ("multi_status", "multiple_status", "multi_stati", "multiple_stati"),
38
+ 208: ("already_reported",),
39
+ 226: ("im_used",),
40
+ # Redirection.
41
+ 300: ("multiple_choices",),
42
+ 301: ("moved_permanently", "moved", "\\o-"),
43
+ 302: ("found",),
44
+ 303: ("see_other", "other"),
45
+ 304: ("not_modified",),
46
+ 305: ("use_proxy",),
47
+ 306: ("switch_proxy",),
48
+ 307: ("temporary_redirect", "temporary_moved", "temporary"),
49
+ 308: (
50
+ "permanent_redirect",
51
+ "resume_incomplete",
52
+ "resume",
53
+ ), # "resume" and "resume_incomplete" to be removed in 3.0
54
+ # Client Error.
55
+ 400: ("bad_request", "bad"),
56
+ 401: ("unauthorized",),
57
+ 402: ("payment_required", "payment"),
58
+ 403: ("forbidden",),
59
+ 404: ("not_found", "-o-"),
60
+ 405: ("method_not_allowed", "not_allowed"),
61
+ 406: ("not_acceptable",),
62
+ 407: ("proxy_authentication_required", "proxy_auth", "proxy_authentication"),
63
+ 408: ("request_timeout", "timeout"),
64
+ 409: ("conflict",),
65
+ 410: ("gone",),
66
+ 411: ("length_required",),
67
+ 412: ("precondition_failed", "precondition"),
68
+ 413: ("request_entity_too_large",),
69
+ 414: ("request_uri_too_large",),
70
+ 415: ("unsupported_media_type", "unsupported_media", "media_type"),
71
+ 416: (
72
+ "requested_range_not_satisfiable",
73
+ "requested_range",
74
+ "range_not_satisfiable",
75
+ ),
76
+ 417: ("expectation_failed",),
77
+ 418: ("im_a_teapot", "teapot", "i_am_a_teapot"),
78
+ 421: ("misdirected_request",),
79
+ 422: ("unprocessable_entity", "unprocessable"),
80
+ 423: ("locked",),
81
+ 424: ("failed_dependency", "dependency"),
82
+ 425: ("unordered_collection", "unordered"),
83
+ 426: ("upgrade_required", "upgrade"),
84
+ 428: ("precondition_required", "precondition"),
85
+ 429: ("too_many_requests", "too_many"),
86
+ 431: ("header_fields_too_large", "fields_too_large"),
87
+ 444: ("no_response", "none"),
88
+ 449: ("retry_with", "retry"),
89
+ 450: ("blocked_by_windows_parental_controls", "parental_controls"),
90
+ 451: ("unavailable_for_legal_reasons", "legal_reasons"),
91
+ 499: ("client_closed_request",),
92
+ # Server Error.
93
+ 500: ("internal_server_error", "server_error", "/o\\", "✗"),
94
+ 501: ("not_implemented",),
95
+ 502: ("bad_gateway",),
96
+ 503: ("service_unavailable", "unavailable"),
97
+ 504: ("gateway_timeout",),
98
+ 505: ("http_version_not_supported", "http_version"),
99
+ 506: ("variant_also_negotiates",),
100
+ 507: ("insufficient_storage",),
101
+ 509: ("bandwidth_limit_exceeded", "bandwidth"),
102
+ 510: ("not_extended",),
103
+ 511: ("network_authentication_required", "network_auth", "network_authentication"),
104
+ }
105
+
106
+ codes = LookupDict(name="status_codes")
107
+
108
+
109
+ def _init():
110
+ for code, titles in _codes.items():
111
+ for title in titles:
112
+ setattr(codes, title, code)
113
+ if not title.startswith(("\\", "/")):
114
+ setattr(codes, title.upper(), code)
115
+
116
+ def doc(code):
117
+ names = ", ".join(f"``{n}``" for n in _codes[code])
118
+ return "* %d: %s" % (code, names)
119
+
120
+ global __doc__
121
+ __doc__ = (
122
+ __doc__ + "\n" + "\n".join(doc(code) for code in sorted(_codes))
123
+ if __doc__ is not None
124
+ else None
125
+ )
126
+
127
+
128
+ _init()
.venv/lib/python3.11/site-packages/pip/_vendor/requests/structures.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.structures
3
+ ~~~~~~~~~~~~~~~~~~~
4
+
5
+ Data structures that power Requests.
6
+ """
7
+
8
+ from collections import OrderedDict
9
+
10
+ from .compat import Mapping, MutableMapping
11
+
12
+
13
+ class CaseInsensitiveDict(MutableMapping):
14
+ """A case-insensitive ``dict``-like object.
15
+
16
+ Implements all methods and operations of
17
+ ``MutableMapping`` as well as dict's ``copy``. Also
18
+ provides ``lower_items``.
19
+
20
+ All keys are expected to be strings. The structure remembers the
21
+ case of the last key to be set, and ``iter(instance)``,
22
+ ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()``
23
+ will contain case-sensitive keys. However, querying and contains
24
+ testing is case insensitive::
25
+
26
+ cid = CaseInsensitiveDict()
27
+ cid['Accept'] = 'application/json'
28
+ cid['aCCEPT'] == 'application/json' # True
29
+ list(cid) == ['Accept'] # True
30
+
31
+ For example, ``headers['content-encoding']`` will return the
32
+ value of a ``'Content-Encoding'`` response header, regardless
33
+ of how the header name was originally stored.
34
+
35
+ If the constructor, ``.update``, or equality comparison
36
+ operations are given keys that have equal ``.lower()``s, the
37
+ behavior is undefined.
38
+ """
39
+
40
+ def __init__(self, data=None, **kwargs):
41
+ self._store = OrderedDict()
42
+ if data is None:
43
+ data = {}
44
+ self.update(data, **kwargs)
45
+
46
+ def __setitem__(self, key, value):
47
+ # Use the lowercased key for lookups, but store the actual
48
+ # key alongside the value.
49
+ self._store[key.lower()] = (key, value)
50
+
51
+ def __getitem__(self, key):
52
+ return self._store[key.lower()][1]
53
+
54
+ def __delitem__(self, key):
55
+ del self._store[key.lower()]
56
+
57
+ def __iter__(self):
58
+ return (casedkey for casedkey, mappedvalue in self._store.values())
59
+
60
+ def __len__(self):
61
+ return len(self._store)
62
+
63
+ def lower_items(self):
64
+ """Like iteritems(), but with all lowercase keys."""
65
+ return ((lowerkey, keyval[1]) for (lowerkey, keyval) in self._store.items())
66
+
67
+ def __eq__(self, other):
68
+ if isinstance(other, Mapping):
69
+ other = CaseInsensitiveDict(other)
70
+ else:
71
+ return NotImplemented
72
+ # Compare insensitively
73
+ return dict(self.lower_items()) == dict(other.lower_items())
74
+
75
+ # Copy is required
76
+ def copy(self):
77
+ return CaseInsensitiveDict(self._store.values())
78
+
79
+ def __repr__(self):
80
+ return str(dict(self.items()))
81
+
82
+
83
+ class LookupDict(dict):
84
+ """Dictionary lookup object."""
85
+
86
+ def __init__(self, name=None):
87
+ self.name = name
88
+ super().__init__()
89
+
90
+ def __repr__(self):
91
+ return f"<lookup '{self.name}'>"
92
+
93
+ def __getitem__(self, key):
94
+ # We allow fall-through here, so values default to None
95
+
96
+ return self.__dict__.get(key, None)
97
+
98
+ def get(self, key, default=None):
99
+ return self.__dict__.get(key, default)
.venv/lib/python3.11/site-packages/pip/_vendor/requests/utils.py ADDED
@@ -0,0 +1,1094 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ requests.utils
3
+ ~~~~~~~~~~~~~~
4
+
5
+ This module provides utility functions that are used within Requests
6
+ that are also useful for external consumption.
7
+ """
8
+
9
+ import codecs
10
+ import contextlib
11
+ import io
12
+ import os
13
+ import re
14
+ import socket
15
+ import struct
16
+ import sys
17
+ import tempfile
18
+ import warnings
19
+ import zipfile
20
+ from collections import OrderedDict
21
+
22
+ from pip._vendor.urllib3.util import make_headers, parse_url
23
+
24
+ from . import certs
25
+ from .__version__ import __version__
26
+
27
+ # to_native_string is unused here, but imported here for backwards compatibility
28
+ from ._internal_utils import ( # noqa: F401
29
+ _HEADER_VALIDATORS_BYTE,
30
+ _HEADER_VALIDATORS_STR,
31
+ HEADER_VALIDATORS,
32
+ to_native_string,
33
+ )
34
+ from .compat import (
35
+ Mapping,
36
+ basestring,
37
+ bytes,
38
+ getproxies,
39
+ getproxies_environment,
40
+ integer_types,
41
+ )
42
+ from .compat import parse_http_list as _parse_list_header
43
+ from .compat import (
44
+ proxy_bypass,
45
+ proxy_bypass_environment,
46
+ quote,
47
+ str,
48
+ unquote,
49
+ urlparse,
50
+ urlunparse,
51
+ )
52
+ from .cookies import cookiejar_from_dict
53
+ from .exceptions import (
54
+ FileModeWarning,
55
+ InvalidHeader,
56
+ InvalidURL,
57
+ UnrewindableBodyError,
58
+ )
59
+ from .structures import CaseInsensitiveDict
60
+
61
+ NETRC_FILES = (".netrc", "_netrc")
62
+
63
+ DEFAULT_CA_BUNDLE_PATH = certs.where()
64
+
65
+ DEFAULT_PORTS = {"http": 80, "https": 443}
66
+
67
+ # Ensure that ', ' is used to preserve previous delimiter behavior.
68
+ DEFAULT_ACCEPT_ENCODING = ", ".join(
69
+ re.split(r",\s*", make_headers(accept_encoding=True)["accept-encoding"])
70
+ )
71
+
72
+
73
+ if sys.platform == "win32":
74
+ # provide a proxy_bypass version on Windows without DNS lookups
75
+
76
+ def proxy_bypass_registry(host):
77
+ try:
78
+ import winreg
79
+ except ImportError:
80
+ return False
81
+
82
+ try:
83
+ internetSettings = winreg.OpenKey(
84
+ winreg.HKEY_CURRENT_USER,
85
+ r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",
86
+ )
87
+ # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it
88
+ proxyEnable = int(winreg.QueryValueEx(internetSettings, "ProxyEnable")[0])
89
+ # ProxyOverride is almost always a string
90
+ proxyOverride = winreg.QueryValueEx(internetSettings, "ProxyOverride")[0]
91
+ except (OSError, ValueError):
92
+ return False
93
+ if not proxyEnable or not proxyOverride:
94
+ return False
95
+
96
+ # make a check value list from the registry entry: replace the
97
+ # '<local>' string by the localhost entry and the corresponding
98
+ # canonical entry.
99
+ proxyOverride = proxyOverride.split(";")
100
+ # now check if we match one of the registry values.
101
+ for test in proxyOverride:
102
+ if test == "<local>":
103
+ if "." not in host:
104
+ return True
105
+ test = test.replace(".", r"\.") # mask dots
106
+ test = test.replace("*", r".*") # change glob sequence
107
+ test = test.replace("?", r".") # change glob char
108
+ if re.match(test, host, re.I):
109
+ return True
110
+ return False
111
+
112
+ def proxy_bypass(host): # noqa
113
+ """Return True, if the host should be bypassed.
114
+
115
+ Checks proxy settings gathered from the environment, if specified,
116
+ or the registry.
117
+ """
118
+ if getproxies_environment():
119
+ return proxy_bypass_environment(host)
120
+ else:
121
+ return proxy_bypass_registry(host)
122
+
123
+
124
+ def dict_to_sequence(d):
125
+ """Returns an internal sequence dictionary update."""
126
+
127
+ if hasattr(d, "items"):
128
+ d = d.items()
129
+
130
+ return d
131
+
132
+
133
+ def super_len(o):
134
+ total_length = None
135
+ current_position = 0
136
+
137
+ if hasattr(o, "__len__"):
138
+ total_length = len(o)
139
+
140
+ elif hasattr(o, "len"):
141
+ total_length = o.len
142
+
143
+ elif hasattr(o, "fileno"):
144
+ try:
145
+ fileno = o.fileno()
146
+ except (io.UnsupportedOperation, AttributeError):
147
+ # AttributeError is a surprising exception, seeing as how we've just checked
148
+ # that `hasattr(o, 'fileno')`. It happens for objects obtained via
149
+ # `Tarfile.extractfile()`, per issue 5229.
150
+ pass
151
+ else:
152
+ total_length = os.fstat(fileno).st_size
153
+
154
+ # Having used fstat to determine the file length, we need to
155
+ # confirm that this file was opened up in binary mode.
156
+ if "b" not in o.mode:
157
+ warnings.warn(
158
+ (
159
+ "Requests has determined the content-length for this "
160
+ "request using the binary size of the file: however, the "
161
+ "file has been opened in text mode (i.e. without the 'b' "
162
+ "flag in the mode). This may lead to an incorrect "
163
+ "content-length. In Requests 3.0, support will be removed "
164
+ "for files in text mode."
165
+ ),
166
+ FileModeWarning,
167
+ )
168
+
169
+ if hasattr(o, "tell"):
170
+ try:
171
+ current_position = o.tell()
172
+ except OSError:
173
+ # This can happen in some weird situations, such as when the file
174
+ # is actually a special file descriptor like stdin. In this
175
+ # instance, we don't know what the length is, so set it to zero and
176
+ # let requests chunk it instead.
177
+ if total_length is not None:
178
+ current_position = total_length
179
+ else:
180
+ if hasattr(o, "seek") and total_length is None:
181
+ # StringIO and BytesIO have seek but no usable fileno
182
+ try:
183
+ # seek to end of file
184
+ o.seek(0, 2)
185
+ total_length = o.tell()
186
+
187
+ # seek back to current position to support
188
+ # partially read file-like objects
189
+ o.seek(current_position or 0)
190
+ except OSError:
191
+ total_length = 0
192
+
193
+ if total_length is None:
194
+ total_length = 0
195
+
196
+ return max(0, total_length - current_position)
197
+
198
+
199
+ def get_netrc_auth(url, raise_errors=False):
200
+ """Returns the Requests tuple auth for a given url from netrc."""
201
+
202
+ netrc_file = os.environ.get("NETRC")
203
+ if netrc_file is not None:
204
+ netrc_locations = (netrc_file,)
205
+ else:
206
+ netrc_locations = (f"~/{f}" for f in NETRC_FILES)
207
+
208
+ try:
209
+ from netrc import NetrcParseError, netrc
210
+
211
+ netrc_path = None
212
+
213
+ for f in netrc_locations:
214
+ try:
215
+ loc = os.path.expanduser(f)
216
+ except KeyError:
217
+ # os.path.expanduser can fail when $HOME is undefined and
218
+ # getpwuid fails. See https://bugs.python.org/issue20164 &
219
+ # https://github.com/psf/requests/issues/1846
220
+ return
221
+
222
+ if os.path.exists(loc):
223
+ netrc_path = loc
224
+ break
225
+
226
+ # Abort early if there isn't one.
227
+ if netrc_path is None:
228
+ return
229
+
230
+ ri = urlparse(url)
231
+
232
+ # Strip port numbers from netloc. This weird `if...encode`` dance is
233
+ # used for Python 3.2, which doesn't support unicode literals.
234
+ splitstr = b":"
235
+ if isinstance(url, str):
236
+ splitstr = splitstr.decode("ascii")
237
+ host = ri.netloc.split(splitstr)[0]
238
+
239
+ try:
240
+ _netrc = netrc(netrc_path).authenticators(host)
241
+ if _netrc:
242
+ # Return with login / password
243
+ login_i = 0 if _netrc[0] else 1
244
+ return (_netrc[login_i], _netrc[2])
245
+ except (NetrcParseError, OSError):
246
+ # If there was a parsing error or a permissions issue reading the file,
247
+ # we'll just skip netrc auth unless explicitly asked to raise errors.
248
+ if raise_errors:
249
+ raise
250
+
251
+ # App Engine hackiness.
252
+ except (ImportError, AttributeError):
253
+ pass
254
+
255
+
256
+ def guess_filename(obj):
257
+ """Tries to guess the filename of the given object."""
258
+ name = getattr(obj, "name", None)
259
+ if name and isinstance(name, basestring) and name[0] != "<" and name[-1] != ">":
260
+ return os.path.basename(name)
261
+
262
+
263
+ def extract_zipped_paths(path):
264
+ """Replace nonexistent paths that look like they refer to a member of a zip
265
+ archive with the location of an extracted copy of the target, or else
266
+ just return the provided path unchanged.
267
+ """
268
+ if os.path.exists(path):
269
+ # this is already a valid path, no need to do anything further
270
+ return path
271
+
272
+ # find the first valid part of the provided path and treat that as a zip archive
273
+ # assume the rest of the path is the name of a member in the archive
274
+ archive, member = os.path.split(path)
275
+ while archive and not os.path.exists(archive):
276
+ archive, prefix = os.path.split(archive)
277
+ if not prefix:
278
+ # If we don't check for an empty prefix after the split (in other words, archive remains unchanged after the split),
279
+ # we _can_ end up in an infinite loop on a rare corner case affecting a small number of users
280
+ break
281
+ member = "/".join([prefix, member])
282
+
283
+ if not zipfile.is_zipfile(archive):
284
+ return path
285
+
286
+ zip_file = zipfile.ZipFile(archive)
287
+ if member not in zip_file.namelist():
288
+ return path
289
+
290
+ # we have a valid zip archive and a valid member of that archive
291
+ tmp = tempfile.gettempdir()
292
+ extracted_path = os.path.join(tmp, member.split("/")[-1])
293
+ if not os.path.exists(extracted_path):
294
+ # use read + write to avoid the creating nested folders, we only want the file, avoids mkdir racing condition
295
+ with atomic_open(extracted_path) as file_handler:
296
+ file_handler.write(zip_file.read(member))
297
+ return extracted_path
298
+
299
+
300
+ @contextlib.contextmanager
301
+ def atomic_open(filename):
302
+ """Write a file to the disk in an atomic fashion"""
303
+ tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename))
304
+ try:
305
+ with os.fdopen(tmp_descriptor, "wb") as tmp_handler:
306
+ yield tmp_handler
307
+ os.replace(tmp_name, filename)
308
+ except BaseException:
309
+ os.remove(tmp_name)
310
+ raise
311
+
312
+
313
+ def from_key_val_list(value):
314
+ """Take an object and test to see if it can be represented as a
315
+ dictionary. Unless it can not be represented as such, return an
316
+ OrderedDict, e.g.,
317
+
318
+ ::
319
+
320
+ >>> from_key_val_list([('key', 'val')])
321
+ OrderedDict([('key', 'val')])
322
+ >>> from_key_val_list('string')
323
+ Traceback (most recent call last):
324
+ ...
325
+ ValueError: cannot encode objects that are not 2-tuples
326
+ >>> from_key_val_list({'key': 'val'})
327
+ OrderedDict([('key', 'val')])
328
+
329
+ :rtype: OrderedDict
330
+ """
331
+ if value is None:
332
+ return None
333
+
334
+ if isinstance(value, (str, bytes, bool, int)):
335
+ raise ValueError("cannot encode objects that are not 2-tuples")
336
+
337
+ return OrderedDict(value)
338
+
339
+
340
+ def to_key_val_list(value):
341
+ """Take an object and test to see if it can be represented as a
342
+ dictionary. If it can be, return a list of tuples, e.g.,
343
+
344
+ ::
345
+
346
+ >>> to_key_val_list([('key', 'val')])
347
+ [('key', 'val')]
348
+ >>> to_key_val_list({'key': 'val'})
349
+ [('key', 'val')]
350
+ >>> to_key_val_list('string')
351
+ Traceback (most recent call last):
352
+ ...
353
+ ValueError: cannot encode objects that are not 2-tuples
354
+
355
+ :rtype: list
356
+ """
357
+ if value is None:
358
+ return None
359
+
360
+ if isinstance(value, (str, bytes, bool, int)):
361
+ raise ValueError("cannot encode objects that are not 2-tuples")
362
+
363
+ if isinstance(value, Mapping):
364
+ value = value.items()
365
+
366
+ return list(value)
367
+
368
+
369
+ # From mitsuhiko/werkzeug (used with permission).
370
+ def parse_list_header(value):
371
+ """Parse lists as described by RFC 2068 Section 2.
372
+
373
+ In particular, parse comma-separated lists where the elements of
374
+ the list may include quoted-strings. A quoted-string could
375
+ contain a comma. A non-quoted string could have quotes in the
376
+ middle. Quotes are removed automatically after parsing.
377
+
378
+ It basically works like :func:`parse_set_header` just that items
379
+ may appear multiple times and case sensitivity is preserved.
380
+
381
+ The return value is a standard :class:`list`:
382
+
383
+ >>> parse_list_header('token, "quoted value"')
384
+ ['token', 'quoted value']
385
+
386
+ To create a header from the :class:`list` again, use the
387
+ :func:`dump_header` function.
388
+
389
+ :param value: a string with a list header.
390
+ :return: :class:`list`
391
+ :rtype: list
392
+ """
393
+ result = []
394
+ for item in _parse_list_header(value):
395
+ if item[:1] == item[-1:] == '"':
396
+ item = unquote_header_value(item[1:-1])
397
+ result.append(item)
398
+ return result
399
+
400
+
401
+ # From mitsuhiko/werkzeug (used with permission).
402
+ def parse_dict_header(value):
403
+ """Parse lists of key, value pairs as described by RFC 2068 Section 2 and
404
+ convert them into a python dict:
405
+
406
+ >>> d = parse_dict_header('foo="is a fish", bar="as well"')
407
+ >>> type(d) is dict
408
+ True
409
+ >>> sorted(d.items())
410
+ [('bar', 'as well'), ('foo', 'is a fish')]
411
+
412
+ If there is no value for a key it will be `None`:
413
+
414
+ >>> parse_dict_header('key_without_value')
415
+ {'key_without_value': None}
416
+
417
+ To create a header from the :class:`dict` again, use the
418
+ :func:`dump_header` function.
419
+
420
+ :param value: a string with a dict header.
421
+ :return: :class:`dict`
422
+ :rtype: dict
423
+ """
424
+ result = {}
425
+ for item in _parse_list_header(value):
426
+ if "=" not in item:
427
+ result[item] = None
428
+ continue
429
+ name, value = item.split("=", 1)
430
+ if value[:1] == value[-1:] == '"':
431
+ value = unquote_header_value(value[1:-1])
432
+ result[name] = value
433
+ return result
434
+
435
+
436
+ # From mitsuhiko/werkzeug (used with permission).
437
+ def unquote_header_value(value, is_filename=False):
438
+ r"""Unquotes a header value. (Reversal of :func:`quote_header_value`).
439
+ This does not use the real unquoting but what browsers are actually
440
+ using for quoting.
441
+
442
+ :param value: the header value to unquote.
443
+ :rtype: str
444
+ """
445
+ if value and value[0] == value[-1] == '"':
446
+ # this is not the real unquoting, but fixing this so that the
447
+ # RFC is met will result in bugs with internet explorer and
448
+ # probably some other browsers as well. IE for example is
449
+ # uploading files with "C:\foo\bar.txt" as filename
450
+ value = value[1:-1]
451
+
452
+ # if this is a filename and the starting characters look like
453
+ # a UNC path, then just return the value without quotes. Using the
454
+ # replace sequence below on a UNC path has the effect of turning
455
+ # the leading double slash into a single slash and then
456
+ # _fix_ie_filename() doesn't work correctly. See #458.
457
+ if not is_filename or value[:2] != "\\\\":
458
+ return value.replace("\\\\", "\\").replace('\\"', '"')
459
+ return value
460
+
461
+
462
+ def dict_from_cookiejar(cj):
463
+ """Returns a key/value dictionary from a CookieJar.
464
+
465
+ :param cj: CookieJar object to extract cookies from.
466
+ :rtype: dict
467
+ """
468
+
469
+ cookie_dict = {}
470
+
471
+ for cookie in cj:
472
+ cookie_dict[cookie.name] = cookie.value
473
+
474
+ return cookie_dict
475
+
476
+
477
+ def add_dict_to_cookiejar(cj, cookie_dict):
478
+ """Returns a CookieJar from a key/value dictionary.
479
+
480
+ :param cj: CookieJar to insert cookies into.
481
+ :param cookie_dict: Dict of key/values to insert into CookieJar.
482
+ :rtype: CookieJar
483
+ """
484
+
485
+ return cookiejar_from_dict(cookie_dict, cj)
486
+
487
+
488
+ def get_encodings_from_content(content):
489
+ """Returns encodings from given content string.
490
+
491
+ :param content: bytestring to extract encodings from.
492
+ """
493
+ warnings.warn(
494
+ (
495
+ "In requests 3.0, get_encodings_from_content will be removed. For "
496
+ "more information, please see the discussion on issue #2266. (This"
497
+ " warning should only appear once.)"
498
+ ),
499
+ DeprecationWarning,
500
+ )
501
+
502
+ charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I)
503
+ pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I)
504
+ xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]')
505
+
506
+ return (
507
+ charset_re.findall(content)
508
+ + pragma_re.findall(content)
509
+ + xml_re.findall(content)
510
+ )
511
+
512
+
513
+ def _parse_content_type_header(header):
514
+ """Returns content type and parameters from given header
515
+
516
+ :param header: string
517
+ :return: tuple containing content type and dictionary of
518
+ parameters
519
+ """
520
+
521
+ tokens = header.split(";")
522
+ content_type, params = tokens[0].strip(), tokens[1:]
523
+ params_dict = {}
524
+ items_to_strip = "\"' "
525
+
526
+ for param in params:
527
+ param = param.strip()
528
+ if param:
529
+ key, value = param, True
530
+ index_of_equals = param.find("=")
531
+ if index_of_equals != -1:
532
+ key = param[:index_of_equals].strip(items_to_strip)
533
+ value = param[index_of_equals + 1 :].strip(items_to_strip)
534
+ params_dict[key.lower()] = value
535
+ return content_type, params_dict
536
+
537
+
538
+ def get_encoding_from_headers(headers):
539
+ """Returns encodings from given HTTP Header Dict.
540
+
541
+ :param headers: dictionary to extract encoding from.
542
+ :rtype: str
543
+ """
544
+
545
+ content_type = headers.get("content-type")
546
+
547
+ if not content_type:
548
+ return None
549
+
550
+ content_type, params = _parse_content_type_header(content_type)
551
+
552
+ if "charset" in params:
553
+ return params["charset"].strip("'\"")
554
+
555
+ if "text" in content_type:
556
+ return "ISO-8859-1"
557
+
558
+ if "application/json" in content_type:
559
+ # Assume UTF-8 based on RFC 4627: https://www.ietf.org/rfc/rfc4627.txt since the charset was unset
560
+ return "utf-8"
561
+
562
+
563
+ def stream_decode_response_unicode(iterator, r):
564
+ """Stream decodes an iterator."""
565
+
566
+ if r.encoding is None:
567
+ yield from iterator
568
+ return
569
+
570
+ decoder = codecs.getincrementaldecoder(r.encoding)(errors="replace")
571
+ for chunk in iterator:
572
+ rv = decoder.decode(chunk)
573
+ if rv:
574
+ yield rv
575
+ rv = decoder.decode(b"", final=True)
576
+ if rv:
577
+ yield rv
578
+
579
+
580
+ def iter_slices(string, slice_length):
581
+ """Iterate over slices of a string."""
582
+ pos = 0
583
+ if slice_length is None or slice_length <= 0:
584
+ slice_length = len(string)
585
+ while pos < len(string):
586
+ yield string[pos : pos + slice_length]
587
+ pos += slice_length
588
+
589
+
590
+ def get_unicode_from_response(r):
591
+ """Returns the requested content back in unicode.
592
+
593
+ :param r: Response object to get unicode content from.
594
+
595
+ Tried:
596
+
597
+ 1. charset from content-type
598
+ 2. fall back and replace all unicode characters
599
+
600
+ :rtype: str
601
+ """
602
+ warnings.warn(
603
+ (
604
+ "In requests 3.0, get_unicode_from_response will be removed. For "
605
+ "more information, please see the discussion on issue #2266. (This"
606
+ " warning should only appear once.)"
607
+ ),
608
+ DeprecationWarning,
609
+ )
610
+
611
+ tried_encodings = []
612
+
613
+ # Try charset from content-type
614
+ encoding = get_encoding_from_headers(r.headers)
615
+
616
+ if encoding:
617
+ try:
618
+ return str(r.content, encoding)
619
+ except UnicodeError:
620
+ tried_encodings.append(encoding)
621
+
622
+ # Fall back:
623
+ try:
624
+ return str(r.content, encoding, errors="replace")
625
+ except TypeError:
626
+ return r.content
627
+
628
+
629
+ # The unreserved URI characters (RFC 3986)
630
+ UNRESERVED_SET = frozenset(
631
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~"
632
+ )
633
+
634
+
635
+ def unquote_unreserved(uri):
636
+ """Un-escape any percent-escape sequences in a URI that are unreserved
637
+ characters. This leaves all reserved, illegal and non-ASCII bytes encoded.
638
+
639
+ :rtype: str
640
+ """
641
+ parts = uri.split("%")
642
+ for i in range(1, len(parts)):
643
+ h = parts[i][0:2]
644
+ if len(h) == 2 and h.isalnum():
645
+ try:
646
+ c = chr(int(h, 16))
647
+ except ValueError:
648
+ raise InvalidURL(f"Invalid percent-escape sequence: '{h}'")
649
+
650
+ if c in UNRESERVED_SET:
651
+ parts[i] = c + parts[i][2:]
652
+ else:
653
+ parts[i] = f"%{parts[i]}"
654
+ else:
655
+ parts[i] = f"%{parts[i]}"
656
+ return "".join(parts)
657
+
658
+
659
+ def requote_uri(uri):
660
+ """Re-quote the given URI.
661
+
662
+ This function passes the given URI through an unquote/quote cycle to
663
+ ensure that it is fully and consistently quoted.
664
+
665
+ :rtype: str
666
+ """
667
+ safe_with_percent = "!#$%&'()*+,/:;=?@[]~"
668
+ safe_without_percent = "!#$&'()*+,/:;=?@[]~"
669
+ try:
670
+ # Unquote only the unreserved characters
671
+ # Then quote only illegal characters (do not quote reserved,
672
+ # unreserved, or '%')
673
+ return quote(unquote_unreserved(uri), safe=safe_with_percent)
674
+ except InvalidURL:
675
+ # We couldn't unquote the given URI, so let's try quoting it, but
676
+ # there may be unquoted '%'s in the URI. We need to make sure they're
677
+ # properly quoted so they do not cause issues elsewhere.
678
+ return quote(uri, safe=safe_without_percent)
679
+
680
+
681
+ def address_in_network(ip, net):
682
+ """This function allows you to check if an IP belongs to a network subnet
683
+
684
+ Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
685
+ returns False if ip = 192.168.1.1 and net = 192.168.100.0/24
686
+
687
+ :rtype: bool
688
+ """
689
+ ipaddr = struct.unpack("=L", socket.inet_aton(ip))[0]
690
+ netaddr, bits = net.split("/")
691
+ netmask = struct.unpack("=L", socket.inet_aton(dotted_netmask(int(bits))))[0]
692
+ network = struct.unpack("=L", socket.inet_aton(netaddr))[0] & netmask
693
+ return (ipaddr & netmask) == (network & netmask)
694
+
695
+
696
+ def dotted_netmask(mask):
697
+ """Converts mask from /xx format to xxx.xxx.xxx.xxx
698
+
699
+ Example: if mask is 24 function returns 255.255.255.0
700
+
701
+ :rtype: str
702
+ """
703
+ bits = 0xFFFFFFFF ^ (1 << 32 - mask) - 1
704
+ return socket.inet_ntoa(struct.pack(">I", bits))
705
+
706
+
707
+ def is_ipv4_address(string_ip):
708
+ """
709
+ :rtype: bool
710
+ """
711
+ try:
712
+ socket.inet_aton(string_ip)
713
+ except OSError:
714
+ return False
715
+ return True
716
+
717
+
718
+ def is_valid_cidr(string_network):
719
+ """
720
+ Very simple check of the cidr format in no_proxy variable.
721
+
722
+ :rtype: bool
723
+ """
724
+ if string_network.count("/") == 1:
725
+ try:
726
+ mask = int(string_network.split("/")[1])
727
+ except ValueError:
728
+ return False
729
+
730
+ if mask < 1 or mask > 32:
731
+ return False
732
+
733
+ try:
734
+ socket.inet_aton(string_network.split("/")[0])
735
+ except OSError:
736
+ return False
737
+ else:
738
+ return False
739
+ return True
740
+
741
+
742
+ @contextlib.contextmanager
743
+ def set_environ(env_name, value):
744
+ """Set the environment variable 'env_name' to 'value'
745
+
746
+ Save previous value, yield, and then restore the previous value stored in
747
+ the environment variable 'env_name'.
748
+
749
+ If 'value' is None, do nothing"""
750
+ value_changed = value is not None
751
+ if value_changed:
752
+ old_value = os.environ.get(env_name)
753
+ os.environ[env_name] = value
754
+ try:
755
+ yield
756
+ finally:
757
+ if value_changed:
758
+ if old_value is None:
759
+ del os.environ[env_name]
760
+ else:
761
+ os.environ[env_name] = old_value
762
+
763
+
764
+ def should_bypass_proxies(url, no_proxy):
765
+ """
766
+ Returns whether we should bypass proxies or not.
767
+
768
+ :rtype: bool
769
+ """
770
+ # Prioritize lowercase environment variables over uppercase
771
+ # to keep a consistent behaviour with other http projects (curl, wget).
772
+ def get_proxy(key):
773
+ return os.environ.get(key) or os.environ.get(key.upper())
774
+
775
+ # First check whether no_proxy is defined. If it is, check that the URL
776
+ # we're getting isn't in the no_proxy list.
777
+ no_proxy_arg = no_proxy
778
+ if no_proxy is None:
779
+ no_proxy = get_proxy("no_proxy")
780
+ parsed = urlparse(url)
781
+
782
+ if parsed.hostname is None:
783
+ # URLs don't always have hostnames, e.g. file:/// urls.
784
+ return True
785
+
786
+ if no_proxy:
787
+ # We need to check whether we match here. We need to see if we match
788
+ # the end of the hostname, both with and without the port.
789
+ no_proxy = (host for host in no_proxy.replace(" ", "").split(",") if host)
790
+
791
+ if is_ipv4_address(parsed.hostname):
792
+ for proxy_ip in no_proxy:
793
+ if is_valid_cidr(proxy_ip):
794
+ if address_in_network(parsed.hostname, proxy_ip):
795
+ return True
796
+ elif parsed.hostname == proxy_ip:
797
+ # If no_proxy ip was defined in plain IP notation instead of cidr notation &
798
+ # matches the IP of the index
799
+ return True
800
+ else:
801
+ host_with_port = parsed.hostname
802
+ if parsed.port:
803
+ host_with_port += f":{parsed.port}"
804
+
805
+ for host in no_proxy:
806
+ if parsed.hostname.endswith(host) or host_with_port.endswith(host):
807
+ # The URL does match something in no_proxy, so we don't want
808
+ # to apply the proxies on this URL.
809
+ return True
810
+
811
+ with set_environ("no_proxy", no_proxy_arg):
812
+ # parsed.hostname can be `None` in cases such as a file URI.
813
+ try:
814
+ bypass = proxy_bypass(parsed.hostname)
815
+ except (TypeError, socket.gaierror):
816
+ bypass = False
817
+
818
+ if bypass:
819
+ return True
820
+
821
+ return False
822
+
823
+
824
+ def get_environ_proxies(url, no_proxy=None):
825
+ """
826
+ Return a dict of environment proxies.
827
+
828
+ :rtype: dict
829
+ """
830
+ if should_bypass_proxies(url, no_proxy=no_proxy):
831
+ return {}
832
+ else:
833
+ return getproxies()
834
+
835
+
836
+ def select_proxy(url, proxies):
837
+ """Select a proxy for the url, if applicable.
838
+
839
+ :param url: The url being for the request
840
+ :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
841
+ """
842
+ proxies = proxies or {}
843
+ urlparts = urlparse(url)
844
+ if urlparts.hostname is None:
845
+ return proxies.get(urlparts.scheme, proxies.get("all"))
846
+
847
+ proxy_keys = [
848
+ urlparts.scheme + "://" + urlparts.hostname,
849
+ urlparts.scheme,
850
+ "all://" + urlparts.hostname,
851
+ "all",
852
+ ]
853
+ proxy = None
854
+ for proxy_key in proxy_keys:
855
+ if proxy_key in proxies:
856
+ proxy = proxies[proxy_key]
857
+ break
858
+
859
+ return proxy
860
+
861
+
862
+ def resolve_proxies(request, proxies, trust_env=True):
863
+ """This method takes proxy information from a request and configuration
864
+ input to resolve a mapping of target proxies. This will consider settings
865
+ such a NO_PROXY to strip proxy configurations.
866
+
867
+ :param request: Request or PreparedRequest
868
+ :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
869
+ :param trust_env: Boolean declaring whether to trust environment configs
870
+
871
+ :rtype: dict
872
+ """
873
+ proxies = proxies if proxies is not None else {}
874
+ url = request.url
875
+ scheme = urlparse(url).scheme
876
+ no_proxy = proxies.get("no_proxy")
877
+ new_proxies = proxies.copy()
878
+
879
+ if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
880
+ environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
881
+
882
+ proxy = environ_proxies.get(scheme, environ_proxies.get("all"))
883
+
884
+ if proxy:
885
+ new_proxies.setdefault(scheme, proxy)
886
+ return new_proxies
887
+
888
+
889
+ def default_user_agent(name="python-requests"):
890
+ """
891
+ Return a string representing the default user agent.
892
+
893
+ :rtype: str
894
+ """
895
+ return f"{name}/{__version__}"
896
+
897
+
898
+ def default_headers():
899
+ """
900
+ :rtype: requests.structures.CaseInsensitiveDict
901
+ """
902
+ return CaseInsensitiveDict(
903
+ {
904
+ "User-Agent": default_user_agent(),
905
+ "Accept-Encoding": DEFAULT_ACCEPT_ENCODING,
906
+ "Accept": "*/*",
907
+ "Connection": "keep-alive",
908
+ }
909
+ )
910
+
911
+
912
+ def parse_header_links(value):
913
+ """Return a list of parsed link headers proxies.
914
+
915
+ i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"
916
+
917
+ :rtype: list
918
+ """
919
+
920
+ links = []
921
+
922
+ replace_chars = " '\""
923
+
924
+ value = value.strip(replace_chars)
925
+ if not value:
926
+ return links
927
+
928
+ for val in re.split(", *<", value):
929
+ try:
930
+ url, params = val.split(";", 1)
931
+ except ValueError:
932
+ url, params = val, ""
933
+
934
+ link = {"url": url.strip("<> '\"")}
935
+
936
+ for param in params.split(";"):
937
+ try:
938
+ key, value = param.split("=")
939
+ except ValueError:
940
+ break
941
+
942
+ link[key.strip(replace_chars)] = value.strip(replace_chars)
943
+
944
+ links.append(link)
945
+
946
+ return links
947
+
948
+
949
+ # Null bytes; no need to recreate these on each call to guess_json_utf
950
+ _null = "\x00".encode("ascii") # encoding to ASCII for Python 3
951
+ _null2 = _null * 2
952
+ _null3 = _null * 3
953
+
954
+
955
+ def guess_json_utf(data):
956
+ """
957
+ :rtype: str
958
+ """
959
+ # JSON always starts with two ASCII characters, so detection is as
960
+ # easy as counting the nulls and from their location and count
961
+ # determine the encoding. Also detect a BOM, if present.
962
+ sample = data[:4]
963
+ if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE):
964
+ return "utf-32" # BOM included
965
+ if sample[:3] == codecs.BOM_UTF8:
966
+ return "utf-8-sig" # BOM included, MS style (discouraged)
967
+ if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE):
968
+ return "utf-16" # BOM included
969
+ nullcount = sample.count(_null)
970
+ if nullcount == 0:
971
+ return "utf-8"
972
+ if nullcount == 2:
973
+ if sample[::2] == _null2: # 1st and 3rd are null
974
+ return "utf-16-be"
975
+ if sample[1::2] == _null2: # 2nd and 4th are null
976
+ return "utf-16-le"
977
+ # Did not detect 2 valid UTF-16 ascii-range characters
978
+ if nullcount == 3:
979
+ if sample[:3] == _null3:
980
+ return "utf-32-be"
981
+ if sample[1:] == _null3:
982
+ return "utf-32-le"
983
+ # Did not detect a valid UTF-32 ascii-range character
984
+ return None
985
+
986
+
987
+ def prepend_scheme_if_needed(url, new_scheme):
988
+ """Given a URL that may or may not have a scheme, prepend the given scheme.
989
+ Does not replace a present scheme with the one provided as an argument.
990
+
991
+ :rtype: str
992
+ """
993
+ parsed = parse_url(url)
994
+ scheme, auth, host, port, path, query, fragment = parsed
995
+
996
+ # A defect in urlparse determines that there isn't a netloc present in some
997
+ # urls. We previously assumed parsing was overly cautious, and swapped the
998
+ # netloc and path. Due to a lack of tests on the original defect, this is
999
+ # maintained with parse_url for backwards compatibility.
1000
+ netloc = parsed.netloc
1001
+ if not netloc:
1002
+ netloc, path = path, netloc
1003
+
1004
+ if auth:
1005
+ # parse_url doesn't provide the netloc with auth
1006
+ # so we'll add it ourselves.
1007
+ netloc = "@".join([auth, netloc])
1008
+ if scheme is None:
1009
+ scheme = new_scheme
1010
+ if path is None:
1011
+ path = ""
1012
+
1013
+ return urlunparse((scheme, netloc, path, "", query, fragment))
1014
+
1015
+
1016
+ def get_auth_from_url(url):
1017
+ """Given a url with authentication components, extract them into a tuple of
1018
+ username,password.
1019
+
1020
+ :rtype: (str,str)
1021
+ """
1022
+ parsed = urlparse(url)
1023
+
1024
+ try:
1025
+ auth = (unquote(parsed.username), unquote(parsed.password))
1026
+ except (AttributeError, TypeError):
1027
+ auth = ("", "")
1028
+
1029
+ return auth
1030
+
1031
+
1032
+ def check_header_validity(header):
1033
+ """Verifies that header parts don't contain leading whitespace
1034
+ reserved characters, or return characters.
1035
+
1036
+ :param header: tuple, in the format (name, value).
1037
+ """
1038
+ name, value = header
1039
+ _validate_header_part(header, name, 0)
1040
+ _validate_header_part(header, value, 1)
1041
+
1042
+
1043
+ def _validate_header_part(header, header_part, header_validator_index):
1044
+ if isinstance(header_part, str):
1045
+ validator = _HEADER_VALIDATORS_STR[header_validator_index]
1046
+ elif isinstance(header_part, bytes):
1047
+ validator = _HEADER_VALIDATORS_BYTE[header_validator_index]
1048
+ else:
1049
+ raise InvalidHeader(
1050
+ f"Header part ({header_part!r}) from {header} "
1051
+ f"must be of type str or bytes, not {type(header_part)}"
1052
+ )
1053
+
1054
+ if not validator.match(header_part):
1055
+ header_kind = "name" if header_validator_index == 0 else "value"
1056
+ raise InvalidHeader(
1057
+ f"Invalid leading whitespace, reserved character(s), or return"
1058
+ f"character(s) in header {header_kind}: {header_part!r}"
1059
+ )
1060
+
1061
+
1062
+ def urldefragauth(url):
1063
+ """
1064
+ Given a url remove the fragment and the authentication part.
1065
+
1066
+ :rtype: str
1067
+ """
1068
+ scheme, netloc, path, params, query, fragment = urlparse(url)
1069
+
1070
+ # see func:`prepend_scheme_if_needed`
1071
+ if not netloc:
1072
+ netloc, path = path, netloc
1073
+
1074
+ netloc = netloc.rsplit("@", 1)[-1]
1075
+
1076
+ return urlunparse((scheme, netloc, path, params, query, ""))
1077
+
1078
+
1079
+ def rewind_body(prepared_request):
1080
+ """Move file pointer back to its recorded starting position
1081
+ so it can be read again on redirect.
1082
+ """
1083
+ body_seek = getattr(prepared_request.body, "seek", None)
1084
+ if body_seek is not None and isinstance(
1085
+ prepared_request._body_position, integer_types
1086
+ ):
1087
+ try:
1088
+ body_seek(prepared_request._body_position)
1089
+ except OSError:
1090
+ raise UnrewindableBodyError(
1091
+ "An error occurred when rewinding request body for redirect."
1092
+ )
1093
+ else:
1094
+ raise UnrewindableBodyError("Unable to rewind request body for redirect.")
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (7.49 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-311.pyc ADDED
Binary file (1.93 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-311.pyc ADDED
Binary file (2.32 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-311.pyc ADDED
Binary file (629 Bytes). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-311.pyc ADDED
Binary file (2.11 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-311.pyc ADDED
Binary file (4.17 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-311.pyc ADDED
Binary file (13.7 kB). View file
 
.venv/lib/python3.11/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-311.pyc ADDED
Binary file (977 Bytes). View file