Puyiiii commited on
Commit
9eeebce
·
verified ·
1 Parent(s): 9fa47b2

Add files using upload-large-folder tool

Browse files
Files changed (50) hide show
  1. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/certifi/__init__.py +3 -0
  2. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/certifi/__main__.py +12 -0
  3. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/certifi/cacert.pem +0 -0
  4. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/certifi/core.py +76 -0
  5. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__init__.py +5 -0
  6. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/_base.py +40 -0
  7. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/py.py +67 -0
  8. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py +30 -0
  9. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py +54 -0
  10. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/sax.py +50 -0
  11. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/base.py +417 -0
  12. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/dom.py +239 -0
  13. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/__init__.py +6 -0
  14. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/_parser.py +703 -0
  15. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/_re.py +83 -0
  16. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__init__.py +85 -0
  17. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/_collections.py +337 -0
  18. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/_version.py +2 -0
  19. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/connection.py +539 -0
  20. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/connectionpool.py +1067 -0
  21. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__init__.py +0 -0
  22. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py +36 -0
  23. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +0 -0
  24. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +519 -0
  25. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +396 -0
  26. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/appengine.py +314 -0
  27. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py +130 -0
  28. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +511 -0
  29. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +922 -0
  30. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/socks.py +216 -0
  31. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/exceptions.py +323 -0
  32. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/fields.py +274 -0
  33. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/filepost.py +98 -0
  34. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/__init__.py +5 -0
  35. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/six.py +1077 -0
  36. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/poolmanager.py +536 -0
  37. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/request.py +170 -0
  38. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/response.py +821 -0
  39. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__init__.py +49 -0
  40. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/connection.py +150 -0
  41. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/proxy.py +56 -0
  42. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/queue.py +22 -0
  43. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/request.py +143 -0
  44. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/response.py +107 -0
  45. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/retry.py +602 -0
  46. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssl_.py +495 -0
  47. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssltransport.py +221 -0
  48. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/timeout.py +268 -0
  49. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/url.py +432 -0
  50. astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/wait.py +153 -0
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/certifi/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .core import contents, where
2
+
3
+ __version__ = "2021.05.30"
astra_scene_test/Scene_04/.venv/lib/python3.9/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())
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/certifi/cacert.pem ADDED
The diff for this file is too large to render. See raw diff
 
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/certifi/core.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ certifi.py
5
+ ~~~~~~~~~~
6
+
7
+ This module returns the installation location of cacert.pem or its contents.
8
+ """
9
+ import os
10
+
11
+
12
+ class _PipPatchedCertificate(Exception):
13
+ pass
14
+
15
+
16
+ try:
17
+ # Return a certificate file on disk for a standalone pip zipapp running in
18
+ # an isolated build environment to use. Passing --cert to the standalone
19
+ # pip does not work since requests calls where() unconditionally on import.
20
+ _PIP_STANDALONE_CERT = os.environ.get("_PIP_STANDALONE_CERT")
21
+ if _PIP_STANDALONE_CERT:
22
+ def where():
23
+ return _PIP_STANDALONE_CERT
24
+ raise _PipPatchedCertificate()
25
+
26
+ from importlib.resources import path as get_path, read_text
27
+
28
+ _CACERT_CTX = None
29
+ _CACERT_PATH = None
30
+
31
+ def where():
32
+ # This is slightly terrible, but we want to delay extracting the file
33
+ # in cases where we're inside of a zipimport situation until someone
34
+ # actually calls where(), but we don't want to re-extract the file
35
+ # on every call of where(), so we'll do it once then store it in a
36
+ # global variable.
37
+ global _CACERT_CTX
38
+ global _CACERT_PATH
39
+ if _CACERT_PATH is None:
40
+ # This is slightly janky, the importlib.resources API wants you to
41
+ # manage the cleanup of this file, so it doesn't actually return a
42
+ # path, it returns a context manager that will give you the path
43
+ # when you enter it and will do any cleanup when you leave it. In
44
+ # the common case of not needing a temporary file, it will just
45
+ # return the file system location and the __exit__() is a no-op.
46
+ #
47
+ # We also have to hold onto the actual context manager, because
48
+ # it will do the cleanup whenever it gets garbage collected, so
49
+ # we will also store that at the global level as well.
50
+ _CACERT_CTX = get_path("pip._vendor.certifi", "cacert.pem")
51
+ _CACERT_PATH = str(_CACERT_CTX.__enter__())
52
+
53
+ return _CACERT_PATH
54
+
55
+ except _PipPatchedCertificate:
56
+ pass
57
+
58
+ except ImportError:
59
+ # This fallback will work for Python versions prior to 3.7 that lack the
60
+ # importlib.resources module but relies on the existing `where` function
61
+ # so won't address issues with environments like PyOxidizer that don't set
62
+ # __file__ on modules.
63
+ def read_text(_module, _path, encoding="ascii"):
64
+ with open(where(), "r", encoding=encoding) as data:
65
+ return data.read()
66
+
67
+ # If we don't have importlib.resources, then we will just do the old logic
68
+ # of assuming we're on the filesystem and munge the path directly.
69
+ def where():
70
+ f = os.path.dirname(__file__)
71
+
72
+ return os.path.join(f, "cacert.pem")
73
+
74
+
75
+ def contents():
76
+ return read_text("certifi", "cacert.pem", encoding="ascii")
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from __future__ import absolute_import, division, unicode_literals
2
+
3
+ from .py import Trie
4
+
5
+ __all__ = ["Trie"]
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/_base.py ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import, division, unicode_literals
2
+
3
+ try:
4
+ from collections.abc import Mapping
5
+ except ImportError: # Python 2.7
6
+ from collections import Mapping
7
+
8
+
9
+ class Trie(Mapping):
10
+ """Abstract base class for tries"""
11
+
12
+ def keys(self, prefix=None):
13
+ # pylint:disable=arguments-differ
14
+ keys = super(Trie, self).keys()
15
+
16
+ if prefix is None:
17
+ return set(keys)
18
+
19
+ return {x for x in keys if x.startswith(prefix)}
20
+
21
+ def has_keys_with_prefix(self, prefix):
22
+ for key in self.keys():
23
+ if key.startswith(prefix):
24
+ return True
25
+
26
+ return False
27
+
28
+ def longest_prefix(self, prefix):
29
+ if prefix in self:
30
+ return prefix
31
+
32
+ for i in range(1, len(prefix) + 1):
33
+ if prefix[:-i] in self:
34
+ return prefix[:-i]
35
+
36
+ raise KeyError(prefix)
37
+
38
+ def longest_prefix_item(self, prefix):
39
+ lprefix = self.longest_prefix(prefix)
40
+ return (lprefix, self[lprefix])
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/_trie/py.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import, division, unicode_literals
2
+ from pip._vendor.six import text_type
3
+
4
+ from bisect import bisect_left
5
+
6
+ from ._base import Trie as ABCTrie
7
+
8
+
9
+ class Trie(ABCTrie):
10
+ def __init__(self, data):
11
+ if not all(isinstance(x, text_type) for x in data.keys()):
12
+ raise TypeError("All keys must be strings")
13
+
14
+ self._data = data
15
+ self._keys = sorted(data.keys())
16
+ self._cachestr = ""
17
+ self._cachepoints = (0, len(data))
18
+
19
+ def __contains__(self, key):
20
+ return key in self._data
21
+
22
+ def __len__(self):
23
+ return len(self._data)
24
+
25
+ def __iter__(self):
26
+ return iter(self._data)
27
+
28
+ def __getitem__(self, key):
29
+ return self._data[key]
30
+
31
+ def keys(self, prefix=None):
32
+ if prefix is None or prefix == "" or not self._keys:
33
+ return set(self._keys)
34
+
35
+ if prefix.startswith(self._cachestr):
36
+ lo, hi = self._cachepoints
37
+ start = i = bisect_left(self._keys, prefix, lo, hi)
38
+ else:
39
+ start = i = bisect_left(self._keys, prefix)
40
+
41
+ keys = set()
42
+ if start == len(self._keys):
43
+ return keys
44
+
45
+ while self._keys[i].startswith(prefix):
46
+ keys.add(self._keys[i])
47
+ i += 1
48
+
49
+ self._cachestr = prefix
50
+ self._cachepoints = (start, i)
51
+
52
+ return keys
53
+
54
+ def has_keys_with_prefix(self, prefix):
55
+ if prefix in self._data:
56
+ return True
57
+
58
+ if prefix.startswith(self._cachestr):
59
+ lo, hi = self._cachepoints
60
+ i = bisect_left(self._keys, prefix, lo, hi)
61
+ else:
62
+ i = bisect_left(self._keys, prefix)
63
+
64
+ if i == len(self._keys):
65
+ return False
66
+
67
+ return self._keys[i].startswith(prefix)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Tree adapters let you convert from one tree structure to another
2
+
3
+ Example:
4
+
5
+ .. code-block:: python
6
+
7
+ from pip._vendor import html5lib
8
+ from pip._vendor.html5lib.treeadapters import genshi
9
+
10
+ doc = '<html><body>Hi!</body></html>'
11
+ treebuilder = html5lib.getTreeBuilder('etree')
12
+ parser = html5lib.HTMLParser(tree=treebuilder)
13
+ tree = parser.parse(doc)
14
+ TreeWalker = html5lib.getTreeWalker('etree')
15
+
16
+ genshi_tree = genshi.to_genshi(TreeWalker(tree))
17
+
18
+ """
19
+ from __future__ import absolute_import, division, unicode_literals
20
+
21
+ from . import sax
22
+
23
+ __all__ = ["sax"]
24
+
25
+ try:
26
+ from . import genshi # noqa
27
+ except ImportError:
28
+ pass
29
+ else:
30
+ __all__.append("genshi")
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import, division, unicode_literals
2
+
3
+ from genshi.core import QName, Attrs
4
+ from genshi.core import START, END, TEXT, COMMENT, DOCTYPE
5
+
6
+
7
+ def to_genshi(walker):
8
+ """Convert a tree to a genshi tree
9
+
10
+ :arg walker: the treewalker to use to walk the tree to convert it
11
+
12
+ :returns: generator of genshi nodes
13
+
14
+ """
15
+ text = []
16
+ for token in walker:
17
+ type = token["type"]
18
+ if type in ("Characters", "SpaceCharacters"):
19
+ text.append(token["data"])
20
+ elif text:
21
+ yield TEXT, "".join(text), (None, -1, -1)
22
+ text = []
23
+
24
+ if type in ("StartTag", "EmptyTag"):
25
+ if token["namespace"]:
26
+ name = "{%s}%s" % (token["namespace"], token["name"])
27
+ else:
28
+ name = token["name"]
29
+ attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value)
30
+ for attr, value in token["data"].items()])
31
+ yield (START, (QName(name), attrs), (None, -1, -1))
32
+ if type == "EmptyTag":
33
+ type = "EndTag"
34
+
35
+ if type == "EndTag":
36
+ if token["namespace"]:
37
+ name = "{%s}%s" % (token["namespace"], token["name"])
38
+ else:
39
+ name = token["name"]
40
+
41
+ yield END, QName(name), (None, -1, -1)
42
+
43
+ elif type == "Comment":
44
+ yield COMMENT, token["data"], (None, -1, -1)
45
+
46
+ elif type == "Doctype":
47
+ yield DOCTYPE, (token["name"], token["publicId"],
48
+ token["systemId"]), (None, -1, -1)
49
+
50
+ else:
51
+ pass # FIXME: What to do?
52
+
53
+ if text:
54
+ yield TEXT, "".join(text), (None, -1, -1)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treeadapters/sax.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import, division, unicode_literals
2
+
3
+ from xml.sax.xmlreader import AttributesNSImpl
4
+
5
+ from ..constants import adjustForeignAttributes, unadjustForeignAttributes
6
+
7
+ prefix_mapping = {}
8
+ for prefix, localName, namespace in adjustForeignAttributes.values():
9
+ if prefix is not None:
10
+ prefix_mapping[prefix] = namespace
11
+
12
+
13
+ def to_sax(walker, handler):
14
+ """Call SAX-like content handler based on treewalker walker
15
+
16
+ :arg walker: the treewalker to use to walk the tree to convert it
17
+
18
+ :arg handler: SAX handler to use
19
+
20
+ """
21
+ handler.startDocument()
22
+ for prefix, namespace in prefix_mapping.items():
23
+ handler.startPrefixMapping(prefix, namespace)
24
+
25
+ for token in walker:
26
+ type = token["type"]
27
+ if type == "Doctype":
28
+ continue
29
+ elif type in ("StartTag", "EmptyTag"):
30
+ attrs = AttributesNSImpl(token["data"],
31
+ unadjustForeignAttributes)
32
+ handler.startElementNS((token["namespace"], token["name"]),
33
+ token["name"],
34
+ attrs)
35
+ if type == "EmptyTag":
36
+ handler.endElementNS((token["namespace"], token["name"]),
37
+ token["name"])
38
+ elif type == "EndTag":
39
+ handler.endElementNS((token["namespace"], token["name"]),
40
+ token["name"])
41
+ elif type in ("Characters", "SpaceCharacters"):
42
+ handler.characters(token["data"])
43
+ elif type == "Comment":
44
+ pass
45
+ else:
46
+ assert False, "Unknown token type"
47
+
48
+ for prefix, namespace in prefix_mapping.items():
49
+ handler.endPrefixMapping(prefix)
50
+ handler.endDocument()
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/base.py ADDED
@@ -0,0 +1,417 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import, division, unicode_literals
2
+ from pip._vendor.six import text_type
3
+
4
+ from ..constants import scopingElements, tableInsertModeElements, namespaces
5
+
6
+ # The scope markers are inserted when entering object elements,
7
+ # marquees, table cells, and table captions, and are used to prevent formatting
8
+ # from "leaking" into tables, object elements, and marquees.
9
+ Marker = None
10
+
11
+ listElementsMap = {
12
+ None: (frozenset(scopingElements), False),
13
+ "button": (frozenset(scopingElements | {(namespaces["html"], "button")}), False),
14
+ "list": (frozenset(scopingElements | {(namespaces["html"], "ol"),
15
+ (namespaces["html"], "ul")}), False),
16
+ "table": (frozenset([(namespaces["html"], "html"),
17
+ (namespaces["html"], "table")]), False),
18
+ "select": (frozenset([(namespaces["html"], "optgroup"),
19
+ (namespaces["html"], "option")]), True)
20
+ }
21
+
22
+
23
+ class Node(object):
24
+ """Represents an item in the tree"""
25
+ def __init__(self, name):
26
+ """Creates a Node
27
+
28
+ :arg name: The tag name associated with the node
29
+
30
+ """
31
+ # The tag name associated with the node
32
+ self.name = name
33
+ # The parent of the current node (or None for the document node)
34
+ self.parent = None
35
+ # The value of the current node (applies to text nodes and comments)
36
+ self.value = None
37
+ # A dict holding name -> value pairs for attributes of the node
38
+ self.attributes = {}
39
+ # A list of child nodes of the current node. This must include all
40
+ # elements but not necessarily other node types.
41
+ self.childNodes = []
42
+ # A list of miscellaneous flags that can be set on the node.
43
+ self._flags = []
44
+
45
+ def __str__(self):
46
+ attributesStr = " ".join(["%s=\"%s\"" % (name, value)
47
+ for name, value in
48
+ self.attributes.items()])
49
+ if attributesStr:
50
+ return "<%s %s>" % (self.name, attributesStr)
51
+ else:
52
+ return "<%s>" % (self.name)
53
+
54
+ def __repr__(self):
55
+ return "<%s>" % (self.name)
56
+
57
+ def appendChild(self, node):
58
+ """Insert node as a child of the current node
59
+
60
+ :arg node: the node to insert
61
+
62
+ """
63
+ raise NotImplementedError
64
+
65
+ def insertText(self, data, insertBefore=None):
66
+ """Insert data as text in the current node, positioned before the
67
+ start of node insertBefore or to the end of the node's text.
68
+
69
+ :arg data: the data to insert
70
+
71
+ :arg insertBefore: True if you want to insert the text before the node
72
+ and False if you want to insert it after the node
73
+
74
+ """
75
+ raise NotImplementedError
76
+
77
+ def insertBefore(self, node, refNode):
78
+ """Insert node as a child of the current node, before refNode in the
79
+ list of child nodes. Raises ValueError if refNode is not a child of
80
+ the current node
81
+
82
+ :arg node: the node to insert
83
+
84
+ :arg refNode: the child node to insert the node before
85
+
86
+ """
87
+ raise NotImplementedError
88
+
89
+ def removeChild(self, node):
90
+ """Remove node from the children of the current node
91
+
92
+ :arg node: the child node to remove
93
+
94
+ """
95
+ raise NotImplementedError
96
+
97
+ def reparentChildren(self, newParent):
98
+ """Move all the children of the current node to newParent.
99
+ This is needed so that trees that don't store text as nodes move the
100
+ text in the correct way
101
+
102
+ :arg newParent: the node to move all this node's children to
103
+
104
+ """
105
+ # XXX - should this method be made more general?
106
+ for child in self.childNodes:
107
+ newParent.appendChild(child)
108
+ self.childNodes = []
109
+
110
+ def cloneNode(self):
111
+ """Return a shallow copy of the current node i.e. a node with the same
112
+ name and attributes but with no parent or child nodes
113
+ """
114
+ raise NotImplementedError
115
+
116
+ def hasContent(self):
117
+ """Return true if the node has children or text, false otherwise
118
+ """
119
+ raise NotImplementedError
120
+
121
+
122
+ class ActiveFormattingElements(list):
123
+ def append(self, node):
124
+ equalCount = 0
125
+ if node != Marker:
126
+ for element in self[::-1]:
127
+ if element == Marker:
128
+ break
129
+ if self.nodesEqual(element, node):
130
+ equalCount += 1
131
+ if equalCount == 3:
132
+ self.remove(element)
133
+ break
134
+ list.append(self, node)
135
+
136
+ def nodesEqual(self, node1, node2):
137
+ if not node1.nameTuple == node2.nameTuple:
138
+ return False
139
+
140
+ if not node1.attributes == node2.attributes:
141
+ return False
142
+
143
+ return True
144
+
145
+
146
+ class TreeBuilder(object):
147
+ """Base treebuilder implementation
148
+
149
+ * documentClass - the class to use for the bottommost node of a document
150
+ * elementClass - the class to use for HTML Elements
151
+ * commentClass - the class to use for comments
152
+ * doctypeClass - the class to use for doctypes
153
+
154
+ """
155
+ # pylint:disable=not-callable
156
+
157
+ # Document class
158
+ documentClass = None
159
+
160
+ # The class to use for creating a node
161
+ elementClass = None
162
+
163
+ # The class to use for creating comments
164
+ commentClass = None
165
+
166
+ # The class to use for creating doctypes
167
+ doctypeClass = None
168
+
169
+ # Fragment class
170
+ fragmentClass = None
171
+
172
+ def __init__(self, namespaceHTMLElements):
173
+ """Create a TreeBuilder
174
+
175
+ :arg namespaceHTMLElements: whether or not to namespace HTML elements
176
+
177
+ """
178
+ if namespaceHTMLElements:
179
+ self.defaultNamespace = "http://www.w3.org/1999/xhtml"
180
+ else:
181
+ self.defaultNamespace = None
182
+ self.reset()
183
+
184
+ def reset(self):
185
+ self.openElements = []
186
+ self.activeFormattingElements = ActiveFormattingElements()
187
+
188
+ # XXX - rename these to headElement, formElement
189
+ self.headPointer = None
190
+ self.formPointer = None
191
+
192
+ self.insertFromTable = False
193
+
194
+ self.document = self.documentClass()
195
+
196
+ def elementInScope(self, target, variant=None):
197
+
198
+ # If we pass a node in we match that. if we pass a string
199
+ # match any node with that name
200
+ exactNode = hasattr(target, "nameTuple")
201
+ if not exactNode:
202
+ if isinstance(target, text_type):
203
+ target = (namespaces["html"], target)
204
+ assert isinstance(target, tuple)
205
+
206
+ listElements, invert = listElementsMap[variant]
207
+
208
+ for node in reversed(self.openElements):
209
+ if exactNode and node == target:
210
+ return True
211
+ elif not exactNode and node.nameTuple == target:
212
+ return True
213
+ elif (invert ^ (node.nameTuple in listElements)):
214
+ return False
215
+
216
+ assert False # We should never reach this point
217
+
218
+ def reconstructActiveFormattingElements(self):
219
+ # Within this algorithm the order of steps described in the
220
+ # specification is not quite the same as the order of steps in the
221
+ # code. It should still do the same though.
222
+
223
+ # Step 1: stop the algorithm when there's nothing to do.
224
+ if not self.activeFormattingElements:
225
+ return
226
+
227
+ # Step 2 and step 3: we start with the last element. So i is -1.
228
+ i = len(self.activeFormattingElements) - 1
229
+ entry = self.activeFormattingElements[i]
230
+ if entry == Marker or entry in self.openElements:
231
+ return
232
+
233
+ # Step 6
234
+ while entry != Marker and entry not in self.openElements:
235
+ if i == 0:
236
+ # This will be reset to 0 below
237
+ i = -1
238
+ break
239
+ i -= 1
240
+ # Step 5: let entry be one earlier in the list.
241
+ entry = self.activeFormattingElements[i]
242
+
243
+ while True:
244
+ # Step 7
245
+ i += 1
246
+
247
+ # Step 8
248
+ entry = self.activeFormattingElements[i]
249
+ clone = entry.cloneNode() # Mainly to get a new copy of the attributes
250
+
251
+ # Step 9
252
+ element = self.insertElement({"type": "StartTag",
253
+ "name": clone.name,
254
+ "namespace": clone.namespace,
255
+ "data": clone.attributes})
256
+
257
+ # Step 10
258
+ self.activeFormattingElements[i] = element
259
+
260
+ # Step 11
261
+ if element == self.activeFormattingElements[-1]:
262
+ break
263
+
264
+ def clearActiveFormattingElements(self):
265
+ entry = self.activeFormattingElements.pop()
266
+ while self.activeFormattingElements and entry != Marker:
267
+ entry = self.activeFormattingElements.pop()
268
+
269
+ def elementInActiveFormattingElements(self, name):
270
+ """Check if an element exists between the end of the active
271
+ formatting elements and the last marker. If it does, return it, else
272
+ return false"""
273
+
274
+ for item in self.activeFormattingElements[::-1]:
275
+ # Check for Marker first because if it's a Marker it doesn't have a
276
+ # name attribute.
277
+ if item == Marker:
278
+ break
279
+ elif item.name == name:
280
+ return item
281
+ return False
282
+
283
+ def insertRoot(self, token):
284
+ element = self.createElement(token)
285
+ self.openElements.append(element)
286
+ self.document.appendChild(element)
287
+
288
+ def insertDoctype(self, token):
289
+ name = token["name"]
290
+ publicId = token["publicId"]
291
+ systemId = token["systemId"]
292
+
293
+ doctype = self.doctypeClass(name, publicId, systemId)
294
+ self.document.appendChild(doctype)
295
+
296
+ def insertComment(self, token, parent=None):
297
+ if parent is None:
298
+ parent = self.openElements[-1]
299
+ parent.appendChild(self.commentClass(token["data"]))
300
+
301
+ def createElement(self, token):
302
+ """Create an element but don't insert it anywhere"""
303
+ name = token["name"]
304
+ namespace = token.get("namespace", self.defaultNamespace)
305
+ element = self.elementClass(name, namespace)
306
+ element.attributes = token["data"]
307
+ return element
308
+
309
+ def _getInsertFromTable(self):
310
+ return self._insertFromTable
311
+
312
+ def _setInsertFromTable(self, value):
313
+ """Switch the function used to insert an element from the
314
+ normal one to the misnested table one and back again"""
315
+ self._insertFromTable = value
316
+ if value:
317
+ self.insertElement = self.insertElementTable
318
+ else:
319
+ self.insertElement = self.insertElementNormal
320
+
321
+ insertFromTable = property(_getInsertFromTable, _setInsertFromTable)
322
+
323
+ def insertElementNormal(self, token):
324
+ name = token["name"]
325
+ assert isinstance(name, text_type), "Element %s not unicode" % name
326
+ namespace = token.get("namespace", self.defaultNamespace)
327
+ element = self.elementClass(name, namespace)
328
+ element.attributes = token["data"]
329
+ self.openElements[-1].appendChild(element)
330
+ self.openElements.append(element)
331
+ return element
332
+
333
+ def insertElementTable(self, token):
334
+ """Create an element and insert it into the tree"""
335
+ element = self.createElement(token)
336
+ if self.openElements[-1].name not in tableInsertModeElements:
337
+ return self.insertElementNormal(token)
338
+ else:
339
+ # We should be in the InTable mode. This means we want to do
340
+ # special magic element rearranging
341
+ parent, insertBefore = self.getTableMisnestedNodePosition()
342
+ if insertBefore is None:
343
+ parent.appendChild(element)
344
+ else:
345
+ parent.insertBefore(element, insertBefore)
346
+ self.openElements.append(element)
347
+ return element
348
+
349
+ def insertText(self, data, parent=None):
350
+ """Insert text data."""
351
+ if parent is None:
352
+ parent = self.openElements[-1]
353
+
354
+ if (not self.insertFromTable or (self.insertFromTable and
355
+ self.openElements[-1].name
356
+ not in tableInsertModeElements)):
357
+ parent.insertText(data)
358
+ else:
359
+ # We should be in the InTable mode. This means we want to do
360
+ # special magic element rearranging
361
+ parent, insertBefore = self.getTableMisnestedNodePosition()
362
+ parent.insertText(data, insertBefore)
363
+
364
+ def getTableMisnestedNodePosition(self):
365
+ """Get the foster parent element, and sibling to insert before
366
+ (or None) when inserting a misnested table node"""
367
+ # The foster parent element is the one which comes before the most
368
+ # recently opened table element
369
+ # XXX - this is really inelegant
370
+ lastTable = None
371
+ fosterParent = None
372
+ insertBefore = None
373
+ for elm in self.openElements[::-1]:
374
+ if elm.name == "table":
375
+ lastTable = elm
376
+ break
377
+ if lastTable:
378
+ # XXX - we should really check that this parent is actually a
379
+ # node here
380
+ if lastTable.parent:
381
+ fosterParent = lastTable.parent
382
+ insertBefore = lastTable
383
+ else:
384
+ fosterParent = self.openElements[
385
+ self.openElements.index(lastTable) - 1]
386
+ else:
387
+ fosterParent = self.openElements[0]
388
+ return fosterParent, insertBefore
389
+
390
+ def generateImpliedEndTags(self, exclude=None):
391
+ name = self.openElements[-1].name
392
+ # XXX td, th and tr are not actually needed
393
+ if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and
394
+ name != exclude):
395
+ self.openElements.pop()
396
+ # XXX This is not entirely what the specification says. We should
397
+ # investigate it more closely.
398
+ self.generateImpliedEndTags(exclude)
399
+
400
+ def getDocument(self):
401
+ """Return the final tree"""
402
+ return self.document
403
+
404
+ def getFragment(self):
405
+ """Return the final fragment"""
406
+ # assert self.innerHTML
407
+ fragment = self.fragmentClass()
408
+ self.openElements[0].reparentChildren(fragment)
409
+ return fragment
410
+
411
+ def testSerializer(self, node):
412
+ """Serialize the subtree of node in the format required by unit tests
413
+
414
+ :arg node: the node from which to start serializing
415
+
416
+ """
417
+ raise NotImplementedError
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/html5lib/treebuilders/dom.py ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import, division, unicode_literals
2
+
3
+
4
+ try:
5
+ from collections.abc import MutableMapping
6
+ except ImportError: # Python 2.7
7
+ from collections import MutableMapping
8
+ from xml.dom import minidom, Node
9
+ import weakref
10
+
11
+ from . import base
12
+ from .. import constants
13
+ from ..constants import namespaces
14
+ from .._utils import moduleFactoryFactory
15
+
16
+
17
+ def getDomBuilder(DomImplementation):
18
+ Dom = DomImplementation
19
+
20
+ class AttrList(MutableMapping):
21
+ def __init__(self, element):
22
+ self.element = element
23
+
24
+ def __iter__(self):
25
+ return iter(self.element.attributes.keys())
26
+
27
+ def __setitem__(self, name, value):
28
+ if isinstance(name, tuple):
29
+ raise NotImplementedError
30
+ else:
31
+ attr = self.element.ownerDocument.createAttribute(name)
32
+ attr.value = value
33
+ self.element.attributes[name] = attr
34
+
35
+ def __len__(self):
36
+ return len(self.element.attributes)
37
+
38
+ def items(self):
39
+ return list(self.element.attributes.items())
40
+
41
+ def values(self):
42
+ return list(self.element.attributes.values())
43
+
44
+ def __getitem__(self, name):
45
+ if isinstance(name, tuple):
46
+ raise NotImplementedError
47
+ else:
48
+ return self.element.attributes[name].value
49
+
50
+ def __delitem__(self, name):
51
+ if isinstance(name, tuple):
52
+ raise NotImplementedError
53
+ else:
54
+ del self.element.attributes[name]
55
+
56
+ class NodeBuilder(base.Node):
57
+ def __init__(self, element):
58
+ base.Node.__init__(self, element.nodeName)
59
+ self.element = element
60
+
61
+ namespace = property(lambda self: hasattr(self.element, "namespaceURI") and
62
+ self.element.namespaceURI or None)
63
+
64
+ def appendChild(self, node):
65
+ node.parent = self
66
+ self.element.appendChild(node.element)
67
+
68
+ def insertText(self, data, insertBefore=None):
69
+ text = self.element.ownerDocument.createTextNode(data)
70
+ if insertBefore:
71
+ self.element.insertBefore(text, insertBefore.element)
72
+ else:
73
+ self.element.appendChild(text)
74
+
75
+ def insertBefore(self, node, refNode):
76
+ self.element.insertBefore(node.element, refNode.element)
77
+ node.parent = self
78
+
79
+ def removeChild(self, node):
80
+ if node.element.parentNode == self.element:
81
+ self.element.removeChild(node.element)
82
+ node.parent = None
83
+
84
+ def reparentChildren(self, newParent):
85
+ while self.element.hasChildNodes():
86
+ child = self.element.firstChild
87
+ self.element.removeChild(child)
88
+ newParent.element.appendChild(child)
89
+ self.childNodes = []
90
+
91
+ def getAttributes(self):
92
+ return AttrList(self.element)
93
+
94
+ def setAttributes(self, attributes):
95
+ if attributes:
96
+ for name, value in list(attributes.items()):
97
+ if isinstance(name, tuple):
98
+ if name[0] is not None:
99
+ qualifiedName = (name[0] + ":" + name[1])
100
+ else:
101
+ qualifiedName = name[1]
102
+ self.element.setAttributeNS(name[2], qualifiedName,
103
+ value)
104
+ else:
105
+ self.element.setAttribute(
106
+ name, value)
107
+ attributes = property(getAttributes, setAttributes)
108
+
109
+ def cloneNode(self):
110
+ return NodeBuilder(self.element.cloneNode(False))
111
+
112
+ def hasContent(self):
113
+ return self.element.hasChildNodes()
114
+
115
+ def getNameTuple(self):
116
+ if self.namespace is None:
117
+ return namespaces["html"], self.name
118
+ else:
119
+ return self.namespace, self.name
120
+
121
+ nameTuple = property(getNameTuple)
122
+
123
+ class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable
124
+ def documentClass(self):
125
+ self.dom = Dom.getDOMImplementation().createDocument(None, None, None)
126
+ return weakref.proxy(self)
127
+
128
+ def insertDoctype(self, token):
129
+ name = token["name"]
130
+ publicId = token["publicId"]
131
+ systemId = token["systemId"]
132
+
133
+ domimpl = Dom.getDOMImplementation()
134
+ doctype = domimpl.createDocumentType(name, publicId, systemId)
135
+ self.document.appendChild(NodeBuilder(doctype))
136
+ if Dom == minidom:
137
+ doctype.ownerDocument = self.dom
138
+
139
+ def elementClass(self, name, namespace=None):
140
+ if namespace is None and self.defaultNamespace is None:
141
+ node = self.dom.createElement(name)
142
+ else:
143
+ node = self.dom.createElementNS(namespace, name)
144
+
145
+ return NodeBuilder(node)
146
+
147
+ def commentClass(self, data):
148
+ return NodeBuilder(self.dom.createComment(data))
149
+
150
+ def fragmentClass(self):
151
+ return NodeBuilder(self.dom.createDocumentFragment())
152
+
153
+ def appendChild(self, node):
154
+ self.dom.appendChild(node.element)
155
+
156
+ def testSerializer(self, element):
157
+ return testSerializer(element)
158
+
159
+ def getDocument(self):
160
+ return self.dom
161
+
162
+ def getFragment(self):
163
+ return base.TreeBuilder.getFragment(self).element
164
+
165
+ def insertText(self, data, parent=None):
166
+ data = data
167
+ if parent != self:
168
+ base.TreeBuilder.insertText(self, data, parent)
169
+ else:
170
+ # HACK: allow text nodes as children of the document node
171
+ if hasattr(self.dom, '_child_node_types'):
172
+ # pylint:disable=protected-access
173
+ if Node.TEXT_NODE not in self.dom._child_node_types:
174
+ self.dom._child_node_types = list(self.dom._child_node_types)
175
+ self.dom._child_node_types.append(Node.TEXT_NODE)
176
+ self.dom.appendChild(self.dom.createTextNode(data))
177
+
178
+ implementation = DomImplementation
179
+ name = None
180
+
181
+ def testSerializer(element):
182
+ element.normalize()
183
+ rv = []
184
+
185
+ def serializeElement(element, indent=0):
186
+ if element.nodeType == Node.DOCUMENT_TYPE_NODE:
187
+ if element.name:
188
+ if element.publicId or element.systemId:
189
+ publicId = element.publicId or ""
190
+ systemId = element.systemId or ""
191
+ rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" %
192
+ (' ' * indent, element.name, publicId, systemId))
193
+ else:
194
+ rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name))
195
+ else:
196
+ rv.append("|%s<!DOCTYPE >" % (' ' * indent,))
197
+ elif element.nodeType == Node.DOCUMENT_NODE:
198
+ rv.append("#document")
199
+ elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
200
+ rv.append("#document-fragment")
201
+ elif element.nodeType == Node.COMMENT_NODE:
202
+ rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue))
203
+ elif element.nodeType == Node.TEXT_NODE:
204
+ rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue))
205
+ else:
206
+ if (hasattr(element, "namespaceURI") and
207
+ element.namespaceURI is not None):
208
+ name = "%s %s" % (constants.prefixes[element.namespaceURI],
209
+ element.nodeName)
210
+ else:
211
+ name = element.nodeName
212
+ rv.append("|%s<%s>" % (' ' * indent, name))
213
+ if element.hasAttributes():
214
+ attributes = []
215
+ for i in range(len(element.attributes)):
216
+ attr = element.attributes.item(i)
217
+ name = attr.nodeName
218
+ value = attr.value
219
+ ns = attr.namespaceURI
220
+ if ns:
221
+ name = "%s %s" % (constants.prefixes[ns], attr.localName)
222
+ else:
223
+ name = attr.nodeName
224
+ attributes.append((name, value))
225
+
226
+ for name, value in sorted(attributes):
227
+ rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value))
228
+ indent += 2
229
+ for child in element.childNodes:
230
+ serializeElement(child, indent)
231
+ serializeElement(element, 0)
232
+
233
+ return "\n".join(rv)
234
+
235
+ return locals()
236
+
237
+
238
+ # The actual means to get a module!
239
+ getDomModule = moduleFactoryFactory(getDomBuilder)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ """A lil' TOML parser."""
2
+
3
+ __all__ = ("loads", "load", "TOMLDecodeError")
4
+ __version__ = "1.0.3" # DO NOT EDIT THIS LINE MANUALLY. LET bump2version UTILITY DO IT
5
+
6
+ from pip._vendor.tomli._parser import TOMLDecodeError, load, loads
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/_parser.py ADDED
@@ -0,0 +1,703 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import string
2
+ from types import MappingProxyType
3
+ from typing import (
4
+ TYPE_CHECKING,
5
+ Any,
6
+ Callable,
7
+ Dict,
8
+ FrozenSet,
9
+ Iterable,
10
+ Optional,
11
+ TextIO,
12
+ Tuple,
13
+ )
14
+
15
+ from pip._vendor.tomli._re import (
16
+ RE_BIN,
17
+ RE_DATETIME,
18
+ RE_HEX,
19
+ RE_LOCALTIME,
20
+ RE_NUMBER,
21
+ RE_OCT,
22
+ match_to_datetime,
23
+ match_to_localtime,
24
+ match_to_number,
25
+ )
26
+
27
+ if TYPE_CHECKING:
28
+ from re import Pattern
29
+
30
+
31
+ ASCII_CTRL = frozenset(chr(i) for i in range(32)) | frozenset(chr(127))
32
+
33
+ # Neither of these sets include quotation mark or backslash. They are
34
+ # currently handled as separate cases in the parser functions.
35
+ ILLEGAL_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t")
36
+ ILLEGAL_MULTILINE_BASIC_STR_CHARS = ASCII_CTRL - frozenset("\t\n\r")
37
+
38
+ ILLEGAL_LITERAL_STR_CHARS = ILLEGAL_BASIC_STR_CHARS
39
+ ILLEGAL_MULTILINE_LITERAL_STR_CHARS = ASCII_CTRL - frozenset("\t\n")
40
+
41
+ ILLEGAL_COMMENT_CHARS = ILLEGAL_BASIC_STR_CHARS
42
+
43
+ TOML_WS = frozenset(" \t")
44
+ TOML_WS_AND_NEWLINE = TOML_WS | frozenset("\n")
45
+ BARE_KEY_CHARS = frozenset(string.ascii_letters + string.digits + "-_")
46
+ KEY_INITIAL_CHARS = BARE_KEY_CHARS | frozenset("\"'")
47
+
48
+ BASIC_STR_ESCAPE_REPLACEMENTS = MappingProxyType(
49
+ {
50
+ "\\b": "\u0008", # backspace
51
+ "\\t": "\u0009", # tab
52
+ "\\n": "\u000A", # linefeed
53
+ "\\f": "\u000C", # form feed
54
+ "\\r": "\u000D", # carriage return
55
+ '\\"': "\u0022", # quote
56
+ "\\\\": "\u005C", # backslash
57
+ }
58
+ )
59
+
60
+ # Type annotations
61
+ ParseFloat = Callable[[str], Any]
62
+ Key = Tuple[str, ...]
63
+ Pos = int
64
+
65
+
66
+ class TOMLDecodeError(ValueError):
67
+ """An error raised if a document is not valid TOML."""
68
+
69
+
70
+ def load(fp: TextIO, *, parse_float: ParseFloat = float) -> Dict[str, Any]:
71
+ """Parse TOML from a file object."""
72
+ s = fp.read()
73
+ return loads(s, parse_float=parse_float)
74
+
75
+
76
+ def loads(s: str, *, parse_float: ParseFloat = float) -> Dict[str, Any]: # noqa: C901
77
+ """Parse TOML from a string."""
78
+
79
+ # The spec allows converting "\r\n" to "\n", even in string
80
+ # literals. Let's do so to simplify parsing.
81
+ src = s.replace("\r\n", "\n")
82
+ pos = 0
83
+ state = State()
84
+
85
+ # Parse one statement at a time
86
+ # (typically means one line in TOML source)
87
+ while True:
88
+ # 1. Skip line leading whitespace
89
+ pos = skip_chars(src, pos, TOML_WS)
90
+
91
+ # 2. Parse rules. Expect one of the following:
92
+ # - end of file
93
+ # - end of line
94
+ # - comment
95
+ # - key/value pair
96
+ # - append dict to list (and move to its namespace)
97
+ # - create dict (and move to its namespace)
98
+ # Skip trailing whitespace when applicable.
99
+ try:
100
+ char = src[pos]
101
+ except IndexError:
102
+ break
103
+ if char == "\n":
104
+ pos += 1
105
+ continue
106
+ if char in KEY_INITIAL_CHARS:
107
+ pos = key_value_rule(src, pos, state, parse_float)
108
+ pos = skip_chars(src, pos, TOML_WS)
109
+ elif char == "[":
110
+ try:
111
+ second_char: Optional[str] = src[pos + 1]
112
+ except IndexError:
113
+ second_char = None
114
+ if second_char == "[":
115
+ pos = create_list_rule(src, pos, state)
116
+ else:
117
+ pos = create_dict_rule(src, pos, state)
118
+ pos = skip_chars(src, pos, TOML_WS)
119
+ elif char != "#":
120
+ raise suffixed_err(src, pos, "Invalid statement")
121
+
122
+ # 3. Skip comment
123
+ pos = skip_comment(src, pos)
124
+
125
+ # 4. Expect end of line or end of file
126
+ try:
127
+ char = src[pos]
128
+ except IndexError:
129
+ break
130
+ if char != "\n":
131
+ raise suffixed_err(
132
+ src, pos, "Expected newline or end of document after a statement"
133
+ )
134
+ pos += 1
135
+
136
+ return state.out.dict
137
+
138
+
139
+ class State:
140
+ def __init__(self) -> None:
141
+ # Mutable, read-only
142
+ self.out = NestedDict()
143
+ self.flags = Flags()
144
+
145
+ # Immutable, read and write
146
+ self.header_namespace: Key = ()
147
+
148
+
149
+ class Flags:
150
+ """Flags that map to parsed keys/namespaces."""
151
+
152
+ # Marks an immutable namespace (inline array or inline table).
153
+ FROZEN = 0
154
+ # Marks a nest that has been explicitly created and can no longer
155
+ # be opened using the "[table]" syntax.
156
+ EXPLICIT_NEST = 1
157
+
158
+ def __init__(self) -> None:
159
+ self._flags: Dict[str, dict] = {}
160
+
161
+ def unset_all(self, key: Key) -> None:
162
+ cont = self._flags
163
+ for k in key[:-1]:
164
+ if k not in cont:
165
+ return
166
+ cont = cont[k]["nested"]
167
+ cont.pop(key[-1], None)
168
+
169
+ def set_for_relative_key(self, head_key: Key, rel_key: Key, flag: int) -> None:
170
+ cont = self._flags
171
+ for k in head_key:
172
+ if k not in cont:
173
+ cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}}
174
+ cont = cont[k]["nested"]
175
+ for k in rel_key:
176
+ if k in cont:
177
+ cont[k]["flags"].add(flag)
178
+ else:
179
+ cont[k] = {"flags": {flag}, "recursive_flags": set(), "nested": {}}
180
+ cont = cont[k]["nested"]
181
+
182
+ def set(self, key: Key, flag: int, *, recursive: bool) -> None: # noqa: A003
183
+ cont = self._flags
184
+ key_parent, key_stem = key[:-1], key[-1]
185
+ for k in key_parent:
186
+ if k not in cont:
187
+ cont[k] = {"flags": set(), "recursive_flags": set(), "nested": {}}
188
+ cont = cont[k]["nested"]
189
+ if key_stem not in cont:
190
+ cont[key_stem] = {"flags": set(), "recursive_flags": set(), "nested": {}}
191
+ cont[key_stem]["recursive_flags" if recursive else "flags"].add(flag)
192
+
193
+ def is_(self, key: Key, flag: int) -> bool:
194
+ if not key:
195
+ return False # document root has no flags
196
+ cont = self._flags
197
+ for k in key[:-1]:
198
+ if k not in cont:
199
+ return False
200
+ inner_cont = cont[k]
201
+ if flag in inner_cont["recursive_flags"]:
202
+ return True
203
+ cont = inner_cont["nested"]
204
+ key_stem = key[-1]
205
+ if key_stem in cont:
206
+ cont = cont[key_stem]
207
+ return flag in cont["flags"] or flag in cont["recursive_flags"]
208
+ return False
209
+
210
+
211
+ class NestedDict:
212
+ def __init__(self) -> None:
213
+ # The parsed content of the TOML document
214
+ self.dict: Dict[str, Any] = {}
215
+
216
+ def get_or_create_nest(
217
+ self,
218
+ key: Key,
219
+ *,
220
+ access_lists: bool = True,
221
+ ) -> dict:
222
+ cont: Any = self.dict
223
+ for k in key:
224
+ if k not in cont:
225
+ cont[k] = {}
226
+ cont = cont[k]
227
+ if access_lists and isinstance(cont, list):
228
+ cont = cont[-1]
229
+ if not isinstance(cont, dict):
230
+ raise KeyError("There is no nest behind this key")
231
+ return cont
232
+
233
+ def append_nest_to_list(self, key: Key) -> None:
234
+ cont = self.get_or_create_nest(key[:-1])
235
+ last_key = key[-1]
236
+ if last_key in cont:
237
+ list_ = cont[last_key]
238
+ if not isinstance(list_, list):
239
+ raise KeyError("An object other than list found behind this key")
240
+ list_.append({})
241
+ else:
242
+ cont[last_key] = [{}]
243
+
244
+
245
+ def skip_chars(src: str, pos: Pos, chars: Iterable[str]) -> Pos:
246
+ try:
247
+ while src[pos] in chars:
248
+ pos += 1
249
+ except IndexError:
250
+ pass
251
+ return pos
252
+
253
+
254
+ def skip_until(
255
+ src: str,
256
+ pos: Pos,
257
+ expect: str,
258
+ *,
259
+ error_on: FrozenSet[str],
260
+ error_on_eof: bool,
261
+ ) -> Pos:
262
+ try:
263
+ new_pos = src.index(expect, pos)
264
+ except ValueError:
265
+ new_pos = len(src)
266
+ if error_on_eof:
267
+ raise suffixed_err(src, new_pos, f'Expected "{expect!r}"')
268
+
269
+ bad_chars = error_on.intersection(src[pos:new_pos])
270
+ if bad_chars:
271
+ bad_char = next(iter(bad_chars))
272
+ bad_pos = src.index(bad_char, pos)
273
+ raise suffixed_err(src, bad_pos, f'Found invalid character "{bad_char!r}"')
274
+ return new_pos
275
+
276
+
277
+ def skip_comment(src: str, pos: Pos) -> Pos:
278
+ try:
279
+ char: Optional[str] = src[pos]
280
+ except IndexError:
281
+ char = None
282
+ if char == "#":
283
+ return skip_until(
284
+ src, pos + 1, "\n", error_on=ILLEGAL_COMMENT_CHARS, error_on_eof=False
285
+ )
286
+ return pos
287
+
288
+
289
+ def skip_comments_and_array_ws(src: str, pos: Pos) -> Pos:
290
+ while True:
291
+ pos_before_skip = pos
292
+ pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE)
293
+ pos = skip_comment(src, pos)
294
+ if pos == pos_before_skip:
295
+ return pos
296
+
297
+
298
+ def create_dict_rule(src: str, pos: Pos, state: State) -> Pos:
299
+ pos += 1 # Skip "["
300
+ pos = skip_chars(src, pos, TOML_WS)
301
+ pos, key = parse_key(src, pos)
302
+
303
+ if state.flags.is_(key, Flags.EXPLICIT_NEST) or state.flags.is_(key, Flags.FROZEN):
304
+ raise suffixed_err(src, pos, f"Can not declare {key} twice")
305
+ state.flags.set(key, Flags.EXPLICIT_NEST, recursive=False)
306
+ try:
307
+ state.out.get_or_create_nest(key)
308
+ except KeyError:
309
+ raise suffixed_err(src, pos, "Can not overwrite a value")
310
+ state.header_namespace = key
311
+
312
+ if src[pos : pos + 1] != "]":
313
+ raise suffixed_err(src, pos, 'Expected "]" at the end of a table declaration')
314
+ return pos + 1
315
+
316
+
317
+ def create_list_rule(src: str, pos: Pos, state: State) -> Pos:
318
+ pos += 2 # Skip "[["
319
+ pos = skip_chars(src, pos, TOML_WS)
320
+ pos, key = parse_key(src, pos)
321
+
322
+ if state.flags.is_(key, Flags.FROZEN):
323
+ raise suffixed_err(src, pos, f"Can not mutate immutable namespace {key}")
324
+ # Free the namespace now that it points to another empty list item...
325
+ state.flags.unset_all(key)
326
+ # ...but this key precisely is still prohibited from table declaration
327
+ state.flags.set(key, Flags.EXPLICIT_NEST, recursive=False)
328
+ try:
329
+ state.out.append_nest_to_list(key)
330
+ except KeyError:
331
+ raise suffixed_err(src, pos, "Can not overwrite a value")
332
+ state.header_namespace = key
333
+
334
+ end_marker = src[pos : pos + 2]
335
+ if end_marker != "]]":
336
+ raise suffixed_err(
337
+ src,
338
+ pos,
339
+ f'Found "{end_marker!r}" at the end of an array declaration.'
340
+ ' Expected "]]"',
341
+ )
342
+ return pos + 2
343
+
344
+
345
+ def key_value_rule(src: str, pos: Pos, state: State, parse_float: ParseFloat) -> Pos:
346
+ pos, key, value = parse_key_value_pair(src, pos, parse_float)
347
+ key_parent, key_stem = key[:-1], key[-1]
348
+ abs_key_parent = state.header_namespace + key_parent
349
+
350
+ if state.flags.is_(abs_key_parent, Flags.FROZEN):
351
+ raise suffixed_err(
352
+ src, pos, f"Can not mutate immutable namespace {abs_key_parent}"
353
+ )
354
+ # Containers in the relative path can't be opened with the table syntax after this
355
+ state.flags.set_for_relative_key(state.header_namespace, key, Flags.EXPLICIT_NEST)
356
+ try:
357
+ nest = state.out.get_or_create_nest(abs_key_parent)
358
+ except KeyError:
359
+ raise suffixed_err(src, pos, "Can not overwrite a value")
360
+ if key_stem in nest:
361
+ raise suffixed_err(src, pos, "Can not overwrite a value")
362
+ # Mark inline table and array namespaces recursively immutable
363
+ if isinstance(value, (dict, list)):
364
+ abs_key = state.header_namespace + key
365
+ state.flags.set(abs_key, Flags.FROZEN, recursive=True)
366
+ nest[key_stem] = value
367
+ return pos
368
+
369
+
370
+ def parse_key_value_pair(
371
+ src: str, pos: Pos, parse_float: ParseFloat
372
+ ) -> Tuple[Pos, Key, Any]:
373
+ pos, key = parse_key(src, pos)
374
+ try:
375
+ char: Optional[str] = src[pos]
376
+ except IndexError:
377
+ char = None
378
+ if char != "=":
379
+ raise suffixed_err(src, pos, 'Expected "=" after a key in a key/value pair')
380
+ pos += 1
381
+ pos = skip_chars(src, pos, TOML_WS)
382
+ pos, value = parse_value(src, pos, parse_float)
383
+ return pos, key, value
384
+
385
+
386
+ def parse_key(src: str, pos: Pos) -> Tuple[Pos, Key]:
387
+ pos, key_part = parse_key_part(src, pos)
388
+ key = [key_part]
389
+ pos = skip_chars(src, pos, TOML_WS)
390
+ while True:
391
+ try:
392
+ char: Optional[str] = src[pos]
393
+ except IndexError:
394
+ char = None
395
+ if char != ".":
396
+ return pos, tuple(key)
397
+ pos += 1
398
+ pos = skip_chars(src, pos, TOML_WS)
399
+ pos, key_part = parse_key_part(src, pos)
400
+ key.append(key_part)
401
+ pos = skip_chars(src, pos, TOML_WS)
402
+
403
+
404
+ def parse_key_part(src: str, pos: Pos) -> Tuple[Pos, str]:
405
+ try:
406
+ char: Optional[str] = src[pos]
407
+ except IndexError:
408
+ char = None
409
+ if char in BARE_KEY_CHARS:
410
+ start_pos = pos
411
+ pos = skip_chars(src, pos, BARE_KEY_CHARS)
412
+ return pos, src[start_pos:pos]
413
+ if char == "'":
414
+ return parse_literal_str(src, pos)
415
+ if char == '"':
416
+ return parse_one_line_basic_str(src, pos)
417
+ raise suffixed_err(src, pos, "Invalid initial character for a key part")
418
+
419
+
420
+ def parse_one_line_basic_str(src: str, pos: Pos) -> Tuple[Pos, str]:
421
+ pos += 1
422
+ return parse_basic_str(src, pos, multiline=False)
423
+
424
+
425
+ def parse_array(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, list]:
426
+ pos += 1
427
+ array: list = []
428
+
429
+ pos = skip_comments_and_array_ws(src, pos)
430
+ if src[pos : pos + 1] == "]":
431
+ return pos + 1, array
432
+ while True:
433
+ pos, val = parse_value(src, pos, parse_float)
434
+ array.append(val)
435
+ pos = skip_comments_and_array_ws(src, pos)
436
+
437
+ c = src[pos : pos + 1]
438
+ if c == "]":
439
+ return pos + 1, array
440
+ if c != ",":
441
+ raise suffixed_err(src, pos, "Unclosed array")
442
+ pos += 1
443
+
444
+ pos = skip_comments_and_array_ws(src, pos)
445
+ if src[pos : pos + 1] == "]":
446
+ return pos + 1, array
447
+
448
+
449
+ def parse_inline_table(src: str, pos: Pos, parse_float: ParseFloat) -> Tuple[Pos, dict]:
450
+ pos += 1
451
+ nested_dict = NestedDict()
452
+ flags = Flags()
453
+
454
+ pos = skip_chars(src, pos, TOML_WS)
455
+ if src[pos : pos + 1] == "}":
456
+ return pos + 1, nested_dict.dict
457
+ while True:
458
+ pos, key, value = parse_key_value_pair(src, pos, parse_float)
459
+ key_parent, key_stem = key[:-1], key[-1]
460
+ if flags.is_(key, Flags.FROZEN):
461
+ raise suffixed_err(src, pos, f"Can not mutate immutable namespace {key}")
462
+ try:
463
+ nest = nested_dict.get_or_create_nest(key_parent, access_lists=False)
464
+ except KeyError:
465
+ raise suffixed_err(src, pos, "Can not overwrite a value")
466
+ if key_stem in nest:
467
+ raise suffixed_err(src, pos, f'Duplicate inline table key "{key_stem}"')
468
+ nest[key_stem] = value
469
+ pos = skip_chars(src, pos, TOML_WS)
470
+ c = src[pos : pos + 1]
471
+ if c == "}":
472
+ return pos + 1, nested_dict.dict
473
+ if c != ",":
474
+ raise suffixed_err(src, pos, "Unclosed inline table")
475
+ if isinstance(value, (dict, list)):
476
+ flags.set(key, Flags.FROZEN, recursive=True)
477
+ pos += 1
478
+ pos = skip_chars(src, pos, TOML_WS)
479
+
480
+
481
+ def parse_basic_str_escape(
482
+ src: str, pos: Pos, *, multiline: bool = False
483
+ ) -> Tuple[Pos, str]:
484
+ escape_id = src[pos : pos + 2]
485
+ pos += 2
486
+ if multiline and escape_id in {"\\ ", "\\\t", "\\\n"}:
487
+ # Skip whitespace until next non-whitespace character or end of
488
+ # the doc. Error if non-whitespace is found before newline.
489
+ if escape_id != "\\\n":
490
+ pos = skip_chars(src, pos, TOML_WS)
491
+ char = src[pos : pos + 1]
492
+ if not char:
493
+ return pos, ""
494
+ if char != "\n":
495
+ raise suffixed_err(src, pos, 'Unescaped "\\" in a string')
496
+ pos += 1
497
+ pos = skip_chars(src, pos, TOML_WS_AND_NEWLINE)
498
+ return pos, ""
499
+ if escape_id == "\\u":
500
+ return parse_hex_char(src, pos, 4)
501
+ if escape_id == "\\U":
502
+ return parse_hex_char(src, pos, 8)
503
+ try:
504
+ return pos, BASIC_STR_ESCAPE_REPLACEMENTS[escape_id]
505
+ except KeyError:
506
+ if len(escape_id) != 2:
507
+ raise suffixed_err(src, pos, "Unterminated string")
508
+ raise suffixed_err(src, pos, 'Unescaped "\\" in a string')
509
+
510
+
511
+ def parse_basic_str_escape_multiline(src: str, pos: Pos) -> Tuple[Pos, str]:
512
+ return parse_basic_str_escape(src, pos, multiline=True)
513
+
514
+
515
+ def parse_hex_char(src: str, pos: Pos, hex_len: int) -> Tuple[Pos, str]:
516
+ hex_str = src[pos : pos + hex_len]
517
+ if len(hex_str) != hex_len or any(c not in string.hexdigits for c in hex_str):
518
+ raise suffixed_err(src, pos, "Invalid hex value")
519
+ pos += hex_len
520
+ hex_int = int(hex_str, 16)
521
+ if not is_unicode_scalar_value(hex_int):
522
+ raise suffixed_err(src, pos, "Escaped character is not a Unicode scalar value")
523
+ return pos, chr(hex_int)
524
+
525
+
526
+ def parse_literal_str(src: str, pos: Pos) -> Tuple[Pos, str]:
527
+ pos += 1 # Skip starting apostrophe
528
+ start_pos = pos
529
+ pos = skip_until(
530
+ src, pos, "'", error_on=ILLEGAL_LITERAL_STR_CHARS, error_on_eof=True
531
+ )
532
+ return pos + 1, src[start_pos:pos] # Skip ending apostrophe
533
+
534
+
535
+ def parse_multiline_str(src: str, pos: Pos, *, literal: bool) -> Tuple[Pos, str]:
536
+ pos += 3
537
+ if src[pos : pos + 1] == "\n":
538
+ pos += 1
539
+
540
+ if literal:
541
+ delim = "'"
542
+ end_pos = skip_until(
543
+ src,
544
+ pos,
545
+ "'''",
546
+ error_on=ILLEGAL_MULTILINE_LITERAL_STR_CHARS,
547
+ error_on_eof=True,
548
+ )
549
+ result = src[pos:end_pos]
550
+ pos = end_pos + 3
551
+ else:
552
+ delim = '"'
553
+ pos, result = parse_basic_str(src, pos, multiline=True)
554
+
555
+ # Add at maximum two extra apostrophes/quotes if the end sequence
556
+ # is 4 or 5 chars long instead of just 3.
557
+ if src[pos : pos + 1] != delim:
558
+ return pos, result
559
+ pos += 1
560
+ if src[pos : pos + 1] != delim:
561
+ return pos, result + delim
562
+ pos += 1
563
+ return pos, result + (delim * 2)
564
+
565
+
566
+ def parse_basic_str(src: str, pos: Pos, *, multiline: bool) -> Tuple[Pos, str]:
567
+ if multiline:
568
+ error_on = ILLEGAL_MULTILINE_BASIC_STR_CHARS
569
+ parse_escapes = parse_basic_str_escape_multiline
570
+ else:
571
+ error_on = ILLEGAL_BASIC_STR_CHARS
572
+ parse_escapes = parse_basic_str_escape
573
+ result = ""
574
+ start_pos = pos
575
+ while True:
576
+ try:
577
+ char = src[pos]
578
+ except IndexError:
579
+ raise suffixed_err(src, pos, "Unterminated string")
580
+ if char == '"':
581
+ if not multiline:
582
+ return pos + 1, result + src[start_pos:pos]
583
+ if src[pos + 1 : pos + 3] == '""':
584
+ return pos + 3, result + src[start_pos:pos]
585
+ pos += 1
586
+ continue
587
+ if char == "\\":
588
+ result += src[start_pos:pos]
589
+ pos, parsed_escape = parse_escapes(src, pos)
590
+ result += parsed_escape
591
+ start_pos = pos
592
+ continue
593
+ if char in error_on:
594
+ raise suffixed_err(src, pos, f'Illegal character "{char!r}"')
595
+ pos += 1
596
+
597
+
598
+ def parse_regex(src: str, pos: Pos, regex: "Pattern") -> Tuple[Pos, str]:
599
+ match = regex.match(src, pos)
600
+ if not match:
601
+ raise suffixed_err(src, pos, "Unexpected sequence")
602
+ return match.end(), match.group()
603
+
604
+
605
+ def parse_value( # noqa: C901
606
+ src: str, pos: Pos, parse_float: ParseFloat
607
+ ) -> Tuple[Pos, Any]:
608
+ try:
609
+ char: Optional[str] = src[pos]
610
+ except IndexError:
611
+ char = None
612
+
613
+ # Basic strings
614
+ if char == '"':
615
+ if src[pos + 1 : pos + 3] == '""':
616
+ return parse_multiline_str(src, pos, literal=False)
617
+ return parse_one_line_basic_str(src, pos)
618
+
619
+ # Literal strings
620
+ if char == "'":
621
+ if src[pos + 1 : pos + 3] == "''":
622
+ return parse_multiline_str(src, pos, literal=True)
623
+ return parse_literal_str(src, pos)
624
+
625
+ # Booleans
626
+ if char == "t":
627
+ if src[pos + 1 : pos + 4] == "rue":
628
+ return pos + 4, True
629
+ if char == "f":
630
+ if src[pos + 1 : pos + 5] == "alse":
631
+ return pos + 5, False
632
+
633
+ # Dates and times
634
+ datetime_match = RE_DATETIME.match(src, pos)
635
+ if datetime_match:
636
+ try:
637
+ datetime_obj = match_to_datetime(datetime_match)
638
+ except ValueError:
639
+ raise suffixed_err(src, pos, "Invalid date or datetime")
640
+ return datetime_match.end(), datetime_obj
641
+ localtime_match = RE_LOCALTIME.match(src, pos)
642
+ if localtime_match:
643
+ return localtime_match.end(), match_to_localtime(localtime_match)
644
+
645
+ # Non-decimal integers
646
+ if char == "0":
647
+ second_char = src[pos + 1 : pos + 2]
648
+ if second_char == "x":
649
+ pos, hex_str = parse_regex(src, pos + 2, RE_HEX)
650
+ return pos, int(hex_str, 16)
651
+ if second_char == "o":
652
+ pos, oct_str = parse_regex(src, pos + 2, RE_OCT)
653
+ return pos, int(oct_str, 8)
654
+ if second_char == "b":
655
+ pos, bin_str = parse_regex(src, pos + 2, RE_BIN)
656
+ return pos, int(bin_str, 2)
657
+
658
+ # Decimal integers and "normal" floats.
659
+ # The regex will greedily match any type starting with a decimal
660
+ # char, so needs to be located after handling of non-decimal ints,
661
+ # and dates and times.
662
+ number_match = RE_NUMBER.match(src, pos)
663
+ if number_match:
664
+ return number_match.end(), match_to_number(number_match, parse_float)
665
+
666
+ # Arrays
667
+ if char == "[":
668
+ return parse_array(src, pos, parse_float)
669
+
670
+ # Inline tables
671
+ if char == "{":
672
+ return parse_inline_table(src, pos, parse_float)
673
+
674
+ # Special floats
675
+ first_three = src[pos : pos + 3]
676
+ if first_three in {"inf", "nan"}:
677
+ return pos + 3, parse_float(first_three)
678
+ first_four = src[pos : pos + 4]
679
+ if first_four in {"-inf", "+inf", "-nan", "+nan"}:
680
+ return pos + 4, parse_float(first_four)
681
+
682
+ raise suffixed_err(src, pos, "Invalid value")
683
+
684
+
685
+ def suffixed_err(src: str, pos: Pos, msg: str) -> TOMLDecodeError:
686
+ """Return a `TOMLDecodeError` where error message is suffixed with
687
+ coordinates in source."""
688
+
689
+ def coord_repr(src: str, pos: Pos) -> str:
690
+ if pos >= len(src):
691
+ return "end of document"
692
+ line = src.count("\n", 0, pos) + 1
693
+ if line == 1:
694
+ column = pos + 1
695
+ else:
696
+ column = pos - src.rindex("\n", 0, pos)
697
+ return f"line {line}, column {column}"
698
+
699
+ return TOMLDecodeError(f"{msg} (at {coord_repr(src, pos)})")
700
+
701
+
702
+ def is_unicode_scalar_value(codepoint: int) -> bool:
703
+ return (0 <= codepoint <= 55295) or (57344 <= codepoint <= 1114111)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/tomli/_re.py ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import date, datetime, time, timedelta, timezone, tzinfo
2
+ import re
3
+ from typing import TYPE_CHECKING, Any, Optional, Union
4
+
5
+ if TYPE_CHECKING:
6
+ from re import Match
7
+
8
+ from pip._vendor.tomli._parser import ParseFloat
9
+
10
+ # E.g.
11
+ # - 00:32:00.999999
12
+ # - 00:32:00
13
+ _TIME_RE_STR = r"([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?"
14
+
15
+ RE_HEX = re.compile(r"[0-9A-Fa-f](?:_?[0-9A-Fa-f])*")
16
+ RE_BIN = re.compile(r"[01](?:_?[01])*")
17
+ RE_OCT = re.compile(r"[0-7](?:_?[0-7])*")
18
+ RE_NUMBER = re.compile(
19
+ r"[+-]?(?:0|[1-9](?:_?[0-9])*)" # integer
20
+ + r"(?:\.[0-9](?:_?[0-9])*)?" # optional fractional part
21
+ + r"(?:[eE][+-]?[0-9](?:_?[0-9])*)?" # optional exponent part
22
+ )
23
+ RE_LOCALTIME = re.compile(_TIME_RE_STR)
24
+ RE_DATETIME = re.compile(
25
+ r"([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|1[0-9]|2[0-9]|3[01])" # date, e.g. 1988-10-27
26
+ + r"(?:"
27
+ + r"[T ]"
28
+ + _TIME_RE_STR
29
+ + r"(?:(Z)|([+-])([01][0-9]|2[0-3]):([0-5][0-9]))?" # time offset
30
+ + r")?"
31
+ )
32
+
33
+
34
+ def match_to_datetime(match: "Match") -> Union[datetime, date]:
35
+ """Convert a `RE_DATETIME` match to `datetime.datetime` or `datetime.date`.
36
+
37
+ Raises ValueError if the match does not correspond to a valid date
38
+ or datetime.
39
+ """
40
+ (
41
+ year_str,
42
+ month_str,
43
+ day_str,
44
+ hour_str,
45
+ minute_str,
46
+ sec_str,
47
+ micros_str,
48
+ zulu_time,
49
+ offset_dir_str,
50
+ offset_hour_str,
51
+ offset_minute_str,
52
+ ) = match.groups()
53
+ year, month, day = int(year_str), int(month_str), int(day_str)
54
+ if hour_str is None:
55
+ return date(year, month, day)
56
+ hour, minute, sec = int(hour_str), int(minute_str), int(sec_str)
57
+ micros = int(micros_str[1:].ljust(6, "0")[:6]) if micros_str else 0
58
+ if offset_dir_str:
59
+ offset_dir = 1 if offset_dir_str == "+" else -1
60
+ tz: Optional[tzinfo] = timezone(
61
+ timedelta(
62
+ hours=offset_dir * int(offset_hour_str),
63
+ minutes=offset_dir * int(offset_minute_str),
64
+ )
65
+ )
66
+ elif zulu_time:
67
+ tz = timezone.utc
68
+ else: # local date-time
69
+ tz = None
70
+ return datetime(year, month, day, hour, minute, sec, micros, tzinfo=tz)
71
+
72
+
73
+ def match_to_localtime(match: "Match") -> time:
74
+ hour_str, minute_str, sec_str, micros_str = match.groups()
75
+ micros = int(micros_str[1:].ljust(6, "0")[:6]) if micros_str else 0
76
+ return time(int(hour_str), int(minute_str), int(sec_str), micros)
77
+
78
+
79
+ def match_to_number(match: "Match", parse_float: "ParseFloat") -> Any:
80
+ match_str = match.group()
81
+ if "." in match_str or "e" in match_str or "E" in match_str:
82
+ return parse_float(match_str)
83
+ return int(match_str)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/__init__.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Python HTTP library with thread-safe connection pooling, file post support, user friendly, and more
3
+ """
4
+ from __future__ import absolute_import
5
+
6
+ # Set default logging handler to avoid "No handler found" warnings.
7
+ import logging
8
+ import warnings
9
+ from logging import NullHandler
10
+
11
+ from . import exceptions
12
+ from ._version import __version__
13
+ from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, connection_from_url
14
+ from .filepost import encode_multipart_formdata
15
+ from .poolmanager import PoolManager, ProxyManager, proxy_from_url
16
+ from .response import HTTPResponse
17
+ from .util.request import make_headers
18
+ from .util.retry import Retry
19
+ from .util.timeout import Timeout
20
+ from .util.url import get_host
21
+
22
+ __author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
23
+ __license__ = "MIT"
24
+ __version__ = __version__
25
+
26
+ __all__ = (
27
+ "HTTPConnectionPool",
28
+ "HTTPSConnectionPool",
29
+ "PoolManager",
30
+ "ProxyManager",
31
+ "HTTPResponse",
32
+ "Retry",
33
+ "Timeout",
34
+ "add_stderr_logger",
35
+ "connection_from_url",
36
+ "disable_warnings",
37
+ "encode_multipart_formdata",
38
+ "get_host",
39
+ "make_headers",
40
+ "proxy_from_url",
41
+ )
42
+
43
+ logging.getLogger(__name__).addHandler(NullHandler())
44
+
45
+
46
+ def add_stderr_logger(level=logging.DEBUG):
47
+ """
48
+ Helper for quickly adding a StreamHandler to the logger. Useful for
49
+ debugging.
50
+
51
+ Returns the handler after adding it.
52
+ """
53
+ # This method needs to be in this __init__.py to get the __name__ correct
54
+ # even if urllib3 is vendored within another package.
55
+ logger = logging.getLogger(__name__)
56
+ handler = logging.StreamHandler()
57
+ handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
58
+ logger.addHandler(handler)
59
+ logger.setLevel(level)
60
+ logger.debug("Added a stderr logging handler to logger: %s", __name__)
61
+ return handler
62
+
63
+
64
+ # ... Clean up.
65
+ del NullHandler
66
+
67
+
68
+ # All warning filters *must* be appended unless you're really certain that they
69
+ # shouldn't be: otherwise, it's very hard for users to use most Python
70
+ # mechanisms to silence them.
71
+ # SecurityWarning's always go off by default.
72
+ warnings.simplefilter("always", exceptions.SecurityWarning, append=True)
73
+ # SubjectAltNameWarning's should go off once per host
74
+ warnings.simplefilter("default", exceptions.SubjectAltNameWarning, append=True)
75
+ # InsecurePlatformWarning's don't vary between requests, so we keep it default.
76
+ warnings.simplefilter("default", exceptions.InsecurePlatformWarning, append=True)
77
+ # SNIMissingWarnings should go off only once.
78
+ warnings.simplefilter("default", exceptions.SNIMissingWarning, append=True)
79
+
80
+
81
+ def disable_warnings(category=exceptions.HTTPWarning):
82
+ """
83
+ Helper for quickly disabling all urllib3 warnings.
84
+ """
85
+ warnings.simplefilter("ignore", category)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/_collections.py ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ try:
4
+ from collections.abc import Mapping, MutableMapping
5
+ except ImportError:
6
+ from collections import Mapping, MutableMapping
7
+ try:
8
+ from threading import RLock
9
+ except ImportError: # Platform-specific: No threads available
10
+
11
+ class RLock:
12
+ def __enter__(self):
13
+ pass
14
+
15
+ def __exit__(self, exc_type, exc_value, traceback):
16
+ pass
17
+
18
+
19
+ from collections import OrderedDict
20
+
21
+ from .exceptions import InvalidHeader
22
+ from .packages import six
23
+ from .packages.six import iterkeys, itervalues
24
+
25
+ __all__ = ["RecentlyUsedContainer", "HTTPHeaderDict"]
26
+
27
+
28
+ _Null = object()
29
+
30
+
31
+ class RecentlyUsedContainer(MutableMapping):
32
+ """
33
+ Provides a thread-safe dict-like container which maintains up to
34
+ ``maxsize`` keys while throwing away the least-recently-used keys beyond
35
+ ``maxsize``.
36
+
37
+ :param maxsize:
38
+ Maximum number of recent elements to retain.
39
+
40
+ :param dispose_func:
41
+ Every time an item is evicted from the container,
42
+ ``dispose_func(value)`` is called. Callback which will get called
43
+ """
44
+
45
+ ContainerCls = OrderedDict
46
+
47
+ def __init__(self, maxsize=10, dispose_func=None):
48
+ self._maxsize = maxsize
49
+ self.dispose_func = dispose_func
50
+
51
+ self._container = self.ContainerCls()
52
+ self.lock = RLock()
53
+
54
+ def __getitem__(self, key):
55
+ # Re-insert the item, moving it to the end of the eviction line.
56
+ with self.lock:
57
+ item = self._container.pop(key)
58
+ self._container[key] = item
59
+ return item
60
+
61
+ def __setitem__(self, key, value):
62
+ evicted_value = _Null
63
+ with self.lock:
64
+ # Possibly evict the existing value of 'key'
65
+ evicted_value = self._container.get(key, _Null)
66
+ self._container[key] = value
67
+
68
+ # If we didn't evict an existing value, we might have to evict the
69
+ # least recently used item from the beginning of the container.
70
+ if len(self._container) > self._maxsize:
71
+ _key, evicted_value = self._container.popitem(last=False)
72
+
73
+ if self.dispose_func and evicted_value is not _Null:
74
+ self.dispose_func(evicted_value)
75
+
76
+ def __delitem__(self, key):
77
+ with self.lock:
78
+ value = self._container.pop(key)
79
+
80
+ if self.dispose_func:
81
+ self.dispose_func(value)
82
+
83
+ def __len__(self):
84
+ with self.lock:
85
+ return len(self._container)
86
+
87
+ def __iter__(self):
88
+ raise NotImplementedError(
89
+ "Iteration over this class is unlikely to be threadsafe."
90
+ )
91
+
92
+ def clear(self):
93
+ with self.lock:
94
+ # Copy pointers to all values, then wipe the mapping
95
+ values = list(itervalues(self._container))
96
+ self._container.clear()
97
+
98
+ if self.dispose_func:
99
+ for value in values:
100
+ self.dispose_func(value)
101
+
102
+ def keys(self):
103
+ with self.lock:
104
+ return list(iterkeys(self._container))
105
+
106
+
107
+ class HTTPHeaderDict(MutableMapping):
108
+ """
109
+ :param headers:
110
+ An iterable of field-value pairs. Must not contain multiple field names
111
+ when compared case-insensitively.
112
+
113
+ :param kwargs:
114
+ Additional field-value pairs to pass in to ``dict.update``.
115
+
116
+ A ``dict`` like container for storing HTTP Headers.
117
+
118
+ Field names are stored and compared case-insensitively in compliance with
119
+ RFC 7230. Iteration provides the first case-sensitive key seen for each
120
+ case-insensitive pair.
121
+
122
+ Using ``__setitem__`` syntax overwrites fields that compare equal
123
+ case-insensitively in order to maintain ``dict``'s api. For fields that
124
+ compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add``
125
+ in a loop.
126
+
127
+ If multiple fields that are equal case-insensitively are passed to the
128
+ constructor or ``.update``, the behavior is undefined and some will be
129
+ lost.
130
+
131
+ >>> headers = HTTPHeaderDict()
132
+ >>> headers.add('Set-Cookie', 'foo=bar')
133
+ >>> headers.add('set-cookie', 'baz=quxx')
134
+ >>> headers['content-length'] = '7'
135
+ >>> headers['SET-cookie']
136
+ 'foo=bar, baz=quxx'
137
+ >>> headers['Content-Length']
138
+ '7'
139
+ """
140
+
141
+ def __init__(self, headers=None, **kwargs):
142
+ super(HTTPHeaderDict, self).__init__()
143
+ self._container = OrderedDict()
144
+ if headers is not None:
145
+ if isinstance(headers, HTTPHeaderDict):
146
+ self._copy_from(headers)
147
+ else:
148
+ self.extend(headers)
149
+ if kwargs:
150
+ self.extend(kwargs)
151
+
152
+ def __setitem__(self, key, val):
153
+ self._container[key.lower()] = [key, val]
154
+ return self._container[key.lower()]
155
+
156
+ def __getitem__(self, key):
157
+ val = self._container[key.lower()]
158
+ return ", ".join(val[1:])
159
+
160
+ def __delitem__(self, key):
161
+ del self._container[key.lower()]
162
+
163
+ def __contains__(self, key):
164
+ return key.lower() in self._container
165
+
166
+ def __eq__(self, other):
167
+ if not isinstance(other, Mapping) and not hasattr(other, "keys"):
168
+ return False
169
+ if not isinstance(other, type(self)):
170
+ other = type(self)(other)
171
+ return dict((k.lower(), v) for k, v in self.itermerged()) == dict(
172
+ (k.lower(), v) for k, v in other.itermerged()
173
+ )
174
+
175
+ def __ne__(self, other):
176
+ return not self.__eq__(other)
177
+
178
+ if six.PY2: # Python 2
179
+ iterkeys = MutableMapping.iterkeys
180
+ itervalues = MutableMapping.itervalues
181
+
182
+ __marker = object()
183
+
184
+ def __len__(self):
185
+ return len(self._container)
186
+
187
+ def __iter__(self):
188
+ # Only provide the originally cased names
189
+ for vals in self._container.values():
190
+ yield vals[0]
191
+
192
+ def pop(self, key, default=__marker):
193
+ """D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
194
+ If key is not found, d is returned if given, otherwise KeyError is raised.
195
+ """
196
+ # Using the MutableMapping function directly fails due to the private marker.
197
+ # Using ordinary dict.pop would expose the internal structures.
198
+ # So let's reinvent the wheel.
199
+ try:
200
+ value = self[key]
201
+ except KeyError:
202
+ if default is self.__marker:
203
+ raise
204
+ return default
205
+ else:
206
+ del self[key]
207
+ return value
208
+
209
+ def discard(self, key):
210
+ try:
211
+ del self[key]
212
+ except KeyError:
213
+ pass
214
+
215
+ def add(self, key, val):
216
+ """Adds a (name, value) pair, doesn't overwrite the value if it already
217
+ exists.
218
+
219
+ >>> headers = HTTPHeaderDict(foo='bar')
220
+ >>> headers.add('Foo', 'baz')
221
+ >>> headers['foo']
222
+ 'bar, baz'
223
+ """
224
+ key_lower = key.lower()
225
+ new_vals = [key, val]
226
+ # Keep the common case aka no item present as fast as possible
227
+ vals = self._container.setdefault(key_lower, new_vals)
228
+ if new_vals is not vals:
229
+ vals.append(val)
230
+
231
+ def extend(self, *args, **kwargs):
232
+ """Generic import function for any type of header-like object.
233
+ Adapted version of MutableMapping.update in order to insert items
234
+ with self.add instead of self.__setitem__
235
+ """
236
+ if len(args) > 1:
237
+ raise TypeError(
238
+ "extend() takes at most 1 positional "
239
+ "arguments ({0} given)".format(len(args))
240
+ )
241
+ other = args[0] if len(args) >= 1 else ()
242
+
243
+ if isinstance(other, HTTPHeaderDict):
244
+ for key, val in other.iteritems():
245
+ self.add(key, val)
246
+ elif isinstance(other, Mapping):
247
+ for key in other:
248
+ self.add(key, other[key])
249
+ elif hasattr(other, "keys"):
250
+ for key in other.keys():
251
+ self.add(key, other[key])
252
+ else:
253
+ for key, value in other:
254
+ self.add(key, value)
255
+
256
+ for key, value in kwargs.items():
257
+ self.add(key, value)
258
+
259
+ def getlist(self, key, default=__marker):
260
+ """Returns a list of all the values for the named field. Returns an
261
+ empty list if the key doesn't exist."""
262
+ try:
263
+ vals = self._container[key.lower()]
264
+ except KeyError:
265
+ if default is self.__marker:
266
+ return []
267
+ return default
268
+ else:
269
+ return vals[1:]
270
+
271
+ # Backwards compatibility for httplib
272
+ getheaders = getlist
273
+ getallmatchingheaders = getlist
274
+ iget = getlist
275
+
276
+ # Backwards compatibility for http.cookiejar
277
+ get_all = getlist
278
+
279
+ def __repr__(self):
280
+ return "%s(%s)" % (type(self).__name__, dict(self.itermerged()))
281
+
282
+ def _copy_from(self, other):
283
+ for key in other:
284
+ val = other.getlist(key)
285
+ if isinstance(val, list):
286
+ # Don't need to convert tuples
287
+ val = list(val)
288
+ self._container[key.lower()] = [key] + val
289
+
290
+ def copy(self):
291
+ clone = type(self)()
292
+ clone._copy_from(self)
293
+ return clone
294
+
295
+ def iteritems(self):
296
+ """Iterate over all header lines, including duplicate ones."""
297
+ for key in self:
298
+ vals = self._container[key.lower()]
299
+ for val in vals[1:]:
300
+ yield vals[0], val
301
+
302
+ def itermerged(self):
303
+ """Iterate over all headers, merging duplicate ones together."""
304
+ for key in self:
305
+ val = self._container[key.lower()]
306
+ yield val[0], ", ".join(val[1:])
307
+
308
+ def items(self):
309
+ return list(self.iteritems())
310
+
311
+ @classmethod
312
+ def from_httplib(cls, message): # Python 2
313
+ """Read headers from a Python 2 httplib message object."""
314
+ # python2.7 does not expose a proper API for exporting multiheaders
315
+ # efficiently. This function re-reads raw lines from the message
316
+ # object and extracts the multiheaders properly.
317
+ obs_fold_continued_leaders = (" ", "\t")
318
+ headers = []
319
+
320
+ for line in message.headers:
321
+ if line.startswith(obs_fold_continued_leaders):
322
+ if not headers:
323
+ # We received a header line that starts with OWS as described
324
+ # in RFC-7230 S3.2.4. This indicates a multiline header, but
325
+ # there exists no previous header to which we can attach it.
326
+ raise InvalidHeader(
327
+ "Header continuation with no previous header: %s" % line
328
+ )
329
+ else:
330
+ key, value = headers[-1]
331
+ headers[-1] = (key, value + " " + line.strip())
332
+ continue
333
+
334
+ key, value = line.split(":", 1)
335
+ headers.append((key, value.strip()))
336
+
337
+ return cls(headers)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/_version.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ # This file is protected via CODEOWNERS
2
+ __version__ = "1.26.6"
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/connection.py ADDED
@@ -0,0 +1,539 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import datetime
4
+ import logging
5
+ import os
6
+ import re
7
+ import socket
8
+ import warnings
9
+ from socket import error as SocketError
10
+ from socket import timeout as SocketTimeout
11
+
12
+ from .packages import six
13
+ from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection
14
+ from .packages.six.moves.http_client import HTTPException # noqa: F401
15
+ from .util.proxy import create_proxy_ssl_context
16
+
17
+ try: # Compiled with SSL?
18
+ import ssl
19
+
20
+ BaseSSLError = ssl.SSLError
21
+ except (ImportError, AttributeError): # Platform-specific: No SSL.
22
+ ssl = None
23
+
24
+ class BaseSSLError(BaseException):
25
+ pass
26
+
27
+
28
+ try:
29
+ # Python 3: not a no-op, we're adding this to the namespace so it can be imported.
30
+ ConnectionError = ConnectionError
31
+ except NameError:
32
+ # Python 2
33
+ class ConnectionError(Exception):
34
+ pass
35
+
36
+
37
+ try: # Python 3:
38
+ # Not a no-op, we're adding this to the namespace so it can be imported.
39
+ BrokenPipeError = BrokenPipeError
40
+ except NameError: # Python 2:
41
+
42
+ class BrokenPipeError(Exception):
43
+ pass
44
+
45
+
46
+ from ._collections import HTTPHeaderDict # noqa (historical, removed in v2)
47
+ from ._version import __version__
48
+ from .exceptions import (
49
+ ConnectTimeoutError,
50
+ NewConnectionError,
51
+ SubjectAltNameWarning,
52
+ SystemTimeWarning,
53
+ )
54
+ from .packages.ssl_match_hostname import CertificateError, match_hostname
55
+ from .util import SKIP_HEADER, SKIPPABLE_HEADERS, connection
56
+ from .util.ssl_ import (
57
+ assert_fingerprint,
58
+ create_urllib3_context,
59
+ resolve_cert_reqs,
60
+ resolve_ssl_version,
61
+ ssl_wrap_socket,
62
+ )
63
+
64
+ log = logging.getLogger(__name__)
65
+
66
+ port_by_scheme = {"http": 80, "https": 443}
67
+
68
+ # When it comes time to update this value as a part of regular maintenance
69
+ # (ie test_recent_date is failing) update it to ~6 months before the current date.
70
+ RECENT_DATE = datetime.date(2020, 7, 1)
71
+
72
+ _CONTAINS_CONTROL_CHAR_RE = re.compile(r"[^-!#$%&'*+.^_`|~0-9a-zA-Z]")
73
+
74
+
75
+ class HTTPConnection(_HTTPConnection, object):
76
+ """
77
+ Based on :class:`http.client.HTTPConnection` but provides an extra constructor
78
+ backwards-compatibility layer between older and newer Pythons.
79
+
80
+ Additional keyword parameters are used to configure attributes of the connection.
81
+ Accepted parameters include:
82
+
83
+ - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool`
84
+ - ``source_address``: Set the source address for the current connection.
85
+ - ``socket_options``: Set specific options on the underlying socket. If not specified, then
86
+ defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling
87
+ Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy.
88
+
89
+ For example, if you wish to enable TCP Keep Alive in addition to the defaults,
90
+ you might pass:
91
+
92
+ .. code-block:: python
93
+
94
+ HTTPConnection.default_socket_options + [
95
+ (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),
96
+ ]
97
+
98
+ Or you may want to disable the defaults by passing an empty list (e.g., ``[]``).
99
+ """
100
+
101
+ default_port = port_by_scheme["http"]
102
+
103
+ #: Disable Nagle's algorithm by default.
104
+ #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]``
105
+ default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]
106
+
107
+ #: Whether this connection verifies the host's certificate.
108
+ is_verified = False
109
+
110
+ def __init__(self, *args, **kw):
111
+ if not six.PY2:
112
+ kw.pop("strict", None)
113
+
114
+ # Pre-set source_address.
115
+ self.source_address = kw.get("source_address")
116
+
117
+ #: The socket options provided by the user. If no options are
118
+ #: provided, we use the default options.
119
+ self.socket_options = kw.pop("socket_options", self.default_socket_options)
120
+
121
+ # Proxy options provided by the user.
122
+ self.proxy = kw.pop("proxy", None)
123
+ self.proxy_config = kw.pop("proxy_config", None)
124
+
125
+ _HTTPConnection.__init__(self, *args, **kw)
126
+
127
+ @property
128
+ def host(self):
129
+ """
130
+ Getter method to remove any trailing dots that indicate the hostname is an FQDN.
131
+
132
+ In general, SSL certificates don't include the trailing dot indicating a
133
+ fully-qualified domain name, and thus, they don't validate properly when
134
+ checked against a domain name that includes the dot. In addition, some
135
+ servers may not expect to receive the trailing dot when provided.
136
+
137
+ However, the hostname with trailing dot is critical to DNS resolution; doing a
138
+ lookup with the trailing dot will properly only resolve the appropriate FQDN,
139
+ whereas a lookup without a trailing dot will search the system's search domain
140
+ list. Thus, it's important to keep the original host around for use only in
141
+ those cases where it's appropriate (i.e., when doing DNS lookup to establish the
142
+ actual TCP connection across which we're going to send HTTP requests).
143
+ """
144
+ return self._dns_host.rstrip(".")
145
+
146
+ @host.setter
147
+ def host(self, value):
148
+ """
149
+ Setter for the `host` property.
150
+
151
+ We assume that only urllib3 uses the _dns_host attribute; httplib itself
152
+ only uses `host`, and it seems reasonable that other libraries follow suit.
153
+ """
154
+ self._dns_host = value
155
+
156
+ def _new_conn(self):
157
+ """Establish a socket connection and set nodelay settings on it.
158
+
159
+ :return: New socket connection.
160
+ """
161
+ extra_kw = {}
162
+ if self.source_address:
163
+ extra_kw["source_address"] = self.source_address
164
+
165
+ if self.socket_options:
166
+ extra_kw["socket_options"] = self.socket_options
167
+
168
+ try:
169
+ conn = connection.create_connection(
170
+ (self._dns_host, self.port), self.timeout, **extra_kw
171
+ )
172
+
173
+ except SocketTimeout:
174
+ raise ConnectTimeoutError(
175
+ self,
176
+ "Connection to %s timed out. (connect timeout=%s)"
177
+ % (self.host, self.timeout),
178
+ )
179
+
180
+ except SocketError as e:
181
+ raise NewConnectionError(
182
+ self, "Failed to establish a new connection: %s" % e
183
+ )
184
+
185
+ return conn
186
+
187
+ def _is_using_tunnel(self):
188
+ # Google App Engine's httplib does not define _tunnel_host
189
+ return getattr(self, "_tunnel_host", None)
190
+
191
+ def _prepare_conn(self, conn):
192
+ self.sock = conn
193
+ if self._is_using_tunnel():
194
+ # TODO: Fix tunnel so it doesn't depend on self.sock state.
195
+ self._tunnel()
196
+ # Mark this connection as not reusable
197
+ self.auto_open = 0
198
+
199
+ def connect(self):
200
+ conn = self._new_conn()
201
+ self._prepare_conn(conn)
202
+
203
+ def putrequest(self, method, url, *args, **kwargs):
204
+ """ """
205
+ # Empty docstring because the indentation of CPython's implementation
206
+ # is broken but we don't want this method in our documentation.
207
+ match = _CONTAINS_CONTROL_CHAR_RE.search(method)
208
+ if match:
209
+ raise ValueError(
210
+ "Method cannot contain non-token characters %r (found at least %r)"
211
+ % (method, match.group())
212
+ )
213
+
214
+ return _HTTPConnection.putrequest(self, method, url, *args, **kwargs)
215
+
216
+ def putheader(self, header, *values):
217
+ """ """
218
+ if not any(isinstance(v, str) and v == SKIP_HEADER for v in values):
219
+ _HTTPConnection.putheader(self, header, *values)
220
+ elif six.ensure_str(header.lower()) not in SKIPPABLE_HEADERS:
221
+ raise ValueError(
222
+ "urllib3.util.SKIP_HEADER only supports '%s'"
223
+ % ("', '".join(map(str.title, sorted(SKIPPABLE_HEADERS))),)
224
+ )
225
+
226
+ def request(self, method, url, body=None, headers=None):
227
+ if headers is None:
228
+ headers = {}
229
+ else:
230
+ # Avoid modifying the headers passed into .request()
231
+ headers = headers.copy()
232
+ if "user-agent" not in (six.ensure_str(k.lower()) for k in headers):
233
+ headers["User-Agent"] = _get_default_user_agent()
234
+ super(HTTPConnection, self).request(method, url, body=body, headers=headers)
235
+
236
+ def request_chunked(self, method, url, body=None, headers=None):
237
+ """
238
+ Alternative to the common request method, which sends the
239
+ body with chunked encoding and not as one block
240
+ """
241
+ headers = headers or {}
242
+ header_keys = set([six.ensure_str(k.lower()) for k in headers])
243
+ skip_accept_encoding = "accept-encoding" in header_keys
244
+ skip_host = "host" in header_keys
245
+ self.putrequest(
246
+ method, url, skip_accept_encoding=skip_accept_encoding, skip_host=skip_host
247
+ )
248
+ if "user-agent" not in header_keys:
249
+ self.putheader("User-Agent", _get_default_user_agent())
250
+ for header, value in headers.items():
251
+ self.putheader(header, value)
252
+ if "transfer-encoding" not in header_keys:
253
+ self.putheader("Transfer-Encoding", "chunked")
254
+ self.endheaders()
255
+
256
+ if body is not None:
257
+ stringish_types = six.string_types + (bytes,)
258
+ if isinstance(body, stringish_types):
259
+ body = (body,)
260
+ for chunk in body:
261
+ if not chunk:
262
+ continue
263
+ if not isinstance(chunk, bytes):
264
+ chunk = chunk.encode("utf8")
265
+ len_str = hex(len(chunk))[2:]
266
+ to_send = bytearray(len_str.encode())
267
+ to_send += b"\r\n"
268
+ to_send += chunk
269
+ to_send += b"\r\n"
270
+ self.send(to_send)
271
+
272
+ # After the if clause, to always have a closed body
273
+ self.send(b"0\r\n\r\n")
274
+
275
+
276
+ class HTTPSConnection(HTTPConnection):
277
+ """
278
+ Many of the parameters to this constructor are passed to the underlying SSL
279
+ socket by means of :py:func:`urllib3.util.ssl_wrap_socket`.
280
+ """
281
+
282
+ default_port = port_by_scheme["https"]
283
+
284
+ cert_reqs = None
285
+ ca_certs = None
286
+ ca_cert_dir = None
287
+ ca_cert_data = None
288
+ ssl_version = None
289
+ assert_fingerprint = None
290
+ tls_in_tls_required = False
291
+
292
+ def __init__(
293
+ self,
294
+ host,
295
+ port=None,
296
+ key_file=None,
297
+ cert_file=None,
298
+ key_password=None,
299
+ strict=None,
300
+ timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
301
+ ssl_context=None,
302
+ server_hostname=None,
303
+ **kw
304
+ ):
305
+
306
+ HTTPConnection.__init__(self, host, port, strict=strict, timeout=timeout, **kw)
307
+
308
+ self.key_file = key_file
309
+ self.cert_file = cert_file
310
+ self.key_password = key_password
311
+ self.ssl_context = ssl_context
312
+ self.server_hostname = server_hostname
313
+
314
+ # Required property for Google AppEngine 1.9.0 which otherwise causes
315
+ # HTTPS requests to go out as HTTP. (See Issue #356)
316
+ self._protocol = "https"
317
+
318
+ def set_cert(
319
+ self,
320
+ key_file=None,
321
+ cert_file=None,
322
+ cert_reqs=None,
323
+ key_password=None,
324
+ ca_certs=None,
325
+ assert_hostname=None,
326
+ assert_fingerprint=None,
327
+ ca_cert_dir=None,
328
+ ca_cert_data=None,
329
+ ):
330
+ """
331
+ This method should only be called once, before the connection is used.
332
+ """
333
+ # If cert_reqs is not provided we'll assume CERT_REQUIRED unless we also
334
+ # have an SSLContext object in which case we'll use its verify_mode.
335
+ if cert_reqs is None:
336
+ if self.ssl_context is not None:
337
+ cert_reqs = self.ssl_context.verify_mode
338
+ else:
339
+ cert_reqs = resolve_cert_reqs(None)
340
+
341
+ self.key_file = key_file
342
+ self.cert_file = cert_file
343
+ self.cert_reqs = cert_reqs
344
+ self.key_password = key_password
345
+ self.assert_hostname = assert_hostname
346
+ self.assert_fingerprint = assert_fingerprint
347
+ self.ca_certs = ca_certs and os.path.expanduser(ca_certs)
348
+ self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir)
349
+ self.ca_cert_data = ca_cert_data
350
+
351
+ def connect(self):
352
+ # Add certificate verification
353
+ conn = self._new_conn()
354
+ hostname = self.host
355
+ tls_in_tls = False
356
+
357
+ if self._is_using_tunnel():
358
+ if self.tls_in_tls_required:
359
+ conn = self._connect_tls_proxy(hostname, conn)
360
+ tls_in_tls = True
361
+
362
+ self.sock = conn
363
+
364
+ # Calls self._set_hostport(), so self.host is
365
+ # self._tunnel_host below.
366
+ self._tunnel()
367
+ # Mark this connection as not reusable
368
+ self.auto_open = 0
369
+
370
+ # Override the host with the one we're requesting data from.
371
+ hostname = self._tunnel_host
372
+
373
+ server_hostname = hostname
374
+ if self.server_hostname is not None:
375
+ server_hostname = self.server_hostname
376
+
377
+ is_time_off = datetime.date.today() < RECENT_DATE
378
+ if is_time_off:
379
+ warnings.warn(
380
+ (
381
+ "System time is way off (before {0}). This will probably "
382
+ "lead to SSL verification errors"
383
+ ).format(RECENT_DATE),
384
+ SystemTimeWarning,
385
+ )
386
+
387
+ # Wrap socket using verification with the root certs in
388
+ # trusted_root_certs
389
+ default_ssl_context = False
390
+ if self.ssl_context is None:
391
+ default_ssl_context = True
392
+ self.ssl_context = create_urllib3_context(
393
+ ssl_version=resolve_ssl_version(self.ssl_version),
394
+ cert_reqs=resolve_cert_reqs(self.cert_reqs),
395
+ )
396
+
397
+ context = self.ssl_context
398
+ context.verify_mode = resolve_cert_reqs(self.cert_reqs)
399
+
400
+ # Try to load OS default certs if none are given.
401
+ # Works well on Windows (requires Python3.4+)
402
+ if (
403
+ not self.ca_certs
404
+ and not self.ca_cert_dir
405
+ and not self.ca_cert_data
406
+ and default_ssl_context
407
+ and hasattr(context, "load_default_certs")
408
+ ):
409
+ context.load_default_certs()
410
+
411
+ self.sock = ssl_wrap_socket(
412
+ sock=conn,
413
+ keyfile=self.key_file,
414
+ certfile=self.cert_file,
415
+ key_password=self.key_password,
416
+ ca_certs=self.ca_certs,
417
+ ca_cert_dir=self.ca_cert_dir,
418
+ ca_cert_data=self.ca_cert_data,
419
+ server_hostname=server_hostname,
420
+ ssl_context=context,
421
+ tls_in_tls=tls_in_tls,
422
+ )
423
+
424
+ # If we're using all defaults and the connection
425
+ # is TLSv1 or TLSv1.1 we throw a DeprecationWarning
426
+ # for the host.
427
+ if (
428
+ default_ssl_context
429
+ and self.ssl_version is None
430
+ and hasattr(self.sock, "version")
431
+ and self.sock.version() in {"TLSv1", "TLSv1.1"}
432
+ ):
433
+ warnings.warn(
434
+ "Negotiating TLSv1/TLSv1.1 by default is deprecated "
435
+ "and will be disabled in urllib3 v2.0.0. Connecting to "
436
+ "'%s' with '%s' can be enabled by explicitly opting-in "
437
+ "with 'ssl_version'" % (self.host, self.sock.version()),
438
+ DeprecationWarning,
439
+ )
440
+
441
+ if self.assert_fingerprint:
442
+ assert_fingerprint(
443
+ self.sock.getpeercert(binary_form=True), self.assert_fingerprint
444
+ )
445
+ elif (
446
+ context.verify_mode != ssl.CERT_NONE
447
+ and not getattr(context, "check_hostname", False)
448
+ and self.assert_hostname is not False
449
+ ):
450
+ # While urllib3 attempts to always turn off hostname matching from
451
+ # the TLS library, this cannot always be done. So we check whether
452
+ # the TLS Library still thinks it's matching hostnames.
453
+ cert = self.sock.getpeercert()
454
+ if not cert.get("subjectAltName", ()):
455
+ warnings.warn(
456
+ (
457
+ "Certificate for {0} has no `subjectAltName`, falling back to check for a "
458
+ "`commonName` for now. This feature is being removed by major browsers and "
459
+ "deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
460
+ "for details.)".format(hostname)
461
+ ),
462
+ SubjectAltNameWarning,
463
+ )
464
+ _match_hostname(cert, self.assert_hostname or server_hostname)
465
+
466
+ self.is_verified = (
467
+ context.verify_mode == ssl.CERT_REQUIRED
468
+ or self.assert_fingerprint is not None
469
+ )
470
+
471
+ def _connect_tls_proxy(self, hostname, conn):
472
+ """
473
+ Establish a TLS connection to the proxy using the provided SSL context.
474
+ """
475
+ proxy_config = self.proxy_config
476
+ ssl_context = proxy_config.ssl_context
477
+ if ssl_context:
478
+ # If the user provided a proxy context, we assume CA and client
479
+ # certificates have already been set
480
+ return ssl_wrap_socket(
481
+ sock=conn,
482
+ server_hostname=hostname,
483
+ ssl_context=ssl_context,
484
+ )
485
+
486
+ ssl_context = create_proxy_ssl_context(
487
+ self.ssl_version,
488
+ self.cert_reqs,
489
+ self.ca_certs,
490
+ self.ca_cert_dir,
491
+ self.ca_cert_data,
492
+ )
493
+ # By default urllib3's SSLContext disables `check_hostname` and uses
494
+ # a custom check. For proxies we're good with relying on the default
495
+ # verification.
496
+ ssl_context.check_hostname = True
497
+
498
+ # If no cert was provided, use only the default options for server
499
+ # certificate validation
500
+ return ssl_wrap_socket(
501
+ sock=conn,
502
+ ca_certs=self.ca_certs,
503
+ ca_cert_dir=self.ca_cert_dir,
504
+ ca_cert_data=self.ca_cert_data,
505
+ server_hostname=hostname,
506
+ ssl_context=ssl_context,
507
+ )
508
+
509
+
510
+ def _match_hostname(cert, asserted_hostname):
511
+ try:
512
+ match_hostname(cert, asserted_hostname)
513
+ except CertificateError as e:
514
+ log.warning(
515
+ "Certificate did not match expected hostname: %s. Certificate: %s",
516
+ asserted_hostname,
517
+ cert,
518
+ )
519
+ # Add cert to exception and reraise so client code can inspect
520
+ # the cert when catching the exception, if they want to
521
+ e._peer_cert = cert
522
+ raise
523
+
524
+
525
+ def _get_default_user_agent():
526
+ return "python-urllib3/%s" % __version__
527
+
528
+
529
+ class DummyConnection(object):
530
+ """Used to detect a failed ConnectionCls import."""
531
+
532
+ pass
533
+
534
+
535
+ if not ssl:
536
+ HTTPSConnection = DummyConnection # noqa: F811
537
+
538
+
539
+ VerifiedHTTPSConnection = HTTPSConnection
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/connectionpool.py ADDED
@@ -0,0 +1,1067 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import errno
4
+ import logging
5
+ import socket
6
+ import sys
7
+ import warnings
8
+ from socket import error as SocketError
9
+ from socket import timeout as SocketTimeout
10
+
11
+ from .connection import (
12
+ BaseSSLError,
13
+ BrokenPipeError,
14
+ DummyConnection,
15
+ HTTPConnection,
16
+ HTTPException,
17
+ HTTPSConnection,
18
+ VerifiedHTTPSConnection,
19
+ port_by_scheme,
20
+ )
21
+ from .exceptions import (
22
+ ClosedPoolError,
23
+ EmptyPoolError,
24
+ HeaderParsingError,
25
+ HostChangedError,
26
+ InsecureRequestWarning,
27
+ LocationValueError,
28
+ MaxRetryError,
29
+ NewConnectionError,
30
+ ProtocolError,
31
+ ProxyError,
32
+ ReadTimeoutError,
33
+ SSLError,
34
+ TimeoutError,
35
+ )
36
+ from .packages import six
37
+ from .packages.six.moves import queue
38
+ from .packages.ssl_match_hostname import CertificateError
39
+ from .request import RequestMethods
40
+ from .response import HTTPResponse
41
+ from .util.connection import is_connection_dropped
42
+ from .util.proxy import connection_requires_http_tunnel
43
+ from .util.queue import LifoQueue
44
+ from .util.request import set_file_position
45
+ from .util.response import assert_header_parsing
46
+ from .util.retry import Retry
47
+ from .util.timeout import Timeout
48
+ from .util.url import Url, _encode_target
49
+ from .util.url import _normalize_host as normalize_host
50
+ from .util.url import get_host, parse_url
51
+
52
+ xrange = six.moves.xrange
53
+
54
+ log = logging.getLogger(__name__)
55
+
56
+ _Default = object()
57
+
58
+
59
+ # Pool objects
60
+ class ConnectionPool(object):
61
+ """
62
+ Base class for all connection pools, such as
63
+ :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`.
64
+
65
+ .. note::
66
+ ConnectionPool.urlopen() does not normalize or percent-encode target URIs
67
+ which is useful if your target server doesn't support percent-encoded
68
+ target URIs.
69
+ """
70
+
71
+ scheme = None
72
+ QueueCls = LifoQueue
73
+
74
+ def __init__(self, host, port=None):
75
+ if not host:
76
+ raise LocationValueError("No host specified.")
77
+
78
+ self.host = _normalize_host(host, scheme=self.scheme)
79
+ self._proxy_host = host.lower()
80
+ self.port = port
81
+
82
+ def __str__(self):
83
+ return "%s(host=%r, port=%r)" % (type(self).__name__, self.host, self.port)
84
+
85
+ def __enter__(self):
86
+ return self
87
+
88
+ def __exit__(self, exc_type, exc_val, exc_tb):
89
+ self.close()
90
+ # Return False to re-raise any potential exceptions
91
+ return False
92
+
93
+ def close(self):
94
+ """
95
+ Close all pooled connections and disable the pool.
96
+ """
97
+ pass
98
+
99
+
100
+ # This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252
101
+ _blocking_errnos = {errno.EAGAIN, errno.EWOULDBLOCK}
102
+
103
+
104
+ class HTTPConnectionPool(ConnectionPool, RequestMethods):
105
+ """
106
+ Thread-safe connection pool for one host.
107
+
108
+ :param host:
109
+ Host used for this HTTP Connection (e.g. "localhost"), passed into
110
+ :class:`http.client.HTTPConnection`.
111
+
112
+ :param port:
113
+ Port used for this HTTP Connection (None is equivalent to 80), passed
114
+ into :class:`http.client.HTTPConnection`.
115
+
116
+ :param strict:
117
+ Causes BadStatusLine to be raised if the status line can't be parsed
118
+ as a valid HTTP/1.0 or 1.1 status line, passed into
119
+ :class:`http.client.HTTPConnection`.
120
+
121
+ .. note::
122
+ Only works in Python 2. This parameter is ignored in Python 3.
123
+
124
+ :param timeout:
125
+ Socket timeout in seconds for each individual connection. This can
126
+ be a float or integer, which sets the timeout for the HTTP request,
127
+ or an instance of :class:`urllib3.util.Timeout` which gives you more
128
+ fine-grained control over request timeouts. After the constructor has
129
+ been parsed, this is always a `urllib3.util.Timeout` object.
130
+
131
+ :param maxsize:
132
+ Number of connections to save that can be reused. More than 1 is useful
133
+ in multithreaded situations. If ``block`` is set to False, more
134
+ connections will be created but they will not be saved once they've
135
+ been used.
136
+
137
+ :param block:
138
+ If set to True, no more than ``maxsize`` connections will be used at
139
+ a time. When no free connections are available, the call will block
140
+ until a connection has been released. This is a useful side effect for
141
+ particular multithreaded situations where one does not want to use more
142
+ than maxsize connections per host to prevent flooding.
143
+
144
+ :param headers:
145
+ Headers to include with all requests, unless other headers are given
146
+ explicitly.
147
+
148
+ :param retries:
149
+ Retry configuration to use by default with requests in this pool.
150
+
151
+ :param _proxy:
152
+ Parsed proxy URL, should not be used directly, instead, see
153
+ :class:`urllib3.ProxyManager`
154
+
155
+ :param _proxy_headers:
156
+ A dictionary with proxy headers, should not be used directly,
157
+ instead, see :class:`urllib3.ProxyManager`
158
+
159
+ :param \\**conn_kw:
160
+ Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`,
161
+ :class:`urllib3.connection.HTTPSConnection` instances.
162
+ """
163
+
164
+ scheme = "http"
165
+ ConnectionCls = HTTPConnection
166
+ ResponseCls = HTTPResponse
167
+
168
+ def __init__(
169
+ self,
170
+ host,
171
+ port=None,
172
+ strict=False,
173
+ timeout=Timeout.DEFAULT_TIMEOUT,
174
+ maxsize=1,
175
+ block=False,
176
+ headers=None,
177
+ retries=None,
178
+ _proxy=None,
179
+ _proxy_headers=None,
180
+ _proxy_config=None,
181
+ **conn_kw
182
+ ):
183
+ ConnectionPool.__init__(self, host, port)
184
+ RequestMethods.__init__(self, headers)
185
+
186
+ self.strict = strict
187
+
188
+ if not isinstance(timeout, Timeout):
189
+ timeout = Timeout.from_float(timeout)
190
+
191
+ if retries is None:
192
+ retries = Retry.DEFAULT
193
+
194
+ self.timeout = timeout
195
+ self.retries = retries
196
+
197
+ self.pool = self.QueueCls(maxsize)
198
+ self.block = block
199
+
200
+ self.proxy = _proxy
201
+ self.proxy_headers = _proxy_headers or {}
202
+ self.proxy_config = _proxy_config
203
+
204
+ # Fill the queue up so that doing get() on it will block properly
205
+ for _ in xrange(maxsize):
206
+ self.pool.put(None)
207
+
208
+ # These are mostly for testing and debugging purposes.
209
+ self.num_connections = 0
210
+ self.num_requests = 0
211
+ self.conn_kw = conn_kw
212
+
213
+ if self.proxy:
214
+ # Enable Nagle's algorithm for proxies, to avoid packet fragmentation.
215
+ # We cannot know if the user has added default socket options, so we cannot replace the
216
+ # list.
217
+ self.conn_kw.setdefault("socket_options", [])
218
+
219
+ self.conn_kw["proxy"] = self.proxy
220
+ self.conn_kw["proxy_config"] = self.proxy_config
221
+
222
+ def _new_conn(self):
223
+ """
224
+ Return a fresh :class:`HTTPConnection`.
225
+ """
226
+ self.num_connections += 1
227
+ log.debug(
228
+ "Starting new HTTP connection (%d): %s:%s",
229
+ self.num_connections,
230
+ self.host,
231
+ self.port or "80",
232
+ )
233
+
234
+ conn = self.ConnectionCls(
235
+ host=self.host,
236
+ port=self.port,
237
+ timeout=self.timeout.connect_timeout,
238
+ strict=self.strict,
239
+ **self.conn_kw
240
+ )
241
+ return conn
242
+
243
+ def _get_conn(self, timeout=None):
244
+ """
245
+ Get a connection. Will return a pooled connection if one is available.
246
+
247
+ If no connections are available and :prop:`.block` is ``False``, then a
248
+ fresh connection is returned.
249
+
250
+ :param timeout:
251
+ Seconds to wait before giving up and raising
252
+ :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and
253
+ :prop:`.block` is ``True``.
254
+ """
255
+ conn = None
256
+ try:
257
+ conn = self.pool.get(block=self.block, timeout=timeout)
258
+
259
+ except AttributeError: # self.pool is None
260
+ raise ClosedPoolError(self, "Pool is closed.")
261
+
262
+ except queue.Empty:
263
+ if self.block:
264
+ raise EmptyPoolError(
265
+ self,
266
+ "Pool reached maximum size and no more connections are allowed.",
267
+ )
268
+ pass # Oh well, we'll create a new connection then
269
+
270
+ # If this is a persistent connection, check if it got disconnected
271
+ if conn and is_connection_dropped(conn):
272
+ log.debug("Resetting dropped connection: %s", self.host)
273
+ conn.close()
274
+ if getattr(conn, "auto_open", 1) == 0:
275
+ # This is a proxied connection that has been mutated by
276
+ # http.client._tunnel() and cannot be reused (since it would
277
+ # attempt to bypass the proxy)
278
+ conn = None
279
+
280
+ return conn or self._new_conn()
281
+
282
+ def _put_conn(self, conn):
283
+ """
284
+ Put a connection back into the pool.
285
+
286
+ :param conn:
287
+ Connection object for the current host and port as returned by
288
+ :meth:`._new_conn` or :meth:`._get_conn`.
289
+
290
+ If the pool is already full, the connection is closed and discarded
291
+ because we exceeded maxsize. If connections are discarded frequently,
292
+ then maxsize should be increased.
293
+
294
+ If the pool is closed, then the connection will be closed and discarded.
295
+ """
296
+ try:
297
+ self.pool.put(conn, block=False)
298
+ return # Everything is dandy, done.
299
+ except AttributeError:
300
+ # self.pool is None.
301
+ pass
302
+ except queue.Full:
303
+ # This should never happen if self.block == True
304
+ log.warning("Connection pool is full, discarding connection: %s", self.host)
305
+
306
+ # Connection never got put back into the pool, close it.
307
+ if conn:
308
+ conn.close()
309
+
310
+ def _validate_conn(self, conn):
311
+ """
312
+ Called right before a request is made, after the socket is created.
313
+ """
314
+ pass
315
+
316
+ def _prepare_proxy(self, conn):
317
+ # Nothing to do for HTTP connections.
318
+ pass
319
+
320
+ def _get_timeout(self, timeout):
321
+ """Helper that always returns a :class:`urllib3.util.Timeout`"""
322
+ if timeout is _Default:
323
+ return self.timeout.clone()
324
+
325
+ if isinstance(timeout, Timeout):
326
+ return timeout.clone()
327
+ else:
328
+ # User passed us an int/float. This is for backwards compatibility,
329
+ # can be removed later
330
+ return Timeout.from_float(timeout)
331
+
332
+ def _raise_timeout(self, err, url, timeout_value):
333
+ """Is the error actually a timeout? Will raise a ReadTimeout or pass"""
334
+
335
+ if isinstance(err, SocketTimeout):
336
+ raise ReadTimeoutError(
337
+ self, url, "Read timed out. (read timeout=%s)" % timeout_value
338
+ )
339
+
340
+ # See the above comment about EAGAIN in Python 3. In Python 2 we have
341
+ # to specifically catch it and throw the timeout error
342
+ if hasattr(err, "errno") and err.errno in _blocking_errnos:
343
+ raise ReadTimeoutError(
344
+ self, url, "Read timed out. (read timeout=%s)" % timeout_value
345
+ )
346
+
347
+ # Catch possible read timeouts thrown as SSL errors. If not the
348
+ # case, rethrow the original. We need to do this because of:
349
+ # http://bugs.python.org/issue10272
350
+ if "timed out" in str(err) or "did not complete (read)" in str(
351
+ err
352
+ ): # Python < 2.7.4
353
+ raise ReadTimeoutError(
354
+ self, url, "Read timed out. (read timeout=%s)" % timeout_value
355
+ )
356
+
357
+ def _make_request(
358
+ self, conn, method, url, timeout=_Default, chunked=False, **httplib_request_kw
359
+ ):
360
+ """
361
+ Perform a request on a given urllib connection object taken from our
362
+ pool.
363
+
364
+ :param conn:
365
+ a connection from one of our connection pools
366
+
367
+ :param timeout:
368
+ Socket timeout in seconds for the request. This can be a
369
+ float or integer, which will set the same timeout value for
370
+ the socket connect and the socket read, or an instance of
371
+ :class:`urllib3.util.Timeout`, which gives you more fine-grained
372
+ control over your timeouts.
373
+ """
374
+ self.num_requests += 1
375
+
376
+ timeout_obj = self._get_timeout(timeout)
377
+ timeout_obj.start_connect()
378
+ conn.timeout = timeout_obj.connect_timeout
379
+
380
+ # Trigger any extra validation we need to do.
381
+ try:
382
+ self._validate_conn(conn)
383
+ except (SocketTimeout, BaseSSLError) as e:
384
+ # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout.
385
+ self._raise_timeout(err=e, url=url, timeout_value=conn.timeout)
386
+ raise
387
+
388
+ # conn.request() calls http.client.*.request, not the method in
389
+ # urllib3.request. It also calls makefile (recv) on the socket.
390
+ try:
391
+ if chunked:
392
+ conn.request_chunked(method, url, **httplib_request_kw)
393
+ else:
394
+ conn.request(method, url, **httplib_request_kw)
395
+
396
+ # We are swallowing BrokenPipeError (errno.EPIPE) since the server is
397
+ # legitimately able to close the connection after sending a valid response.
398
+ # With this behaviour, the received response is still readable.
399
+ except BrokenPipeError:
400
+ # Python 3
401
+ pass
402
+ except IOError as e:
403
+ # Python 2 and macOS/Linux
404
+ # EPIPE and ESHUTDOWN are BrokenPipeError on Python 2, and EPROTOTYPE is needed on macOS
405
+ # https://erickt.github.io/blog/2014/11/19/adventures-in-debugging-a-potential-osx-kernel-bug/
406
+ if e.errno not in {
407
+ errno.EPIPE,
408
+ errno.ESHUTDOWN,
409
+ errno.EPROTOTYPE,
410
+ }:
411
+ raise
412
+
413
+ # Reset the timeout for the recv() on the socket
414
+ read_timeout = timeout_obj.read_timeout
415
+
416
+ # App Engine doesn't have a sock attr
417
+ if getattr(conn, "sock", None):
418
+ # In Python 3 socket.py will catch EAGAIN and return None when you
419
+ # try and read into the file pointer created by http.client, which
420
+ # instead raises a BadStatusLine exception. Instead of catching
421
+ # the exception and assuming all BadStatusLine exceptions are read
422
+ # timeouts, check for a zero timeout before making the request.
423
+ if read_timeout == 0:
424
+ raise ReadTimeoutError(
425
+ self, url, "Read timed out. (read timeout=%s)" % read_timeout
426
+ )
427
+ if read_timeout is Timeout.DEFAULT_TIMEOUT:
428
+ conn.sock.settimeout(socket.getdefaulttimeout())
429
+ else: # None or a value
430
+ conn.sock.settimeout(read_timeout)
431
+
432
+ # Receive the response from the server
433
+ try:
434
+ try:
435
+ # Python 2.7, use buffering of HTTP responses
436
+ httplib_response = conn.getresponse(buffering=True)
437
+ except TypeError:
438
+ # Python 3
439
+ try:
440
+ httplib_response = conn.getresponse()
441
+ except BaseException as e:
442
+ # Remove the TypeError from the exception chain in
443
+ # Python 3 (including for exceptions like SystemExit).
444
+ # Otherwise it looks like a bug in the code.
445
+ six.raise_from(e, None)
446
+ except (SocketTimeout, BaseSSLError, SocketError) as e:
447
+ self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
448
+ raise
449
+
450
+ # AppEngine doesn't have a version attr.
451
+ http_version = getattr(conn, "_http_vsn_str", "HTTP/?")
452
+ log.debug(
453
+ '%s://%s:%s "%s %s %s" %s %s',
454
+ self.scheme,
455
+ self.host,
456
+ self.port,
457
+ method,
458
+ url,
459
+ http_version,
460
+ httplib_response.status,
461
+ httplib_response.length,
462
+ )
463
+
464
+ try:
465
+ assert_header_parsing(httplib_response.msg)
466
+ except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3
467
+ log.warning(
468
+ "Failed to parse headers (url=%s): %s",
469
+ self._absolute_url(url),
470
+ hpe,
471
+ exc_info=True,
472
+ )
473
+
474
+ return httplib_response
475
+
476
+ def _absolute_url(self, path):
477
+ return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url
478
+
479
+ def close(self):
480
+ """
481
+ Close all pooled connections and disable the pool.
482
+ """
483
+ if self.pool is None:
484
+ return
485
+ # Disable access to the pool
486
+ old_pool, self.pool = self.pool, None
487
+
488
+ try:
489
+ while True:
490
+ conn = old_pool.get(block=False)
491
+ if conn:
492
+ conn.close()
493
+
494
+ except queue.Empty:
495
+ pass # Done.
496
+
497
+ def is_same_host(self, url):
498
+ """
499
+ Check if the given ``url`` is a member of the same host as this
500
+ connection pool.
501
+ """
502
+ if url.startswith("/"):
503
+ return True
504
+
505
+ # TODO: Add optional support for socket.gethostbyname checking.
506
+ scheme, host, port = get_host(url)
507
+ if host is not None:
508
+ host = _normalize_host(host, scheme=scheme)
509
+
510
+ # Use explicit default port for comparison when none is given
511
+ if self.port and not port:
512
+ port = port_by_scheme.get(scheme)
513
+ elif not self.port and port == port_by_scheme.get(scheme):
514
+ port = None
515
+
516
+ return (scheme, host, port) == (self.scheme, self.host, self.port)
517
+
518
+ def urlopen(
519
+ self,
520
+ method,
521
+ url,
522
+ body=None,
523
+ headers=None,
524
+ retries=None,
525
+ redirect=True,
526
+ assert_same_host=True,
527
+ timeout=_Default,
528
+ pool_timeout=None,
529
+ release_conn=None,
530
+ chunked=False,
531
+ body_pos=None,
532
+ **response_kw
533
+ ):
534
+ """
535
+ Get a connection from the pool and perform an HTTP request. This is the
536
+ lowest level call for making a request, so you'll need to specify all
537
+ the raw details.
538
+
539
+ .. note::
540
+
541
+ More commonly, it's appropriate to use a convenience method provided
542
+ by :class:`.RequestMethods`, such as :meth:`request`.
543
+
544
+ .. note::
545
+
546
+ `release_conn` will only behave as expected if
547
+ `preload_content=False` because we want to make
548
+ `preload_content=False` the default behaviour someday soon without
549
+ breaking backwards compatibility.
550
+
551
+ :param method:
552
+ HTTP request method (such as GET, POST, PUT, etc.)
553
+
554
+ :param url:
555
+ The URL to perform the request on.
556
+
557
+ :param body:
558
+ Data to send in the request body, either :class:`str`, :class:`bytes`,
559
+ an iterable of :class:`str`/:class:`bytes`, or a file-like object.
560
+
561
+ :param headers:
562
+ Dictionary of custom headers to send, such as User-Agent,
563
+ If-None-Match, etc. If None, pool headers are used. If provided,
564
+ these headers completely replace any pool-specific headers.
565
+
566
+ :param retries:
567
+ Configure the number of retries to allow before raising a
568
+ :class:`~urllib3.exceptions.MaxRetryError` exception.
569
+
570
+ Pass ``None`` to retry until you receive a response. Pass a
571
+ :class:`~urllib3.util.retry.Retry` object for fine-grained control
572
+ over different types of retries.
573
+ Pass an integer number to retry connection errors that many times,
574
+ but no other types of errors. Pass zero to never retry.
575
+
576
+ If ``False``, then retries are disabled and any exception is raised
577
+ immediately. Also, instead of raising a MaxRetryError on redirects,
578
+ the redirect response will be returned.
579
+
580
+ :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int.
581
+
582
+ :param redirect:
583
+ If True, automatically handle redirects (status codes 301, 302,
584
+ 303, 307, 308). Each redirect counts as a retry. Disabling retries
585
+ will disable redirect, too.
586
+
587
+ :param assert_same_host:
588
+ If ``True``, will make sure that the host of the pool requests is
589
+ consistent else will raise HostChangedError. When ``False``, you can
590
+ use the pool on an HTTP proxy and request foreign hosts.
591
+
592
+ :param timeout:
593
+ If specified, overrides the default timeout for this one
594
+ request. It may be a float (in seconds) or an instance of
595
+ :class:`urllib3.util.Timeout`.
596
+
597
+ :param pool_timeout:
598
+ If set and the pool is set to block=True, then this method will
599
+ block for ``pool_timeout`` seconds and raise EmptyPoolError if no
600
+ connection is available within the time period.
601
+
602
+ :param release_conn:
603
+ If False, then the urlopen call will not release the connection
604
+ back into the pool once a response is received (but will release if
605
+ you read the entire contents of the response such as when
606
+ `preload_content=True`). This is useful if you're not preloading
607
+ the response's content immediately. You will need to call
608
+ ``r.release_conn()`` on the response ``r`` to return the connection
609
+ back into the pool. If None, it takes the value of
610
+ ``response_kw.get('preload_content', True)``.
611
+
612
+ :param chunked:
613
+ If True, urllib3 will send the body using chunked transfer
614
+ encoding. Otherwise, urllib3 will send the body using the standard
615
+ content-length form. Defaults to False.
616
+
617
+ :param int body_pos:
618
+ Position to seek to in file-like body in the event of a retry or
619
+ redirect. Typically this won't need to be set because urllib3 will
620
+ auto-populate the value when needed.
621
+
622
+ :param \\**response_kw:
623
+ Additional parameters are passed to
624
+ :meth:`urllib3.response.HTTPResponse.from_httplib`
625
+ """
626
+
627
+ parsed_url = parse_url(url)
628
+ destination_scheme = parsed_url.scheme
629
+
630
+ if headers is None:
631
+ headers = self.headers
632
+
633
+ if not isinstance(retries, Retry):
634
+ retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
635
+
636
+ if release_conn is None:
637
+ release_conn = response_kw.get("preload_content", True)
638
+
639
+ # Check host
640
+ if assert_same_host and not self.is_same_host(url):
641
+ raise HostChangedError(self, url, retries)
642
+
643
+ # Ensure that the URL we're connecting to is properly encoded
644
+ if url.startswith("/"):
645
+ url = six.ensure_str(_encode_target(url))
646
+ else:
647
+ url = six.ensure_str(parsed_url.url)
648
+
649
+ conn = None
650
+
651
+ # Track whether `conn` needs to be released before
652
+ # returning/raising/recursing. Update this variable if necessary, and
653
+ # leave `release_conn` constant throughout the function. That way, if
654
+ # the function recurses, the original value of `release_conn` will be
655
+ # passed down into the recursive call, and its value will be respected.
656
+ #
657
+ # See issue #651 [1] for details.
658
+ #
659
+ # [1] <https://github.com/urllib3/urllib3/issues/651>
660
+ release_this_conn = release_conn
661
+
662
+ http_tunnel_required = connection_requires_http_tunnel(
663
+ self.proxy, self.proxy_config, destination_scheme
664
+ )
665
+
666
+ # Merge the proxy headers. Only done when not using HTTP CONNECT. We
667
+ # have to copy the headers dict so we can safely change it without those
668
+ # changes being reflected in anyone else's copy.
669
+ if not http_tunnel_required:
670
+ headers = headers.copy()
671
+ headers.update(self.proxy_headers)
672
+
673
+ # Must keep the exception bound to a separate variable or else Python 3
674
+ # complains about UnboundLocalError.
675
+ err = None
676
+
677
+ # Keep track of whether we cleanly exited the except block. This
678
+ # ensures we do proper cleanup in finally.
679
+ clean_exit = False
680
+
681
+ # Rewind body position, if needed. Record current position
682
+ # for future rewinds in the event of a redirect/retry.
683
+ body_pos = set_file_position(body, body_pos)
684
+
685
+ try:
686
+ # Request a connection from the queue.
687
+ timeout_obj = self._get_timeout(timeout)
688
+ conn = self._get_conn(timeout=pool_timeout)
689
+
690
+ conn.timeout = timeout_obj.connect_timeout
691
+
692
+ is_new_proxy_conn = self.proxy is not None and not getattr(
693
+ conn, "sock", None
694
+ )
695
+ if is_new_proxy_conn and http_tunnel_required:
696
+ self._prepare_proxy(conn)
697
+
698
+ # Make the request on the httplib connection object.
699
+ httplib_response = self._make_request(
700
+ conn,
701
+ method,
702
+ url,
703
+ timeout=timeout_obj,
704
+ body=body,
705
+ headers=headers,
706
+ chunked=chunked,
707
+ )
708
+
709
+ # If we're going to release the connection in ``finally:``, then
710
+ # the response doesn't need to know about the connection. Otherwise
711
+ # it will also try to release it and we'll have a double-release
712
+ # mess.
713
+ response_conn = conn if not release_conn else None
714
+
715
+ # Pass method to Response for length checking
716
+ response_kw["request_method"] = method
717
+
718
+ # Import httplib's response into our own wrapper object
719
+ response = self.ResponseCls.from_httplib(
720
+ httplib_response,
721
+ pool=self,
722
+ connection=response_conn,
723
+ retries=retries,
724
+ **response_kw
725
+ )
726
+
727
+ # Everything went great!
728
+ clean_exit = True
729
+
730
+ except EmptyPoolError:
731
+ # Didn't get a connection from the pool, no need to clean up
732
+ clean_exit = True
733
+ release_this_conn = False
734
+ raise
735
+
736
+ except (
737
+ TimeoutError,
738
+ HTTPException,
739
+ SocketError,
740
+ ProtocolError,
741
+ BaseSSLError,
742
+ SSLError,
743
+ CertificateError,
744
+ ) as e:
745
+ # Discard the connection for these exceptions. It will be
746
+ # replaced during the next _get_conn() call.
747
+ clean_exit = False
748
+ if isinstance(e, (BaseSSLError, CertificateError)):
749
+ e = SSLError(e)
750
+ elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy:
751
+ e = ProxyError("Cannot connect to proxy.", e)
752
+ elif isinstance(e, (SocketError, HTTPException)):
753
+ e = ProtocolError("Connection aborted.", e)
754
+
755
+ retries = retries.increment(
756
+ method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
757
+ )
758
+ retries.sleep()
759
+
760
+ # Keep track of the error for the retry warning.
761
+ err = e
762
+
763
+ finally:
764
+ if not clean_exit:
765
+ # We hit some kind of exception, handled or otherwise. We need
766
+ # to throw the connection away unless explicitly told not to.
767
+ # Close the connection, set the variable to None, and make sure
768
+ # we put the None back in the pool to avoid leaking it.
769
+ conn = conn and conn.close()
770
+ release_this_conn = True
771
+
772
+ if release_this_conn:
773
+ # Put the connection back to be reused. If the connection is
774
+ # expired then it will be None, which will get replaced with a
775
+ # fresh connection during _get_conn.
776
+ self._put_conn(conn)
777
+
778
+ if not conn:
779
+ # Try again
780
+ log.warning(
781
+ "Retrying (%r) after connection broken by '%r': %s", retries, err, url
782
+ )
783
+ return self.urlopen(
784
+ method,
785
+ url,
786
+ body,
787
+ headers,
788
+ retries,
789
+ redirect,
790
+ assert_same_host,
791
+ timeout=timeout,
792
+ pool_timeout=pool_timeout,
793
+ release_conn=release_conn,
794
+ chunked=chunked,
795
+ body_pos=body_pos,
796
+ **response_kw
797
+ )
798
+
799
+ # Handle redirect?
800
+ redirect_location = redirect and response.get_redirect_location()
801
+ if redirect_location:
802
+ if response.status == 303:
803
+ method = "GET"
804
+
805
+ try:
806
+ retries = retries.increment(method, url, response=response, _pool=self)
807
+ except MaxRetryError:
808
+ if retries.raise_on_redirect:
809
+ response.drain_conn()
810
+ raise
811
+ return response
812
+
813
+ response.drain_conn()
814
+ retries.sleep_for_retry(response)
815
+ log.debug("Redirecting %s -> %s", url, redirect_location)
816
+ return self.urlopen(
817
+ method,
818
+ redirect_location,
819
+ body,
820
+ headers,
821
+ retries=retries,
822
+ redirect=redirect,
823
+ assert_same_host=assert_same_host,
824
+ timeout=timeout,
825
+ pool_timeout=pool_timeout,
826
+ release_conn=release_conn,
827
+ chunked=chunked,
828
+ body_pos=body_pos,
829
+ **response_kw
830
+ )
831
+
832
+ # Check if we should retry the HTTP response.
833
+ has_retry_after = bool(response.getheader("Retry-After"))
834
+ if retries.is_retry(method, response.status, has_retry_after):
835
+ try:
836
+ retries = retries.increment(method, url, response=response, _pool=self)
837
+ except MaxRetryError:
838
+ if retries.raise_on_status:
839
+ response.drain_conn()
840
+ raise
841
+ return response
842
+
843
+ response.drain_conn()
844
+ retries.sleep(response)
845
+ log.debug("Retry: %s", url)
846
+ return self.urlopen(
847
+ method,
848
+ url,
849
+ body,
850
+ headers,
851
+ retries=retries,
852
+ redirect=redirect,
853
+ assert_same_host=assert_same_host,
854
+ timeout=timeout,
855
+ pool_timeout=pool_timeout,
856
+ release_conn=release_conn,
857
+ chunked=chunked,
858
+ body_pos=body_pos,
859
+ **response_kw
860
+ )
861
+
862
+ return response
863
+
864
+
865
+ class HTTPSConnectionPool(HTTPConnectionPool):
866
+ """
867
+ Same as :class:`.HTTPConnectionPool`, but HTTPS.
868
+
869
+ :class:`.HTTPSConnection` uses one of ``assert_fingerprint``,
870
+ ``assert_hostname`` and ``host`` in this order to verify connections.
871
+ If ``assert_hostname`` is False, no verification is done.
872
+
873
+ The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``,
874
+ ``ca_cert_dir``, ``ssl_version``, ``key_password`` are only used if :mod:`ssl`
875
+ is available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade
876
+ the connection socket into an SSL socket.
877
+ """
878
+
879
+ scheme = "https"
880
+ ConnectionCls = HTTPSConnection
881
+
882
+ def __init__(
883
+ self,
884
+ host,
885
+ port=None,
886
+ strict=False,
887
+ timeout=Timeout.DEFAULT_TIMEOUT,
888
+ maxsize=1,
889
+ block=False,
890
+ headers=None,
891
+ retries=None,
892
+ _proxy=None,
893
+ _proxy_headers=None,
894
+ key_file=None,
895
+ cert_file=None,
896
+ cert_reqs=None,
897
+ key_password=None,
898
+ ca_certs=None,
899
+ ssl_version=None,
900
+ assert_hostname=None,
901
+ assert_fingerprint=None,
902
+ ca_cert_dir=None,
903
+ **conn_kw
904
+ ):
905
+
906
+ HTTPConnectionPool.__init__(
907
+ self,
908
+ host,
909
+ port,
910
+ strict,
911
+ timeout,
912
+ maxsize,
913
+ block,
914
+ headers,
915
+ retries,
916
+ _proxy,
917
+ _proxy_headers,
918
+ **conn_kw
919
+ )
920
+
921
+ self.key_file = key_file
922
+ self.cert_file = cert_file
923
+ self.cert_reqs = cert_reqs
924
+ self.key_password = key_password
925
+ self.ca_certs = ca_certs
926
+ self.ca_cert_dir = ca_cert_dir
927
+ self.ssl_version = ssl_version
928
+ self.assert_hostname = assert_hostname
929
+ self.assert_fingerprint = assert_fingerprint
930
+
931
+ def _prepare_conn(self, conn):
932
+ """
933
+ Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket`
934
+ and establish the tunnel if proxy is used.
935
+ """
936
+
937
+ if isinstance(conn, VerifiedHTTPSConnection):
938
+ conn.set_cert(
939
+ key_file=self.key_file,
940
+ key_password=self.key_password,
941
+ cert_file=self.cert_file,
942
+ cert_reqs=self.cert_reqs,
943
+ ca_certs=self.ca_certs,
944
+ ca_cert_dir=self.ca_cert_dir,
945
+ assert_hostname=self.assert_hostname,
946
+ assert_fingerprint=self.assert_fingerprint,
947
+ )
948
+ conn.ssl_version = self.ssl_version
949
+ return conn
950
+
951
+ def _prepare_proxy(self, conn):
952
+ """
953
+ Establishes a tunnel connection through HTTP CONNECT.
954
+
955
+ Tunnel connection is established early because otherwise httplib would
956
+ improperly set Host: header to proxy's IP:port.
957
+ """
958
+
959
+ conn.set_tunnel(self._proxy_host, self.port, self.proxy_headers)
960
+
961
+ if self.proxy.scheme == "https":
962
+ conn.tls_in_tls_required = True
963
+
964
+ conn.connect()
965
+
966
+ def _new_conn(self):
967
+ """
968
+ Return a fresh :class:`http.client.HTTPSConnection`.
969
+ """
970
+ self.num_connections += 1
971
+ log.debug(
972
+ "Starting new HTTPS connection (%d): %s:%s",
973
+ self.num_connections,
974
+ self.host,
975
+ self.port or "443",
976
+ )
977
+
978
+ if not self.ConnectionCls or self.ConnectionCls is DummyConnection:
979
+ raise SSLError(
980
+ "Can't connect to HTTPS URL because the SSL module is not available."
981
+ )
982
+
983
+ actual_host = self.host
984
+ actual_port = self.port
985
+ if self.proxy is not None:
986
+ actual_host = self.proxy.host
987
+ actual_port = self.proxy.port
988
+
989
+ conn = self.ConnectionCls(
990
+ host=actual_host,
991
+ port=actual_port,
992
+ timeout=self.timeout.connect_timeout,
993
+ strict=self.strict,
994
+ cert_file=self.cert_file,
995
+ key_file=self.key_file,
996
+ key_password=self.key_password,
997
+ **self.conn_kw
998
+ )
999
+
1000
+ return self._prepare_conn(conn)
1001
+
1002
+ def _validate_conn(self, conn):
1003
+ """
1004
+ Called right before a request is made, after the socket is created.
1005
+ """
1006
+ super(HTTPSConnectionPool, self)._validate_conn(conn)
1007
+
1008
+ # Force connect early to allow us to validate the connection.
1009
+ if not getattr(conn, "sock", None): # AppEngine might not have `.sock`
1010
+ conn.connect()
1011
+
1012
+ if not conn.is_verified:
1013
+ warnings.warn(
1014
+ (
1015
+ "Unverified HTTPS request is being made to host '%s'. "
1016
+ "Adding certificate verification is strongly advised. See: "
1017
+ "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
1018
+ "#ssl-warnings" % conn.host
1019
+ ),
1020
+ InsecureRequestWarning,
1021
+ )
1022
+
1023
+
1024
+ def connection_from_url(url, **kw):
1025
+ """
1026
+ Given a url, return an :class:`.ConnectionPool` instance of its host.
1027
+
1028
+ This is a shortcut for not having to parse out the scheme, host, and port
1029
+ of the url before creating an :class:`.ConnectionPool` instance.
1030
+
1031
+ :param url:
1032
+ Absolute URL string that must include the scheme. Port is optional.
1033
+
1034
+ :param \\**kw:
1035
+ Passes additional parameters to the constructor of the appropriate
1036
+ :class:`.ConnectionPool`. Useful for specifying things like
1037
+ timeout, maxsize, headers, etc.
1038
+
1039
+ Example::
1040
+
1041
+ >>> conn = connection_from_url('http://google.com/')
1042
+ >>> r = conn.request('GET', '/')
1043
+ """
1044
+ scheme, host, port = get_host(url)
1045
+ port = port or port_by_scheme.get(scheme, 80)
1046
+ if scheme == "https":
1047
+ return HTTPSConnectionPool(host, port=port, **kw)
1048
+ else:
1049
+ return HTTPConnectionPool(host, port=port, **kw)
1050
+
1051
+
1052
+ def _normalize_host(host, scheme):
1053
+ """
1054
+ Normalize hosts for comparisons and use with sockets.
1055
+ """
1056
+
1057
+ host = normalize_host(host, scheme)
1058
+
1059
+ # httplib doesn't like it when we include brackets in IPv6 addresses
1060
+ # Specifically, if we include brackets but also pass the port then
1061
+ # httplib crazily doubles up the square brackets on the Host header.
1062
+ # Instead, we need to make sure we never pass ``None`` as the port.
1063
+ # However, for backward compatibility reasons we can't actually
1064
+ # *assert* that. See http://bugs.python.org/issue28539
1065
+ if host.startswith("[") and host.endswith("]"):
1066
+ host = host[1:-1]
1067
+ return host
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/__init__.py ADDED
File without changes
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module provides means to detect the App Engine environment.
3
+ """
4
+
5
+ import os
6
+
7
+
8
+ def is_appengine():
9
+ return is_local_appengine() or is_prod_appengine()
10
+
11
+
12
+ def is_appengine_sandbox():
13
+ """Reports if the app is running in the first generation sandbox.
14
+
15
+ The second generation runtimes are technically still in a sandbox, but it
16
+ is much less restrictive, so generally you shouldn't need to check for it.
17
+ see https://cloud.google.com/appengine/docs/standard/runtimes
18
+ """
19
+ return is_appengine() and os.environ["APPENGINE_RUNTIME"] == "python27"
20
+
21
+
22
+ def is_local_appengine():
23
+ return "APPENGINE_RUNTIME" in os.environ and os.environ.get(
24
+ "SERVER_SOFTWARE", ""
25
+ ).startswith("Development/")
26
+
27
+
28
+ def is_prod_appengine():
29
+ return "APPENGINE_RUNTIME" in os.environ and os.environ.get(
30
+ "SERVER_SOFTWARE", ""
31
+ ).startswith("Google App Engine/")
32
+
33
+
34
+ def is_prod_appengine_mvms():
35
+ """Deprecated."""
36
+ return False
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py ADDED
File without changes
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py ADDED
@@ -0,0 +1,519 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module uses ctypes to bind a whole bunch of functions and constants from
3
+ SecureTransport. The goal here is to provide the low-level API to
4
+ SecureTransport. These are essentially the C-level functions and constants, and
5
+ they're pretty gross to work with.
6
+
7
+ This code is a bastardised version of the code found in Will Bond's oscrypto
8
+ library. An enormous debt is owed to him for blazing this trail for us. For
9
+ that reason, this code should be considered to be covered both by urllib3's
10
+ license and by oscrypto's:
11
+
12
+ Copyright (c) 2015-2016 Will Bond <will@wbond.net>
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a
15
+ copy of this software and associated documentation files (the "Software"),
16
+ to deal in the Software without restriction, including without limitation
17
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
18
+ and/or sell copies of the Software, and to permit persons to whom the
19
+ Software is furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in
22
+ all copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30
+ DEALINGS IN THE SOFTWARE.
31
+ """
32
+ from __future__ import absolute_import
33
+
34
+ import platform
35
+ from ctypes import (
36
+ CDLL,
37
+ CFUNCTYPE,
38
+ POINTER,
39
+ c_bool,
40
+ c_byte,
41
+ c_char_p,
42
+ c_int32,
43
+ c_long,
44
+ c_size_t,
45
+ c_uint32,
46
+ c_ulong,
47
+ c_void_p,
48
+ )
49
+ from ctypes.util import find_library
50
+
51
+ from pip._vendor.urllib3.packages.six import raise_from
52
+
53
+ if platform.system() != "Darwin":
54
+ raise ImportError("Only macOS is supported")
55
+
56
+ version = platform.mac_ver()[0]
57
+ version_info = tuple(map(int, version.split(".")))
58
+ if version_info < (10, 8):
59
+ raise OSError(
60
+ "Only OS X 10.8 and newer are supported, not %s.%s"
61
+ % (version_info[0], version_info[1])
62
+ )
63
+
64
+
65
+ def load_cdll(name, macos10_16_path):
66
+ """Loads a CDLL by name, falling back to known path on 10.16+"""
67
+ try:
68
+ # Big Sur is technically 11 but we use 10.16 due to the Big Sur
69
+ # beta being labeled as 10.16.
70
+ if version_info >= (10, 16):
71
+ path = macos10_16_path
72
+ else:
73
+ path = find_library(name)
74
+ if not path:
75
+ raise OSError # Caught and reraised as 'ImportError'
76
+ return CDLL(path, use_errno=True)
77
+ except OSError:
78
+ raise_from(ImportError("The library %s failed to load" % name), None)
79
+
80
+
81
+ Security = load_cdll(
82
+ "Security", "/System/Library/Frameworks/Security.framework/Security"
83
+ )
84
+ CoreFoundation = load_cdll(
85
+ "CoreFoundation",
86
+ "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation",
87
+ )
88
+
89
+
90
+ Boolean = c_bool
91
+ CFIndex = c_long
92
+ CFStringEncoding = c_uint32
93
+ CFData = c_void_p
94
+ CFString = c_void_p
95
+ CFArray = c_void_p
96
+ CFMutableArray = c_void_p
97
+ CFDictionary = c_void_p
98
+ CFError = c_void_p
99
+ CFType = c_void_p
100
+ CFTypeID = c_ulong
101
+
102
+ CFTypeRef = POINTER(CFType)
103
+ CFAllocatorRef = c_void_p
104
+
105
+ OSStatus = c_int32
106
+
107
+ CFDataRef = POINTER(CFData)
108
+ CFStringRef = POINTER(CFString)
109
+ CFArrayRef = POINTER(CFArray)
110
+ CFMutableArrayRef = POINTER(CFMutableArray)
111
+ CFDictionaryRef = POINTER(CFDictionary)
112
+ CFArrayCallBacks = c_void_p
113
+ CFDictionaryKeyCallBacks = c_void_p
114
+ CFDictionaryValueCallBacks = c_void_p
115
+
116
+ SecCertificateRef = POINTER(c_void_p)
117
+ SecExternalFormat = c_uint32
118
+ SecExternalItemType = c_uint32
119
+ SecIdentityRef = POINTER(c_void_p)
120
+ SecItemImportExportFlags = c_uint32
121
+ SecItemImportExportKeyParameters = c_void_p
122
+ SecKeychainRef = POINTER(c_void_p)
123
+ SSLProtocol = c_uint32
124
+ SSLCipherSuite = c_uint32
125
+ SSLContextRef = POINTER(c_void_p)
126
+ SecTrustRef = POINTER(c_void_p)
127
+ SSLConnectionRef = c_uint32
128
+ SecTrustResultType = c_uint32
129
+ SecTrustOptionFlags = c_uint32
130
+ SSLProtocolSide = c_uint32
131
+ SSLConnectionType = c_uint32
132
+ SSLSessionOption = c_uint32
133
+
134
+
135
+ try:
136
+ Security.SecItemImport.argtypes = [
137
+ CFDataRef,
138
+ CFStringRef,
139
+ POINTER(SecExternalFormat),
140
+ POINTER(SecExternalItemType),
141
+ SecItemImportExportFlags,
142
+ POINTER(SecItemImportExportKeyParameters),
143
+ SecKeychainRef,
144
+ POINTER(CFArrayRef),
145
+ ]
146
+ Security.SecItemImport.restype = OSStatus
147
+
148
+ Security.SecCertificateGetTypeID.argtypes = []
149
+ Security.SecCertificateGetTypeID.restype = CFTypeID
150
+
151
+ Security.SecIdentityGetTypeID.argtypes = []
152
+ Security.SecIdentityGetTypeID.restype = CFTypeID
153
+
154
+ Security.SecKeyGetTypeID.argtypes = []
155
+ Security.SecKeyGetTypeID.restype = CFTypeID
156
+
157
+ Security.SecCertificateCreateWithData.argtypes = [CFAllocatorRef, CFDataRef]
158
+ Security.SecCertificateCreateWithData.restype = SecCertificateRef
159
+
160
+ Security.SecCertificateCopyData.argtypes = [SecCertificateRef]
161
+ Security.SecCertificateCopyData.restype = CFDataRef
162
+
163
+ Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
164
+ Security.SecCopyErrorMessageString.restype = CFStringRef
165
+
166
+ Security.SecIdentityCreateWithCertificate.argtypes = [
167
+ CFTypeRef,
168
+ SecCertificateRef,
169
+ POINTER(SecIdentityRef),
170
+ ]
171
+ Security.SecIdentityCreateWithCertificate.restype = OSStatus
172
+
173
+ Security.SecKeychainCreate.argtypes = [
174
+ c_char_p,
175
+ c_uint32,
176
+ c_void_p,
177
+ Boolean,
178
+ c_void_p,
179
+ POINTER(SecKeychainRef),
180
+ ]
181
+ Security.SecKeychainCreate.restype = OSStatus
182
+
183
+ Security.SecKeychainDelete.argtypes = [SecKeychainRef]
184
+ Security.SecKeychainDelete.restype = OSStatus
185
+
186
+ Security.SecPKCS12Import.argtypes = [
187
+ CFDataRef,
188
+ CFDictionaryRef,
189
+ POINTER(CFArrayRef),
190
+ ]
191
+ Security.SecPKCS12Import.restype = OSStatus
192
+
193
+ SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t))
194
+ SSLWriteFunc = CFUNCTYPE(
195
+ OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)
196
+ )
197
+
198
+ Security.SSLSetIOFuncs.argtypes = [SSLContextRef, SSLReadFunc, SSLWriteFunc]
199
+ Security.SSLSetIOFuncs.restype = OSStatus
200
+
201
+ Security.SSLSetPeerID.argtypes = [SSLContextRef, c_char_p, c_size_t]
202
+ Security.SSLSetPeerID.restype = OSStatus
203
+
204
+ Security.SSLSetCertificate.argtypes = [SSLContextRef, CFArrayRef]
205
+ Security.SSLSetCertificate.restype = OSStatus
206
+
207
+ Security.SSLSetCertificateAuthorities.argtypes = [SSLContextRef, CFTypeRef, Boolean]
208
+ Security.SSLSetCertificateAuthorities.restype = OSStatus
209
+
210
+ Security.SSLSetConnection.argtypes = [SSLContextRef, SSLConnectionRef]
211
+ Security.SSLSetConnection.restype = OSStatus
212
+
213
+ Security.SSLSetPeerDomainName.argtypes = [SSLContextRef, c_char_p, c_size_t]
214
+ Security.SSLSetPeerDomainName.restype = OSStatus
215
+
216
+ Security.SSLHandshake.argtypes = [SSLContextRef]
217
+ Security.SSLHandshake.restype = OSStatus
218
+
219
+ Security.SSLRead.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
220
+ Security.SSLRead.restype = OSStatus
221
+
222
+ Security.SSLWrite.argtypes = [SSLContextRef, c_char_p, c_size_t, POINTER(c_size_t)]
223
+ Security.SSLWrite.restype = OSStatus
224
+
225
+ Security.SSLClose.argtypes = [SSLContextRef]
226
+ Security.SSLClose.restype = OSStatus
227
+
228
+ Security.SSLGetNumberSupportedCiphers.argtypes = [SSLContextRef, POINTER(c_size_t)]
229
+ Security.SSLGetNumberSupportedCiphers.restype = OSStatus
230
+
231
+ Security.SSLGetSupportedCiphers.argtypes = [
232
+ SSLContextRef,
233
+ POINTER(SSLCipherSuite),
234
+ POINTER(c_size_t),
235
+ ]
236
+ Security.SSLGetSupportedCiphers.restype = OSStatus
237
+
238
+ Security.SSLSetEnabledCiphers.argtypes = [
239
+ SSLContextRef,
240
+ POINTER(SSLCipherSuite),
241
+ c_size_t,
242
+ ]
243
+ Security.SSLSetEnabledCiphers.restype = OSStatus
244
+
245
+ Security.SSLGetNumberEnabledCiphers.argtype = [SSLContextRef, POINTER(c_size_t)]
246
+ Security.SSLGetNumberEnabledCiphers.restype = OSStatus
247
+
248
+ Security.SSLGetEnabledCiphers.argtypes = [
249
+ SSLContextRef,
250
+ POINTER(SSLCipherSuite),
251
+ POINTER(c_size_t),
252
+ ]
253
+ Security.SSLGetEnabledCiphers.restype = OSStatus
254
+
255
+ Security.SSLGetNegotiatedCipher.argtypes = [SSLContextRef, POINTER(SSLCipherSuite)]
256
+ Security.SSLGetNegotiatedCipher.restype = OSStatus
257
+
258
+ Security.SSLGetNegotiatedProtocolVersion.argtypes = [
259
+ SSLContextRef,
260
+ POINTER(SSLProtocol),
261
+ ]
262
+ Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus
263
+
264
+ Security.SSLCopyPeerTrust.argtypes = [SSLContextRef, POINTER(SecTrustRef)]
265
+ Security.SSLCopyPeerTrust.restype = OSStatus
266
+
267
+ Security.SecTrustSetAnchorCertificates.argtypes = [SecTrustRef, CFArrayRef]
268
+ Security.SecTrustSetAnchorCertificates.restype = OSStatus
269
+
270
+ Security.SecTrustSetAnchorCertificatesOnly.argstypes = [SecTrustRef, Boolean]
271
+ Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus
272
+
273
+ Security.SecTrustEvaluate.argtypes = [SecTrustRef, POINTER(SecTrustResultType)]
274
+ Security.SecTrustEvaluate.restype = OSStatus
275
+
276
+ Security.SecTrustGetCertificateCount.argtypes = [SecTrustRef]
277
+ Security.SecTrustGetCertificateCount.restype = CFIndex
278
+
279
+ Security.SecTrustGetCertificateAtIndex.argtypes = [SecTrustRef, CFIndex]
280
+ Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef
281
+
282
+ Security.SSLCreateContext.argtypes = [
283
+ CFAllocatorRef,
284
+ SSLProtocolSide,
285
+ SSLConnectionType,
286
+ ]
287
+ Security.SSLCreateContext.restype = SSLContextRef
288
+
289
+ Security.SSLSetSessionOption.argtypes = [SSLContextRef, SSLSessionOption, Boolean]
290
+ Security.SSLSetSessionOption.restype = OSStatus
291
+
292
+ Security.SSLSetProtocolVersionMin.argtypes = [SSLContextRef, SSLProtocol]
293
+ Security.SSLSetProtocolVersionMin.restype = OSStatus
294
+
295
+ Security.SSLSetProtocolVersionMax.argtypes = [SSLContextRef, SSLProtocol]
296
+ Security.SSLSetProtocolVersionMax.restype = OSStatus
297
+
298
+ try:
299
+ Security.SSLSetALPNProtocols.argtypes = [SSLContextRef, CFArrayRef]
300
+ Security.SSLSetALPNProtocols.restype = OSStatus
301
+ except AttributeError:
302
+ # Supported only in 10.12+
303
+ pass
304
+
305
+ Security.SecCopyErrorMessageString.argtypes = [OSStatus, c_void_p]
306
+ Security.SecCopyErrorMessageString.restype = CFStringRef
307
+
308
+ Security.SSLReadFunc = SSLReadFunc
309
+ Security.SSLWriteFunc = SSLWriteFunc
310
+ Security.SSLContextRef = SSLContextRef
311
+ Security.SSLProtocol = SSLProtocol
312
+ Security.SSLCipherSuite = SSLCipherSuite
313
+ Security.SecIdentityRef = SecIdentityRef
314
+ Security.SecKeychainRef = SecKeychainRef
315
+ Security.SecTrustRef = SecTrustRef
316
+ Security.SecTrustResultType = SecTrustResultType
317
+ Security.SecExternalFormat = SecExternalFormat
318
+ Security.OSStatus = OSStatus
319
+
320
+ Security.kSecImportExportPassphrase = CFStringRef.in_dll(
321
+ Security, "kSecImportExportPassphrase"
322
+ )
323
+ Security.kSecImportItemIdentity = CFStringRef.in_dll(
324
+ Security, "kSecImportItemIdentity"
325
+ )
326
+
327
+ # CoreFoundation time!
328
+ CoreFoundation.CFRetain.argtypes = [CFTypeRef]
329
+ CoreFoundation.CFRetain.restype = CFTypeRef
330
+
331
+ CoreFoundation.CFRelease.argtypes = [CFTypeRef]
332
+ CoreFoundation.CFRelease.restype = None
333
+
334
+ CoreFoundation.CFGetTypeID.argtypes = [CFTypeRef]
335
+ CoreFoundation.CFGetTypeID.restype = CFTypeID
336
+
337
+ CoreFoundation.CFStringCreateWithCString.argtypes = [
338
+ CFAllocatorRef,
339
+ c_char_p,
340
+ CFStringEncoding,
341
+ ]
342
+ CoreFoundation.CFStringCreateWithCString.restype = CFStringRef
343
+
344
+ CoreFoundation.CFStringGetCStringPtr.argtypes = [CFStringRef, CFStringEncoding]
345
+ CoreFoundation.CFStringGetCStringPtr.restype = c_char_p
346
+
347
+ CoreFoundation.CFStringGetCString.argtypes = [
348
+ CFStringRef,
349
+ c_char_p,
350
+ CFIndex,
351
+ CFStringEncoding,
352
+ ]
353
+ CoreFoundation.CFStringGetCString.restype = c_bool
354
+
355
+ CoreFoundation.CFDataCreate.argtypes = [CFAllocatorRef, c_char_p, CFIndex]
356
+ CoreFoundation.CFDataCreate.restype = CFDataRef
357
+
358
+ CoreFoundation.CFDataGetLength.argtypes = [CFDataRef]
359
+ CoreFoundation.CFDataGetLength.restype = CFIndex
360
+
361
+ CoreFoundation.CFDataGetBytePtr.argtypes = [CFDataRef]
362
+ CoreFoundation.CFDataGetBytePtr.restype = c_void_p
363
+
364
+ CoreFoundation.CFDictionaryCreate.argtypes = [
365
+ CFAllocatorRef,
366
+ POINTER(CFTypeRef),
367
+ POINTER(CFTypeRef),
368
+ CFIndex,
369
+ CFDictionaryKeyCallBacks,
370
+ CFDictionaryValueCallBacks,
371
+ ]
372
+ CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef
373
+
374
+ CoreFoundation.CFDictionaryGetValue.argtypes = [CFDictionaryRef, CFTypeRef]
375
+ CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef
376
+
377
+ CoreFoundation.CFArrayCreate.argtypes = [
378
+ CFAllocatorRef,
379
+ POINTER(CFTypeRef),
380
+ CFIndex,
381
+ CFArrayCallBacks,
382
+ ]
383
+ CoreFoundation.CFArrayCreate.restype = CFArrayRef
384
+
385
+ CoreFoundation.CFArrayCreateMutable.argtypes = [
386
+ CFAllocatorRef,
387
+ CFIndex,
388
+ CFArrayCallBacks,
389
+ ]
390
+ CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef
391
+
392
+ CoreFoundation.CFArrayAppendValue.argtypes = [CFMutableArrayRef, c_void_p]
393
+ CoreFoundation.CFArrayAppendValue.restype = None
394
+
395
+ CoreFoundation.CFArrayGetCount.argtypes = [CFArrayRef]
396
+ CoreFoundation.CFArrayGetCount.restype = CFIndex
397
+
398
+ CoreFoundation.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
399
+ CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p
400
+
401
+ CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll(
402
+ CoreFoundation, "kCFAllocatorDefault"
403
+ )
404
+ CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(
405
+ CoreFoundation, "kCFTypeArrayCallBacks"
406
+ )
407
+ CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll(
408
+ CoreFoundation, "kCFTypeDictionaryKeyCallBacks"
409
+ )
410
+ CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll(
411
+ CoreFoundation, "kCFTypeDictionaryValueCallBacks"
412
+ )
413
+
414
+ CoreFoundation.CFTypeRef = CFTypeRef
415
+ CoreFoundation.CFArrayRef = CFArrayRef
416
+ CoreFoundation.CFStringRef = CFStringRef
417
+ CoreFoundation.CFDictionaryRef = CFDictionaryRef
418
+
419
+ except (AttributeError):
420
+ raise ImportError("Error initializing ctypes")
421
+
422
+
423
+ class CFConst(object):
424
+ """
425
+ A class object that acts as essentially a namespace for CoreFoundation
426
+ constants.
427
+ """
428
+
429
+ kCFStringEncodingUTF8 = CFStringEncoding(0x08000100)
430
+
431
+
432
+ class SecurityConst(object):
433
+ """
434
+ A class object that acts as essentially a namespace for Security constants.
435
+ """
436
+
437
+ kSSLSessionOptionBreakOnServerAuth = 0
438
+
439
+ kSSLProtocol2 = 1
440
+ kSSLProtocol3 = 2
441
+ kTLSProtocol1 = 4
442
+ kTLSProtocol11 = 7
443
+ kTLSProtocol12 = 8
444
+ # SecureTransport does not support TLS 1.3 even if there's a constant for it
445
+ kTLSProtocol13 = 10
446
+ kTLSProtocolMaxSupported = 999
447
+
448
+ kSSLClientSide = 1
449
+ kSSLStreamType = 0
450
+
451
+ kSecFormatPEMSequence = 10
452
+
453
+ kSecTrustResultInvalid = 0
454
+ kSecTrustResultProceed = 1
455
+ # This gap is present on purpose: this was kSecTrustResultConfirm, which
456
+ # is deprecated.
457
+ kSecTrustResultDeny = 3
458
+ kSecTrustResultUnspecified = 4
459
+ kSecTrustResultRecoverableTrustFailure = 5
460
+ kSecTrustResultFatalTrustFailure = 6
461
+ kSecTrustResultOtherError = 7
462
+
463
+ errSSLProtocol = -9800
464
+ errSSLWouldBlock = -9803
465
+ errSSLClosedGraceful = -9805
466
+ errSSLClosedNoNotify = -9816
467
+ errSSLClosedAbort = -9806
468
+
469
+ errSSLXCertChainInvalid = -9807
470
+ errSSLCrypto = -9809
471
+ errSSLInternal = -9810
472
+ errSSLCertExpired = -9814
473
+ errSSLCertNotYetValid = -9815
474
+ errSSLUnknownRootCert = -9812
475
+ errSSLNoRootCert = -9813
476
+ errSSLHostNameMismatch = -9843
477
+ errSSLPeerHandshakeFail = -9824
478
+ errSSLPeerUserCancelled = -9839
479
+ errSSLWeakPeerEphemeralDHKey = -9850
480
+ errSSLServerAuthCompleted = -9841
481
+ errSSLRecordOverflow = -9847
482
+
483
+ errSecVerifyFailed = -67808
484
+ errSecNoTrustSettings = -25263
485
+ errSecItemNotFound = -25300
486
+ errSecInvalidTrustSettings = -25262
487
+
488
+ # Cipher suites. We only pick the ones our default cipher string allows.
489
+ # Source: https://developer.apple.com/documentation/security/1550981-ssl_cipher_suite_values
490
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C
491
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030
492
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B
493
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F
494
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9
495
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8
496
+ TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F
497
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E
498
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024
499
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028
500
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A
501
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014
502
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B
503
+ TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039
504
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023
505
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027
506
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009
507
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013
508
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067
509
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033
510
+ TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D
511
+ TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C
512
+ TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D
513
+ TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C
514
+ TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035
515
+ TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F
516
+ TLS_AES_128_GCM_SHA256 = 0x1301
517
+ TLS_AES_256_GCM_SHA384 = 0x1302
518
+ TLS_AES_128_CCM_8_SHA256 = 0x1305
519
+ TLS_AES_128_CCM_SHA256 = 0x1304
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Low-level helpers for the SecureTransport bindings.
3
+
4
+ These are Python functions that are not directly related to the high-level APIs
5
+ but are necessary to get them to work. They include a whole bunch of low-level
6
+ CoreFoundation messing about and memory management. The concerns in this module
7
+ are almost entirely about trying to avoid memory leaks and providing
8
+ appropriate and useful assistance to the higher-level code.
9
+ """
10
+ import base64
11
+ import ctypes
12
+ import itertools
13
+ import os
14
+ import re
15
+ import ssl
16
+ import struct
17
+ import tempfile
18
+
19
+ from .bindings import CFConst, CoreFoundation, Security
20
+
21
+ # This regular expression is used to grab PEM data out of a PEM bundle.
22
+ _PEM_CERTS_RE = re.compile(
23
+ b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL
24
+ )
25
+
26
+
27
+ def _cf_data_from_bytes(bytestring):
28
+ """
29
+ Given a bytestring, create a CFData object from it. This CFData object must
30
+ be CFReleased by the caller.
31
+ """
32
+ return CoreFoundation.CFDataCreate(
33
+ CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring)
34
+ )
35
+
36
+
37
+ def _cf_dictionary_from_tuples(tuples):
38
+ """
39
+ Given a list of Python tuples, create an associated CFDictionary.
40
+ """
41
+ dictionary_size = len(tuples)
42
+
43
+ # We need to get the dictionary keys and values out in the same order.
44
+ keys = (t[0] for t in tuples)
45
+ values = (t[1] for t in tuples)
46
+ cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys)
47
+ cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values)
48
+
49
+ return CoreFoundation.CFDictionaryCreate(
50
+ CoreFoundation.kCFAllocatorDefault,
51
+ cf_keys,
52
+ cf_values,
53
+ dictionary_size,
54
+ CoreFoundation.kCFTypeDictionaryKeyCallBacks,
55
+ CoreFoundation.kCFTypeDictionaryValueCallBacks,
56
+ )
57
+
58
+
59
+ def _cfstr(py_bstr):
60
+ """
61
+ Given a Python binary data, create a CFString.
62
+ The string must be CFReleased by the caller.
63
+ """
64
+ c_str = ctypes.c_char_p(py_bstr)
65
+ cf_str = CoreFoundation.CFStringCreateWithCString(
66
+ CoreFoundation.kCFAllocatorDefault,
67
+ c_str,
68
+ CFConst.kCFStringEncodingUTF8,
69
+ )
70
+ return cf_str
71
+
72
+
73
+ def _create_cfstring_array(lst):
74
+ """
75
+ Given a list of Python binary data, create an associated CFMutableArray.
76
+ The array must be CFReleased by the caller.
77
+
78
+ Raises an ssl.SSLError on failure.
79
+ """
80
+ cf_arr = None
81
+ try:
82
+ cf_arr = CoreFoundation.CFArrayCreateMutable(
83
+ CoreFoundation.kCFAllocatorDefault,
84
+ 0,
85
+ ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
86
+ )
87
+ if not cf_arr:
88
+ raise MemoryError("Unable to allocate memory!")
89
+ for item in lst:
90
+ cf_str = _cfstr(item)
91
+ if not cf_str:
92
+ raise MemoryError("Unable to allocate memory!")
93
+ try:
94
+ CoreFoundation.CFArrayAppendValue(cf_arr, cf_str)
95
+ finally:
96
+ CoreFoundation.CFRelease(cf_str)
97
+ except BaseException as e:
98
+ if cf_arr:
99
+ CoreFoundation.CFRelease(cf_arr)
100
+ raise ssl.SSLError("Unable to allocate array: %s" % (e,))
101
+ return cf_arr
102
+
103
+
104
+ def _cf_string_to_unicode(value):
105
+ """
106
+ Creates a Unicode string from a CFString object. Used entirely for error
107
+ reporting.
108
+
109
+ Yes, it annoys me quite a lot that this function is this complex.
110
+ """
111
+ value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p))
112
+
113
+ string = CoreFoundation.CFStringGetCStringPtr(
114
+ value_as_void_p, CFConst.kCFStringEncodingUTF8
115
+ )
116
+ if string is None:
117
+ buffer = ctypes.create_string_buffer(1024)
118
+ result = CoreFoundation.CFStringGetCString(
119
+ value_as_void_p, buffer, 1024, CFConst.kCFStringEncodingUTF8
120
+ )
121
+ if not result:
122
+ raise OSError("Error copying C string from CFStringRef")
123
+ string = buffer.value
124
+ if string is not None:
125
+ string = string.decode("utf-8")
126
+ return string
127
+
128
+
129
+ def _assert_no_error(error, exception_class=None):
130
+ """
131
+ Checks the return code and throws an exception if there is an error to
132
+ report
133
+ """
134
+ if error == 0:
135
+ return
136
+
137
+ cf_error_string = Security.SecCopyErrorMessageString(error, None)
138
+ output = _cf_string_to_unicode(cf_error_string)
139
+ CoreFoundation.CFRelease(cf_error_string)
140
+
141
+ if output is None or output == u"":
142
+ output = u"OSStatus %s" % error
143
+
144
+ if exception_class is None:
145
+ exception_class = ssl.SSLError
146
+
147
+ raise exception_class(output)
148
+
149
+
150
+ def _cert_array_from_pem(pem_bundle):
151
+ """
152
+ Given a bundle of certs in PEM format, turns them into a CFArray of certs
153
+ that can be used to validate a cert chain.
154
+ """
155
+ # Normalize the PEM bundle's line endings.
156
+ pem_bundle = pem_bundle.replace(b"\r\n", b"\n")
157
+
158
+ der_certs = [
159
+ base64.b64decode(match.group(1)) for match in _PEM_CERTS_RE.finditer(pem_bundle)
160
+ ]
161
+ if not der_certs:
162
+ raise ssl.SSLError("No root certificates specified")
163
+
164
+ cert_array = CoreFoundation.CFArrayCreateMutable(
165
+ CoreFoundation.kCFAllocatorDefault,
166
+ 0,
167
+ ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
168
+ )
169
+ if not cert_array:
170
+ raise ssl.SSLError("Unable to allocate memory!")
171
+
172
+ try:
173
+ for der_bytes in der_certs:
174
+ certdata = _cf_data_from_bytes(der_bytes)
175
+ if not certdata:
176
+ raise ssl.SSLError("Unable to allocate memory!")
177
+ cert = Security.SecCertificateCreateWithData(
178
+ CoreFoundation.kCFAllocatorDefault, certdata
179
+ )
180
+ CoreFoundation.CFRelease(certdata)
181
+ if not cert:
182
+ raise ssl.SSLError("Unable to build cert object!")
183
+
184
+ CoreFoundation.CFArrayAppendValue(cert_array, cert)
185
+ CoreFoundation.CFRelease(cert)
186
+ except Exception:
187
+ # We need to free the array before the exception bubbles further.
188
+ # We only want to do that if an error occurs: otherwise, the caller
189
+ # should free.
190
+ CoreFoundation.CFRelease(cert_array)
191
+
192
+ return cert_array
193
+
194
+
195
+ def _is_cert(item):
196
+ """
197
+ Returns True if a given CFTypeRef is a certificate.
198
+ """
199
+ expected = Security.SecCertificateGetTypeID()
200
+ return CoreFoundation.CFGetTypeID(item) == expected
201
+
202
+
203
+ def _is_identity(item):
204
+ """
205
+ Returns True if a given CFTypeRef is an identity.
206
+ """
207
+ expected = Security.SecIdentityGetTypeID()
208
+ return CoreFoundation.CFGetTypeID(item) == expected
209
+
210
+
211
+ def _temporary_keychain():
212
+ """
213
+ This function creates a temporary Mac keychain that we can use to work with
214
+ credentials. This keychain uses a one-time password and a temporary file to
215
+ store the data. We expect to have one keychain per socket. The returned
216
+ SecKeychainRef must be freed by the caller, including calling
217
+ SecKeychainDelete.
218
+
219
+ Returns a tuple of the SecKeychainRef and the path to the temporary
220
+ directory that contains it.
221
+ """
222
+ # Unfortunately, SecKeychainCreate requires a path to a keychain. This
223
+ # means we cannot use mkstemp to use a generic temporary file. Instead,
224
+ # we're going to create a temporary directory and a filename to use there.
225
+ # This filename will be 8 random bytes expanded into base64. We also need
226
+ # some random bytes to password-protect the keychain we're creating, so we
227
+ # ask for 40 random bytes.
228
+ random_bytes = os.urandom(40)
229
+ filename = base64.b16encode(random_bytes[:8]).decode("utf-8")
230
+ password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8
231
+ tempdirectory = tempfile.mkdtemp()
232
+
233
+ keychain_path = os.path.join(tempdirectory, filename).encode("utf-8")
234
+
235
+ # We now want to create the keychain itself.
236
+ keychain = Security.SecKeychainRef()
237
+ status = Security.SecKeychainCreate(
238
+ keychain_path, len(password), password, False, None, ctypes.byref(keychain)
239
+ )
240
+ _assert_no_error(status)
241
+
242
+ # Having created the keychain, we want to pass it off to the caller.
243
+ return keychain, tempdirectory
244
+
245
+
246
+ def _load_items_from_file(keychain, path):
247
+ """
248
+ Given a single file, loads all the trust objects from it into arrays and
249
+ the keychain.
250
+ Returns a tuple of lists: the first list is a list of identities, the
251
+ second a list of certs.
252
+ """
253
+ certificates = []
254
+ identities = []
255
+ result_array = None
256
+
257
+ with open(path, "rb") as f:
258
+ raw_filedata = f.read()
259
+
260
+ try:
261
+ filedata = CoreFoundation.CFDataCreate(
262
+ CoreFoundation.kCFAllocatorDefault, raw_filedata, len(raw_filedata)
263
+ )
264
+ result_array = CoreFoundation.CFArrayRef()
265
+ result = Security.SecItemImport(
266
+ filedata, # cert data
267
+ None, # Filename, leaving it out for now
268
+ None, # What the type of the file is, we don't care
269
+ None, # what's in the file, we don't care
270
+ 0, # import flags
271
+ None, # key params, can include passphrase in the future
272
+ keychain, # The keychain to insert into
273
+ ctypes.byref(result_array), # Results
274
+ )
275
+ _assert_no_error(result)
276
+
277
+ # A CFArray is not very useful to us as an intermediary
278
+ # representation, so we are going to extract the objects we want
279
+ # and then free the array. We don't need to keep hold of keys: the
280
+ # keychain already has them!
281
+ result_count = CoreFoundation.CFArrayGetCount(result_array)
282
+ for index in range(result_count):
283
+ item = CoreFoundation.CFArrayGetValueAtIndex(result_array, index)
284
+ item = ctypes.cast(item, CoreFoundation.CFTypeRef)
285
+
286
+ if _is_cert(item):
287
+ CoreFoundation.CFRetain(item)
288
+ certificates.append(item)
289
+ elif _is_identity(item):
290
+ CoreFoundation.CFRetain(item)
291
+ identities.append(item)
292
+ finally:
293
+ if result_array:
294
+ CoreFoundation.CFRelease(result_array)
295
+
296
+ CoreFoundation.CFRelease(filedata)
297
+
298
+ return (identities, certificates)
299
+
300
+
301
+ def _load_client_cert_chain(keychain, *paths):
302
+ """
303
+ Load certificates and maybe keys from a number of files. Has the end goal
304
+ of returning a CFArray containing one SecIdentityRef, and then zero or more
305
+ SecCertificateRef objects, suitable for use as a client certificate trust
306
+ chain.
307
+ """
308
+ # Ok, the strategy.
309
+ #
310
+ # This relies on knowing that macOS will not give you a SecIdentityRef
311
+ # unless you have imported a key into a keychain. This is a somewhat
312
+ # artificial limitation of macOS (for example, it doesn't necessarily
313
+ # affect iOS), but there is nothing inside Security.framework that lets you
314
+ # get a SecIdentityRef without having a key in a keychain.
315
+ #
316
+ # So the policy here is we take all the files and iterate them in order.
317
+ # Each one will use SecItemImport to have one or more objects loaded from
318
+ # it. We will also point at a keychain that macOS can use to work with the
319
+ # private key.
320
+ #
321
+ # Once we have all the objects, we'll check what we actually have. If we
322
+ # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise,
323
+ # we'll take the first certificate (which we assume to be our leaf) and
324
+ # ask the keychain to give us a SecIdentityRef with that cert's associated
325
+ # key.
326
+ #
327
+ # We'll then return a CFArray containing the trust chain: one
328
+ # SecIdentityRef and then zero-or-more SecCertificateRef objects. The
329
+ # responsibility for freeing this CFArray will be with the caller. This
330
+ # CFArray must remain alive for the entire connection, so in practice it
331
+ # will be stored with a single SSLSocket, along with the reference to the
332
+ # keychain.
333
+ certificates = []
334
+ identities = []
335
+
336
+ # Filter out bad paths.
337
+ paths = (path for path in paths if path)
338
+
339
+ try:
340
+ for file_path in paths:
341
+ new_identities, new_certs = _load_items_from_file(keychain, file_path)
342
+ identities.extend(new_identities)
343
+ certificates.extend(new_certs)
344
+
345
+ # Ok, we have everything. The question is: do we have an identity? If
346
+ # not, we want to grab one from the first cert we have.
347
+ if not identities:
348
+ new_identity = Security.SecIdentityRef()
349
+ status = Security.SecIdentityCreateWithCertificate(
350
+ keychain, certificates[0], ctypes.byref(new_identity)
351
+ )
352
+ _assert_no_error(status)
353
+ identities.append(new_identity)
354
+
355
+ # We now want to release the original certificate, as we no longer
356
+ # need it.
357
+ CoreFoundation.CFRelease(certificates.pop(0))
358
+
359
+ # We now need to build a new CFArray that holds the trust chain.
360
+ trust_chain = CoreFoundation.CFArrayCreateMutable(
361
+ CoreFoundation.kCFAllocatorDefault,
362
+ 0,
363
+ ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks),
364
+ )
365
+ for item in itertools.chain(identities, certificates):
366
+ # ArrayAppendValue does a CFRetain on the item. That's fine,
367
+ # because the finally block will release our other refs to them.
368
+ CoreFoundation.CFArrayAppendValue(trust_chain, item)
369
+
370
+ return trust_chain
371
+ finally:
372
+ for obj in itertools.chain(identities, certificates):
373
+ CoreFoundation.CFRelease(obj)
374
+
375
+
376
+ TLS_PROTOCOL_VERSIONS = {
377
+ "SSLv2": (0, 2),
378
+ "SSLv3": (3, 0),
379
+ "TLSv1": (3, 1),
380
+ "TLSv1.1": (3, 2),
381
+ "TLSv1.2": (3, 3),
382
+ }
383
+
384
+
385
+ def _build_tls_unknown_ca_alert(version):
386
+ """
387
+ Builds a TLS alert record for an unknown CA.
388
+ """
389
+ ver_maj, ver_min = TLS_PROTOCOL_VERSIONS[version]
390
+ severity_fatal = 0x02
391
+ description_unknown_ca = 0x30
392
+ msg = struct.pack(">BB", severity_fatal, description_unknown_ca)
393
+ msg_len = len(msg)
394
+ record_type_alert = 0x15
395
+ record = struct.pack(">BBBH", record_type_alert, ver_maj, ver_min, msg_len) + msg
396
+ return record
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/appengine.py ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This module provides a pool manager that uses Google App Engine's
3
+ `URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
4
+
5
+ Example usage::
6
+
7
+ from pip._vendor.urllib3 import PoolManager
8
+ from pip._vendor.urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox
9
+
10
+ if is_appengine_sandbox():
11
+ # AppEngineManager uses AppEngine's URLFetch API behind the scenes
12
+ http = AppEngineManager()
13
+ else:
14
+ # PoolManager uses a socket-level API behind the scenes
15
+ http = PoolManager()
16
+
17
+ r = http.request('GET', 'https://google.com/')
18
+
19
+ There are `limitations <https://cloud.google.com/appengine/docs/python/\
20
+ urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be
21
+ the best choice for your application. There are three options for using
22
+ urllib3 on Google App Engine:
23
+
24
+ 1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is
25
+ cost-effective in many circumstances as long as your usage is within the
26
+ limitations.
27
+ 2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets.
28
+ Sockets also have `limitations and restrictions
29
+ <https://cloud.google.com/appengine/docs/python/sockets/\
30
+ #limitations-and-restrictions>`_ and have a lower free quota than URLFetch.
31
+ To use sockets, be sure to specify the following in your ``app.yaml``::
32
+
33
+ env_variables:
34
+ GAE_USE_SOCKETS_HTTPLIB : 'true'
35
+
36
+ 3. If you are using `App Engine Flexible
37
+ <https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard
38
+ :class:`PoolManager` without any configuration or special environment variables.
39
+ """
40
+
41
+ from __future__ import absolute_import
42
+
43
+ import io
44
+ import logging
45
+ import warnings
46
+
47
+ from ..exceptions import (
48
+ HTTPError,
49
+ HTTPWarning,
50
+ MaxRetryError,
51
+ ProtocolError,
52
+ SSLError,
53
+ TimeoutError,
54
+ )
55
+ from ..packages.six.moves.urllib.parse import urljoin
56
+ from ..request import RequestMethods
57
+ from ..response import HTTPResponse
58
+ from ..util.retry import Retry
59
+ from ..util.timeout import Timeout
60
+ from . import _appengine_environ
61
+
62
+ try:
63
+ from google.appengine.api import urlfetch
64
+ except ImportError:
65
+ urlfetch = None
66
+
67
+
68
+ log = logging.getLogger(__name__)
69
+
70
+
71
+ class AppEnginePlatformWarning(HTTPWarning):
72
+ pass
73
+
74
+
75
+ class AppEnginePlatformError(HTTPError):
76
+ pass
77
+
78
+
79
+ class AppEngineManager(RequestMethods):
80
+ """
81
+ Connection manager for Google App Engine sandbox applications.
82
+
83
+ This manager uses the URLFetch service directly instead of using the
84
+ emulated httplib, and is subject to URLFetch limitations as described in
85
+ the App Engine documentation `here
86
+ <https://cloud.google.com/appengine/docs/python/urlfetch>`_.
87
+
88
+ Notably it will raise an :class:`AppEnginePlatformError` if:
89
+ * URLFetch is not available.
90
+ * If you attempt to use this on App Engine Flexible, as full socket
91
+ support is available.
92
+ * If a request size is more than 10 megabytes.
93
+ * If a response size is more than 32 megabytes.
94
+ * If you use an unsupported request method such as OPTIONS.
95
+
96
+ Beyond those cases, it will raise normal urllib3 errors.
97
+ """
98
+
99
+ def __init__(
100
+ self,
101
+ headers=None,
102
+ retries=None,
103
+ validate_certificate=True,
104
+ urlfetch_retries=True,
105
+ ):
106
+ if not urlfetch:
107
+ raise AppEnginePlatformError(
108
+ "URLFetch is not available in this environment."
109
+ )
110
+
111
+ warnings.warn(
112
+ "urllib3 is using URLFetch on Google App Engine sandbox instead "
113
+ "of sockets. To use sockets directly instead of URLFetch see "
114
+ "https://urllib3.readthedocs.io/en/1.26.x/reference/urllib3.contrib.html.",
115
+ AppEnginePlatformWarning,
116
+ )
117
+
118
+ RequestMethods.__init__(self, headers)
119
+ self.validate_certificate = validate_certificate
120
+ self.urlfetch_retries = urlfetch_retries
121
+
122
+ self.retries = retries or Retry.DEFAULT
123
+
124
+ def __enter__(self):
125
+ return self
126
+
127
+ def __exit__(self, exc_type, exc_val, exc_tb):
128
+ # Return False to re-raise any potential exceptions
129
+ return False
130
+
131
+ def urlopen(
132
+ self,
133
+ method,
134
+ url,
135
+ body=None,
136
+ headers=None,
137
+ retries=None,
138
+ redirect=True,
139
+ timeout=Timeout.DEFAULT_TIMEOUT,
140
+ **response_kw
141
+ ):
142
+
143
+ retries = self._get_retries(retries, redirect)
144
+
145
+ try:
146
+ follow_redirects = redirect and retries.redirect != 0 and retries.total
147
+ response = urlfetch.fetch(
148
+ url,
149
+ payload=body,
150
+ method=method,
151
+ headers=headers or {},
152
+ allow_truncated=False,
153
+ follow_redirects=self.urlfetch_retries and follow_redirects,
154
+ deadline=self._get_absolute_timeout(timeout),
155
+ validate_certificate=self.validate_certificate,
156
+ )
157
+ except urlfetch.DeadlineExceededError as e:
158
+ raise TimeoutError(self, e)
159
+
160
+ except urlfetch.InvalidURLError as e:
161
+ if "too large" in str(e):
162
+ raise AppEnginePlatformError(
163
+ "URLFetch request too large, URLFetch only "
164
+ "supports requests up to 10mb in size.",
165
+ e,
166
+ )
167
+ raise ProtocolError(e)
168
+
169
+ except urlfetch.DownloadError as e:
170
+ if "Too many redirects" in str(e):
171
+ raise MaxRetryError(self, url, reason=e)
172
+ raise ProtocolError(e)
173
+
174
+ except urlfetch.ResponseTooLargeError as e:
175
+ raise AppEnginePlatformError(
176
+ "URLFetch response too large, URLFetch only supports"
177
+ "responses up to 32mb in size.",
178
+ e,
179
+ )
180
+
181
+ except urlfetch.SSLCertificateError as e:
182
+ raise SSLError(e)
183
+
184
+ except urlfetch.InvalidMethodError as e:
185
+ raise AppEnginePlatformError(
186
+ "URLFetch does not support method: %s" % method, e
187
+ )
188
+
189
+ http_response = self._urlfetch_response_to_http_response(
190
+ response, retries=retries, **response_kw
191
+ )
192
+
193
+ # Handle redirect?
194
+ redirect_location = redirect and http_response.get_redirect_location()
195
+ if redirect_location:
196
+ # Check for redirect response
197
+ if self.urlfetch_retries and retries.raise_on_redirect:
198
+ raise MaxRetryError(self, url, "too many redirects")
199
+ else:
200
+ if http_response.status == 303:
201
+ method = "GET"
202
+
203
+ try:
204
+ retries = retries.increment(
205
+ method, url, response=http_response, _pool=self
206
+ )
207
+ except MaxRetryError:
208
+ if retries.raise_on_redirect:
209
+ raise MaxRetryError(self, url, "too many redirects")
210
+ return http_response
211
+
212
+ retries.sleep_for_retry(http_response)
213
+ log.debug("Redirecting %s -> %s", url, redirect_location)
214
+ redirect_url = urljoin(url, redirect_location)
215
+ return self.urlopen(
216
+ method,
217
+ redirect_url,
218
+ body,
219
+ headers,
220
+ retries=retries,
221
+ redirect=redirect,
222
+ timeout=timeout,
223
+ **response_kw
224
+ )
225
+
226
+ # Check if we should retry the HTTP response.
227
+ has_retry_after = bool(http_response.getheader("Retry-After"))
228
+ if retries.is_retry(method, http_response.status, has_retry_after):
229
+ retries = retries.increment(method, url, response=http_response, _pool=self)
230
+ log.debug("Retry: %s", url)
231
+ retries.sleep(http_response)
232
+ return self.urlopen(
233
+ method,
234
+ url,
235
+ body=body,
236
+ headers=headers,
237
+ retries=retries,
238
+ redirect=redirect,
239
+ timeout=timeout,
240
+ **response_kw
241
+ )
242
+
243
+ return http_response
244
+
245
+ def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw):
246
+
247
+ if is_prod_appengine():
248
+ # Production GAE handles deflate encoding automatically, but does
249
+ # not remove the encoding header.
250
+ content_encoding = urlfetch_resp.headers.get("content-encoding")
251
+
252
+ if content_encoding == "deflate":
253
+ del urlfetch_resp.headers["content-encoding"]
254
+
255
+ transfer_encoding = urlfetch_resp.headers.get("transfer-encoding")
256
+ # We have a full response's content,
257
+ # so let's make sure we don't report ourselves as chunked data.
258
+ if transfer_encoding == "chunked":
259
+ encodings = transfer_encoding.split(",")
260
+ encodings.remove("chunked")
261
+ urlfetch_resp.headers["transfer-encoding"] = ",".join(encodings)
262
+
263
+ original_response = HTTPResponse(
264
+ # In order for decoding to work, we must present the content as
265
+ # a file-like object.
266
+ body=io.BytesIO(urlfetch_resp.content),
267
+ msg=urlfetch_resp.header_msg,
268
+ headers=urlfetch_resp.headers,
269
+ status=urlfetch_resp.status_code,
270
+ **response_kw
271
+ )
272
+
273
+ return HTTPResponse(
274
+ body=io.BytesIO(urlfetch_resp.content),
275
+ headers=urlfetch_resp.headers,
276
+ status=urlfetch_resp.status_code,
277
+ original_response=original_response,
278
+ **response_kw
279
+ )
280
+
281
+ def _get_absolute_timeout(self, timeout):
282
+ if timeout is Timeout.DEFAULT_TIMEOUT:
283
+ return None # Defer to URLFetch's default.
284
+ if isinstance(timeout, Timeout):
285
+ if timeout._read is not None or timeout._connect is not None:
286
+ warnings.warn(
287
+ "URLFetch does not support granular timeout settings, "
288
+ "reverting to total or default URLFetch timeout.",
289
+ AppEnginePlatformWarning,
290
+ )
291
+ return timeout.total
292
+ return timeout
293
+
294
+ def _get_retries(self, retries, redirect):
295
+ if not isinstance(retries, Retry):
296
+ retries = Retry.from_int(retries, redirect=redirect, default=self.retries)
297
+
298
+ if retries.connect or retries.read or retries.redirect:
299
+ warnings.warn(
300
+ "URLFetch only supports total retries and does not "
301
+ "recognize connect, read, or redirect retry parameters.",
302
+ AppEnginePlatformWarning,
303
+ )
304
+
305
+ return retries
306
+
307
+
308
+ # Alias methods from _appengine_environ to maintain public API interface.
309
+
310
+ is_appengine = _appengine_environ.is_appengine
311
+ is_appengine_sandbox = _appengine_environ.is_appengine_sandbox
312
+ is_local_appengine = _appengine_environ.is_local_appengine
313
+ is_prod_appengine = _appengine_environ.is_prod_appengine
314
+ is_prod_appengine_mvms = _appengine_environ.is_prod_appengine_mvms
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ NTLM authenticating pool, contributed by erikcederstran
3
+
4
+ Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10
5
+ """
6
+ from __future__ import absolute_import
7
+
8
+ import warnings
9
+ from logging import getLogger
10
+
11
+ from ntlm import ntlm
12
+
13
+ from .. import HTTPSConnectionPool
14
+ from ..packages.six.moves.http_client import HTTPSConnection
15
+
16
+ warnings.warn(
17
+ "The 'urllib3.contrib.ntlmpool' module is deprecated and will be removed "
18
+ "in urllib3 v2.0 release, urllib3 is not able to support it properly due "
19
+ "to reasons listed in issue: https://github.com/urllib3/urllib3/issues/2282. "
20
+ "If you are a user of this module please comment in the mentioned issue.",
21
+ DeprecationWarning,
22
+ )
23
+
24
+ log = getLogger(__name__)
25
+
26
+
27
+ class NTLMConnectionPool(HTTPSConnectionPool):
28
+ """
29
+ Implements an NTLM authentication version of an urllib3 connection pool
30
+ """
31
+
32
+ scheme = "https"
33
+
34
+ def __init__(self, user, pw, authurl, *args, **kwargs):
35
+ """
36
+ authurl is a random URL on the server that is protected by NTLM.
37
+ user is the Windows user, probably in the DOMAIN\\username format.
38
+ pw is the password for the user.
39
+ """
40
+ super(NTLMConnectionPool, self).__init__(*args, **kwargs)
41
+ self.authurl = authurl
42
+ self.rawuser = user
43
+ user_parts = user.split("\\", 1)
44
+ self.domain = user_parts[0].upper()
45
+ self.user = user_parts[1]
46
+ self.pw = pw
47
+
48
+ def _new_conn(self):
49
+ # Performs the NTLM handshake that secures the connection. The socket
50
+ # must be kept open while requests are performed.
51
+ self.num_connections += 1
52
+ log.debug(
53
+ "Starting NTLM HTTPS connection no. %d: https://%s%s",
54
+ self.num_connections,
55
+ self.host,
56
+ self.authurl,
57
+ )
58
+
59
+ headers = {"Connection": "Keep-Alive"}
60
+ req_header = "Authorization"
61
+ resp_header = "www-authenticate"
62
+
63
+ conn = HTTPSConnection(host=self.host, port=self.port)
64
+
65
+ # Send negotiation message
66
+ headers[req_header] = "NTLM %s" % ntlm.create_NTLM_NEGOTIATE_MESSAGE(
67
+ self.rawuser
68
+ )
69
+ log.debug("Request headers: %s", headers)
70
+ conn.request("GET", self.authurl, None, headers)
71
+ res = conn.getresponse()
72
+ reshdr = dict(res.getheaders())
73
+ log.debug("Response status: %s %s", res.status, res.reason)
74
+ log.debug("Response headers: %s", reshdr)
75
+ log.debug("Response data: %s [...]", res.read(100))
76
+
77
+ # Remove the reference to the socket, so that it can not be closed by
78
+ # the response object (we want to keep the socket open)
79
+ res.fp = None
80
+
81
+ # Server should respond with a challenge message
82
+ auth_header_values = reshdr[resp_header].split(", ")
83
+ auth_header_value = None
84
+ for s in auth_header_values:
85
+ if s[:5] == "NTLM ":
86
+ auth_header_value = s[5:]
87
+ if auth_header_value is None:
88
+ raise Exception(
89
+ "Unexpected %s response header: %s" % (resp_header, reshdr[resp_header])
90
+ )
91
+
92
+ # Send authentication message
93
+ ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(
94
+ auth_header_value
95
+ )
96
+ auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(
97
+ ServerChallenge, self.user, self.domain, self.pw, NegotiateFlags
98
+ )
99
+ headers[req_header] = "NTLM %s" % auth_msg
100
+ log.debug("Request headers: %s", headers)
101
+ conn.request("GET", self.authurl, None, headers)
102
+ res = conn.getresponse()
103
+ log.debug("Response status: %s %s", res.status, res.reason)
104
+ log.debug("Response headers: %s", dict(res.getheaders()))
105
+ log.debug("Response data: %s [...]", res.read()[:100])
106
+ if res.status != 200:
107
+ if res.status == 401:
108
+ raise Exception("Server rejected request: wrong username or password")
109
+ raise Exception("Wrong server response: %s %s" % (res.status, res.reason))
110
+
111
+ res.fp = None
112
+ log.debug("Connection established")
113
+ return conn
114
+
115
+ def urlopen(
116
+ self,
117
+ method,
118
+ url,
119
+ body=None,
120
+ headers=None,
121
+ retries=3,
122
+ redirect=True,
123
+ assert_same_host=True,
124
+ ):
125
+ if headers is None:
126
+ headers = {}
127
+ headers["Connection"] = "Keep-Alive"
128
+ return super(NTLMConnectionPool, self).urlopen(
129
+ method, url, body, headers, retries, redirect, assert_same_host
130
+ )
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py ADDED
@@ -0,0 +1,511 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ TLS with SNI_-support for Python 2. Follow these instructions if you would
3
+ like to verify TLS certificates in Python 2. Note, the default libraries do
4
+ *not* do certificate checking; you need to do additional work to validate
5
+ certificates yourself.
6
+
7
+ This needs the following packages installed:
8
+
9
+ * `pyOpenSSL`_ (tested with 16.0.0)
10
+ * `cryptography`_ (minimum 1.3.4, from pyopenssl)
11
+ * `idna`_ (minimum 2.0, from cryptography)
12
+
13
+ However, pyopenssl depends on cryptography, which depends on idna, so while we
14
+ use all three directly here we end up having relatively few packages required.
15
+
16
+ You can install them with the following command:
17
+
18
+ .. code-block:: bash
19
+
20
+ $ python -m pip install pyopenssl cryptography idna
21
+
22
+ To activate certificate checking, call
23
+ :func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
24
+ before you begin making HTTP requests. This can be done in a ``sitecustomize``
25
+ module, or at any other time before your application begins using ``urllib3``,
26
+ like this:
27
+
28
+ .. code-block:: python
29
+
30
+ try:
31
+ import urllib3.contrib.pyopenssl
32
+ urllib3.contrib.pyopenssl.inject_into_urllib3()
33
+ except ImportError:
34
+ pass
35
+
36
+ Now you can use :mod:`urllib3` as you normally would, and it will support SNI
37
+ when the required modules are installed.
38
+
39
+ Activating this module also has the positive side effect of disabling SSL/TLS
40
+ compression in Python 2 (see `CRIME attack`_).
41
+
42
+ .. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication
43
+ .. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)
44
+ .. _pyopenssl: https://www.pyopenssl.org
45
+ .. _cryptography: https://cryptography.io
46
+ .. _idna: https://github.com/kjd/idna
47
+ """
48
+ from __future__ import absolute_import
49
+
50
+ import OpenSSL.SSL
51
+ from cryptography import x509
52
+ from cryptography.hazmat.backends.openssl import backend as openssl_backend
53
+ from cryptography.hazmat.backends.openssl.x509 import _Certificate
54
+
55
+ try:
56
+ from cryptography.x509 import UnsupportedExtension
57
+ except ImportError:
58
+ # UnsupportedExtension is gone in cryptography >= 2.1.0
59
+ class UnsupportedExtension(Exception):
60
+ pass
61
+
62
+
63
+ from io import BytesIO
64
+ from socket import error as SocketError
65
+ from socket import timeout
66
+
67
+ try: # Platform-specific: Python 2
68
+ from socket import _fileobject
69
+ except ImportError: # Platform-specific: Python 3
70
+ _fileobject = None
71
+ from ..packages.backports.makefile import backport_makefile
72
+
73
+ import logging
74
+ import ssl
75
+ import sys
76
+
77
+ from .. import util
78
+ from ..packages import six
79
+ from ..util.ssl_ import PROTOCOL_TLS_CLIENT
80
+
81
+ __all__ = ["inject_into_urllib3", "extract_from_urllib3"]
82
+
83
+ # SNI always works.
84
+ HAS_SNI = True
85
+
86
+ # Map from urllib3 to PyOpenSSL compatible parameter-values.
87
+ _openssl_versions = {
88
+ util.PROTOCOL_TLS: OpenSSL.SSL.SSLv23_METHOD,
89
+ PROTOCOL_TLS_CLIENT: OpenSSL.SSL.SSLv23_METHOD,
90
+ ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD,
91
+ }
92
+
93
+ if hasattr(ssl, "PROTOCOL_SSLv3") and hasattr(OpenSSL.SSL, "SSLv3_METHOD"):
94
+ _openssl_versions[ssl.PROTOCOL_SSLv3] = OpenSSL.SSL.SSLv3_METHOD
95
+
96
+ if hasattr(ssl, "PROTOCOL_TLSv1_1") and hasattr(OpenSSL.SSL, "TLSv1_1_METHOD"):
97
+ _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD
98
+
99
+ if hasattr(ssl, "PROTOCOL_TLSv1_2") and hasattr(OpenSSL.SSL, "TLSv1_2_METHOD"):
100
+ _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD
101
+
102
+
103
+ _stdlib_to_openssl_verify = {
104
+ ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE,
105
+ ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER,
106
+ ssl.CERT_REQUIRED: OpenSSL.SSL.VERIFY_PEER
107
+ + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
108
+ }
109
+ _openssl_to_stdlib_verify = dict((v, k) for k, v in _stdlib_to_openssl_verify.items())
110
+
111
+ # OpenSSL will only write 16K at a time
112
+ SSL_WRITE_BLOCKSIZE = 16384
113
+
114
+ orig_util_HAS_SNI = util.HAS_SNI
115
+ orig_util_SSLContext = util.ssl_.SSLContext
116
+
117
+
118
+ log = logging.getLogger(__name__)
119
+
120
+
121
+ def inject_into_urllib3():
122
+ "Monkey-patch urllib3 with PyOpenSSL-backed SSL-support."
123
+
124
+ _validate_dependencies_met()
125
+
126
+ util.SSLContext = PyOpenSSLContext
127
+ util.ssl_.SSLContext = PyOpenSSLContext
128
+ util.HAS_SNI = HAS_SNI
129
+ util.ssl_.HAS_SNI = HAS_SNI
130
+ util.IS_PYOPENSSL = True
131
+ util.ssl_.IS_PYOPENSSL = True
132
+
133
+
134
+ def extract_from_urllib3():
135
+ "Undo monkey-patching by :func:`inject_into_urllib3`."
136
+
137
+ util.SSLContext = orig_util_SSLContext
138
+ util.ssl_.SSLContext = orig_util_SSLContext
139
+ util.HAS_SNI = orig_util_HAS_SNI
140
+ util.ssl_.HAS_SNI = orig_util_HAS_SNI
141
+ util.IS_PYOPENSSL = False
142
+ util.ssl_.IS_PYOPENSSL = False
143
+
144
+
145
+ def _validate_dependencies_met():
146
+ """
147
+ Verifies that PyOpenSSL's package-level dependencies have been met.
148
+ Throws `ImportError` if they are not met.
149
+ """
150
+ # Method added in `cryptography==1.1`; not available in older versions
151
+ from cryptography.x509.extensions import Extensions
152
+
153
+ if getattr(Extensions, "get_extension_for_class", None) is None:
154
+ raise ImportError(
155
+ "'cryptography' module missing required functionality. "
156
+ "Try upgrading to v1.3.4 or newer."
157
+ )
158
+
159
+ # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509
160
+ # attribute is only present on those versions.
161
+ from OpenSSL.crypto import X509
162
+
163
+ x509 = X509()
164
+ if getattr(x509, "_x509", None) is None:
165
+ raise ImportError(
166
+ "'pyOpenSSL' module missing required functionality. "
167
+ "Try upgrading to v0.14 or newer."
168
+ )
169
+
170
+
171
+ def _dnsname_to_stdlib(name):
172
+ """
173
+ Converts a dNSName SubjectAlternativeName field to the form used by the
174
+ standard library on the given Python version.
175
+
176
+ Cryptography produces a dNSName as a unicode string that was idna-decoded
177
+ from ASCII bytes. We need to idna-encode that string to get it back, and
178
+ then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib
179
+ uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8).
180
+
181
+ If the name cannot be idna-encoded then we return None signalling that
182
+ the name given should be skipped.
183
+ """
184
+
185
+ def idna_encode(name):
186
+ """
187
+ Borrowed wholesale from the Python Cryptography Project. It turns out
188
+ that we can't just safely call `idna.encode`: it can explode for
189
+ wildcard names. This avoids that problem.
190
+ """
191
+ from pip._vendor import idna
192
+
193
+ try:
194
+ for prefix in [u"*.", u"."]:
195
+ if name.startswith(prefix):
196
+ name = name[len(prefix) :]
197
+ return prefix.encode("ascii") + idna.encode(name)
198
+ return idna.encode(name)
199
+ except idna.core.IDNAError:
200
+ return None
201
+
202
+ # Don't send IPv6 addresses through the IDNA encoder.
203
+ if ":" in name:
204
+ return name
205
+
206
+ name = idna_encode(name)
207
+ if name is None:
208
+ return None
209
+ elif sys.version_info >= (3, 0):
210
+ name = name.decode("utf-8")
211
+ return name
212
+
213
+
214
+ def get_subj_alt_name(peer_cert):
215
+ """
216
+ Given an PyOpenSSL certificate, provides all the subject alternative names.
217
+ """
218
+ # Pass the cert to cryptography, which has much better APIs for this.
219
+ if hasattr(peer_cert, "to_cryptography"):
220
+ cert = peer_cert.to_cryptography()
221
+ else:
222
+ # This is technically using private APIs, but should work across all
223
+ # relevant versions before PyOpenSSL got a proper API for this.
224
+ cert = _Certificate(openssl_backend, peer_cert._x509)
225
+
226
+ # We want to find the SAN extension. Ask Cryptography to locate it (it's
227
+ # faster than looping in Python)
228
+ try:
229
+ ext = cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value
230
+ except x509.ExtensionNotFound:
231
+ # No such extension, return the empty list.
232
+ return []
233
+ except (
234
+ x509.DuplicateExtension,
235
+ UnsupportedExtension,
236
+ x509.UnsupportedGeneralNameType,
237
+ UnicodeError,
238
+ ) as e:
239
+ # A problem has been found with the quality of the certificate. Assume
240
+ # no SAN field is present.
241
+ log.warning(
242
+ "A problem was encountered with the certificate that prevented "
243
+ "urllib3 from finding the SubjectAlternativeName field. This can "
244
+ "affect certificate validation. The error was %s",
245
+ e,
246
+ )
247
+ return []
248
+
249
+ # We want to return dNSName and iPAddress fields. We need to cast the IPs
250
+ # back to strings because the match_hostname function wants them as
251
+ # strings.
252
+ # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8
253
+ # decoded. This is pretty frustrating, but that's what the standard library
254
+ # does with certificates, and so we need to attempt to do the same.
255
+ # We also want to skip over names which cannot be idna encoded.
256
+ names = [
257
+ ("DNS", name)
258
+ for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName))
259
+ if name is not None
260
+ ]
261
+ names.extend(
262
+ ("IP Address", str(name)) for name in ext.get_values_for_type(x509.IPAddress)
263
+ )
264
+
265
+ return names
266
+
267
+
268
+ class WrappedSocket(object):
269
+ """API-compatibility wrapper for Python OpenSSL's Connection-class.
270
+
271
+ Note: _makefile_refs, _drop() and _reuse() are needed for the garbage
272
+ collector of pypy.
273
+ """
274
+
275
+ def __init__(self, connection, socket, suppress_ragged_eofs=True):
276
+ self.connection = connection
277
+ self.socket = socket
278
+ self.suppress_ragged_eofs = suppress_ragged_eofs
279
+ self._makefile_refs = 0
280
+ self._closed = False
281
+
282
+ def fileno(self):
283
+ return self.socket.fileno()
284
+
285
+ # Copy-pasted from Python 3.5 source code
286
+ def _decref_socketios(self):
287
+ if self._makefile_refs > 0:
288
+ self._makefile_refs -= 1
289
+ if self._closed:
290
+ self.close()
291
+
292
+ def recv(self, *args, **kwargs):
293
+ try:
294
+ data = self.connection.recv(*args, **kwargs)
295
+ except OpenSSL.SSL.SysCallError as e:
296
+ if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"):
297
+ return b""
298
+ else:
299
+ raise SocketError(str(e))
300
+ except OpenSSL.SSL.ZeroReturnError:
301
+ if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
302
+ return b""
303
+ else:
304
+ raise
305
+ except OpenSSL.SSL.WantReadError:
306
+ if not util.wait_for_read(self.socket, self.socket.gettimeout()):
307
+ raise timeout("The read operation timed out")
308
+ else:
309
+ return self.recv(*args, **kwargs)
310
+
311
+ # TLS 1.3 post-handshake authentication
312
+ except OpenSSL.SSL.Error as e:
313
+ raise ssl.SSLError("read error: %r" % e)
314
+ else:
315
+ return data
316
+
317
+ def recv_into(self, *args, **kwargs):
318
+ try:
319
+ return self.connection.recv_into(*args, **kwargs)
320
+ except OpenSSL.SSL.SysCallError as e:
321
+ if self.suppress_ragged_eofs and e.args == (-1, "Unexpected EOF"):
322
+ return 0
323
+ else:
324
+ raise SocketError(str(e))
325
+ except OpenSSL.SSL.ZeroReturnError:
326
+ if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN:
327
+ return 0
328
+ else:
329
+ raise
330
+ except OpenSSL.SSL.WantReadError:
331
+ if not util.wait_for_read(self.socket, self.socket.gettimeout()):
332
+ raise timeout("The read operation timed out")
333
+ else:
334
+ return self.recv_into(*args, **kwargs)
335
+
336
+ # TLS 1.3 post-handshake authentication
337
+ except OpenSSL.SSL.Error as e:
338
+ raise ssl.SSLError("read error: %r" % e)
339
+
340
+ def settimeout(self, timeout):
341
+ return self.socket.settimeout(timeout)
342
+
343
+ def _send_until_done(self, data):
344
+ while True:
345
+ try:
346
+ return self.connection.send(data)
347
+ except OpenSSL.SSL.WantWriteError:
348
+ if not util.wait_for_write(self.socket, self.socket.gettimeout()):
349
+ raise timeout()
350
+ continue
351
+ except OpenSSL.SSL.SysCallError as e:
352
+ raise SocketError(str(e))
353
+
354
+ def sendall(self, data):
355
+ total_sent = 0
356
+ while total_sent < len(data):
357
+ sent = self._send_until_done(
358
+ data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE]
359
+ )
360
+ total_sent += sent
361
+
362
+ def shutdown(self):
363
+ # FIXME rethrow compatible exceptions should we ever use this
364
+ self.connection.shutdown()
365
+
366
+ def close(self):
367
+ if self._makefile_refs < 1:
368
+ try:
369
+ self._closed = True
370
+ return self.connection.close()
371
+ except OpenSSL.SSL.Error:
372
+ return
373
+ else:
374
+ self._makefile_refs -= 1
375
+
376
+ def getpeercert(self, binary_form=False):
377
+ x509 = self.connection.get_peer_certificate()
378
+
379
+ if not x509:
380
+ return x509
381
+
382
+ if binary_form:
383
+ return OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_ASN1, x509)
384
+
385
+ return {
386
+ "subject": ((("commonName", x509.get_subject().CN),),),
387
+ "subjectAltName": get_subj_alt_name(x509),
388
+ }
389
+
390
+ def version(self):
391
+ return self.connection.get_protocol_version_name()
392
+
393
+ def _reuse(self):
394
+ self._makefile_refs += 1
395
+
396
+ def _drop(self):
397
+ if self._makefile_refs < 1:
398
+ self.close()
399
+ else:
400
+ self._makefile_refs -= 1
401
+
402
+
403
+ if _fileobject: # Platform-specific: Python 2
404
+
405
+ def makefile(self, mode, bufsize=-1):
406
+ self._makefile_refs += 1
407
+ return _fileobject(self, mode, bufsize, close=True)
408
+
409
+
410
+ else: # Platform-specific: Python 3
411
+ makefile = backport_makefile
412
+
413
+ WrappedSocket.makefile = makefile
414
+
415
+
416
+ class PyOpenSSLContext(object):
417
+ """
418
+ I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible
419
+ for translating the interface of the standard library ``SSLContext`` object
420
+ to calls into PyOpenSSL.
421
+ """
422
+
423
+ def __init__(self, protocol):
424
+ self.protocol = _openssl_versions[protocol]
425
+ self._ctx = OpenSSL.SSL.Context(self.protocol)
426
+ self._options = 0
427
+ self.check_hostname = False
428
+
429
+ @property
430
+ def options(self):
431
+ return self._options
432
+
433
+ @options.setter
434
+ def options(self, value):
435
+ self._options = value
436
+ self._ctx.set_options(value)
437
+
438
+ @property
439
+ def verify_mode(self):
440
+ return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()]
441
+
442
+ @verify_mode.setter
443
+ def verify_mode(self, value):
444
+ self._ctx.set_verify(_stdlib_to_openssl_verify[value], _verify_callback)
445
+
446
+ def set_default_verify_paths(self):
447
+ self._ctx.set_default_verify_paths()
448
+
449
+ def set_ciphers(self, ciphers):
450
+ if isinstance(ciphers, six.text_type):
451
+ ciphers = ciphers.encode("utf-8")
452
+ self._ctx.set_cipher_list(ciphers)
453
+
454
+ def load_verify_locations(self, cafile=None, capath=None, cadata=None):
455
+ if cafile is not None:
456
+ cafile = cafile.encode("utf-8")
457
+ if capath is not None:
458
+ capath = capath.encode("utf-8")
459
+ try:
460
+ self._ctx.load_verify_locations(cafile, capath)
461
+ if cadata is not None:
462
+ self._ctx.load_verify_locations(BytesIO(cadata))
463
+ except OpenSSL.SSL.Error as e:
464
+ raise ssl.SSLError("unable to load trusted certificates: %r" % e)
465
+
466
+ def load_cert_chain(self, certfile, keyfile=None, password=None):
467
+ self._ctx.use_certificate_chain_file(certfile)
468
+ if password is not None:
469
+ if not isinstance(password, six.binary_type):
470
+ password = password.encode("utf-8")
471
+ self._ctx.set_passwd_cb(lambda *_: password)
472
+ self._ctx.use_privatekey_file(keyfile or certfile)
473
+
474
+ def set_alpn_protocols(self, protocols):
475
+ protocols = [six.ensure_binary(p) for p in protocols]
476
+ return self._ctx.set_alpn_protos(protocols)
477
+
478
+ def wrap_socket(
479
+ self,
480
+ sock,
481
+ server_side=False,
482
+ do_handshake_on_connect=True,
483
+ suppress_ragged_eofs=True,
484
+ server_hostname=None,
485
+ ):
486
+ cnx = OpenSSL.SSL.Connection(self._ctx, sock)
487
+
488
+ if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3
489
+ server_hostname = server_hostname.encode("utf-8")
490
+
491
+ if server_hostname is not None:
492
+ cnx.set_tlsext_host_name(server_hostname)
493
+
494
+ cnx.set_connect_state()
495
+
496
+ while True:
497
+ try:
498
+ cnx.do_handshake()
499
+ except OpenSSL.SSL.WantReadError:
500
+ if not util.wait_for_read(sock, sock.gettimeout()):
501
+ raise timeout("select timed out")
502
+ continue
503
+ except OpenSSL.SSL.Error as e:
504
+ raise ssl.SSLError("bad handshake: %r" % e)
505
+ break
506
+
507
+ return WrappedSocket(cnx, sock)
508
+
509
+
510
+ def _verify_callback(cnx, x509, err_no, err_depth, return_code):
511
+ return err_no == 0
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/securetransport.py ADDED
@@ -0,0 +1,922 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ SecureTranport support for urllib3 via ctypes.
3
+
4
+ This makes platform-native TLS available to urllib3 users on macOS without the
5
+ use of a compiler. This is an important feature because the Python Package
6
+ Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL
7
+ that ships with macOS is not capable of doing TLSv1.2. The only way to resolve
8
+ this is to give macOS users an alternative solution to the problem, and that
9
+ solution is to use SecureTransport.
10
+
11
+ We use ctypes here because this solution must not require a compiler. That's
12
+ because pip is not allowed to require a compiler either.
13
+
14
+ This is not intended to be a seriously long-term solution to this problem.
15
+ The hope is that PEP 543 will eventually solve this issue for us, at which
16
+ point we can retire this contrib module. But in the short term, we need to
17
+ solve the impending tire fire that is Python on Mac without this kind of
18
+ contrib module. So...here we are.
19
+
20
+ To use this module, simply import and inject it::
21
+
22
+ import urllib3.contrib.securetransport
23
+ urllib3.contrib.securetransport.inject_into_urllib3()
24
+
25
+ Happy TLSing!
26
+
27
+ This code is a bastardised version of the code found in Will Bond's oscrypto
28
+ library. An enormous debt is owed to him for blazing this trail for us. For
29
+ that reason, this code should be considered to be covered both by urllib3's
30
+ license and by oscrypto's:
31
+
32
+ .. code-block::
33
+
34
+ Copyright (c) 2015-2016 Will Bond <will@wbond.net>
35
+
36
+ Permission is hereby granted, free of charge, to any person obtaining a
37
+ copy of this software and associated documentation files (the "Software"),
38
+ to deal in the Software without restriction, including without limitation
39
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
40
+ and/or sell copies of the Software, and to permit persons to whom the
41
+ Software is furnished to do so, subject to the following conditions:
42
+
43
+ The above copyright notice and this permission notice shall be included in
44
+ all copies or substantial portions of the Software.
45
+
46
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
51
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
52
+ DEALINGS IN THE SOFTWARE.
53
+ """
54
+ from __future__ import absolute_import
55
+
56
+ import contextlib
57
+ import ctypes
58
+ import errno
59
+ import os.path
60
+ import shutil
61
+ import socket
62
+ import ssl
63
+ import struct
64
+ import threading
65
+ import weakref
66
+
67
+ from pip._vendor import six
68
+
69
+ from .. import util
70
+ from ..util.ssl_ import PROTOCOL_TLS_CLIENT
71
+ from ._securetransport.bindings import CoreFoundation, Security, SecurityConst
72
+ from ._securetransport.low_level import (
73
+ _assert_no_error,
74
+ _build_tls_unknown_ca_alert,
75
+ _cert_array_from_pem,
76
+ _create_cfstring_array,
77
+ _load_client_cert_chain,
78
+ _temporary_keychain,
79
+ )
80
+
81
+ try: # Platform-specific: Python 2
82
+ from socket import _fileobject
83
+ except ImportError: # Platform-specific: Python 3
84
+ _fileobject = None
85
+ from ..packages.backports.makefile import backport_makefile
86
+
87
+ __all__ = ["inject_into_urllib3", "extract_from_urllib3"]
88
+
89
+ # SNI always works
90
+ HAS_SNI = True
91
+
92
+ orig_util_HAS_SNI = util.HAS_SNI
93
+ orig_util_SSLContext = util.ssl_.SSLContext
94
+
95
+ # This dictionary is used by the read callback to obtain a handle to the
96
+ # calling wrapped socket. This is a pretty silly approach, but for now it'll
97
+ # do. I feel like I should be able to smuggle a handle to the wrapped socket
98
+ # directly in the SSLConnectionRef, but for now this approach will work I
99
+ # guess.
100
+ #
101
+ # We need to lock around this structure for inserts, but we don't do it for
102
+ # reads/writes in the callbacks. The reasoning here goes as follows:
103
+ #
104
+ # 1. It is not possible to call into the callbacks before the dictionary is
105
+ # populated, so once in the callback the id must be in the dictionary.
106
+ # 2. The callbacks don't mutate the dictionary, they only read from it, and
107
+ # so cannot conflict with any of the insertions.
108
+ #
109
+ # This is good: if we had to lock in the callbacks we'd drastically slow down
110
+ # the performance of this code.
111
+ _connection_refs = weakref.WeakValueDictionary()
112
+ _connection_ref_lock = threading.Lock()
113
+
114
+ # Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over
115
+ # for no better reason than we need *a* limit, and this one is right there.
116
+ SSL_WRITE_BLOCKSIZE = 16384
117
+
118
+ # This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to
119
+ # individual cipher suites. We need to do this because this is how
120
+ # SecureTransport wants them.
121
+ CIPHER_SUITES = [
122
+ SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
123
+ SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
124
+ SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
125
+ SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
126
+ SecurityConst.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,
127
+ SecurityConst.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
128
+ SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
129
+ SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
130
+ SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384,
131
+ SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
132
+ SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
133
+ SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
134
+ SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,
135
+ SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
136
+ SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
137
+ SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
138
+ SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
139
+ SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
140
+ SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
141
+ SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
142
+ SecurityConst.TLS_AES_256_GCM_SHA384,
143
+ SecurityConst.TLS_AES_128_GCM_SHA256,
144
+ SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384,
145
+ SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256,
146
+ SecurityConst.TLS_AES_128_CCM_8_SHA256,
147
+ SecurityConst.TLS_AES_128_CCM_SHA256,
148
+ SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256,
149
+ SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256,
150
+ SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA,
151
+ SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA,
152
+ ]
153
+
154
+ # Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of
155
+ # TLSv1 and a high of TLSv1.2. For everything else, we pin to that version.
156
+ # TLSv1 to 1.2 are supported on macOS 10.8+
157
+ _protocol_to_min_max = {
158
+ util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12),
159
+ PROTOCOL_TLS_CLIENT: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12),
160
+ }
161
+
162
+ if hasattr(ssl, "PROTOCOL_SSLv2"):
163
+ _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = (
164
+ SecurityConst.kSSLProtocol2,
165
+ SecurityConst.kSSLProtocol2,
166
+ )
167
+ if hasattr(ssl, "PROTOCOL_SSLv3"):
168
+ _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = (
169
+ SecurityConst.kSSLProtocol3,
170
+ SecurityConst.kSSLProtocol3,
171
+ )
172
+ if hasattr(ssl, "PROTOCOL_TLSv1"):
173
+ _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = (
174
+ SecurityConst.kTLSProtocol1,
175
+ SecurityConst.kTLSProtocol1,
176
+ )
177
+ if hasattr(ssl, "PROTOCOL_TLSv1_1"):
178
+ _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = (
179
+ SecurityConst.kTLSProtocol11,
180
+ SecurityConst.kTLSProtocol11,
181
+ )
182
+ if hasattr(ssl, "PROTOCOL_TLSv1_2"):
183
+ _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = (
184
+ SecurityConst.kTLSProtocol12,
185
+ SecurityConst.kTLSProtocol12,
186
+ )
187
+
188
+
189
+ def inject_into_urllib3():
190
+ """
191
+ Monkey-patch urllib3 with SecureTransport-backed SSL-support.
192
+ """
193
+ util.SSLContext = SecureTransportContext
194
+ util.ssl_.SSLContext = SecureTransportContext
195
+ util.HAS_SNI = HAS_SNI
196
+ util.ssl_.HAS_SNI = HAS_SNI
197
+ util.IS_SECURETRANSPORT = True
198
+ util.ssl_.IS_SECURETRANSPORT = True
199
+
200
+
201
+ def extract_from_urllib3():
202
+ """
203
+ Undo monkey-patching by :func:`inject_into_urllib3`.
204
+ """
205
+ util.SSLContext = orig_util_SSLContext
206
+ util.ssl_.SSLContext = orig_util_SSLContext
207
+ util.HAS_SNI = orig_util_HAS_SNI
208
+ util.ssl_.HAS_SNI = orig_util_HAS_SNI
209
+ util.IS_SECURETRANSPORT = False
210
+ util.ssl_.IS_SECURETRANSPORT = False
211
+
212
+
213
+ def _read_callback(connection_id, data_buffer, data_length_pointer):
214
+ """
215
+ SecureTransport read callback. This is called by ST to request that data
216
+ be returned from the socket.
217
+ """
218
+ wrapped_socket = None
219
+ try:
220
+ wrapped_socket = _connection_refs.get(connection_id)
221
+ if wrapped_socket is None:
222
+ return SecurityConst.errSSLInternal
223
+ base_socket = wrapped_socket.socket
224
+
225
+ requested_length = data_length_pointer[0]
226
+
227
+ timeout = wrapped_socket.gettimeout()
228
+ error = None
229
+ read_count = 0
230
+
231
+ try:
232
+ while read_count < requested_length:
233
+ if timeout is None or timeout >= 0:
234
+ if not util.wait_for_read(base_socket, timeout):
235
+ raise socket.error(errno.EAGAIN, "timed out")
236
+
237
+ remaining = requested_length - read_count
238
+ buffer = (ctypes.c_char * remaining).from_address(
239
+ data_buffer + read_count
240
+ )
241
+ chunk_size = base_socket.recv_into(buffer, remaining)
242
+ read_count += chunk_size
243
+ if not chunk_size:
244
+ if not read_count:
245
+ return SecurityConst.errSSLClosedGraceful
246
+ break
247
+ except (socket.error) as e:
248
+ error = e.errno
249
+
250
+ if error is not None and error != errno.EAGAIN:
251
+ data_length_pointer[0] = read_count
252
+ if error == errno.ECONNRESET or error == errno.EPIPE:
253
+ return SecurityConst.errSSLClosedAbort
254
+ raise
255
+
256
+ data_length_pointer[0] = read_count
257
+
258
+ if read_count != requested_length:
259
+ return SecurityConst.errSSLWouldBlock
260
+
261
+ return 0
262
+ except Exception as e:
263
+ if wrapped_socket is not None:
264
+ wrapped_socket._exception = e
265
+ return SecurityConst.errSSLInternal
266
+
267
+
268
+ def _write_callback(connection_id, data_buffer, data_length_pointer):
269
+ """
270
+ SecureTransport write callback. This is called by ST to request that data
271
+ actually be sent on the network.
272
+ """
273
+ wrapped_socket = None
274
+ try:
275
+ wrapped_socket = _connection_refs.get(connection_id)
276
+ if wrapped_socket is None:
277
+ return SecurityConst.errSSLInternal
278
+ base_socket = wrapped_socket.socket
279
+
280
+ bytes_to_write = data_length_pointer[0]
281
+ data = ctypes.string_at(data_buffer, bytes_to_write)
282
+
283
+ timeout = wrapped_socket.gettimeout()
284
+ error = None
285
+ sent = 0
286
+
287
+ try:
288
+ while sent < bytes_to_write:
289
+ if timeout is None or timeout >= 0:
290
+ if not util.wait_for_write(base_socket, timeout):
291
+ raise socket.error(errno.EAGAIN, "timed out")
292
+ chunk_sent = base_socket.send(data)
293
+ sent += chunk_sent
294
+
295
+ # This has some needless copying here, but I'm not sure there's
296
+ # much value in optimising this data path.
297
+ data = data[chunk_sent:]
298
+ except (socket.error) as e:
299
+ error = e.errno
300
+
301
+ if error is not None and error != errno.EAGAIN:
302
+ data_length_pointer[0] = sent
303
+ if error == errno.ECONNRESET or error == errno.EPIPE:
304
+ return SecurityConst.errSSLClosedAbort
305
+ raise
306
+
307
+ data_length_pointer[0] = sent
308
+
309
+ if sent != bytes_to_write:
310
+ return SecurityConst.errSSLWouldBlock
311
+
312
+ return 0
313
+ except Exception as e:
314
+ if wrapped_socket is not None:
315
+ wrapped_socket._exception = e
316
+ return SecurityConst.errSSLInternal
317
+
318
+
319
+ # We need to keep these two objects references alive: if they get GC'd while
320
+ # in use then SecureTransport could attempt to call a function that is in freed
321
+ # memory. That would be...uh...bad. Yeah, that's the word. Bad.
322
+ _read_callback_pointer = Security.SSLReadFunc(_read_callback)
323
+ _write_callback_pointer = Security.SSLWriteFunc(_write_callback)
324
+
325
+
326
+ class WrappedSocket(object):
327
+ """
328
+ API-compatibility wrapper for Python's OpenSSL wrapped socket object.
329
+
330
+ Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage
331
+ collector of PyPy.
332
+ """
333
+
334
+ def __init__(self, socket):
335
+ self.socket = socket
336
+ self.context = None
337
+ self._makefile_refs = 0
338
+ self._closed = False
339
+ self._exception = None
340
+ self._keychain = None
341
+ self._keychain_dir = None
342
+ self._client_cert_chain = None
343
+
344
+ # We save off the previously-configured timeout and then set it to
345
+ # zero. This is done because we use select and friends to handle the
346
+ # timeouts, but if we leave the timeout set on the lower socket then
347
+ # Python will "kindly" call select on that socket again for us. Avoid
348
+ # that by forcing the timeout to zero.
349
+ self._timeout = self.socket.gettimeout()
350
+ self.socket.settimeout(0)
351
+
352
+ @contextlib.contextmanager
353
+ def _raise_on_error(self):
354
+ """
355
+ A context manager that can be used to wrap calls that do I/O from
356
+ SecureTransport. If any of the I/O callbacks hit an exception, this
357
+ context manager will correctly propagate the exception after the fact.
358
+ This avoids silently swallowing those exceptions.
359
+
360
+ It also correctly forces the socket closed.
361
+ """
362
+ self._exception = None
363
+
364
+ # We explicitly don't catch around this yield because in the unlikely
365
+ # event that an exception was hit in the block we don't want to swallow
366
+ # it.
367
+ yield
368
+ if self._exception is not None:
369
+ exception, self._exception = self._exception, None
370
+ self.close()
371
+ raise exception
372
+
373
+ def _set_ciphers(self):
374
+ """
375
+ Sets up the allowed ciphers. By default this matches the set in
376
+ util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done
377
+ custom and doesn't allow changing at this time, mostly because parsing
378
+ OpenSSL cipher strings is going to be a freaking nightmare.
379
+ """
380
+ ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES)
381
+ result = Security.SSLSetEnabledCiphers(
382
+ self.context, ciphers, len(CIPHER_SUITES)
383
+ )
384
+ _assert_no_error(result)
385
+
386
+ def _set_alpn_protocols(self, protocols):
387
+ """
388
+ Sets up the ALPN protocols on the context.
389
+ """
390
+ if not protocols:
391
+ return
392
+ protocols_arr = _create_cfstring_array(protocols)
393
+ try:
394
+ result = Security.SSLSetALPNProtocols(self.context, protocols_arr)
395
+ _assert_no_error(result)
396
+ finally:
397
+ CoreFoundation.CFRelease(protocols_arr)
398
+
399
+ def _custom_validate(self, verify, trust_bundle):
400
+ """
401
+ Called when we have set custom validation. We do this in two cases:
402
+ first, when cert validation is entirely disabled; and second, when
403
+ using a custom trust DB.
404
+ Raises an SSLError if the connection is not trusted.
405
+ """
406
+ # If we disabled cert validation, just say: cool.
407
+ if not verify:
408
+ return
409
+
410
+ successes = (
411
+ SecurityConst.kSecTrustResultUnspecified,
412
+ SecurityConst.kSecTrustResultProceed,
413
+ )
414
+ try:
415
+ trust_result = self._evaluate_trust(trust_bundle)
416
+ if trust_result in successes:
417
+ return
418
+ reason = "error code: %d" % (trust_result,)
419
+ except Exception as e:
420
+ # Do not trust on error
421
+ reason = "exception: %r" % (e,)
422
+
423
+ # SecureTransport does not send an alert nor shuts down the connection.
424
+ rec = _build_tls_unknown_ca_alert(self.version())
425
+ self.socket.sendall(rec)
426
+ # close the connection immediately
427
+ # l_onoff = 1, activate linger
428
+ # l_linger = 0, linger for 0 seoncds
429
+ opts = struct.pack("ii", 1, 0)
430
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, opts)
431
+ self.close()
432
+ raise ssl.SSLError("certificate verify failed, %s" % reason)
433
+
434
+ def _evaluate_trust(self, trust_bundle):
435
+ # We want data in memory, so load it up.
436
+ if os.path.isfile(trust_bundle):
437
+ with open(trust_bundle, "rb") as f:
438
+ trust_bundle = f.read()
439
+
440
+ cert_array = None
441
+ trust = Security.SecTrustRef()
442
+
443
+ try:
444
+ # Get a CFArray that contains the certs we want.
445
+ cert_array = _cert_array_from_pem(trust_bundle)
446
+
447
+ # Ok, now the hard part. We want to get the SecTrustRef that ST has
448
+ # created for this connection, shove our CAs into it, tell ST to
449
+ # ignore everything else it knows, and then ask if it can build a
450
+ # chain. This is a buuuunch of code.
451
+ result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust))
452
+ _assert_no_error(result)
453
+ if not trust:
454
+ raise ssl.SSLError("Failed to copy trust reference")
455
+
456
+ result = Security.SecTrustSetAnchorCertificates(trust, cert_array)
457
+ _assert_no_error(result)
458
+
459
+ result = Security.SecTrustSetAnchorCertificatesOnly(trust, True)
460
+ _assert_no_error(result)
461
+
462
+ trust_result = Security.SecTrustResultType()
463
+ result = Security.SecTrustEvaluate(trust, ctypes.byref(trust_result))
464
+ _assert_no_error(result)
465
+ finally:
466
+ if trust:
467
+ CoreFoundation.CFRelease(trust)
468
+
469
+ if cert_array is not None:
470
+ CoreFoundation.CFRelease(cert_array)
471
+
472
+ return trust_result.value
473
+
474
+ def handshake(
475
+ self,
476
+ server_hostname,
477
+ verify,
478
+ trust_bundle,
479
+ min_version,
480
+ max_version,
481
+ client_cert,
482
+ client_key,
483
+ client_key_passphrase,
484
+ alpn_protocols,
485
+ ):
486
+ """
487
+ Actually performs the TLS handshake. This is run automatically by
488
+ wrapped socket, and shouldn't be needed in user code.
489
+ """
490
+ # First, we do the initial bits of connection setup. We need to create
491
+ # a context, set its I/O funcs, and set the connection reference.
492
+ self.context = Security.SSLCreateContext(
493
+ None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType
494
+ )
495
+ result = Security.SSLSetIOFuncs(
496
+ self.context, _read_callback_pointer, _write_callback_pointer
497
+ )
498
+ _assert_no_error(result)
499
+
500
+ # Here we need to compute the handle to use. We do this by taking the
501
+ # id of self modulo 2**31 - 1. If this is already in the dictionary, we
502
+ # just keep incrementing by one until we find a free space.
503
+ with _connection_ref_lock:
504
+ handle = id(self) % 2147483647
505
+ while handle in _connection_refs:
506
+ handle = (handle + 1) % 2147483647
507
+ _connection_refs[handle] = self
508
+
509
+ result = Security.SSLSetConnection(self.context, handle)
510
+ _assert_no_error(result)
511
+
512
+ # If we have a server hostname, we should set that too.
513
+ if server_hostname:
514
+ if not isinstance(server_hostname, bytes):
515
+ server_hostname = server_hostname.encode("utf-8")
516
+
517
+ result = Security.SSLSetPeerDomainName(
518
+ self.context, server_hostname, len(server_hostname)
519
+ )
520
+ _assert_no_error(result)
521
+
522
+ # Setup the ciphers.
523
+ self._set_ciphers()
524
+
525
+ # Setup the ALPN protocols.
526
+ self._set_alpn_protocols(alpn_protocols)
527
+
528
+ # Set the minimum and maximum TLS versions.
529
+ result = Security.SSLSetProtocolVersionMin(self.context, min_version)
530
+ _assert_no_error(result)
531
+
532
+ result = Security.SSLSetProtocolVersionMax(self.context, max_version)
533
+ _assert_no_error(result)
534
+
535
+ # If there's a trust DB, we need to use it. We do that by telling
536
+ # SecureTransport to break on server auth. We also do that if we don't
537
+ # want to validate the certs at all: we just won't actually do any
538
+ # authing in that case.
539
+ if not verify or trust_bundle is not None:
540
+ result = Security.SSLSetSessionOption(
541
+ self.context, SecurityConst.kSSLSessionOptionBreakOnServerAuth, True
542
+ )
543
+ _assert_no_error(result)
544
+
545
+ # If there's a client cert, we need to use it.
546
+ if client_cert:
547
+ self._keychain, self._keychain_dir = _temporary_keychain()
548
+ self._client_cert_chain = _load_client_cert_chain(
549
+ self._keychain, client_cert, client_key
550
+ )
551
+ result = Security.SSLSetCertificate(self.context, self._client_cert_chain)
552
+ _assert_no_error(result)
553
+
554
+ while True:
555
+ with self._raise_on_error():
556
+ result = Security.SSLHandshake(self.context)
557
+
558
+ if result == SecurityConst.errSSLWouldBlock:
559
+ raise socket.timeout("handshake timed out")
560
+ elif result == SecurityConst.errSSLServerAuthCompleted:
561
+ self._custom_validate(verify, trust_bundle)
562
+ continue
563
+ else:
564
+ _assert_no_error(result)
565
+ break
566
+
567
+ def fileno(self):
568
+ return self.socket.fileno()
569
+
570
+ # Copy-pasted from Python 3.5 source code
571
+ def _decref_socketios(self):
572
+ if self._makefile_refs > 0:
573
+ self._makefile_refs -= 1
574
+ if self._closed:
575
+ self.close()
576
+
577
+ def recv(self, bufsiz):
578
+ buffer = ctypes.create_string_buffer(bufsiz)
579
+ bytes_read = self.recv_into(buffer, bufsiz)
580
+ data = buffer[:bytes_read]
581
+ return data
582
+
583
+ def recv_into(self, buffer, nbytes=None):
584
+ # Read short on EOF.
585
+ if self._closed:
586
+ return 0
587
+
588
+ if nbytes is None:
589
+ nbytes = len(buffer)
590
+
591
+ buffer = (ctypes.c_char * nbytes).from_buffer(buffer)
592
+ processed_bytes = ctypes.c_size_t(0)
593
+
594
+ with self._raise_on_error():
595
+ result = Security.SSLRead(
596
+ self.context, buffer, nbytes, ctypes.byref(processed_bytes)
597
+ )
598
+
599
+ # There are some result codes that we want to treat as "not always
600
+ # errors". Specifically, those are errSSLWouldBlock,
601
+ # errSSLClosedGraceful, and errSSLClosedNoNotify.
602
+ if result == SecurityConst.errSSLWouldBlock:
603
+ # If we didn't process any bytes, then this was just a time out.
604
+ # However, we can get errSSLWouldBlock in situations when we *did*
605
+ # read some data, and in those cases we should just read "short"
606
+ # and return.
607
+ if processed_bytes.value == 0:
608
+ # Timed out, no data read.
609
+ raise socket.timeout("recv timed out")
610
+ elif result in (
611
+ SecurityConst.errSSLClosedGraceful,
612
+ SecurityConst.errSSLClosedNoNotify,
613
+ ):
614
+ # The remote peer has closed this connection. We should do so as
615
+ # well. Note that we don't actually return here because in
616
+ # principle this could actually be fired along with return data.
617
+ # It's unlikely though.
618
+ self.close()
619
+ else:
620
+ _assert_no_error(result)
621
+
622
+ # Ok, we read and probably succeeded. We should return whatever data
623
+ # was actually read.
624
+ return processed_bytes.value
625
+
626
+ def settimeout(self, timeout):
627
+ self._timeout = timeout
628
+
629
+ def gettimeout(self):
630
+ return self._timeout
631
+
632
+ def send(self, data):
633
+ processed_bytes = ctypes.c_size_t(0)
634
+
635
+ with self._raise_on_error():
636
+ result = Security.SSLWrite(
637
+ self.context, data, len(data), ctypes.byref(processed_bytes)
638
+ )
639
+
640
+ if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0:
641
+ # Timed out
642
+ raise socket.timeout("send timed out")
643
+ else:
644
+ _assert_no_error(result)
645
+
646
+ # We sent, and probably succeeded. Tell them how much we sent.
647
+ return processed_bytes.value
648
+
649
+ def sendall(self, data):
650
+ total_sent = 0
651
+ while total_sent < len(data):
652
+ sent = self.send(data[total_sent : total_sent + SSL_WRITE_BLOCKSIZE])
653
+ total_sent += sent
654
+
655
+ def shutdown(self):
656
+ with self._raise_on_error():
657
+ Security.SSLClose(self.context)
658
+
659
+ def close(self):
660
+ # TODO: should I do clean shutdown here? Do I have to?
661
+ if self._makefile_refs < 1:
662
+ self._closed = True
663
+ if self.context:
664
+ CoreFoundation.CFRelease(self.context)
665
+ self.context = None
666
+ if self._client_cert_chain:
667
+ CoreFoundation.CFRelease(self._client_cert_chain)
668
+ self._client_cert_chain = None
669
+ if self._keychain:
670
+ Security.SecKeychainDelete(self._keychain)
671
+ CoreFoundation.CFRelease(self._keychain)
672
+ shutil.rmtree(self._keychain_dir)
673
+ self._keychain = self._keychain_dir = None
674
+ return self.socket.close()
675
+ else:
676
+ self._makefile_refs -= 1
677
+
678
+ def getpeercert(self, binary_form=False):
679
+ # Urgh, annoying.
680
+ #
681
+ # Here's how we do this:
682
+ #
683
+ # 1. Call SSLCopyPeerTrust to get hold of the trust object for this
684
+ # connection.
685
+ # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf.
686
+ # 3. To get the CN, call SecCertificateCopyCommonName and process that
687
+ # string so that it's of the appropriate type.
688
+ # 4. To get the SAN, we need to do something a bit more complex:
689
+ # a. Call SecCertificateCopyValues to get the data, requesting
690
+ # kSecOIDSubjectAltName.
691
+ # b. Mess about with this dictionary to try to get the SANs out.
692
+ #
693
+ # This is gross. Really gross. It's going to be a few hundred LoC extra
694
+ # just to repeat something that SecureTransport can *already do*. So my
695
+ # operating assumption at this time is that what we want to do is
696
+ # instead to just flag to urllib3 that it shouldn't do its own hostname
697
+ # validation when using SecureTransport.
698
+ if not binary_form:
699
+ raise ValueError("SecureTransport only supports dumping binary certs")
700
+ trust = Security.SecTrustRef()
701
+ certdata = None
702
+ der_bytes = None
703
+
704
+ try:
705
+ # Grab the trust store.
706
+ result = Security.SSLCopyPeerTrust(self.context, ctypes.byref(trust))
707
+ _assert_no_error(result)
708
+ if not trust:
709
+ # Probably we haven't done the handshake yet. No biggie.
710
+ return None
711
+
712
+ cert_count = Security.SecTrustGetCertificateCount(trust)
713
+ if not cert_count:
714
+ # Also a case that might happen if we haven't handshaked.
715
+ # Handshook? Handshaken?
716
+ return None
717
+
718
+ leaf = Security.SecTrustGetCertificateAtIndex(trust, 0)
719
+ assert leaf
720
+
721
+ # Ok, now we want the DER bytes.
722
+ certdata = Security.SecCertificateCopyData(leaf)
723
+ assert certdata
724
+
725
+ data_length = CoreFoundation.CFDataGetLength(certdata)
726
+ data_buffer = CoreFoundation.CFDataGetBytePtr(certdata)
727
+ der_bytes = ctypes.string_at(data_buffer, data_length)
728
+ finally:
729
+ if certdata:
730
+ CoreFoundation.CFRelease(certdata)
731
+ if trust:
732
+ CoreFoundation.CFRelease(trust)
733
+
734
+ return der_bytes
735
+
736
+ def version(self):
737
+ protocol = Security.SSLProtocol()
738
+ result = Security.SSLGetNegotiatedProtocolVersion(
739
+ self.context, ctypes.byref(protocol)
740
+ )
741
+ _assert_no_error(result)
742
+ if protocol.value == SecurityConst.kTLSProtocol13:
743
+ raise ssl.SSLError("SecureTransport does not support TLS 1.3")
744
+ elif protocol.value == SecurityConst.kTLSProtocol12:
745
+ return "TLSv1.2"
746
+ elif protocol.value == SecurityConst.kTLSProtocol11:
747
+ return "TLSv1.1"
748
+ elif protocol.value == SecurityConst.kTLSProtocol1:
749
+ return "TLSv1"
750
+ elif protocol.value == SecurityConst.kSSLProtocol3:
751
+ return "SSLv3"
752
+ elif protocol.value == SecurityConst.kSSLProtocol2:
753
+ return "SSLv2"
754
+ else:
755
+ raise ssl.SSLError("Unknown TLS version: %r" % protocol)
756
+
757
+ def _reuse(self):
758
+ self._makefile_refs += 1
759
+
760
+ def _drop(self):
761
+ if self._makefile_refs < 1:
762
+ self.close()
763
+ else:
764
+ self._makefile_refs -= 1
765
+
766
+
767
+ if _fileobject: # Platform-specific: Python 2
768
+
769
+ def makefile(self, mode, bufsize=-1):
770
+ self._makefile_refs += 1
771
+ return _fileobject(self, mode, bufsize, close=True)
772
+
773
+
774
+ else: # Platform-specific: Python 3
775
+
776
+ def makefile(self, mode="r", buffering=None, *args, **kwargs):
777
+ # We disable buffering with SecureTransport because it conflicts with
778
+ # the buffering that ST does internally (see issue #1153 for more).
779
+ buffering = 0
780
+ return backport_makefile(self, mode, buffering, *args, **kwargs)
781
+
782
+
783
+ WrappedSocket.makefile = makefile
784
+
785
+
786
+ class SecureTransportContext(object):
787
+ """
788
+ I am a wrapper class for the SecureTransport library, to translate the
789
+ interface of the standard library ``SSLContext`` object to calls into
790
+ SecureTransport.
791
+ """
792
+
793
+ def __init__(self, protocol):
794
+ self._min_version, self._max_version = _protocol_to_min_max[protocol]
795
+ self._options = 0
796
+ self._verify = False
797
+ self._trust_bundle = None
798
+ self._client_cert = None
799
+ self._client_key = None
800
+ self._client_key_passphrase = None
801
+ self._alpn_protocols = None
802
+
803
+ @property
804
+ def check_hostname(self):
805
+ """
806
+ SecureTransport cannot have its hostname checking disabled. For more,
807
+ see the comment on getpeercert() in this file.
808
+ """
809
+ return True
810
+
811
+ @check_hostname.setter
812
+ def check_hostname(self, value):
813
+ """
814
+ SecureTransport cannot have its hostname checking disabled. For more,
815
+ see the comment on getpeercert() in this file.
816
+ """
817
+ pass
818
+
819
+ @property
820
+ def options(self):
821
+ # TODO: Well, crap.
822
+ #
823
+ # So this is the bit of the code that is the most likely to cause us
824
+ # trouble. Essentially we need to enumerate all of the SSL options that
825
+ # users might want to use and try to see if we can sensibly translate
826
+ # them, or whether we should just ignore them.
827
+ return self._options
828
+
829
+ @options.setter
830
+ def options(self, value):
831
+ # TODO: Update in line with above.
832
+ self._options = value
833
+
834
+ @property
835
+ def verify_mode(self):
836
+ return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE
837
+
838
+ @verify_mode.setter
839
+ def verify_mode(self, value):
840
+ self._verify = True if value == ssl.CERT_REQUIRED else False
841
+
842
+ def set_default_verify_paths(self):
843
+ # So, this has to do something a bit weird. Specifically, what it does
844
+ # is nothing.
845
+ #
846
+ # This means that, if we had previously had load_verify_locations
847
+ # called, this does not undo that. We need to do that because it turns
848
+ # out that the rest of the urllib3 code will attempt to load the
849
+ # default verify paths if it hasn't been told about any paths, even if
850
+ # the context itself was sometime earlier. We resolve that by just
851
+ # ignoring it.
852
+ pass
853
+
854
+ def load_default_certs(self):
855
+ return self.set_default_verify_paths()
856
+
857
+ def set_ciphers(self, ciphers):
858
+ # For now, we just require the default cipher string.
859
+ if ciphers != util.ssl_.DEFAULT_CIPHERS:
860
+ raise ValueError("SecureTransport doesn't support custom cipher strings")
861
+
862
+ def load_verify_locations(self, cafile=None, capath=None, cadata=None):
863
+ # OK, we only really support cadata and cafile.
864
+ if capath is not None:
865
+ raise ValueError("SecureTransport does not support cert directories")
866
+
867
+ # Raise if cafile does not exist.
868
+ if cafile is not None:
869
+ with open(cafile):
870
+ pass
871
+
872
+ self._trust_bundle = cafile or cadata
873
+
874
+ def load_cert_chain(self, certfile, keyfile=None, password=None):
875
+ self._client_cert = certfile
876
+ self._client_key = keyfile
877
+ self._client_cert_passphrase = password
878
+
879
+ def set_alpn_protocols(self, protocols):
880
+ """
881
+ Sets the ALPN protocols that will later be set on the context.
882
+
883
+ Raises a NotImplementedError if ALPN is not supported.
884
+ """
885
+ if not hasattr(Security, "SSLSetALPNProtocols"):
886
+ raise NotImplementedError(
887
+ "SecureTransport supports ALPN only in macOS 10.12+"
888
+ )
889
+ self._alpn_protocols = [six.ensure_binary(p) for p in protocols]
890
+
891
+ def wrap_socket(
892
+ self,
893
+ sock,
894
+ server_side=False,
895
+ do_handshake_on_connect=True,
896
+ suppress_ragged_eofs=True,
897
+ server_hostname=None,
898
+ ):
899
+ # So, what do we do here? Firstly, we assert some properties. This is a
900
+ # stripped down shim, so there is some functionality we don't support.
901
+ # See PEP 543 for the real deal.
902
+ assert not server_side
903
+ assert do_handshake_on_connect
904
+ assert suppress_ragged_eofs
905
+
906
+ # Ok, we're good to go. Now we want to create the wrapped socket object
907
+ # and store it in the appropriate place.
908
+ wrapped_socket = WrappedSocket(sock)
909
+
910
+ # Now we can handshake
911
+ wrapped_socket.handshake(
912
+ server_hostname,
913
+ self._verify,
914
+ self._trust_bundle,
915
+ self._min_version,
916
+ self._max_version,
917
+ self._client_cert,
918
+ self._client_key,
919
+ self._client_key_passphrase,
920
+ self._alpn_protocols,
921
+ )
922
+ return wrapped_socket
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/contrib/socks.py ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ This module contains provisional support for SOCKS proxies from within
4
+ urllib3. This module supports SOCKS4, SOCKS4A (an extension of SOCKS4), and
5
+ SOCKS5. To enable its functionality, either install PySocks or install this
6
+ module with the ``socks`` extra.
7
+
8
+ The SOCKS implementation supports the full range of urllib3 features. It also
9
+ supports the following SOCKS features:
10
+
11
+ - SOCKS4A (``proxy_url='socks4a://...``)
12
+ - SOCKS4 (``proxy_url='socks4://...``)
13
+ - SOCKS5 with remote DNS (``proxy_url='socks5h://...``)
14
+ - SOCKS5 with local DNS (``proxy_url='socks5://...``)
15
+ - Usernames and passwords for the SOCKS proxy
16
+
17
+ .. note::
18
+ It is recommended to use ``socks5h://`` or ``socks4a://`` schemes in
19
+ your ``proxy_url`` to ensure that DNS resolution is done from the remote
20
+ server instead of client-side when connecting to a domain name.
21
+
22
+ SOCKS4 supports IPv4 and domain names with the SOCKS4A extension. SOCKS5
23
+ supports IPv4, IPv6, and domain names.
24
+
25
+ When connecting to a SOCKS4 proxy the ``username`` portion of the ``proxy_url``
26
+ will be sent as the ``userid`` section of the SOCKS request:
27
+
28
+ .. code-block:: python
29
+
30
+ proxy_url="socks4a://<userid>@proxy-host"
31
+
32
+ When connecting to a SOCKS5 proxy the ``username`` and ``password`` portion
33
+ of the ``proxy_url`` will be sent as the username/password to authenticate
34
+ with the proxy:
35
+
36
+ .. code-block:: python
37
+
38
+ proxy_url="socks5h://<username>:<password>@proxy-host"
39
+
40
+ """
41
+ from __future__ import absolute_import
42
+
43
+ try:
44
+ import socks
45
+ except ImportError:
46
+ import warnings
47
+
48
+ from ..exceptions import DependencyWarning
49
+
50
+ warnings.warn(
51
+ (
52
+ "SOCKS support in urllib3 requires the installation of optional "
53
+ "dependencies: specifically, PySocks. For more information, see "
54
+ "https://urllib3.readthedocs.io/en/1.26.x/contrib.html#socks-proxies"
55
+ ),
56
+ DependencyWarning,
57
+ )
58
+ raise
59
+
60
+ from socket import error as SocketError
61
+ from socket import timeout as SocketTimeout
62
+
63
+ from ..connection import HTTPConnection, HTTPSConnection
64
+ from ..connectionpool import HTTPConnectionPool, HTTPSConnectionPool
65
+ from ..exceptions import ConnectTimeoutError, NewConnectionError
66
+ from ..poolmanager import PoolManager
67
+ from ..util.url import parse_url
68
+
69
+ try:
70
+ import ssl
71
+ except ImportError:
72
+ ssl = None
73
+
74
+
75
+ class SOCKSConnection(HTTPConnection):
76
+ """
77
+ A plain-text HTTP connection that connects via a SOCKS proxy.
78
+ """
79
+
80
+ def __init__(self, *args, **kwargs):
81
+ self._socks_options = kwargs.pop("_socks_options")
82
+ super(SOCKSConnection, self).__init__(*args, **kwargs)
83
+
84
+ def _new_conn(self):
85
+ """
86
+ Establish a new connection via the SOCKS proxy.
87
+ """
88
+ extra_kw = {}
89
+ if self.source_address:
90
+ extra_kw["source_address"] = self.source_address
91
+
92
+ if self.socket_options:
93
+ extra_kw["socket_options"] = self.socket_options
94
+
95
+ try:
96
+ conn = socks.create_connection(
97
+ (self.host, self.port),
98
+ proxy_type=self._socks_options["socks_version"],
99
+ proxy_addr=self._socks_options["proxy_host"],
100
+ proxy_port=self._socks_options["proxy_port"],
101
+ proxy_username=self._socks_options["username"],
102
+ proxy_password=self._socks_options["password"],
103
+ proxy_rdns=self._socks_options["rdns"],
104
+ timeout=self.timeout,
105
+ **extra_kw
106
+ )
107
+
108
+ except SocketTimeout:
109
+ raise ConnectTimeoutError(
110
+ self,
111
+ "Connection to %s timed out. (connect timeout=%s)"
112
+ % (self.host, self.timeout),
113
+ )
114
+
115
+ except socks.ProxyError as e:
116
+ # This is fragile as hell, but it seems to be the only way to raise
117
+ # useful errors here.
118
+ if e.socket_err:
119
+ error = e.socket_err
120
+ if isinstance(error, SocketTimeout):
121
+ raise ConnectTimeoutError(
122
+ self,
123
+ "Connection to %s timed out. (connect timeout=%s)"
124
+ % (self.host, self.timeout),
125
+ )
126
+ else:
127
+ raise NewConnectionError(
128
+ self, "Failed to establish a new connection: %s" % error
129
+ )
130
+ else:
131
+ raise NewConnectionError(
132
+ self, "Failed to establish a new connection: %s" % e
133
+ )
134
+
135
+ except SocketError as e: # Defensive: PySocks should catch all these.
136
+ raise NewConnectionError(
137
+ self, "Failed to establish a new connection: %s" % e
138
+ )
139
+
140
+ return conn
141
+
142
+
143
+ # We don't need to duplicate the Verified/Unverified distinction from
144
+ # urllib3/connection.py here because the HTTPSConnection will already have been
145
+ # correctly set to either the Verified or Unverified form by that module. This
146
+ # means the SOCKSHTTPSConnection will automatically be the correct type.
147
+ class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection):
148
+ pass
149
+
150
+
151
+ class SOCKSHTTPConnectionPool(HTTPConnectionPool):
152
+ ConnectionCls = SOCKSConnection
153
+
154
+
155
+ class SOCKSHTTPSConnectionPool(HTTPSConnectionPool):
156
+ ConnectionCls = SOCKSHTTPSConnection
157
+
158
+
159
+ class SOCKSProxyManager(PoolManager):
160
+ """
161
+ A version of the urllib3 ProxyManager that routes connections via the
162
+ defined SOCKS proxy.
163
+ """
164
+
165
+ pool_classes_by_scheme = {
166
+ "http": SOCKSHTTPConnectionPool,
167
+ "https": SOCKSHTTPSConnectionPool,
168
+ }
169
+
170
+ def __init__(
171
+ self,
172
+ proxy_url,
173
+ username=None,
174
+ password=None,
175
+ num_pools=10,
176
+ headers=None,
177
+ **connection_pool_kw
178
+ ):
179
+ parsed = parse_url(proxy_url)
180
+
181
+ if username is None and password is None and parsed.auth is not None:
182
+ split = parsed.auth.split(":")
183
+ if len(split) == 2:
184
+ username, password = split
185
+ if parsed.scheme == "socks5":
186
+ socks_version = socks.PROXY_TYPE_SOCKS5
187
+ rdns = False
188
+ elif parsed.scheme == "socks5h":
189
+ socks_version = socks.PROXY_TYPE_SOCKS5
190
+ rdns = True
191
+ elif parsed.scheme == "socks4":
192
+ socks_version = socks.PROXY_TYPE_SOCKS4
193
+ rdns = False
194
+ elif parsed.scheme == "socks4a":
195
+ socks_version = socks.PROXY_TYPE_SOCKS4
196
+ rdns = True
197
+ else:
198
+ raise ValueError("Unable to determine SOCKS version from %s" % proxy_url)
199
+
200
+ self.proxy_url = proxy_url
201
+
202
+ socks_options = {
203
+ "socks_version": socks_version,
204
+ "proxy_host": parsed.host,
205
+ "proxy_port": parsed.port,
206
+ "username": username,
207
+ "password": password,
208
+ "rdns": rdns,
209
+ }
210
+ connection_pool_kw["_socks_options"] = socks_options
211
+
212
+ super(SOCKSProxyManager, self).__init__(
213
+ num_pools, headers, **connection_pool_kw
214
+ )
215
+
216
+ self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/exceptions.py ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from .packages.six.moves.http_client import IncompleteRead as httplib_IncompleteRead
4
+
5
+ # Base Exceptions
6
+
7
+
8
+ class HTTPError(Exception):
9
+ """Base exception used by this module."""
10
+
11
+ pass
12
+
13
+
14
+ class HTTPWarning(Warning):
15
+ """Base warning used by this module."""
16
+
17
+ pass
18
+
19
+
20
+ class PoolError(HTTPError):
21
+ """Base exception for errors caused within a pool."""
22
+
23
+ def __init__(self, pool, message):
24
+ self.pool = pool
25
+ HTTPError.__init__(self, "%s: %s" % (pool, message))
26
+
27
+ def __reduce__(self):
28
+ # For pickling purposes.
29
+ return self.__class__, (None, None)
30
+
31
+
32
+ class RequestError(PoolError):
33
+ """Base exception for PoolErrors that have associated URLs."""
34
+
35
+ def __init__(self, pool, url, message):
36
+ self.url = url
37
+ PoolError.__init__(self, pool, message)
38
+
39
+ def __reduce__(self):
40
+ # For pickling purposes.
41
+ return self.__class__, (None, self.url, None)
42
+
43
+
44
+ class SSLError(HTTPError):
45
+ """Raised when SSL certificate fails in an HTTPS connection."""
46
+
47
+ pass
48
+
49
+
50
+ class ProxyError(HTTPError):
51
+ """Raised when the connection to a proxy fails."""
52
+
53
+ def __init__(self, message, error, *args):
54
+ super(ProxyError, self).__init__(message, error, *args)
55
+ self.original_error = error
56
+
57
+
58
+ class DecodeError(HTTPError):
59
+ """Raised when automatic decoding based on Content-Type fails."""
60
+
61
+ pass
62
+
63
+
64
+ class ProtocolError(HTTPError):
65
+ """Raised when something unexpected happens mid-request/response."""
66
+
67
+ pass
68
+
69
+
70
+ #: Renamed to ProtocolError but aliased for backwards compatibility.
71
+ ConnectionError = ProtocolError
72
+
73
+
74
+ # Leaf Exceptions
75
+
76
+
77
+ class MaxRetryError(RequestError):
78
+ """Raised when the maximum number of retries is exceeded.
79
+
80
+ :param pool: The connection pool
81
+ :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool`
82
+ :param string url: The requested Url
83
+ :param exceptions.Exception reason: The underlying error
84
+
85
+ """
86
+
87
+ def __init__(self, pool, url, reason=None):
88
+ self.reason = reason
89
+
90
+ message = "Max retries exceeded with url: %s (Caused by %r)" % (url, reason)
91
+
92
+ RequestError.__init__(self, pool, url, message)
93
+
94
+
95
+ class HostChangedError(RequestError):
96
+ """Raised when an existing pool gets a request for a foreign host."""
97
+
98
+ def __init__(self, pool, url, retries=3):
99
+ message = "Tried to open a foreign host with url: %s" % url
100
+ RequestError.__init__(self, pool, url, message)
101
+ self.retries = retries
102
+
103
+
104
+ class TimeoutStateError(HTTPError):
105
+ """Raised when passing an invalid state to a timeout"""
106
+
107
+ pass
108
+
109
+
110
+ class TimeoutError(HTTPError):
111
+ """Raised when a socket timeout error occurs.
112
+
113
+ Catching this error will catch both :exc:`ReadTimeoutErrors
114
+ <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`.
115
+ """
116
+
117
+ pass
118
+
119
+
120
+ class ReadTimeoutError(TimeoutError, RequestError):
121
+ """Raised when a socket timeout occurs while receiving data from a server"""
122
+
123
+ pass
124
+
125
+
126
+ # This timeout error does not have a URL attached and needs to inherit from the
127
+ # base HTTPError
128
+ class ConnectTimeoutError(TimeoutError):
129
+ """Raised when a socket timeout occurs while connecting to a server"""
130
+
131
+ pass
132
+
133
+
134
+ class NewConnectionError(ConnectTimeoutError, PoolError):
135
+ """Raised when we fail to establish a new connection. Usually ECONNREFUSED."""
136
+
137
+ pass
138
+
139
+
140
+ class EmptyPoolError(PoolError):
141
+ """Raised when a pool runs out of connections and no more are allowed."""
142
+
143
+ pass
144
+
145
+
146
+ class ClosedPoolError(PoolError):
147
+ """Raised when a request enters a pool after the pool has been closed."""
148
+
149
+ pass
150
+
151
+
152
+ class LocationValueError(ValueError, HTTPError):
153
+ """Raised when there is something wrong with a given URL input."""
154
+
155
+ pass
156
+
157
+
158
+ class LocationParseError(LocationValueError):
159
+ """Raised when get_host or similar fails to parse the URL input."""
160
+
161
+ def __init__(self, location):
162
+ message = "Failed to parse: %s" % location
163
+ HTTPError.__init__(self, message)
164
+
165
+ self.location = location
166
+
167
+
168
+ class URLSchemeUnknown(LocationValueError):
169
+ """Raised when a URL input has an unsupported scheme."""
170
+
171
+ def __init__(self, scheme):
172
+ message = "Not supported URL scheme %s" % scheme
173
+ super(URLSchemeUnknown, self).__init__(message)
174
+
175
+ self.scheme = scheme
176
+
177
+
178
+ class ResponseError(HTTPError):
179
+ """Used as a container for an error reason supplied in a MaxRetryError."""
180
+
181
+ GENERIC_ERROR = "too many error responses"
182
+ SPECIFIC_ERROR = "too many {status_code} error responses"
183
+
184
+
185
+ class SecurityWarning(HTTPWarning):
186
+ """Warned when performing security reducing actions"""
187
+
188
+ pass
189
+
190
+
191
+ class SubjectAltNameWarning(SecurityWarning):
192
+ """Warned when connecting to a host with a certificate missing a SAN."""
193
+
194
+ pass
195
+
196
+
197
+ class InsecureRequestWarning(SecurityWarning):
198
+ """Warned when making an unverified HTTPS request."""
199
+
200
+ pass
201
+
202
+
203
+ class SystemTimeWarning(SecurityWarning):
204
+ """Warned when system time is suspected to be wrong"""
205
+
206
+ pass
207
+
208
+
209
+ class InsecurePlatformWarning(SecurityWarning):
210
+ """Warned when certain TLS/SSL configuration is not available on a platform."""
211
+
212
+ pass
213
+
214
+
215
+ class SNIMissingWarning(HTTPWarning):
216
+ """Warned when making a HTTPS request without SNI available."""
217
+
218
+ pass
219
+
220
+
221
+ class DependencyWarning(HTTPWarning):
222
+ """
223
+ Warned when an attempt is made to import a module with missing optional
224
+ dependencies.
225
+ """
226
+
227
+ pass
228
+
229
+
230
+ class ResponseNotChunked(ProtocolError, ValueError):
231
+ """Response needs to be chunked in order to read it as chunks."""
232
+
233
+ pass
234
+
235
+
236
+ class BodyNotHttplibCompatible(HTTPError):
237
+ """
238
+ Body should be :class:`http.client.HTTPResponse` like
239
+ (have an fp attribute which returns raw chunks) for read_chunked().
240
+ """
241
+
242
+ pass
243
+
244
+
245
+ class IncompleteRead(HTTPError, httplib_IncompleteRead):
246
+ """
247
+ Response length doesn't match expected Content-Length
248
+
249
+ Subclass of :class:`http.client.IncompleteRead` to allow int value
250
+ for ``partial`` to avoid creating large objects on streamed reads.
251
+ """
252
+
253
+ def __init__(self, partial, expected):
254
+ super(IncompleteRead, self).__init__(partial, expected)
255
+
256
+ def __repr__(self):
257
+ return "IncompleteRead(%i bytes read, %i more expected)" % (
258
+ self.partial,
259
+ self.expected,
260
+ )
261
+
262
+
263
+ class InvalidChunkLength(HTTPError, httplib_IncompleteRead):
264
+ """Invalid chunk length in a chunked response."""
265
+
266
+ def __init__(self, response, length):
267
+ super(InvalidChunkLength, self).__init__(
268
+ response.tell(), response.length_remaining
269
+ )
270
+ self.response = response
271
+ self.length = length
272
+
273
+ def __repr__(self):
274
+ return "InvalidChunkLength(got length %r, %i bytes read)" % (
275
+ self.length,
276
+ self.partial,
277
+ )
278
+
279
+
280
+ class InvalidHeader(HTTPError):
281
+ """The header provided was somehow invalid."""
282
+
283
+ pass
284
+
285
+
286
+ class ProxySchemeUnknown(AssertionError, URLSchemeUnknown):
287
+ """ProxyManager does not support the supplied scheme"""
288
+
289
+ # TODO(t-8ch): Stop inheriting from AssertionError in v2.0.
290
+
291
+ def __init__(self, scheme):
292
+ # 'localhost' is here because our URL parser parses
293
+ # localhost:8080 -> scheme=localhost, remove if we fix this.
294
+ if scheme == "localhost":
295
+ scheme = None
296
+ if scheme is None:
297
+ message = "Proxy URL had no scheme, should start with http:// or https://"
298
+ else:
299
+ message = (
300
+ "Proxy URL had unsupported scheme %s, should use http:// or https://"
301
+ % scheme
302
+ )
303
+ super(ProxySchemeUnknown, self).__init__(message)
304
+
305
+
306
+ class ProxySchemeUnsupported(ValueError):
307
+ """Fetching HTTPS resources through HTTPS proxies is unsupported"""
308
+
309
+ pass
310
+
311
+
312
+ class HeaderParsingError(HTTPError):
313
+ """Raised by assert_header_parsing, but we convert it to a log.warning statement."""
314
+
315
+ def __init__(self, defects, unparsed_data):
316
+ message = "%s, unparsed data: %r" % (defects or "Unknown", unparsed_data)
317
+ super(HeaderParsingError, self).__init__(message)
318
+
319
+
320
+ class UnrewindableBodyError(HTTPError):
321
+ """urllib3 encountered an error when trying to rewind a body"""
322
+
323
+ pass
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/fields.py ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import email.utils
4
+ import mimetypes
5
+ import re
6
+
7
+ from .packages import six
8
+
9
+
10
+ def guess_content_type(filename, default="application/octet-stream"):
11
+ """
12
+ Guess the "Content-Type" of a file.
13
+
14
+ :param filename:
15
+ The filename to guess the "Content-Type" of using :mod:`mimetypes`.
16
+ :param default:
17
+ If no "Content-Type" can be guessed, default to `default`.
18
+ """
19
+ if filename:
20
+ return mimetypes.guess_type(filename)[0] or default
21
+ return default
22
+
23
+
24
+ def format_header_param_rfc2231(name, value):
25
+ """
26
+ Helper function to format and quote a single header parameter using the
27
+ strategy defined in RFC 2231.
28
+
29
+ Particularly useful for header parameters which might contain
30
+ non-ASCII values, like file names. This follows
31
+ `RFC 2388 Section 4.4 <https://tools.ietf.org/html/rfc2388#section-4.4>`_.
32
+
33
+ :param name:
34
+ The name of the parameter, a string expected to be ASCII only.
35
+ :param value:
36
+ The value of the parameter, provided as ``bytes`` or `str``.
37
+ :ret:
38
+ An RFC-2231-formatted unicode string.
39
+ """
40
+ if isinstance(value, six.binary_type):
41
+ value = value.decode("utf-8")
42
+
43
+ if not any(ch in value for ch in '"\\\r\n'):
44
+ result = u'%s="%s"' % (name, value)
45
+ try:
46
+ result.encode("ascii")
47
+ except (UnicodeEncodeError, UnicodeDecodeError):
48
+ pass
49
+ else:
50
+ return result
51
+
52
+ if six.PY2: # Python 2:
53
+ value = value.encode("utf-8")
54
+
55
+ # encode_rfc2231 accepts an encoded string and returns an ascii-encoded
56
+ # string in Python 2 but accepts and returns unicode strings in Python 3
57
+ value = email.utils.encode_rfc2231(value, "utf-8")
58
+ value = "%s*=%s" % (name, value)
59
+
60
+ if six.PY2: # Python 2:
61
+ value = value.decode("utf-8")
62
+
63
+ return value
64
+
65
+
66
+ _HTML5_REPLACEMENTS = {
67
+ u"\u0022": u"%22",
68
+ # Replace "\" with "\\".
69
+ u"\u005C": u"\u005C\u005C",
70
+ }
71
+
72
+ # All control characters from 0x00 to 0x1F *except* 0x1B.
73
+ _HTML5_REPLACEMENTS.update(
74
+ {
75
+ six.unichr(cc): u"%{:02X}".format(cc)
76
+ for cc in range(0x00, 0x1F + 1)
77
+ if cc not in (0x1B,)
78
+ }
79
+ )
80
+
81
+
82
+ def _replace_multiple(value, needles_and_replacements):
83
+ def replacer(match):
84
+ return needles_and_replacements[match.group(0)]
85
+
86
+ pattern = re.compile(
87
+ r"|".join([re.escape(needle) for needle in needles_and_replacements.keys()])
88
+ )
89
+
90
+ result = pattern.sub(replacer, value)
91
+
92
+ return result
93
+
94
+
95
+ def format_header_param_html5(name, value):
96
+ """
97
+ Helper function to format and quote a single header parameter using the
98
+ HTML5 strategy.
99
+
100
+ Particularly useful for header parameters which might contain
101
+ non-ASCII values, like file names. This follows the `HTML5 Working Draft
102
+ Section 4.10.22.7`_ and matches the behavior of curl and modern browsers.
103
+
104
+ .. _HTML5 Working Draft Section 4.10.22.7:
105
+ https://w3c.github.io/html/sec-forms.html#multipart-form-data
106
+
107
+ :param name:
108
+ The name of the parameter, a string expected to be ASCII only.
109
+ :param value:
110
+ The value of the parameter, provided as ``bytes`` or `str``.
111
+ :ret:
112
+ A unicode string, stripped of troublesome characters.
113
+ """
114
+ if isinstance(value, six.binary_type):
115
+ value = value.decode("utf-8")
116
+
117
+ value = _replace_multiple(value, _HTML5_REPLACEMENTS)
118
+
119
+ return u'%s="%s"' % (name, value)
120
+
121
+
122
+ # For backwards-compatibility.
123
+ format_header_param = format_header_param_html5
124
+
125
+
126
+ class RequestField(object):
127
+ """
128
+ A data container for request body parameters.
129
+
130
+ :param name:
131
+ The name of this request field. Must be unicode.
132
+ :param data:
133
+ The data/value body.
134
+ :param filename:
135
+ An optional filename of the request field. Must be unicode.
136
+ :param headers:
137
+ An optional dict-like object of headers to initially use for the field.
138
+ :param header_formatter:
139
+ An optional callable that is used to encode and format the headers. By
140
+ default, this is :func:`format_header_param_html5`.
141
+ """
142
+
143
+ def __init__(
144
+ self,
145
+ name,
146
+ data,
147
+ filename=None,
148
+ headers=None,
149
+ header_formatter=format_header_param_html5,
150
+ ):
151
+ self._name = name
152
+ self._filename = filename
153
+ self.data = data
154
+ self.headers = {}
155
+ if headers:
156
+ self.headers = dict(headers)
157
+ self.header_formatter = header_formatter
158
+
159
+ @classmethod
160
+ def from_tuples(cls, fieldname, value, header_formatter=format_header_param_html5):
161
+ """
162
+ A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters.
163
+
164
+ Supports constructing :class:`~urllib3.fields.RequestField` from
165
+ parameter of key/value strings AND key/filetuple. A filetuple is a
166
+ (filename, data, MIME type) tuple where the MIME type is optional.
167
+ For example::
168
+
169
+ 'foo': 'bar',
170
+ 'fakefile': ('foofile.txt', 'contents of foofile'),
171
+ 'realfile': ('barfile.txt', open('realfile').read()),
172
+ 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'),
173
+ 'nonamefile': 'contents of nonamefile field',
174
+
175
+ Field names and filenames must be unicode.
176
+ """
177
+ if isinstance(value, tuple):
178
+ if len(value) == 3:
179
+ filename, data, content_type = value
180
+ else:
181
+ filename, data = value
182
+ content_type = guess_content_type(filename)
183
+ else:
184
+ filename = None
185
+ content_type = None
186
+ data = value
187
+
188
+ request_param = cls(
189
+ fieldname, data, filename=filename, header_formatter=header_formatter
190
+ )
191
+ request_param.make_multipart(content_type=content_type)
192
+
193
+ return request_param
194
+
195
+ def _render_part(self, name, value):
196
+ """
197
+ Overridable helper function to format a single header parameter. By
198
+ default, this calls ``self.header_formatter``.
199
+
200
+ :param name:
201
+ The name of the parameter, a string expected to be ASCII only.
202
+ :param value:
203
+ The value of the parameter, provided as a unicode string.
204
+ """
205
+
206
+ return self.header_formatter(name, value)
207
+
208
+ def _render_parts(self, header_parts):
209
+ """
210
+ Helper function to format and quote a single header.
211
+
212
+ Useful for single headers that are composed of multiple items. E.g.,
213
+ 'Content-Disposition' fields.
214
+
215
+ :param header_parts:
216
+ A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format
217
+ as `k1="v1"; k2="v2"; ...`.
218
+ """
219
+ parts = []
220
+ iterable = header_parts
221
+ if isinstance(header_parts, dict):
222
+ iterable = header_parts.items()
223
+
224
+ for name, value in iterable:
225
+ if value is not None:
226
+ parts.append(self._render_part(name, value))
227
+
228
+ return u"; ".join(parts)
229
+
230
+ def render_headers(self):
231
+ """
232
+ Renders the headers for this request field.
233
+ """
234
+ lines = []
235
+
236
+ sort_keys = ["Content-Disposition", "Content-Type", "Content-Location"]
237
+ for sort_key in sort_keys:
238
+ if self.headers.get(sort_key, False):
239
+ lines.append(u"%s: %s" % (sort_key, self.headers[sort_key]))
240
+
241
+ for header_name, header_value in self.headers.items():
242
+ if header_name not in sort_keys:
243
+ if header_value:
244
+ lines.append(u"%s: %s" % (header_name, header_value))
245
+
246
+ lines.append(u"\r\n")
247
+ return u"\r\n".join(lines)
248
+
249
+ def make_multipart(
250
+ self, content_disposition=None, content_type=None, content_location=None
251
+ ):
252
+ """
253
+ Makes this request field into a multipart request field.
254
+
255
+ This method overrides "Content-Disposition", "Content-Type" and
256
+ "Content-Location" headers to the request parameter.
257
+
258
+ :param content_type:
259
+ The 'Content-Type' of the request body.
260
+ :param content_location:
261
+ The 'Content-Location' of the request body.
262
+
263
+ """
264
+ self.headers["Content-Disposition"] = content_disposition or u"form-data"
265
+ self.headers["Content-Disposition"] += u"; ".join(
266
+ [
267
+ u"",
268
+ self._render_parts(
269
+ ((u"name", self._name), (u"filename", self._filename))
270
+ ),
271
+ ]
272
+ )
273
+ self.headers["Content-Type"] = content_type
274
+ self.headers["Content-Location"] = content_location
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/filepost.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import binascii
4
+ import codecs
5
+ import os
6
+ from io import BytesIO
7
+
8
+ from .fields import RequestField
9
+ from .packages import six
10
+ from .packages.six import b
11
+
12
+ writer = codecs.lookup("utf-8")[3]
13
+
14
+
15
+ def choose_boundary():
16
+ """
17
+ Our embarrassingly-simple replacement for mimetools.choose_boundary.
18
+ """
19
+ boundary = binascii.hexlify(os.urandom(16))
20
+ if not six.PY2:
21
+ boundary = boundary.decode("ascii")
22
+ return boundary
23
+
24
+
25
+ def iter_field_objects(fields):
26
+ """
27
+ Iterate over fields.
28
+
29
+ Supports list of (k, v) tuples and dicts, and lists of
30
+ :class:`~urllib3.fields.RequestField`.
31
+
32
+ """
33
+ if isinstance(fields, dict):
34
+ i = six.iteritems(fields)
35
+ else:
36
+ i = iter(fields)
37
+
38
+ for field in i:
39
+ if isinstance(field, RequestField):
40
+ yield field
41
+ else:
42
+ yield RequestField.from_tuples(*field)
43
+
44
+
45
+ def iter_fields(fields):
46
+ """
47
+ .. deprecated:: 1.6
48
+
49
+ Iterate over fields.
50
+
51
+ The addition of :class:`~urllib3.fields.RequestField` makes this function
52
+ obsolete. Instead, use :func:`iter_field_objects`, which returns
53
+ :class:`~urllib3.fields.RequestField` objects.
54
+
55
+ Supports list of (k, v) tuples and dicts.
56
+ """
57
+ if isinstance(fields, dict):
58
+ return ((k, v) for k, v in six.iteritems(fields))
59
+
60
+ return ((k, v) for k, v in fields)
61
+
62
+
63
+ def encode_multipart_formdata(fields, boundary=None):
64
+ """
65
+ Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
66
+
67
+ :param fields:
68
+ Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
69
+
70
+ :param boundary:
71
+ If not specified, then a random boundary will be generated using
72
+ :func:`urllib3.filepost.choose_boundary`.
73
+ """
74
+ body = BytesIO()
75
+ if boundary is None:
76
+ boundary = choose_boundary()
77
+
78
+ for field in iter_field_objects(fields):
79
+ body.write(b("--%s\r\n" % (boundary)))
80
+
81
+ writer(body).write(field.render_headers())
82
+ data = field.data
83
+
84
+ if isinstance(data, int):
85
+ data = str(data) # Backwards compatibility
86
+
87
+ if isinstance(data, six.text_type):
88
+ writer(body).write(data)
89
+ else:
90
+ body.write(data)
91
+
92
+ body.write(b"\r\n")
93
+
94
+ body.write(b("--%s--\r\n" % (boundary)))
95
+
96
+ content_type = str("multipart/form-data; boundary=%s" % boundary)
97
+
98
+ return body.getvalue(), content_type
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/__init__.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from . import ssl_match_hostname
4
+
5
+ __all__ = ("ssl_match_hostname",)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/packages/six.py ADDED
@@ -0,0 +1,1077 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2010-2020 Benjamin Peterson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ """Utilities for writing code that runs on Python 2 and 3"""
22
+
23
+ from __future__ import absolute_import
24
+
25
+ import functools
26
+ import itertools
27
+ import operator
28
+ import sys
29
+ import types
30
+
31
+ __author__ = "Benjamin Peterson <benjamin@python.org>"
32
+ __version__ = "1.16.0"
33
+
34
+
35
+ # Useful for very coarse version differentiation.
36
+ PY2 = sys.version_info[0] == 2
37
+ PY3 = sys.version_info[0] == 3
38
+ PY34 = sys.version_info[0:2] >= (3, 4)
39
+
40
+ if PY3:
41
+ string_types = (str,)
42
+ integer_types = (int,)
43
+ class_types = (type,)
44
+ text_type = str
45
+ binary_type = bytes
46
+
47
+ MAXSIZE = sys.maxsize
48
+ else:
49
+ string_types = (basestring,)
50
+ integer_types = (int, long)
51
+ class_types = (type, types.ClassType)
52
+ text_type = unicode
53
+ binary_type = str
54
+
55
+ if sys.platform.startswith("java"):
56
+ # Jython always uses 32 bits.
57
+ MAXSIZE = int((1 << 31) - 1)
58
+ else:
59
+ # It's possible to have sizeof(long) != sizeof(Py_ssize_t).
60
+ class X(object):
61
+ def __len__(self):
62
+ return 1 << 31
63
+
64
+ try:
65
+ len(X())
66
+ except OverflowError:
67
+ # 32-bit
68
+ MAXSIZE = int((1 << 31) - 1)
69
+ else:
70
+ # 64-bit
71
+ MAXSIZE = int((1 << 63) - 1)
72
+ del X
73
+
74
+ if PY34:
75
+ from importlib.util import spec_from_loader
76
+ else:
77
+ spec_from_loader = None
78
+
79
+
80
+ def _add_doc(func, doc):
81
+ """Add documentation to a function."""
82
+ func.__doc__ = doc
83
+
84
+
85
+ def _import_module(name):
86
+ """Import module, returning the module after the last dot."""
87
+ __import__(name)
88
+ return sys.modules[name]
89
+
90
+
91
+ class _LazyDescr(object):
92
+ def __init__(self, name):
93
+ self.name = name
94
+
95
+ def __get__(self, obj, tp):
96
+ result = self._resolve()
97
+ setattr(obj, self.name, result) # Invokes __set__.
98
+ try:
99
+ # This is a bit ugly, but it avoids running this again by
100
+ # removing this descriptor.
101
+ delattr(obj.__class__, self.name)
102
+ except AttributeError:
103
+ pass
104
+ return result
105
+
106
+
107
+ class MovedModule(_LazyDescr):
108
+ def __init__(self, name, old, new=None):
109
+ super(MovedModule, self).__init__(name)
110
+ if PY3:
111
+ if new is None:
112
+ new = name
113
+ self.mod = new
114
+ else:
115
+ self.mod = old
116
+
117
+ def _resolve(self):
118
+ return _import_module(self.mod)
119
+
120
+ def __getattr__(self, attr):
121
+ _module = self._resolve()
122
+ value = getattr(_module, attr)
123
+ setattr(self, attr, value)
124
+ return value
125
+
126
+
127
+ class _LazyModule(types.ModuleType):
128
+ def __init__(self, name):
129
+ super(_LazyModule, self).__init__(name)
130
+ self.__doc__ = self.__class__.__doc__
131
+
132
+ def __dir__(self):
133
+ attrs = ["__doc__", "__name__"]
134
+ attrs += [attr.name for attr in self._moved_attributes]
135
+ return attrs
136
+
137
+ # Subclasses should override this
138
+ _moved_attributes = []
139
+
140
+
141
+ class MovedAttribute(_LazyDescr):
142
+ def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
143
+ super(MovedAttribute, self).__init__(name)
144
+ if PY3:
145
+ if new_mod is None:
146
+ new_mod = name
147
+ self.mod = new_mod
148
+ if new_attr is None:
149
+ if old_attr is None:
150
+ new_attr = name
151
+ else:
152
+ new_attr = old_attr
153
+ self.attr = new_attr
154
+ else:
155
+ self.mod = old_mod
156
+ if old_attr is None:
157
+ old_attr = name
158
+ self.attr = old_attr
159
+
160
+ def _resolve(self):
161
+ module = _import_module(self.mod)
162
+ return getattr(module, self.attr)
163
+
164
+
165
+ class _SixMetaPathImporter(object):
166
+
167
+ """
168
+ A meta path importer to import six.moves and its submodules.
169
+
170
+ This class implements a PEP302 finder and loader. It should be compatible
171
+ with Python 2.5 and all existing versions of Python3
172
+ """
173
+
174
+ def __init__(self, six_module_name):
175
+ self.name = six_module_name
176
+ self.known_modules = {}
177
+
178
+ def _add_module(self, mod, *fullnames):
179
+ for fullname in fullnames:
180
+ self.known_modules[self.name + "." + fullname] = mod
181
+
182
+ def _get_module(self, fullname):
183
+ return self.known_modules[self.name + "." + fullname]
184
+
185
+ def find_module(self, fullname, path=None):
186
+ if fullname in self.known_modules:
187
+ return self
188
+ return None
189
+
190
+ def find_spec(self, fullname, path, target=None):
191
+ if fullname in self.known_modules:
192
+ return spec_from_loader(fullname, self)
193
+ return None
194
+
195
+ def __get_module(self, fullname):
196
+ try:
197
+ return self.known_modules[fullname]
198
+ except KeyError:
199
+ raise ImportError("This loader does not know module " + fullname)
200
+
201
+ def load_module(self, fullname):
202
+ try:
203
+ # in case of a reload
204
+ return sys.modules[fullname]
205
+ except KeyError:
206
+ pass
207
+ mod = self.__get_module(fullname)
208
+ if isinstance(mod, MovedModule):
209
+ mod = mod._resolve()
210
+ else:
211
+ mod.__loader__ = self
212
+ sys.modules[fullname] = mod
213
+ return mod
214
+
215
+ def is_package(self, fullname):
216
+ """
217
+ Return true, if the named module is a package.
218
+
219
+ We need this method to get correct spec objects with
220
+ Python 3.4 (see PEP451)
221
+ """
222
+ return hasattr(self.__get_module(fullname), "__path__")
223
+
224
+ def get_code(self, fullname):
225
+ """Return None
226
+
227
+ Required, if is_package is implemented"""
228
+ self.__get_module(fullname) # eventually raises ImportError
229
+ return None
230
+
231
+ get_source = get_code # same as get_code
232
+
233
+ def create_module(self, spec):
234
+ return self.load_module(spec.name)
235
+
236
+ def exec_module(self, module):
237
+ pass
238
+
239
+
240
+ _importer = _SixMetaPathImporter(__name__)
241
+
242
+
243
+ class _MovedItems(_LazyModule):
244
+
245
+ """Lazy loading of moved objects"""
246
+
247
+ __path__ = [] # mark as package
248
+
249
+
250
+ _moved_attributes = [
251
+ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"),
252
+ MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"),
253
+ MovedAttribute(
254
+ "filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"
255
+ ),
256
+ MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"),
257
+ MovedAttribute("intern", "__builtin__", "sys"),
258
+ MovedAttribute("map", "itertools", "builtins", "imap", "map"),
259
+ MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"),
260
+ MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"),
261
+ MovedAttribute("getoutput", "commands", "subprocess"),
262
+ MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"),
263
+ MovedAttribute(
264
+ "reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"
265
+ ),
266
+ MovedAttribute("reduce", "__builtin__", "functools"),
267
+ MovedAttribute("shlex_quote", "pipes", "shlex", "quote"),
268
+ MovedAttribute("StringIO", "StringIO", "io"),
269
+ MovedAttribute("UserDict", "UserDict", "collections"),
270
+ MovedAttribute("UserList", "UserList", "collections"),
271
+ MovedAttribute("UserString", "UserString", "collections"),
272
+ MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"),
273
+ MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
274
+ MovedAttribute(
275
+ "zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"
276
+ ),
277
+ MovedModule("builtins", "__builtin__"),
278
+ MovedModule("configparser", "ConfigParser"),
279
+ MovedModule(
280
+ "collections_abc",
281
+ "collections",
282
+ "collections.abc" if sys.version_info >= (3, 3) else "collections",
283
+ ),
284
+ MovedModule("copyreg", "copy_reg"),
285
+ MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
286
+ MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
287
+ MovedModule(
288
+ "_dummy_thread",
289
+ "dummy_thread",
290
+ "_dummy_thread" if sys.version_info < (3, 9) else "_thread",
291
+ ),
292
+ MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
293
+ MovedModule("http_cookies", "Cookie", "http.cookies"),
294
+ MovedModule("html_entities", "htmlentitydefs", "html.entities"),
295
+ MovedModule("html_parser", "HTMLParser", "html.parser"),
296
+ MovedModule("http_client", "httplib", "http.client"),
297
+ MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"),
298
+ MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"),
299
+ MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"),
300
+ MovedModule(
301
+ "email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"
302
+ ),
303
+ MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"),
304
+ MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"),
305
+ MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"),
306
+ MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"),
307
+ MovedModule("cPickle", "cPickle", "pickle"),
308
+ MovedModule("queue", "Queue"),
309
+ MovedModule("reprlib", "repr"),
310
+ MovedModule("socketserver", "SocketServer"),
311
+ MovedModule("_thread", "thread", "_thread"),
312
+ MovedModule("tkinter", "Tkinter"),
313
+ MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"),
314
+ MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"),
315
+ MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"),
316
+ MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"),
317
+ MovedModule("tkinter_tix", "Tix", "tkinter.tix"),
318
+ MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"),
319
+ MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"),
320
+ MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"),
321
+ MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"),
322
+ MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"),
323
+ MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"),
324
+ MovedModule("tkinter_font", "tkFont", "tkinter.font"),
325
+ MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"),
326
+ MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"),
327
+ MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"),
328
+ MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"),
329
+ MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"),
330
+ MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"),
331
+ MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"),
332
+ MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"),
333
+ ]
334
+ # Add windows specific modules.
335
+ if sys.platform == "win32":
336
+ _moved_attributes += [
337
+ MovedModule("winreg", "_winreg"),
338
+ ]
339
+
340
+ for attr in _moved_attributes:
341
+ setattr(_MovedItems, attr.name, attr)
342
+ if isinstance(attr, MovedModule):
343
+ _importer._add_module(attr, "moves." + attr.name)
344
+ del attr
345
+
346
+ _MovedItems._moved_attributes = _moved_attributes
347
+
348
+ moves = _MovedItems(__name__ + ".moves")
349
+ _importer._add_module(moves, "moves")
350
+
351
+
352
+ class Module_six_moves_urllib_parse(_LazyModule):
353
+
354
+ """Lazy loading of moved objects in six.moves.urllib_parse"""
355
+
356
+
357
+ _urllib_parse_moved_attributes = [
358
+ MovedAttribute("ParseResult", "urlparse", "urllib.parse"),
359
+ MovedAttribute("SplitResult", "urlparse", "urllib.parse"),
360
+ MovedAttribute("parse_qs", "urlparse", "urllib.parse"),
361
+ MovedAttribute("parse_qsl", "urlparse", "urllib.parse"),
362
+ MovedAttribute("urldefrag", "urlparse", "urllib.parse"),
363
+ MovedAttribute("urljoin", "urlparse", "urllib.parse"),
364
+ MovedAttribute("urlparse", "urlparse", "urllib.parse"),
365
+ MovedAttribute("urlsplit", "urlparse", "urllib.parse"),
366
+ MovedAttribute("urlunparse", "urlparse", "urllib.parse"),
367
+ MovedAttribute("urlunsplit", "urlparse", "urllib.parse"),
368
+ MovedAttribute("quote", "urllib", "urllib.parse"),
369
+ MovedAttribute("quote_plus", "urllib", "urllib.parse"),
370
+ MovedAttribute("unquote", "urllib", "urllib.parse"),
371
+ MovedAttribute("unquote_plus", "urllib", "urllib.parse"),
372
+ MovedAttribute(
373
+ "unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"
374
+ ),
375
+ MovedAttribute("urlencode", "urllib", "urllib.parse"),
376
+ MovedAttribute("splitquery", "urllib", "urllib.parse"),
377
+ MovedAttribute("splittag", "urllib", "urllib.parse"),
378
+ MovedAttribute("splituser", "urllib", "urllib.parse"),
379
+ MovedAttribute("splitvalue", "urllib", "urllib.parse"),
380
+ MovedAttribute("uses_fragment", "urlparse", "urllib.parse"),
381
+ MovedAttribute("uses_netloc", "urlparse", "urllib.parse"),
382
+ MovedAttribute("uses_params", "urlparse", "urllib.parse"),
383
+ MovedAttribute("uses_query", "urlparse", "urllib.parse"),
384
+ MovedAttribute("uses_relative", "urlparse", "urllib.parse"),
385
+ ]
386
+ for attr in _urllib_parse_moved_attributes:
387
+ setattr(Module_six_moves_urllib_parse, attr.name, attr)
388
+ del attr
389
+
390
+ Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes
391
+
392
+ _importer._add_module(
393
+ Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"),
394
+ "moves.urllib_parse",
395
+ "moves.urllib.parse",
396
+ )
397
+
398
+
399
+ class Module_six_moves_urllib_error(_LazyModule):
400
+
401
+ """Lazy loading of moved objects in six.moves.urllib_error"""
402
+
403
+
404
+ _urllib_error_moved_attributes = [
405
+ MovedAttribute("URLError", "urllib2", "urllib.error"),
406
+ MovedAttribute("HTTPError", "urllib2", "urllib.error"),
407
+ MovedAttribute("ContentTooShortError", "urllib", "urllib.error"),
408
+ ]
409
+ for attr in _urllib_error_moved_attributes:
410
+ setattr(Module_six_moves_urllib_error, attr.name, attr)
411
+ del attr
412
+
413
+ Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes
414
+
415
+ _importer._add_module(
416
+ Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"),
417
+ "moves.urllib_error",
418
+ "moves.urllib.error",
419
+ )
420
+
421
+
422
+ class Module_six_moves_urllib_request(_LazyModule):
423
+
424
+ """Lazy loading of moved objects in six.moves.urllib_request"""
425
+
426
+
427
+ _urllib_request_moved_attributes = [
428
+ MovedAttribute("urlopen", "urllib2", "urllib.request"),
429
+ MovedAttribute("install_opener", "urllib2", "urllib.request"),
430
+ MovedAttribute("build_opener", "urllib2", "urllib.request"),
431
+ MovedAttribute("pathname2url", "urllib", "urllib.request"),
432
+ MovedAttribute("url2pathname", "urllib", "urllib.request"),
433
+ MovedAttribute("getproxies", "urllib", "urllib.request"),
434
+ MovedAttribute("Request", "urllib2", "urllib.request"),
435
+ MovedAttribute("OpenerDirector", "urllib2", "urllib.request"),
436
+ MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"),
437
+ MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"),
438
+ MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"),
439
+ MovedAttribute("ProxyHandler", "urllib2", "urllib.request"),
440
+ MovedAttribute("BaseHandler", "urllib2", "urllib.request"),
441
+ MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"),
442
+ MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"),
443
+ MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"),
444
+ MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"),
445
+ MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"),
446
+ MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"),
447
+ MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"),
448
+ MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"),
449
+ MovedAttribute("HTTPHandler", "urllib2", "urllib.request"),
450
+ MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"),
451
+ MovedAttribute("FileHandler", "urllib2", "urllib.request"),
452
+ MovedAttribute("FTPHandler", "urllib2", "urllib.request"),
453
+ MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"),
454
+ MovedAttribute("UnknownHandler", "urllib2", "urllib.request"),
455
+ MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"),
456
+ MovedAttribute("urlretrieve", "urllib", "urllib.request"),
457
+ MovedAttribute("urlcleanup", "urllib", "urllib.request"),
458
+ MovedAttribute("URLopener", "urllib", "urllib.request"),
459
+ MovedAttribute("FancyURLopener", "urllib", "urllib.request"),
460
+ MovedAttribute("proxy_bypass", "urllib", "urllib.request"),
461
+ MovedAttribute("parse_http_list", "urllib2", "urllib.request"),
462
+ MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"),
463
+ ]
464
+ for attr in _urllib_request_moved_attributes:
465
+ setattr(Module_six_moves_urllib_request, attr.name, attr)
466
+ del attr
467
+
468
+ Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes
469
+
470
+ _importer._add_module(
471
+ Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"),
472
+ "moves.urllib_request",
473
+ "moves.urllib.request",
474
+ )
475
+
476
+
477
+ class Module_six_moves_urllib_response(_LazyModule):
478
+
479
+ """Lazy loading of moved objects in six.moves.urllib_response"""
480
+
481
+
482
+ _urllib_response_moved_attributes = [
483
+ MovedAttribute("addbase", "urllib", "urllib.response"),
484
+ MovedAttribute("addclosehook", "urllib", "urllib.response"),
485
+ MovedAttribute("addinfo", "urllib", "urllib.response"),
486
+ MovedAttribute("addinfourl", "urllib", "urllib.response"),
487
+ ]
488
+ for attr in _urllib_response_moved_attributes:
489
+ setattr(Module_six_moves_urllib_response, attr.name, attr)
490
+ del attr
491
+
492
+ Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes
493
+
494
+ _importer._add_module(
495
+ Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"),
496
+ "moves.urllib_response",
497
+ "moves.urllib.response",
498
+ )
499
+
500
+
501
+ class Module_six_moves_urllib_robotparser(_LazyModule):
502
+
503
+ """Lazy loading of moved objects in six.moves.urllib_robotparser"""
504
+
505
+
506
+ _urllib_robotparser_moved_attributes = [
507
+ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"),
508
+ ]
509
+ for attr in _urllib_robotparser_moved_attributes:
510
+ setattr(Module_six_moves_urllib_robotparser, attr.name, attr)
511
+ del attr
512
+
513
+ Module_six_moves_urllib_robotparser._moved_attributes = (
514
+ _urllib_robotparser_moved_attributes
515
+ )
516
+
517
+ _importer._add_module(
518
+ Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"),
519
+ "moves.urllib_robotparser",
520
+ "moves.urllib.robotparser",
521
+ )
522
+
523
+
524
+ class Module_six_moves_urllib(types.ModuleType):
525
+
526
+ """Create a six.moves.urllib namespace that resembles the Python 3 namespace"""
527
+
528
+ __path__ = [] # mark as package
529
+ parse = _importer._get_module("moves.urllib_parse")
530
+ error = _importer._get_module("moves.urllib_error")
531
+ request = _importer._get_module("moves.urllib_request")
532
+ response = _importer._get_module("moves.urllib_response")
533
+ robotparser = _importer._get_module("moves.urllib_robotparser")
534
+
535
+ def __dir__(self):
536
+ return ["parse", "error", "request", "response", "robotparser"]
537
+
538
+
539
+ _importer._add_module(
540
+ Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib"
541
+ )
542
+
543
+
544
+ def add_move(move):
545
+ """Add an item to six.moves."""
546
+ setattr(_MovedItems, move.name, move)
547
+
548
+
549
+ def remove_move(name):
550
+ """Remove item from six.moves."""
551
+ try:
552
+ delattr(_MovedItems, name)
553
+ except AttributeError:
554
+ try:
555
+ del moves.__dict__[name]
556
+ except KeyError:
557
+ raise AttributeError("no such move, %r" % (name,))
558
+
559
+
560
+ if PY3:
561
+ _meth_func = "__func__"
562
+ _meth_self = "__self__"
563
+
564
+ _func_closure = "__closure__"
565
+ _func_code = "__code__"
566
+ _func_defaults = "__defaults__"
567
+ _func_globals = "__globals__"
568
+ else:
569
+ _meth_func = "im_func"
570
+ _meth_self = "im_self"
571
+
572
+ _func_closure = "func_closure"
573
+ _func_code = "func_code"
574
+ _func_defaults = "func_defaults"
575
+ _func_globals = "func_globals"
576
+
577
+
578
+ try:
579
+ advance_iterator = next
580
+ except NameError:
581
+
582
+ def advance_iterator(it):
583
+ return it.next()
584
+
585
+
586
+ next = advance_iterator
587
+
588
+
589
+ try:
590
+ callable = callable
591
+ except NameError:
592
+
593
+ def callable(obj):
594
+ return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
595
+
596
+
597
+ if PY3:
598
+
599
+ def get_unbound_function(unbound):
600
+ return unbound
601
+
602
+ create_bound_method = types.MethodType
603
+
604
+ def create_unbound_method(func, cls):
605
+ return func
606
+
607
+ Iterator = object
608
+ else:
609
+
610
+ def get_unbound_function(unbound):
611
+ return unbound.im_func
612
+
613
+ def create_bound_method(func, obj):
614
+ return types.MethodType(func, obj, obj.__class__)
615
+
616
+ def create_unbound_method(func, cls):
617
+ return types.MethodType(func, None, cls)
618
+
619
+ class Iterator(object):
620
+ def next(self):
621
+ return type(self).__next__(self)
622
+
623
+ callable = callable
624
+ _add_doc(
625
+ get_unbound_function, """Get the function out of a possibly unbound function"""
626
+ )
627
+
628
+
629
+ get_method_function = operator.attrgetter(_meth_func)
630
+ get_method_self = operator.attrgetter(_meth_self)
631
+ get_function_closure = operator.attrgetter(_func_closure)
632
+ get_function_code = operator.attrgetter(_func_code)
633
+ get_function_defaults = operator.attrgetter(_func_defaults)
634
+ get_function_globals = operator.attrgetter(_func_globals)
635
+
636
+
637
+ if PY3:
638
+
639
+ def iterkeys(d, **kw):
640
+ return iter(d.keys(**kw))
641
+
642
+ def itervalues(d, **kw):
643
+ return iter(d.values(**kw))
644
+
645
+ def iteritems(d, **kw):
646
+ return iter(d.items(**kw))
647
+
648
+ def iterlists(d, **kw):
649
+ return iter(d.lists(**kw))
650
+
651
+ viewkeys = operator.methodcaller("keys")
652
+
653
+ viewvalues = operator.methodcaller("values")
654
+
655
+ viewitems = operator.methodcaller("items")
656
+ else:
657
+
658
+ def iterkeys(d, **kw):
659
+ return d.iterkeys(**kw)
660
+
661
+ def itervalues(d, **kw):
662
+ return d.itervalues(**kw)
663
+
664
+ def iteritems(d, **kw):
665
+ return d.iteritems(**kw)
666
+
667
+ def iterlists(d, **kw):
668
+ return d.iterlists(**kw)
669
+
670
+ viewkeys = operator.methodcaller("viewkeys")
671
+
672
+ viewvalues = operator.methodcaller("viewvalues")
673
+
674
+ viewitems = operator.methodcaller("viewitems")
675
+
676
+ _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.")
677
+ _add_doc(itervalues, "Return an iterator over the values of a dictionary.")
678
+ _add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.")
679
+ _add_doc(
680
+ iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary."
681
+ )
682
+
683
+
684
+ if PY3:
685
+
686
+ def b(s):
687
+ return s.encode("latin-1")
688
+
689
+ def u(s):
690
+ return s
691
+
692
+ unichr = chr
693
+ import struct
694
+
695
+ int2byte = struct.Struct(">B").pack
696
+ del struct
697
+ byte2int = operator.itemgetter(0)
698
+ indexbytes = operator.getitem
699
+ iterbytes = iter
700
+ import io
701
+
702
+ StringIO = io.StringIO
703
+ BytesIO = io.BytesIO
704
+ del io
705
+ _assertCountEqual = "assertCountEqual"
706
+ if sys.version_info[1] <= 1:
707
+ _assertRaisesRegex = "assertRaisesRegexp"
708
+ _assertRegex = "assertRegexpMatches"
709
+ _assertNotRegex = "assertNotRegexpMatches"
710
+ else:
711
+ _assertRaisesRegex = "assertRaisesRegex"
712
+ _assertRegex = "assertRegex"
713
+ _assertNotRegex = "assertNotRegex"
714
+ else:
715
+
716
+ def b(s):
717
+ return s
718
+
719
+ # Workaround for standalone backslash
720
+
721
+ def u(s):
722
+ return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape")
723
+
724
+ unichr = unichr
725
+ int2byte = chr
726
+
727
+ def byte2int(bs):
728
+ return ord(bs[0])
729
+
730
+ def indexbytes(buf, i):
731
+ return ord(buf[i])
732
+
733
+ iterbytes = functools.partial(itertools.imap, ord)
734
+ import StringIO
735
+
736
+ StringIO = BytesIO = StringIO.StringIO
737
+ _assertCountEqual = "assertItemsEqual"
738
+ _assertRaisesRegex = "assertRaisesRegexp"
739
+ _assertRegex = "assertRegexpMatches"
740
+ _assertNotRegex = "assertNotRegexpMatches"
741
+ _add_doc(b, """Byte literal""")
742
+ _add_doc(u, """Text literal""")
743
+
744
+
745
+ def assertCountEqual(self, *args, **kwargs):
746
+ return getattr(self, _assertCountEqual)(*args, **kwargs)
747
+
748
+
749
+ def assertRaisesRegex(self, *args, **kwargs):
750
+ return getattr(self, _assertRaisesRegex)(*args, **kwargs)
751
+
752
+
753
+ def assertRegex(self, *args, **kwargs):
754
+ return getattr(self, _assertRegex)(*args, **kwargs)
755
+
756
+
757
+ def assertNotRegex(self, *args, **kwargs):
758
+ return getattr(self, _assertNotRegex)(*args, **kwargs)
759
+
760
+
761
+ if PY3:
762
+ exec_ = getattr(moves.builtins, "exec")
763
+
764
+ def reraise(tp, value, tb=None):
765
+ try:
766
+ if value is None:
767
+ value = tp()
768
+ if value.__traceback__ is not tb:
769
+ raise value.with_traceback(tb)
770
+ raise value
771
+ finally:
772
+ value = None
773
+ tb = None
774
+
775
+
776
+ else:
777
+
778
+ def exec_(_code_, _globs_=None, _locs_=None):
779
+ """Execute code in a namespace."""
780
+ if _globs_ is None:
781
+ frame = sys._getframe(1)
782
+ _globs_ = frame.f_globals
783
+ if _locs_ is None:
784
+ _locs_ = frame.f_locals
785
+ del frame
786
+ elif _locs_ is None:
787
+ _locs_ = _globs_
788
+ exec ("""exec _code_ in _globs_, _locs_""")
789
+
790
+ exec_(
791
+ """def reraise(tp, value, tb=None):
792
+ try:
793
+ raise tp, value, tb
794
+ finally:
795
+ tb = None
796
+ """
797
+ )
798
+
799
+
800
+ if sys.version_info[:2] > (3,):
801
+ exec_(
802
+ """def raise_from(value, from_value):
803
+ try:
804
+ raise value from from_value
805
+ finally:
806
+ value = None
807
+ """
808
+ )
809
+ else:
810
+
811
+ def raise_from(value, from_value):
812
+ raise value
813
+
814
+
815
+ print_ = getattr(moves.builtins, "print", None)
816
+ if print_ is None:
817
+
818
+ def print_(*args, **kwargs):
819
+ """The new-style print function for Python 2.4 and 2.5."""
820
+ fp = kwargs.pop("file", sys.stdout)
821
+ if fp is None:
822
+ return
823
+
824
+ def write(data):
825
+ if not isinstance(data, basestring):
826
+ data = str(data)
827
+ # If the file has an encoding, encode unicode with it.
828
+ if (
829
+ isinstance(fp, file)
830
+ and isinstance(data, unicode)
831
+ and fp.encoding is not None
832
+ ):
833
+ errors = getattr(fp, "errors", None)
834
+ if errors is None:
835
+ errors = "strict"
836
+ data = data.encode(fp.encoding, errors)
837
+ fp.write(data)
838
+
839
+ want_unicode = False
840
+ sep = kwargs.pop("sep", None)
841
+ if sep is not None:
842
+ if isinstance(sep, unicode):
843
+ want_unicode = True
844
+ elif not isinstance(sep, str):
845
+ raise TypeError("sep must be None or a string")
846
+ end = kwargs.pop("end", None)
847
+ if end is not None:
848
+ if isinstance(end, unicode):
849
+ want_unicode = True
850
+ elif not isinstance(end, str):
851
+ raise TypeError("end must be None or a string")
852
+ if kwargs:
853
+ raise TypeError("invalid keyword arguments to print()")
854
+ if not want_unicode:
855
+ for arg in args:
856
+ if isinstance(arg, unicode):
857
+ want_unicode = True
858
+ break
859
+ if want_unicode:
860
+ newline = unicode("\n")
861
+ space = unicode(" ")
862
+ else:
863
+ newline = "\n"
864
+ space = " "
865
+ if sep is None:
866
+ sep = space
867
+ if end is None:
868
+ end = newline
869
+ for i, arg in enumerate(args):
870
+ if i:
871
+ write(sep)
872
+ write(arg)
873
+ write(end)
874
+
875
+
876
+ if sys.version_info[:2] < (3, 3):
877
+ _print = print_
878
+
879
+ def print_(*args, **kwargs):
880
+ fp = kwargs.get("file", sys.stdout)
881
+ flush = kwargs.pop("flush", False)
882
+ _print(*args, **kwargs)
883
+ if flush and fp is not None:
884
+ fp.flush()
885
+
886
+
887
+ _add_doc(reraise, """Reraise an exception.""")
888
+
889
+ if sys.version_info[0:2] < (3, 4):
890
+ # This does exactly the same what the :func:`py3:functools.update_wrapper`
891
+ # function does on Python versions after 3.2. It sets the ``__wrapped__``
892
+ # attribute on ``wrapper`` object and it doesn't raise an error if any of
893
+ # the attributes mentioned in ``assigned`` and ``updated`` are missing on
894
+ # ``wrapped`` object.
895
+ def _update_wrapper(
896
+ wrapper,
897
+ wrapped,
898
+ assigned=functools.WRAPPER_ASSIGNMENTS,
899
+ updated=functools.WRAPPER_UPDATES,
900
+ ):
901
+ for attr in assigned:
902
+ try:
903
+ value = getattr(wrapped, attr)
904
+ except AttributeError:
905
+ continue
906
+ else:
907
+ setattr(wrapper, attr, value)
908
+ for attr in updated:
909
+ getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
910
+ wrapper.__wrapped__ = wrapped
911
+ return wrapper
912
+
913
+ _update_wrapper.__doc__ = functools.update_wrapper.__doc__
914
+
915
+ def wraps(
916
+ wrapped,
917
+ assigned=functools.WRAPPER_ASSIGNMENTS,
918
+ updated=functools.WRAPPER_UPDATES,
919
+ ):
920
+ return functools.partial(
921
+ _update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated
922
+ )
923
+
924
+ wraps.__doc__ = functools.wraps.__doc__
925
+
926
+ else:
927
+ wraps = functools.wraps
928
+
929
+
930
+ def with_metaclass(meta, *bases):
931
+ """Create a base class with a metaclass."""
932
+ # This requires a bit of explanation: the basic idea is to make a dummy
933
+ # metaclass for one level of class instantiation that replaces itself with
934
+ # the actual metaclass.
935
+ class metaclass(type):
936
+ def __new__(cls, name, this_bases, d):
937
+ if sys.version_info[:2] >= (3, 7):
938
+ # This version introduced PEP 560 that requires a bit
939
+ # of extra care (we mimic what is done by __build_class__).
940
+ resolved_bases = types.resolve_bases(bases)
941
+ if resolved_bases is not bases:
942
+ d["__orig_bases__"] = bases
943
+ else:
944
+ resolved_bases = bases
945
+ return meta(name, resolved_bases, d)
946
+
947
+ @classmethod
948
+ def __prepare__(cls, name, this_bases):
949
+ return meta.__prepare__(name, bases)
950
+
951
+ return type.__new__(metaclass, "temporary_class", (), {})
952
+
953
+
954
+ def add_metaclass(metaclass):
955
+ """Class decorator for creating a class with a metaclass."""
956
+
957
+ def wrapper(cls):
958
+ orig_vars = cls.__dict__.copy()
959
+ slots = orig_vars.get("__slots__")
960
+ if slots is not None:
961
+ if isinstance(slots, str):
962
+ slots = [slots]
963
+ for slots_var in slots:
964
+ orig_vars.pop(slots_var)
965
+ orig_vars.pop("__dict__", None)
966
+ orig_vars.pop("__weakref__", None)
967
+ if hasattr(cls, "__qualname__"):
968
+ orig_vars["__qualname__"] = cls.__qualname__
969
+ return metaclass(cls.__name__, cls.__bases__, orig_vars)
970
+
971
+ return wrapper
972
+
973
+
974
+ def ensure_binary(s, encoding="utf-8", errors="strict"):
975
+ """Coerce **s** to six.binary_type.
976
+
977
+ For Python 2:
978
+ - `unicode` -> encoded to `str`
979
+ - `str` -> `str`
980
+
981
+ For Python 3:
982
+ - `str` -> encoded to `bytes`
983
+ - `bytes` -> `bytes`
984
+ """
985
+ if isinstance(s, binary_type):
986
+ return s
987
+ if isinstance(s, text_type):
988
+ return s.encode(encoding, errors)
989
+ raise TypeError("not expecting type '%s'" % type(s))
990
+
991
+
992
+ def ensure_str(s, encoding="utf-8", errors="strict"):
993
+ """Coerce *s* to `str`.
994
+
995
+ For Python 2:
996
+ - `unicode` -> encoded to `str`
997
+ - `str` -> `str`
998
+
999
+ For Python 3:
1000
+ - `str` -> `str`
1001
+ - `bytes` -> decoded to `str`
1002
+ """
1003
+ # Optimization: Fast return for the common case.
1004
+ if type(s) is str:
1005
+ return s
1006
+ if PY2 and isinstance(s, text_type):
1007
+ return s.encode(encoding, errors)
1008
+ elif PY3 and isinstance(s, binary_type):
1009
+ return s.decode(encoding, errors)
1010
+ elif not isinstance(s, (text_type, binary_type)):
1011
+ raise TypeError("not expecting type '%s'" % type(s))
1012
+ return s
1013
+
1014
+
1015
+ def ensure_text(s, encoding="utf-8", errors="strict"):
1016
+ """Coerce *s* to six.text_type.
1017
+
1018
+ For Python 2:
1019
+ - `unicode` -> `unicode`
1020
+ - `str` -> `unicode`
1021
+
1022
+ For Python 3:
1023
+ - `str` -> `str`
1024
+ - `bytes` -> decoded to `str`
1025
+ """
1026
+ if isinstance(s, binary_type):
1027
+ return s.decode(encoding, errors)
1028
+ elif isinstance(s, text_type):
1029
+ return s
1030
+ else:
1031
+ raise TypeError("not expecting type '%s'" % type(s))
1032
+
1033
+
1034
+ def python_2_unicode_compatible(klass):
1035
+ """
1036
+ A class decorator that defines __unicode__ and __str__ methods under Python 2.
1037
+ Under Python 3 it does nothing.
1038
+
1039
+ To support Python 2 and 3 with a single code base, define a __str__ method
1040
+ returning text and apply this decorator to the class.
1041
+ """
1042
+ if PY2:
1043
+ if "__str__" not in klass.__dict__:
1044
+ raise ValueError(
1045
+ "@python_2_unicode_compatible cannot be applied "
1046
+ "to %s because it doesn't define __str__()." % klass.__name__
1047
+ )
1048
+ klass.__unicode__ = klass.__str__
1049
+ klass.__str__ = lambda self: self.__unicode__().encode("utf-8")
1050
+ return klass
1051
+
1052
+
1053
+ # Complete the moves implementation.
1054
+ # This code is at the end of this module to speed up module loading.
1055
+ # Turn this module into a package.
1056
+ __path__ = [] # required for PEP 302 and PEP 451
1057
+ __package__ = __name__ # see PEP 366 @ReservedAssignment
1058
+ if globals().get("__spec__") is not None:
1059
+ __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable
1060
+ # Remove other six meta path importers, since they cause problems. This can
1061
+ # happen if six is removed from sys.modules and then reloaded. (Setuptools does
1062
+ # this for some reason.)
1063
+ if sys.meta_path:
1064
+ for i, importer in enumerate(sys.meta_path):
1065
+ # Here's some real nastiness: Another "instance" of the six module might
1066
+ # be floating around. Therefore, we can't use isinstance() to check for
1067
+ # the six meta path importer, since the other six instance will have
1068
+ # inserted an importer with different class.
1069
+ if (
1070
+ type(importer).__name__ == "_SixMetaPathImporter"
1071
+ and importer.name == __name__
1072
+ ):
1073
+ del sys.meta_path[i]
1074
+ break
1075
+ del i, importer
1076
+ # Finally, add the importer to the meta path import hook.
1077
+ sys.meta_path.append(_importer)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/poolmanager.py ADDED
@@ -0,0 +1,536 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import collections
4
+ import functools
5
+ import logging
6
+
7
+ from ._collections import RecentlyUsedContainer
8
+ from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme
9
+ from .exceptions import (
10
+ LocationValueError,
11
+ MaxRetryError,
12
+ ProxySchemeUnknown,
13
+ ProxySchemeUnsupported,
14
+ URLSchemeUnknown,
15
+ )
16
+ from .packages import six
17
+ from .packages.six.moves.urllib.parse import urljoin
18
+ from .request import RequestMethods
19
+ from .util.proxy import connection_requires_http_tunnel
20
+ from .util.retry import Retry
21
+ from .util.url import parse_url
22
+
23
+ __all__ = ["PoolManager", "ProxyManager", "proxy_from_url"]
24
+
25
+
26
+ log = logging.getLogger(__name__)
27
+
28
+ SSL_KEYWORDS = (
29
+ "key_file",
30
+ "cert_file",
31
+ "cert_reqs",
32
+ "ca_certs",
33
+ "ssl_version",
34
+ "ca_cert_dir",
35
+ "ssl_context",
36
+ "key_password",
37
+ )
38
+
39
+ # All known keyword arguments that could be provided to the pool manager, its
40
+ # pools, or the underlying connections. This is used to construct a pool key.
41
+ _key_fields = (
42
+ "key_scheme", # str
43
+ "key_host", # str
44
+ "key_port", # int
45
+ "key_timeout", # int or float or Timeout
46
+ "key_retries", # int or Retry
47
+ "key_strict", # bool
48
+ "key_block", # bool
49
+ "key_source_address", # str
50
+ "key_key_file", # str
51
+ "key_key_password", # str
52
+ "key_cert_file", # str
53
+ "key_cert_reqs", # str
54
+ "key_ca_certs", # str
55
+ "key_ssl_version", # str
56
+ "key_ca_cert_dir", # str
57
+ "key_ssl_context", # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext
58
+ "key_maxsize", # int
59
+ "key_headers", # dict
60
+ "key__proxy", # parsed proxy url
61
+ "key__proxy_headers", # dict
62
+ "key__proxy_config", # class
63
+ "key_socket_options", # list of (level (int), optname (int), value (int or str)) tuples
64
+ "key__socks_options", # dict
65
+ "key_assert_hostname", # bool or string
66
+ "key_assert_fingerprint", # str
67
+ "key_server_hostname", # str
68
+ )
69
+
70
+ #: The namedtuple class used to construct keys for the connection pool.
71
+ #: All custom key schemes should include the fields in this key at a minimum.
72
+ PoolKey = collections.namedtuple("PoolKey", _key_fields)
73
+
74
+ _proxy_config_fields = ("ssl_context", "use_forwarding_for_https")
75
+ ProxyConfig = collections.namedtuple("ProxyConfig", _proxy_config_fields)
76
+
77
+
78
+ def _default_key_normalizer(key_class, request_context):
79
+ """
80
+ Create a pool key out of a request context dictionary.
81
+
82
+ According to RFC 3986, both the scheme and host are case-insensitive.
83
+ Therefore, this function normalizes both before constructing the pool
84
+ key for an HTTPS request. If you wish to change this behaviour, provide
85
+ alternate callables to ``key_fn_by_scheme``.
86
+
87
+ :param key_class:
88
+ The class to use when constructing the key. This should be a namedtuple
89
+ with the ``scheme`` and ``host`` keys at a minimum.
90
+ :type key_class: namedtuple
91
+ :param request_context:
92
+ A dictionary-like object that contain the context for a request.
93
+ :type request_context: dict
94
+
95
+ :return: A namedtuple that can be used as a connection pool key.
96
+ :rtype: PoolKey
97
+ """
98
+ # Since we mutate the dictionary, make a copy first
99
+ context = request_context.copy()
100
+ context["scheme"] = context["scheme"].lower()
101
+ context["host"] = context["host"].lower()
102
+
103
+ # These are both dictionaries and need to be transformed into frozensets
104
+ for key in ("headers", "_proxy_headers", "_socks_options"):
105
+ if key in context and context[key] is not None:
106
+ context[key] = frozenset(context[key].items())
107
+
108
+ # The socket_options key may be a list and needs to be transformed into a
109
+ # tuple.
110
+ socket_opts = context.get("socket_options")
111
+ if socket_opts is not None:
112
+ context["socket_options"] = tuple(socket_opts)
113
+
114
+ # Map the kwargs to the names in the namedtuple - this is necessary since
115
+ # namedtuples can't have fields starting with '_'.
116
+ for key in list(context.keys()):
117
+ context["key_" + key] = context.pop(key)
118
+
119
+ # Default to ``None`` for keys missing from the context
120
+ for field in key_class._fields:
121
+ if field not in context:
122
+ context[field] = None
123
+
124
+ return key_class(**context)
125
+
126
+
127
+ #: A dictionary that maps a scheme to a callable that creates a pool key.
128
+ #: This can be used to alter the way pool keys are constructed, if desired.
129
+ #: Each PoolManager makes a copy of this dictionary so they can be configured
130
+ #: globally here, or individually on the instance.
131
+ key_fn_by_scheme = {
132
+ "http": functools.partial(_default_key_normalizer, PoolKey),
133
+ "https": functools.partial(_default_key_normalizer, PoolKey),
134
+ }
135
+
136
+ pool_classes_by_scheme = {"http": HTTPConnectionPool, "https": HTTPSConnectionPool}
137
+
138
+
139
+ class PoolManager(RequestMethods):
140
+ """
141
+ Allows for arbitrary requests while transparently keeping track of
142
+ necessary connection pools for you.
143
+
144
+ :param num_pools:
145
+ Number of connection pools to cache before discarding the least
146
+ recently used pool.
147
+
148
+ :param headers:
149
+ Headers to include with all requests, unless other headers are given
150
+ explicitly.
151
+
152
+ :param \\**connection_pool_kw:
153
+ Additional parameters are used to create fresh
154
+ :class:`urllib3.connectionpool.ConnectionPool` instances.
155
+
156
+ Example::
157
+
158
+ >>> manager = PoolManager(num_pools=2)
159
+ >>> r = manager.request('GET', 'http://google.com/')
160
+ >>> r = manager.request('GET', 'http://google.com/mail')
161
+ >>> r = manager.request('GET', 'http://yahoo.com/')
162
+ >>> len(manager.pools)
163
+ 2
164
+
165
+ """
166
+
167
+ proxy = None
168
+ proxy_config = None
169
+
170
+ def __init__(self, num_pools=10, headers=None, **connection_pool_kw):
171
+ RequestMethods.__init__(self, headers)
172
+ self.connection_pool_kw = connection_pool_kw
173
+ self.pools = RecentlyUsedContainer(num_pools, dispose_func=lambda p: p.close())
174
+
175
+ # Locally set the pool classes and keys so other PoolManagers can
176
+ # override them.
177
+ self.pool_classes_by_scheme = pool_classes_by_scheme
178
+ self.key_fn_by_scheme = key_fn_by_scheme.copy()
179
+
180
+ def __enter__(self):
181
+ return self
182
+
183
+ def __exit__(self, exc_type, exc_val, exc_tb):
184
+ self.clear()
185
+ # Return False to re-raise any potential exceptions
186
+ return False
187
+
188
+ def _new_pool(self, scheme, host, port, request_context=None):
189
+ """
190
+ Create a new :class:`urllib3.connectionpool.ConnectionPool` based on host, port, scheme, and
191
+ any additional pool keyword arguments.
192
+
193
+ If ``request_context`` is provided, it is provided as keyword arguments
194
+ to the pool class used. This method is used to actually create the
195
+ connection pools handed out by :meth:`connection_from_url` and
196
+ companion methods. It is intended to be overridden for customization.
197
+ """
198
+ pool_cls = self.pool_classes_by_scheme[scheme]
199
+ if request_context is None:
200
+ request_context = self.connection_pool_kw.copy()
201
+
202
+ # Although the context has everything necessary to create the pool,
203
+ # this function has historically only used the scheme, host, and port
204
+ # in the positional args. When an API change is acceptable these can
205
+ # be removed.
206
+ for key in ("scheme", "host", "port"):
207
+ request_context.pop(key, None)
208
+
209
+ if scheme == "http":
210
+ for kw in SSL_KEYWORDS:
211
+ request_context.pop(kw, None)
212
+
213
+ return pool_cls(host, port, **request_context)
214
+
215
+ def clear(self):
216
+ """
217
+ Empty our store of pools and direct them all to close.
218
+
219
+ This will not affect in-flight connections, but they will not be
220
+ re-used after completion.
221
+ """
222
+ self.pools.clear()
223
+
224
+ def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
225
+ """
226
+ Get a :class:`urllib3.connectionpool.ConnectionPool` based on the host, port, and scheme.
227
+
228
+ If ``port`` isn't given, it will be derived from the ``scheme`` using
229
+ ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is
230
+ provided, it is merged with the instance's ``connection_pool_kw``
231
+ variable and used to create the new connection pool, if one is
232
+ needed.
233
+ """
234
+
235
+ if not host:
236
+ raise LocationValueError("No host specified.")
237
+
238
+ request_context = self._merge_pool_kwargs(pool_kwargs)
239
+ request_context["scheme"] = scheme or "http"
240
+ if not port:
241
+ port = port_by_scheme.get(request_context["scheme"].lower(), 80)
242
+ request_context["port"] = port
243
+ request_context["host"] = host
244
+
245
+ return self.connection_from_context(request_context)
246
+
247
+ def connection_from_context(self, request_context):
248
+ """
249
+ Get a :class:`urllib3.connectionpool.ConnectionPool` based on the request context.
250
+
251
+ ``request_context`` must at least contain the ``scheme`` key and its
252
+ value must be a key in ``key_fn_by_scheme`` instance variable.
253
+ """
254
+ scheme = request_context["scheme"].lower()
255
+ pool_key_constructor = self.key_fn_by_scheme.get(scheme)
256
+ if not pool_key_constructor:
257
+ raise URLSchemeUnknown(scheme)
258
+ pool_key = pool_key_constructor(request_context)
259
+
260
+ return self.connection_from_pool_key(pool_key, request_context=request_context)
261
+
262
+ def connection_from_pool_key(self, pool_key, request_context=None):
263
+ """
264
+ Get a :class:`urllib3.connectionpool.ConnectionPool` based on the provided pool key.
265
+
266
+ ``pool_key`` should be a namedtuple that only contains immutable
267
+ objects. At a minimum it must have the ``scheme``, ``host``, and
268
+ ``port`` fields.
269
+ """
270
+ with self.pools.lock:
271
+ # If the scheme, host, or port doesn't match existing open
272
+ # connections, open a new ConnectionPool.
273
+ pool = self.pools.get(pool_key)
274
+ if pool:
275
+ return pool
276
+
277
+ # Make a fresh ConnectionPool of the desired type
278
+ scheme = request_context["scheme"]
279
+ host = request_context["host"]
280
+ port = request_context["port"]
281
+ pool = self._new_pool(scheme, host, port, request_context=request_context)
282
+ self.pools[pool_key] = pool
283
+
284
+ return pool
285
+
286
+ def connection_from_url(self, url, pool_kwargs=None):
287
+ """
288
+ Similar to :func:`urllib3.connectionpool.connection_from_url`.
289
+
290
+ If ``pool_kwargs`` is not provided and a new pool needs to be
291
+ constructed, ``self.connection_pool_kw`` is used to initialize
292
+ the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs``
293
+ is provided, it is used instead. Note that if a new pool does not
294
+ need to be created for the request, the provided ``pool_kwargs`` are
295
+ not used.
296
+ """
297
+ u = parse_url(url)
298
+ return self.connection_from_host(
299
+ u.host, port=u.port, scheme=u.scheme, pool_kwargs=pool_kwargs
300
+ )
301
+
302
+ def _merge_pool_kwargs(self, override):
303
+ """
304
+ Merge a dictionary of override values for self.connection_pool_kw.
305
+
306
+ This does not modify self.connection_pool_kw and returns a new dict.
307
+ Any keys in the override dictionary with a value of ``None`` are
308
+ removed from the merged dictionary.
309
+ """
310
+ base_pool_kwargs = self.connection_pool_kw.copy()
311
+ if override:
312
+ for key, value in override.items():
313
+ if value is None:
314
+ try:
315
+ del base_pool_kwargs[key]
316
+ except KeyError:
317
+ pass
318
+ else:
319
+ base_pool_kwargs[key] = value
320
+ return base_pool_kwargs
321
+
322
+ def _proxy_requires_url_absolute_form(self, parsed_url):
323
+ """
324
+ Indicates if the proxy requires the complete destination URL in the
325
+ request. Normally this is only needed when not using an HTTP CONNECT
326
+ tunnel.
327
+ """
328
+ if self.proxy is None:
329
+ return False
330
+
331
+ return not connection_requires_http_tunnel(
332
+ self.proxy, self.proxy_config, parsed_url.scheme
333
+ )
334
+
335
+ def _validate_proxy_scheme_url_selection(self, url_scheme):
336
+ """
337
+ Validates that were not attempting to do TLS in TLS connections on
338
+ Python2 or with unsupported SSL implementations.
339
+ """
340
+ if self.proxy is None or url_scheme != "https":
341
+ return
342
+
343
+ if self.proxy.scheme != "https":
344
+ return
345
+
346
+ if six.PY2 and not self.proxy_config.use_forwarding_for_https:
347
+ raise ProxySchemeUnsupported(
348
+ "Contacting HTTPS destinations through HTTPS proxies "
349
+ "'via CONNECT tunnels' is not supported in Python 2"
350
+ )
351
+
352
+ def urlopen(self, method, url, redirect=True, **kw):
353
+ """
354
+ Same as :meth:`urllib3.HTTPConnectionPool.urlopen`
355
+ with custom cross-host redirect logic and only sends the request-uri
356
+ portion of the ``url``.
357
+
358
+ The given ``url`` parameter must be absolute, such that an appropriate
359
+ :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it.
360
+ """
361
+ u = parse_url(url)
362
+ self._validate_proxy_scheme_url_selection(u.scheme)
363
+
364
+ conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme)
365
+
366
+ kw["assert_same_host"] = False
367
+ kw["redirect"] = False
368
+
369
+ if "headers" not in kw:
370
+ kw["headers"] = self.headers.copy()
371
+
372
+ if self._proxy_requires_url_absolute_form(u):
373
+ response = conn.urlopen(method, url, **kw)
374
+ else:
375
+ response = conn.urlopen(method, u.request_uri, **kw)
376
+
377
+ redirect_location = redirect and response.get_redirect_location()
378
+ if not redirect_location:
379
+ return response
380
+
381
+ # Support relative URLs for redirecting.
382
+ redirect_location = urljoin(url, redirect_location)
383
+
384
+ # RFC 7231, Section 6.4.4
385
+ if response.status == 303:
386
+ method = "GET"
387
+
388
+ retries = kw.get("retries")
389
+ if not isinstance(retries, Retry):
390
+ retries = Retry.from_int(retries, redirect=redirect)
391
+
392
+ # Strip headers marked as unsafe to forward to the redirected location.
393
+ # Check remove_headers_on_redirect to avoid a potential network call within
394
+ # conn.is_same_host() which may use socket.gethostbyname() in the future.
395
+ if retries.remove_headers_on_redirect and not conn.is_same_host(
396
+ redirect_location
397
+ ):
398
+ headers = list(six.iterkeys(kw["headers"]))
399
+ for header in headers:
400
+ if header.lower() in retries.remove_headers_on_redirect:
401
+ kw["headers"].pop(header, None)
402
+
403
+ try:
404
+ retries = retries.increment(method, url, response=response, _pool=conn)
405
+ except MaxRetryError:
406
+ if retries.raise_on_redirect:
407
+ response.drain_conn()
408
+ raise
409
+ return response
410
+
411
+ kw["retries"] = retries
412
+ kw["redirect"] = redirect
413
+
414
+ log.info("Redirecting %s -> %s", url, redirect_location)
415
+
416
+ response.drain_conn()
417
+ return self.urlopen(method, redirect_location, **kw)
418
+
419
+
420
+ class ProxyManager(PoolManager):
421
+ """
422
+ Behaves just like :class:`PoolManager`, but sends all requests through
423
+ the defined proxy, using the CONNECT method for HTTPS URLs.
424
+
425
+ :param proxy_url:
426
+ The URL of the proxy to be used.
427
+
428
+ :param proxy_headers:
429
+ A dictionary containing headers that will be sent to the proxy. In case
430
+ of HTTP they are being sent with each request, while in the
431
+ HTTPS/CONNECT case they are sent only once. Could be used for proxy
432
+ authentication.
433
+
434
+ :param proxy_ssl_context:
435
+ The proxy SSL context is used to establish the TLS connection to the
436
+ proxy when using HTTPS proxies.
437
+
438
+ :param use_forwarding_for_https:
439
+ (Defaults to False) If set to True will forward requests to the HTTPS
440
+ proxy to be made on behalf of the client instead of creating a TLS
441
+ tunnel via the CONNECT method. **Enabling this flag means that request
442
+ and response headers and content will be visible from the HTTPS proxy**
443
+ whereas tunneling keeps request and response headers and content
444
+ private. IP address, target hostname, SNI, and port are always visible
445
+ to an HTTPS proxy even when this flag is disabled.
446
+
447
+ Example:
448
+ >>> proxy = urllib3.ProxyManager('http://localhost:3128/')
449
+ >>> r1 = proxy.request('GET', 'http://google.com/')
450
+ >>> r2 = proxy.request('GET', 'http://httpbin.org/')
451
+ >>> len(proxy.pools)
452
+ 1
453
+ >>> r3 = proxy.request('GET', 'https://httpbin.org/')
454
+ >>> r4 = proxy.request('GET', 'https://twitter.com/')
455
+ >>> len(proxy.pools)
456
+ 3
457
+
458
+ """
459
+
460
+ def __init__(
461
+ self,
462
+ proxy_url,
463
+ num_pools=10,
464
+ headers=None,
465
+ proxy_headers=None,
466
+ proxy_ssl_context=None,
467
+ use_forwarding_for_https=False,
468
+ **connection_pool_kw
469
+ ):
470
+
471
+ if isinstance(proxy_url, HTTPConnectionPool):
472
+ proxy_url = "%s://%s:%i" % (
473
+ proxy_url.scheme,
474
+ proxy_url.host,
475
+ proxy_url.port,
476
+ )
477
+ proxy = parse_url(proxy_url)
478
+
479
+ if proxy.scheme not in ("http", "https"):
480
+ raise ProxySchemeUnknown(proxy.scheme)
481
+
482
+ if not proxy.port:
483
+ port = port_by_scheme.get(proxy.scheme, 80)
484
+ proxy = proxy._replace(port=port)
485
+
486
+ self.proxy = proxy
487
+ self.proxy_headers = proxy_headers or {}
488
+ self.proxy_ssl_context = proxy_ssl_context
489
+ self.proxy_config = ProxyConfig(proxy_ssl_context, use_forwarding_for_https)
490
+
491
+ connection_pool_kw["_proxy"] = self.proxy
492
+ connection_pool_kw["_proxy_headers"] = self.proxy_headers
493
+ connection_pool_kw["_proxy_config"] = self.proxy_config
494
+
495
+ super(ProxyManager, self).__init__(num_pools, headers, **connection_pool_kw)
496
+
497
+ def connection_from_host(self, host, port=None, scheme="http", pool_kwargs=None):
498
+ if scheme == "https":
499
+ return super(ProxyManager, self).connection_from_host(
500
+ host, port, scheme, pool_kwargs=pool_kwargs
501
+ )
502
+
503
+ return super(ProxyManager, self).connection_from_host(
504
+ self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs
505
+ )
506
+
507
+ def _set_proxy_headers(self, url, headers=None):
508
+ """
509
+ Sets headers needed by proxies: specifically, the Accept and Host
510
+ headers. Only sets headers not provided by the user.
511
+ """
512
+ headers_ = {"Accept": "*/*"}
513
+
514
+ netloc = parse_url(url).netloc
515
+ if netloc:
516
+ headers_["Host"] = netloc
517
+
518
+ if headers:
519
+ headers_.update(headers)
520
+ return headers_
521
+
522
+ def urlopen(self, method, url, redirect=True, **kw):
523
+ "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute."
524
+ u = parse_url(url)
525
+ if not connection_requires_http_tunnel(self.proxy, self.proxy_config, u.scheme):
526
+ # For connections using HTTP CONNECT, httplib sets the necessary
527
+ # headers on the CONNECT to the proxy. If we're not using CONNECT,
528
+ # we'll definitely need to set 'Host' at the very least.
529
+ headers = kw.get("headers", self.headers)
530
+ kw["headers"] = self._set_proxy_headers(url, headers)
531
+
532
+ return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw)
533
+
534
+
535
+ def proxy_from_url(url, **kw):
536
+ return ProxyManager(proxy_url=url, **kw)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/request.py ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from .filepost import encode_multipart_formdata
4
+ from .packages.six.moves.urllib.parse import urlencode
5
+
6
+ __all__ = ["RequestMethods"]
7
+
8
+
9
+ class RequestMethods(object):
10
+ """
11
+ Convenience mixin for classes who implement a :meth:`urlopen` method, such
12
+ as :class:`urllib3.HTTPConnectionPool` and
13
+ :class:`urllib3.PoolManager`.
14
+
15
+ Provides behavior for making common types of HTTP request methods and
16
+ decides which type of request field encoding to use.
17
+
18
+ Specifically,
19
+
20
+ :meth:`.request_encode_url` is for sending requests whose fields are
21
+ encoded in the URL (such as GET, HEAD, DELETE).
22
+
23
+ :meth:`.request_encode_body` is for sending requests whose fields are
24
+ encoded in the *body* of the request using multipart or www-form-urlencoded
25
+ (such as for POST, PUT, PATCH).
26
+
27
+ :meth:`.request` is for making any kind of request, it will look up the
28
+ appropriate encoding format and use one of the above two methods to make
29
+ the request.
30
+
31
+ Initializer parameters:
32
+
33
+ :param headers:
34
+ Headers to include with all requests, unless other headers are given
35
+ explicitly.
36
+ """
37
+
38
+ _encode_url_methods = {"DELETE", "GET", "HEAD", "OPTIONS"}
39
+
40
+ def __init__(self, headers=None):
41
+ self.headers = headers or {}
42
+
43
+ def urlopen(
44
+ self,
45
+ method,
46
+ url,
47
+ body=None,
48
+ headers=None,
49
+ encode_multipart=True,
50
+ multipart_boundary=None,
51
+ **kw
52
+ ): # Abstract
53
+ raise NotImplementedError(
54
+ "Classes extending RequestMethods must implement "
55
+ "their own ``urlopen`` method."
56
+ )
57
+
58
+ def request(self, method, url, fields=None, headers=None, **urlopen_kw):
59
+ """
60
+ Make a request using :meth:`urlopen` with the appropriate encoding of
61
+ ``fields`` based on the ``method`` used.
62
+
63
+ This is a convenience method that requires the least amount of manual
64
+ effort. It can be used in most situations, while still having the
65
+ option to drop down to more specific methods when necessary, such as
66
+ :meth:`request_encode_url`, :meth:`request_encode_body`,
67
+ or even the lowest level :meth:`urlopen`.
68
+ """
69
+ method = method.upper()
70
+
71
+ urlopen_kw["request_url"] = url
72
+
73
+ if method in self._encode_url_methods:
74
+ return self.request_encode_url(
75
+ method, url, fields=fields, headers=headers, **urlopen_kw
76
+ )
77
+ else:
78
+ return self.request_encode_body(
79
+ method, url, fields=fields, headers=headers, **urlopen_kw
80
+ )
81
+
82
+ def request_encode_url(self, method, url, fields=None, headers=None, **urlopen_kw):
83
+ """
84
+ Make a request using :meth:`urlopen` with the ``fields`` encoded in
85
+ the url. This is useful for request methods like GET, HEAD, DELETE, etc.
86
+ """
87
+ if headers is None:
88
+ headers = self.headers
89
+
90
+ extra_kw = {"headers": headers}
91
+ extra_kw.update(urlopen_kw)
92
+
93
+ if fields:
94
+ url += "?" + urlencode(fields)
95
+
96
+ return self.urlopen(method, url, **extra_kw)
97
+
98
+ def request_encode_body(
99
+ self,
100
+ method,
101
+ url,
102
+ fields=None,
103
+ headers=None,
104
+ encode_multipart=True,
105
+ multipart_boundary=None,
106
+ **urlopen_kw
107
+ ):
108
+ """
109
+ Make a request using :meth:`urlopen` with the ``fields`` encoded in
110
+ the body. This is useful for request methods like POST, PUT, PATCH, etc.
111
+
112
+ When ``encode_multipart=True`` (default), then
113
+ :func:`urllib3.encode_multipart_formdata` is used to encode
114
+ the payload with the appropriate content type. Otherwise
115
+ :func:`urllib.parse.urlencode` is used with the
116
+ 'application/x-www-form-urlencoded' content type.
117
+
118
+ Multipart encoding must be used when posting files, and it's reasonably
119
+ safe to use it in other times too. However, it may break request
120
+ signing, such as with OAuth.
121
+
122
+ Supports an optional ``fields`` parameter of key/value strings AND
123
+ key/filetuple. A filetuple is a (filename, data, MIME type) tuple where
124
+ the MIME type is optional. For example::
125
+
126
+ fields = {
127
+ 'foo': 'bar',
128
+ 'fakefile': ('foofile.txt', 'contents of foofile'),
129
+ 'realfile': ('barfile.txt', open('realfile').read()),
130
+ 'typedfile': ('bazfile.bin', open('bazfile').read(),
131
+ 'image/jpeg'),
132
+ 'nonamefile': 'contents of nonamefile field',
133
+ }
134
+
135
+ When uploading a file, providing a filename (the first parameter of the
136
+ tuple) is optional but recommended to best mimic behavior of browsers.
137
+
138
+ Note that if ``headers`` are supplied, the 'Content-Type' header will
139
+ be overwritten because it depends on the dynamic random boundary string
140
+ which is used to compose the body of the request. The random boundary
141
+ string can be explicitly set with the ``multipart_boundary`` parameter.
142
+ """
143
+ if headers is None:
144
+ headers = self.headers
145
+
146
+ extra_kw = {"headers": {}}
147
+
148
+ if fields:
149
+ if "body" in urlopen_kw:
150
+ raise TypeError(
151
+ "request got values for both 'fields' and 'body', can only specify one."
152
+ )
153
+
154
+ if encode_multipart:
155
+ body, content_type = encode_multipart_formdata(
156
+ fields, boundary=multipart_boundary
157
+ )
158
+ else:
159
+ body, content_type = (
160
+ urlencode(fields),
161
+ "application/x-www-form-urlencoded",
162
+ )
163
+
164
+ extra_kw["body"] = body
165
+ extra_kw["headers"] = {"Content-Type": content_type}
166
+
167
+ extra_kw["headers"].update(headers)
168
+ extra_kw.update(urlopen_kw)
169
+
170
+ return self.urlopen(method, url, **extra_kw)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/response.py ADDED
@@ -0,0 +1,821 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import io
4
+ import logging
5
+ import zlib
6
+ from contextlib import contextmanager
7
+ from socket import error as SocketError
8
+ from socket import timeout as SocketTimeout
9
+
10
+ try:
11
+ import brotli
12
+ except ImportError:
13
+ brotli = None
14
+
15
+ from ._collections import HTTPHeaderDict
16
+ from .connection import BaseSSLError, HTTPException
17
+ from .exceptions import (
18
+ BodyNotHttplibCompatible,
19
+ DecodeError,
20
+ HTTPError,
21
+ IncompleteRead,
22
+ InvalidChunkLength,
23
+ InvalidHeader,
24
+ ProtocolError,
25
+ ReadTimeoutError,
26
+ ResponseNotChunked,
27
+ SSLError,
28
+ )
29
+ from .packages import six
30
+ from .util.response import is_fp_closed, is_response_to_head
31
+
32
+ log = logging.getLogger(__name__)
33
+
34
+
35
+ class DeflateDecoder(object):
36
+ def __init__(self):
37
+ self._first_try = True
38
+ self._data = b""
39
+ self._obj = zlib.decompressobj()
40
+
41
+ def __getattr__(self, name):
42
+ return getattr(self._obj, name)
43
+
44
+ def decompress(self, data):
45
+ if not data:
46
+ return data
47
+
48
+ if not self._first_try:
49
+ return self._obj.decompress(data)
50
+
51
+ self._data += data
52
+ try:
53
+ decompressed = self._obj.decompress(data)
54
+ if decompressed:
55
+ self._first_try = False
56
+ self._data = None
57
+ return decompressed
58
+ except zlib.error:
59
+ self._first_try = False
60
+ self._obj = zlib.decompressobj(-zlib.MAX_WBITS)
61
+ try:
62
+ return self.decompress(self._data)
63
+ finally:
64
+ self._data = None
65
+
66
+
67
+ class GzipDecoderState(object):
68
+
69
+ FIRST_MEMBER = 0
70
+ OTHER_MEMBERS = 1
71
+ SWALLOW_DATA = 2
72
+
73
+
74
+ class GzipDecoder(object):
75
+ def __init__(self):
76
+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
77
+ self._state = GzipDecoderState.FIRST_MEMBER
78
+
79
+ def __getattr__(self, name):
80
+ return getattr(self._obj, name)
81
+
82
+ def decompress(self, data):
83
+ ret = bytearray()
84
+ if self._state == GzipDecoderState.SWALLOW_DATA or not data:
85
+ return bytes(ret)
86
+ while True:
87
+ try:
88
+ ret += self._obj.decompress(data)
89
+ except zlib.error:
90
+ previous_state = self._state
91
+ # Ignore data after the first error
92
+ self._state = GzipDecoderState.SWALLOW_DATA
93
+ if previous_state == GzipDecoderState.OTHER_MEMBERS:
94
+ # Allow trailing garbage acceptable in other gzip clients
95
+ return bytes(ret)
96
+ raise
97
+ data = self._obj.unused_data
98
+ if not data:
99
+ return bytes(ret)
100
+ self._state = GzipDecoderState.OTHER_MEMBERS
101
+ self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS)
102
+
103
+
104
+ if brotli is not None:
105
+
106
+ class BrotliDecoder(object):
107
+ # Supports both 'brotlipy' and 'Brotli' packages
108
+ # since they share an import name. The top branches
109
+ # are for 'brotlipy' and bottom branches for 'Brotli'
110
+ def __init__(self):
111
+ self._obj = brotli.Decompressor()
112
+ if hasattr(self._obj, "decompress"):
113
+ self.decompress = self._obj.decompress
114
+ else:
115
+ self.decompress = self._obj.process
116
+
117
+ def flush(self):
118
+ if hasattr(self._obj, "flush"):
119
+ return self._obj.flush()
120
+ return b""
121
+
122
+
123
+ class MultiDecoder(object):
124
+ """
125
+ From RFC7231:
126
+ If one or more encodings have been applied to a representation, the
127
+ sender that applied the encodings MUST generate a Content-Encoding
128
+ header field that lists the content codings in the order in which
129
+ they were applied.
130
+ """
131
+
132
+ def __init__(self, modes):
133
+ self._decoders = [_get_decoder(m.strip()) for m in modes.split(",")]
134
+
135
+ def flush(self):
136
+ return self._decoders[0].flush()
137
+
138
+ def decompress(self, data):
139
+ for d in reversed(self._decoders):
140
+ data = d.decompress(data)
141
+ return data
142
+
143
+
144
+ def _get_decoder(mode):
145
+ if "," in mode:
146
+ return MultiDecoder(mode)
147
+
148
+ if mode == "gzip":
149
+ return GzipDecoder()
150
+
151
+ if brotli is not None and mode == "br":
152
+ return BrotliDecoder()
153
+
154
+ return DeflateDecoder()
155
+
156
+
157
+ class HTTPResponse(io.IOBase):
158
+ """
159
+ HTTP Response container.
160
+
161
+ Backwards-compatible with :class:`http.client.HTTPResponse` but the response ``body`` is
162
+ loaded and decoded on-demand when the ``data`` property is accessed. This
163
+ class is also compatible with the Python standard library's :mod:`io`
164
+ module, and can hence be treated as a readable object in the context of that
165
+ framework.
166
+
167
+ Extra parameters for behaviour not present in :class:`http.client.HTTPResponse`:
168
+
169
+ :param preload_content:
170
+ If True, the response's body will be preloaded during construction.
171
+
172
+ :param decode_content:
173
+ If True, will attempt to decode the body based on the
174
+ 'content-encoding' header.
175
+
176
+ :param original_response:
177
+ When this HTTPResponse wrapper is generated from an :class:`http.client.HTTPResponse`
178
+ object, it's convenient to include the original for debug purposes. It's
179
+ otherwise unused.
180
+
181
+ :param retries:
182
+ The retries contains the last :class:`~urllib3.util.retry.Retry` that
183
+ was used during the request.
184
+
185
+ :param enforce_content_length:
186
+ Enforce content length checking. Body returned by server must match
187
+ value of Content-Length header, if present. Otherwise, raise error.
188
+ """
189
+
190
+ CONTENT_DECODERS = ["gzip", "deflate"]
191
+ if brotli is not None:
192
+ CONTENT_DECODERS += ["br"]
193
+ REDIRECT_STATUSES = [301, 302, 303, 307, 308]
194
+
195
+ def __init__(
196
+ self,
197
+ body="",
198
+ headers=None,
199
+ status=0,
200
+ version=0,
201
+ reason=None,
202
+ strict=0,
203
+ preload_content=True,
204
+ decode_content=True,
205
+ original_response=None,
206
+ pool=None,
207
+ connection=None,
208
+ msg=None,
209
+ retries=None,
210
+ enforce_content_length=False,
211
+ request_method=None,
212
+ request_url=None,
213
+ auto_close=True,
214
+ ):
215
+
216
+ if isinstance(headers, HTTPHeaderDict):
217
+ self.headers = headers
218
+ else:
219
+ self.headers = HTTPHeaderDict(headers)
220
+ self.status = status
221
+ self.version = version
222
+ self.reason = reason
223
+ self.strict = strict
224
+ self.decode_content = decode_content
225
+ self.retries = retries
226
+ self.enforce_content_length = enforce_content_length
227
+ self.auto_close = auto_close
228
+
229
+ self._decoder = None
230
+ self._body = None
231
+ self._fp = None
232
+ self._original_response = original_response
233
+ self._fp_bytes_read = 0
234
+ self.msg = msg
235
+ self._request_url = request_url
236
+
237
+ if body and isinstance(body, (six.string_types, bytes)):
238
+ self._body = body
239
+
240
+ self._pool = pool
241
+ self._connection = connection
242
+
243
+ if hasattr(body, "read"):
244
+ self._fp = body
245
+
246
+ # Are we using the chunked-style of transfer encoding?
247
+ self.chunked = False
248
+ self.chunk_left = None
249
+ tr_enc = self.headers.get("transfer-encoding", "").lower()
250
+ # Don't incur the penalty of creating a list and then discarding it
251
+ encodings = (enc.strip() for enc in tr_enc.split(","))
252
+ if "chunked" in encodings:
253
+ self.chunked = True
254
+
255
+ # Determine length of response
256
+ self.length_remaining = self._init_length(request_method)
257
+
258
+ # If requested, preload the body.
259
+ if preload_content and not self._body:
260
+ self._body = self.read(decode_content=decode_content)
261
+
262
+ def get_redirect_location(self):
263
+ """
264
+ Should we redirect and where to?
265
+
266
+ :returns: Truthy redirect location string if we got a redirect status
267
+ code and valid location. ``None`` if redirect status and no
268
+ location. ``False`` if not a redirect status code.
269
+ """
270
+ if self.status in self.REDIRECT_STATUSES:
271
+ return self.headers.get("location")
272
+
273
+ return False
274
+
275
+ def release_conn(self):
276
+ if not self._pool or not self._connection:
277
+ return
278
+
279
+ self._pool._put_conn(self._connection)
280
+ self._connection = None
281
+
282
+ def drain_conn(self):
283
+ """
284
+ Read and discard any remaining HTTP response data in the response connection.
285
+
286
+ Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
287
+ """
288
+ try:
289
+ self.read()
290
+ except (HTTPError, SocketError, BaseSSLError, HTTPException):
291
+ pass
292
+
293
+ @property
294
+ def data(self):
295
+ # For backwards-compat with earlier urllib3 0.4 and earlier.
296
+ if self._body:
297
+ return self._body
298
+
299
+ if self._fp:
300
+ return self.read(cache_content=True)
301
+
302
+ @property
303
+ def connection(self):
304
+ return self._connection
305
+
306
+ def isclosed(self):
307
+ return is_fp_closed(self._fp)
308
+
309
+ def tell(self):
310
+ """
311
+ Obtain the number of bytes pulled over the wire so far. May differ from
312
+ the amount of content returned by :meth:``urllib3.response.HTTPResponse.read``
313
+ if bytes are encoded on the wire (e.g, compressed).
314
+ """
315
+ return self._fp_bytes_read
316
+
317
+ def _init_length(self, request_method):
318
+ """
319
+ Set initial length value for Response content if available.
320
+ """
321
+ length = self.headers.get("content-length")
322
+
323
+ if length is not None:
324
+ if self.chunked:
325
+ # This Response will fail with an IncompleteRead if it can't be
326
+ # received as chunked. This method falls back to attempt reading
327
+ # the response before raising an exception.
328
+ log.warning(
329
+ "Received response with both Content-Length and "
330
+ "Transfer-Encoding set. This is expressly forbidden "
331
+ "by RFC 7230 sec 3.3.2. Ignoring Content-Length and "
332
+ "attempting to process response as Transfer-Encoding: "
333
+ "chunked."
334
+ )
335
+ return None
336
+
337
+ try:
338
+ # RFC 7230 section 3.3.2 specifies multiple content lengths can
339
+ # be sent in a single Content-Length header
340
+ # (e.g. Content-Length: 42, 42). This line ensures the values
341
+ # are all valid ints and that as long as the `set` length is 1,
342
+ # all values are the same. Otherwise, the header is invalid.
343
+ lengths = set([int(val) for val in length.split(",")])
344
+ if len(lengths) > 1:
345
+ raise InvalidHeader(
346
+ "Content-Length contained multiple "
347
+ "unmatching values (%s)" % length
348
+ )
349
+ length = lengths.pop()
350
+ except ValueError:
351
+ length = None
352
+ else:
353
+ if length < 0:
354
+ length = None
355
+
356
+ # Convert status to int for comparison
357
+ # In some cases, httplib returns a status of "_UNKNOWN"
358
+ try:
359
+ status = int(self.status)
360
+ except ValueError:
361
+ status = 0
362
+
363
+ # Check for responses that shouldn't include a body
364
+ if status in (204, 304) or 100 <= status < 200 or request_method == "HEAD":
365
+ length = 0
366
+
367
+ return length
368
+
369
+ def _init_decoder(self):
370
+ """
371
+ Set-up the _decoder attribute if necessary.
372
+ """
373
+ # Note: content-encoding value should be case-insensitive, per RFC 7230
374
+ # Section 3.2
375
+ content_encoding = self.headers.get("content-encoding", "").lower()
376
+ if self._decoder is None:
377
+ if content_encoding in self.CONTENT_DECODERS:
378
+ self._decoder = _get_decoder(content_encoding)
379
+ elif "," in content_encoding:
380
+ encodings = [
381
+ e.strip()
382
+ for e in content_encoding.split(",")
383
+ if e.strip() in self.CONTENT_DECODERS
384
+ ]
385
+ if len(encodings):
386
+ self._decoder = _get_decoder(content_encoding)
387
+
388
+ DECODER_ERROR_CLASSES = (IOError, zlib.error)
389
+ if brotli is not None:
390
+ DECODER_ERROR_CLASSES += (brotli.error,)
391
+
392
+ def _decode(self, data, decode_content, flush_decoder):
393
+ """
394
+ Decode the data passed in and potentially flush the decoder.
395
+ """
396
+ if not decode_content:
397
+ return data
398
+
399
+ try:
400
+ if self._decoder:
401
+ data = self._decoder.decompress(data)
402
+ except self.DECODER_ERROR_CLASSES as e:
403
+ content_encoding = self.headers.get("content-encoding", "").lower()
404
+ raise DecodeError(
405
+ "Received response with content-encoding: %s, but "
406
+ "failed to decode it." % content_encoding,
407
+ e,
408
+ )
409
+ if flush_decoder:
410
+ data += self._flush_decoder()
411
+
412
+ return data
413
+
414
+ def _flush_decoder(self):
415
+ """
416
+ Flushes the decoder. Should only be called if the decoder is actually
417
+ being used.
418
+ """
419
+ if self._decoder:
420
+ buf = self._decoder.decompress(b"")
421
+ return buf + self._decoder.flush()
422
+
423
+ return b""
424
+
425
+ @contextmanager
426
+ def _error_catcher(self):
427
+ """
428
+ Catch low-level python exceptions, instead re-raising urllib3
429
+ variants, so that low-level exceptions are not leaked in the
430
+ high-level api.
431
+
432
+ On exit, release the connection back to the pool.
433
+ """
434
+ clean_exit = False
435
+
436
+ try:
437
+ try:
438
+ yield
439
+
440
+ except SocketTimeout:
441
+ # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but
442
+ # there is yet no clean way to get at it from this context.
443
+ raise ReadTimeoutError(self._pool, None, "Read timed out.")
444
+
445
+ except BaseSSLError as e:
446
+ # FIXME: Is there a better way to differentiate between SSLErrors?
447
+ if "read operation timed out" not in str(e):
448
+ # SSL errors related to framing/MAC get wrapped and reraised here
449
+ raise SSLError(e)
450
+
451
+ raise ReadTimeoutError(self._pool, None, "Read timed out.")
452
+
453
+ except (HTTPException, SocketError) as e:
454
+ # This includes IncompleteRead.
455
+ raise ProtocolError("Connection broken: %r" % e, e)
456
+
457
+ # If no exception is thrown, we should avoid cleaning up
458
+ # unnecessarily.
459
+ clean_exit = True
460
+ finally:
461
+ # If we didn't terminate cleanly, we need to throw away our
462
+ # connection.
463
+ if not clean_exit:
464
+ # The response may not be closed but we're not going to use it
465
+ # anymore so close it now to ensure that the connection is
466
+ # released back to the pool.
467
+ if self._original_response:
468
+ self._original_response.close()
469
+
470
+ # Closing the response may not actually be sufficient to close
471
+ # everything, so if we have a hold of the connection close that
472
+ # too.
473
+ if self._connection:
474
+ self._connection.close()
475
+
476
+ # If we hold the original response but it's closed now, we should
477
+ # return the connection back to the pool.
478
+ if self._original_response and self._original_response.isclosed():
479
+ self.release_conn()
480
+
481
+ def read(self, amt=None, decode_content=None, cache_content=False):
482
+ """
483
+ Similar to :meth:`http.client.HTTPResponse.read`, but with two additional
484
+ parameters: ``decode_content`` and ``cache_content``.
485
+
486
+ :param amt:
487
+ How much of the content to read. If specified, caching is skipped
488
+ because it doesn't make sense to cache partial content as the full
489
+ response.
490
+
491
+ :param decode_content:
492
+ If True, will attempt to decode the body based on the
493
+ 'content-encoding' header.
494
+
495
+ :param cache_content:
496
+ If True, will save the returned data such that the same result is
497
+ returned despite of the state of the underlying file object. This
498
+ is useful if you want the ``.data`` property to continue working
499
+ after having ``.read()`` the file object. (Overridden if ``amt`` is
500
+ set.)
501
+ """
502
+ self._init_decoder()
503
+ if decode_content is None:
504
+ decode_content = self.decode_content
505
+
506
+ if self._fp is None:
507
+ return
508
+
509
+ flush_decoder = False
510
+ fp_closed = getattr(self._fp, "closed", False)
511
+
512
+ with self._error_catcher():
513
+ if amt is None:
514
+ # cStringIO doesn't like amt=None
515
+ data = self._fp.read() if not fp_closed else b""
516
+ flush_decoder = True
517
+ else:
518
+ cache_content = False
519
+ data = self._fp.read(amt) if not fp_closed else b""
520
+ if (
521
+ amt != 0 and not data
522
+ ): # Platform-specific: Buggy versions of Python.
523
+ # Close the connection when no data is returned
524
+ #
525
+ # This is redundant to what httplib/http.client _should_
526
+ # already do. However, versions of python released before
527
+ # December 15, 2012 (http://bugs.python.org/issue16298) do
528
+ # not properly close the connection in all cases. There is
529
+ # no harm in redundantly calling close.
530
+ self._fp.close()
531
+ flush_decoder = True
532
+ if self.enforce_content_length and self.length_remaining not in (
533
+ 0,
534
+ None,
535
+ ):
536
+ # This is an edge case that httplib failed to cover due
537
+ # to concerns of backward compatibility. We're
538
+ # addressing it here to make sure IncompleteRead is
539
+ # raised during streaming, so all calls with incorrect
540
+ # Content-Length are caught.
541
+ raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
542
+
543
+ if data:
544
+ self._fp_bytes_read += len(data)
545
+ if self.length_remaining is not None:
546
+ self.length_remaining -= len(data)
547
+
548
+ data = self._decode(data, decode_content, flush_decoder)
549
+
550
+ if cache_content:
551
+ self._body = data
552
+
553
+ return data
554
+
555
+ def stream(self, amt=2 ** 16, decode_content=None):
556
+ """
557
+ A generator wrapper for the read() method. A call will block until
558
+ ``amt`` bytes have been read from the connection or until the
559
+ connection is closed.
560
+
561
+ :param amt:
562
+ How much of the content to read. The generator will return up to
563
+ much data per iteration, but may return less. This is particularly
564
+ likely when using compressed data. However, the empty string will
565
+ never be returned.
566
+
567
+ :param decode_content:
568
+ If True, will attempt to decode the body based on the
569
+ 'content-encoding' header.
570
+ """
571
+ if self.chunked and self.supports_chunked_reads():
572
+ for line in self.read_chunked(amt, decode_content=decode_content):
573
+ yield line
574
+ else:
575
+ while not is_fp_closed(self._fp):
576
+ data = self.read(amt=amt, decode_content=decode_content)
577
+
578
+ if data:
579
+ yield data
580
+
581
+ @classmethod
582
+ def from_httplib(ResponseCls, r, **response_kw):
583
+ """
584
+ Given an :class:`http.client.HTTPResponse` instance ``r``, return a
585
+ corresponding :class:`urllib3.response.HTTPResponse` object.
586
+
587
+ Remaining parameters are passed to the HTTPResponse constructor, along
588
+ with ``original_response=r``.
589
+ """
590
+ headers = r.msg
591
+
592
+ if not isinstance(headers, HTTPHeaderDict):
593
+ if six.PY2:
594
+ # Python 2.7
595
+ headers = HTTPHeaderDict.from_httplib(headers)
596
+ else:
597
+ headers = HTTPHeaderDict(headers.items())
598
+
599
+ # HTTPResponse objects in Python 3 don't have a .strict attribute
600
+ strict = getattr(r, "strict", 0)
601
+ resp = ResponseCls(
602
+ body=r,
603
+ headers=headers,
604
+ status=r.status,
605
+ version=r.version,
606
+ reason=r.reason,
607
+ strict=strict,
608
+ original_response=r,
609
+ **response_kw
610
+ )
611
+ return resp
612
+
613
+ # Backwards-compatibility methods for http.client.HTTPResponse
614
+ def getheaders(self):
615
+ return self.headers
616
+
617
+ def getheader(self, name, default=None):
618
+ return self.headers.get(name, default)
619
+
620
+ # Backwards compatibility for http.cookiejar
621
+ def info(self):
622
+ return self.headers
623
+
624
+ # Overrides from io.IOBase
625
+ def close(self):
626
+ if not self.closed:
627
+ self._fp.close()
628
+
629
+ if self._connection:
630
+ self._connection.close()
631
+
632
+ if not self.auto_close:
633
+ io.IOBase.close(self)
634
+
635
+ @property
636
+ def closed(self):
637
+ if not self.auto_close:
638
+ return io.IOBase.closed.__get__(self)
639
+ elif self._fp is None:
640
+ return True
641
+ elif hasattr(self._fp, "isclosed"):
642
+ return self._fp.isclosed()
643
+ elif hasattr(self._fp, "closed"):
644
+ return self._fp.closed
645
+ else:
646
+ return True
647
+
648
+ def fileno(self):
649
+ if self._fp is None:
650
+ raise IOError("HTTPResponse has no file to get a fileno from")
651
+ elif hasattr(self._fp, "fileno"):
652
+ return self._fp.fileno()
653
+ else:
654
+ raise IOError(
655
+ "The file-like object this HTTPResponse is wrapped "
656
+ "around has no file descriptor"
657
+ )
658
+
659
+ def flush(self):
660
+ if (
661
+ self._fp is not None
662
+ and hasattr(self._fp, "flush")
663
+ and not getattr(self._fp, "closed", False)
664
+ ):
665
+ return self._fp.flush()
666
+
667
+ def readable(self):
668
+ # This method is required for `io` module compatibility.
669
+ return True
670
+
671
+ def readinto(self, b):
672
+ # This method is required for `io` module compatibility.
673
+ temp = self.read(len(b))
674
+ if len(temp) == 0:
675
+ return 0
676
+ else:
677
+ b[: len(temp)] = temp
678
+ return len(temp)
679
+
680
+ def supports_chunked_reads(self):
681
+ """
682
+ Checks if the underlying file-like object looks like a
683
+ :class:`http.client.HTTPResponse` object. We do this by testing for
684
+ the fp attribute. If it is present we assume it returns raw chunks as
685
+ processed by read_chunked().
686
+ """
687
+ return hasattr(self._fp, "fp")
688
+
689
+ def _update_chunk_length(self):
690
+ # First, we'll figure out length of a chunk and then
691
+ # we'll try to read it from socket.
692
+ if self.chunk_left is not None:
693
+ return
694
+ line = self._fp.fp.readline()
695
+ line = line.split(b";", 1)[0]
696
+ try:
697
+ self.chunk_left = int(line, 16)
698
+ except ValueError:
699
+ # Invalid chunked protocol response, abort.
700
+ self.close()
701
+ raise InvalidChunkLength(self, line)
702
+
703
+ def _handle_chunk(self, amt):
704
+ returned_chunk = None
705
+ if amt is None:
706
+ chunk = self._fp._safe_read(self.chunk_left)
707
+ returned_chunk = chunk
708
+ self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
709
+ self.chunk_left = None
710
+ elif amt < self.chunk_left:
711
+ value = self._fp._safe_read(amt)
712
+ self.chunk_left = self.chunk_left - amt
713
+ returned_chunk = value
714
+ elif amt == self.chunk_left:
715
+ value = self._fp._safe_read(amt)
716
+ self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
717
+ self.chunk_left = None
718
+ returned_chunk = value
719
+ else: # amt > self.chunk_left
720
+ returned_chunk = self._fp._safe_read(self.chunk_left)
721
+ self._fp._safe_read(2) # Toss the CRLF at the end of the chunk.
722
+ self.chunk_left = None
723
+ return returned_chunk
724
+
725
+ def read_chunked(self, amt=None, decode_content=None):
726
+ """
727
+ Similar to :meth:`HTTPResponse.read`, but with an additional
728
+ parameter: ``decode_content``.
729
+
730
+ :param amt:
731
+ How much of the content to read. If specified, caching is skipped
732
+ because it doesn't make sense to cache partial content as the full
733
+ response.
734
+
735
+ :param decode_content:
736
+ If True, will attempt to decode the body based on the
737
+ 'content-encoding' header.
738
+ """
739
+ self._init_decoder()
740
+ # FIXME: Rewrite this method and make it a class with a better structured logic.
741
+ if not self.chunked:
742
+ raise ResponseNotChunked(
743
+ "Response is not chunked. "
744
+ "Header 'transfer-encoding: chunked' is missing."
745
+ )
746
+ if not self.supports_chunked_reads():
747
+ raise BodyNotHttplibCompatible(
748
+ "Body should be http.client.HTTPResponse like. "
749
+ "It should have have an fp attribute which returns raw chunks."
750
+ )
751
+
752
+ with self._error_catcher():
753
+ # Don't bother reading the body of a HEAD request.
754
+ if self._original_response and is_response_to_head(self._original_response):
755
+ self._original_response.close()
756
+ return
757
+
758
+ # If a response is already read and closed
759
+ # then return immediately.
760
+ if self._fp.fp is None:
761
+ return
762
+
763
+ while True:
764
+ self._update_chunk_length()
765
+ if self.chunk_left == 0:
766
+ break
767
+ chunk = self._handle_chunk(amt)
768
+ decoded = self._decode(
769
+ chunk, decode_content=decode_content, flush_decoder=False
770
+ )
771
+ if decoded:
772
+ yield decoded
773
+
774
+ if decode_content:
775
+ # On CPython and PyPy, we should never need to flush the
776
+ # decoder. However, on Jython we *might* need to, so
777
+ # lets defensively do it anyway.
778
+ decoded = self._flush_decoder()
779
+ if decoded: # Platform-specific: Jython.
780
+ yield decoded
781
+
782
+ # Chunk content ends with \r\n: discard it.
783
+ while True:
784
+ line = self._fp.fp.readline()
785
+ if not line:
786
+ # Some sites may not end with '\r\n'.
787
+ break
788
+ if line == b"\r\n":
789
+ break
790
+
791
+ # We read everything; close the "file".
792
+ if self._original_response:
793
+ self._original_response.close()
794
+
795
+ def geturl(self):
796
+ """
797
+ Returns the URL that was the source of this response.
798
+ If the request that generated this response redirected, this method
799
+ will return the final redirect location.
800
+ """
801
+ if self.retries is not None and len(self.retries.history):
802
+ return self.retries.history[-1].redirect_location
803
+ else:
804
+ return self._request_url
805
+
806
+ def __iter__(self):
807
+ buffer = []
808
+ for chunk in self.stream(decode_content=True):
809
+ if b"\n" in chunk:
810
+ chunk = chunk.split(b"\n")
811
+ yield b"".join(buffer) + chunk[0] + b"\n"
812
+ for x in chunk[1:-1]:
813
+ yield x + b"\n"
814
+ if chunk[-1]:
815
+ buffer = [chunk[-1]]
816
+ else:
817
+ buffer = []
818
+ else:
819
+ buffer.append(chunk)
820
+ if buffer:
821
+ yield b"".join(buffer)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ # For backwards compatibility, provide imports that used to be here.
4
+ from .connection import is_connection_dropped
5
+ from .request import SKIP_HEADER, SKIPPABLE_HEADERS, make_headers
6
+ from .response import is_fp_closed
7
+ from .retry import Retry
8
+ from .ssl_ import (
9
+ ALPN_PROTOCOLS,
10
+ HAS_SNI,
11
+ IS_PYOPENSSL,
12
+ IS_SECURETRANSPORT,
13
+ PROTOCOL_TLS,
14
+ SSLContext,
15
+ assert_fingerprint,
16
+ resolve_cert_reqs,
17
+ resolve_ssl_version,
18
+ ssl_wrap_socket,
19
+ )
20
+ from .timeout import Timeout, current_time
21
+ from .url import Url, get_host, parse_url, split_first
22
+ from .wait import wait_for_read, wait_for_write
23
+
24
+ __all__ = (
25
+ "HAS_SNI",
26
+ "IS_PYOPENSSL",
27
+ "IS_SECURETRANSPORT",
28
+ "SSLContext",
29
+ "PROTOCOL_TLS",
30
+ "ALPN_PROTOCOLS",
31
+ "Retry",
32
+ "Timeout",
33
+ "Url",
34
+ "assert_fingerprint",
35
+ "current_time",
36
+ "is_connection_dropped",
37
+ "is_fp_closed",
38
+ "get_host",
39
+ "parse_url",
40
+ "make_headers",
41
+ "resolve_cert_reqs",
42
+ "resolve_ssl_version",
43
+ "split_first",
44
+ "ssl_wrap_socket",
45
+ "wait_for_read",
46
+ "wait_for_write",
47
+ "SKIP_HEADER",
48
+ "SKIPPABLE_HEADERS",
49
+ )
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/connection.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import socket
4
+
5
+ from pip._vendor.urllib3.exceptions import LocationParseError
6
+
7
+ from ..contrib import _appengine_environ
8
+ from ..packages import six
9
+ from .wait import NoWayToWaitForSocketError, wait_for_read
10
+
11
+
12
+ def is_connection_dropped(conn): # Platform-specific
13
+ """
14
+ Returns True if the connection is dropped and should be closed.
15
+
16
+ :param conn:
17
+ :class:`http.client.HTTPConnection` object.
18
+
19
+ Note: For platforms like AppEngine, this will always return ``False`` to
20
+ let the platform handle connection recycling transparently for us.
21
+ """
22
+ sock = getattr(conn, "sock", False)
23
+ if sock is False: # Platform-specific: AppEngine
24
+ return False
25
+ if sock is None: # Connection already closed (such as by httplib).
26
+ return True
27
+ try:
28
+ # Returns True if readable, which here means it's been dropped
29
+ return wait_for_read(sock, timeout=0.0)
30
+ except NoWayToWaitForSocketError: # Platform-specific: AppEngine
31
+ return False
32
+
33
+
34
+ # This function is copied from socket.py in the Python 2.7 standard
35
+ # library test suite. Added to its signature is only `socket_options`.
36
+ # One additional modification is that we avoid binding to IPv6 servers
37
+ # discovered in DNS if the system doesn't have IPv6 functionality.
38
+ def create_connection(
39
+ address,
40
+ timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
41
+ source_address=None,
42
+ socket_options=None,
43
+ ):
44
+ """Connect to *address* and return the socket object.
45
+
46
+ Convenience function. Connect to *address* (a 2-tuple ``(host,
47
+ port)``) and return the socket object. Passing the optional
48
+ *timeout* parameter will set the timeout on the socket instance
49
+ before attempting to connect. If no *timeout* is supplied, the
50
+ global default timeout setting returned by :func:`socket.getdefaulttimeout`
51
+ is used. If *source_address* is set it must be a tuple of (host, port)
52
+ for the socket to bind as a source address before making the connection.
53
+ An host of '' or port 0 tells the OS to use the default.
54
+ """
55
+
56
+ host, port = address
57
+ if host.startswith("["):
58
+ host = host.strip("[]")
59
+ err = None
60
+
61
+ # Using the value from allowed_gai_family() in the context of getaddrinfo lets
62
+ # us select whether to work with IPv4 DNS records, IPv6 records, or both.
63
+ # The original create_connection function always returns all records.
64
+ family = allowed_gai_family()
65
+
66
+ try:
67
+ host.encode("idna")
68
+ except UnicodeError:
69
+ return six.raise_from(
70
+ LocationParseError(u"'%s', label empty or too long" % host), None
71
+ )
72
+
73
+ for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
74
+ af, socktype, proto, canonname, sa = res
75
+ sock = None
76
+ try:
77
+ sock = socket.socket(af, socktype, proto)
78
+
79
+ # If provided, set socket level options before connecting.
80
+ _set_socket_options(sock, socket_options)
81
+
82
+ if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
83
+ sock.settimeout(timeout)
84
+ if source_address:
85
+ sock.bind(source_address)
86
+ sock.connect(sa)
87
+ return sock
88
+
89
+ except socket.error as e:
90
+ err = e
91
+ if sock is not None:
92
+ sock.close()
93
+ sock = None
94
+
95
+ if err is not None:
96
+ raise err
97
+
98
+ raise socket.error("getaddrinfo returns an empty list")
99
+
100
+
101
+ def _set_socket_options(sock, options):
102
+ if options is None:
103
+ return
104
+
105
+ for opt in options:
106
+ sock.setsockopt(*opt)
107
+
108
+
109
+ def allowed_gai_family():
110
+ """This function is designed to work in the context of
111
+ getaddrinfo, where family=socket.AF_UNSPEC is the default and
112
+ will perform a DNS search for both IPv6 and IPv4 records."""
113
+
114
+ family = socket.AF_INET
115
+ if HAS_IPV6:
116
+ family = socket.AF_UNSPEC
117
+ return family
118
+
119
+
120
+ def _has_ipv6(host):
121
+ """Returns True if the system can bind an IPv6 address."""
122
+ sock = None
123
+ has_ipv6 = False
124
+
125
+ # App Engine doesn't support IPV6 sockets and actually has a quota on the
126
+ # number of sockets that can be used, so just early out here instead of
127
+ # creating a socket needlessly.
128
+ # See https://github.com/urllib3/urllib3/issues/1446
129
+ if _appengine_environ.is_appengine_sandbox():
130
+ return False
131
+
132
+ if socket.has_ipv6:
133
+ # has_ipv6 returns true if cPython was compiled with IPv6 support.
134
+ # It does not tell us if the system has IPv6 support enabled. To
135
+ # determine that we must bind to an IPv6 address.
136
+ # https://github.com/urllib3/urllib3/pull/611
137
+ # https://bugs.python.org/issue658327
138
+ try:
139
+ sock = socket.socket(socket.AF_INET6)
140
+ sock.bind((host, 0))
141
+ has_ipv6 = True
142
+ except Exception:
143
+ pass
144
+
145
+ if sock:
146
+ sock.close()
147
+ return has_ipv6
148
+
149
+
150
+ HAS_IPV6 = _has_ipv6("::1")
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/proxy.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .ssl_ import create_urllib3_context, resolve_cert_reqs, resolve_ssl_version
2
+
3
+
4
+ def connection_requires_http_tunnel(
5
+ proxy_url=None, proxy_config=None, destination_scheme=None
6
+ ):
7
+ """
8
+ Returns True if the connection requires an HTTP CONNECT through the proxy.
9
+
10
+ :param URL proxy_url:
11
+ URL of the proxy.
12
+ :param ProxyConfig proxy_config:
13
+ Proxy configuration from poolmanager.py
14
+ :param str destination_scheme:
15
+ The scheme of the destination. (i.e https, http, etc)
16
+ """
17
+ # If we're not using a proxy, no way to use a tunnel.
18
+ if proxy_url is None:
19
+ return False
20
+
21
+ # HTTP destinations never require tunneling, we always forward.
22
+ if destination_scheme == "http":
23
+ return False
24
+
25
+ # Support for forwarding with HTTPS proxies and HTTPS destinations.
26
+ if (
27
+ proxy_url.scheme == "https"
28
+ and proxy_config
29
+ and proxy_config.use_forwarding_for_https
30
+ ):
31
+ return False
32
+
33
+ # Otherwise always use a tunnel.
34
+ return True
35
+
36
+
37
+ def create_proxy_ssl_context(
38
+ ssl_version, cert_reqs, ca_certs=None, ca_cert_dir=None, ca_cert_data=None
39
+ ):
40
+ """
41
+ Generates a default proxy ssl context if one hasn't been provided by the
42
+ user.
43
+ """
44
+ ssl_context = create_urllib3_context(
45
+ ssl_version=resolve_ssl_version(ssl_version),
46
+ cert_reqs=resolve_cert_reqs(cert_reqs),
47
+ )
48
+ if (
49
+ not ca_certs
50
+ and not ca_cert_dir
51
+ and not ca_cert_data
52
+ and hasattr(ssl_context, "load_default_certs")
53
+ ):
54
+ ssl_context.load_default_certs()
55
+
56
+ return ssl_context
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/queue.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import collections
2
+
3
+ from ..packages import six
4
+ from ..packages.six.moves import queue
5
+
6
+ if six.PY2:
7
+ # Queue is imported for side effects on MS Windows. See issue #229.
8
+ import Queue as _unused_module_Queue # noqa: F401
9
+
10
+
11
+ class LifoQueue(queue.Queue):
12
+ def _init(self, _):
13
+ self.queue = collections.deque()
14
+
15
+ def _qsize(self, len=len):
16
+ return len(self.queue)
17
+
18
+ def _put(self, item):
19
+ self.queue.append(item)
20
+
21
+ def _get(self):
22
+ return self.queue.pop()
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/request.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from base64 import b64encode
4
+
5
+ from ..exceptions import UnrewindableBodyError
6
+ from ..packages.six import b, integer_types
7
+
8
+ # Pass as a value within ``headers`` to skip
9
+ # emitting some HTTP headers that are added automatically.
10
+ # The only headers that are supported are ``Accept-Encoding``,
11
+ # ``Host``, and ``User-Agent``.
12
+ SKIP_HEADER = "@@@SKIP_HEADER@@@"
13
+ SKIPPABLE_HEADERS = frozenset(["accept-encoding", "host", "user-agent"])
14
+
15
+ ACCEPT_ENCODING = "gzip,deflate"
16
+ try:
17
+ import brotli as _unused_module_brotli # noqa: F401
18
+ except ImportError:
19
+ pass
20
+ else:
21
+ ACCEPT_ENCODING += ",br"
22
+
23
+ _FAILEDTELL = object()
24
+
25
+
26
+ def make_headers(
27
+ keep_alive=None,
28
+ accept_encoding=None,
29
+ user_agent=None,
30
+ basic_auth=None,
31
+ proxy_basic_auth=None,
32
+ disable_cache=None,
33
+ ):
34
+ """
35
+ Shortcuts for generating request headers.
36
+
37
+ :param keep_alive:
38
+ If ``True``, adds 'connection: keep-alive' header.
39
+
40
+ :param accept_encoding:
41
+ Can be a boolean, list, or string.
42
+ ``True`` translates to 'gzip,deflate'.
43
+ List will get joined by comma.
44
+ String will be used as provided.
45
+
46
+ :param user_agent:
47
+ String representing the user-agent you want, such as
48
+ "python-urllib3/0.6"
49
+
50
+ :param basic_auth:
51
+ Colon-separated username:password string for 'authorization: basic ...'
52
+ auth header.
53
+
54
+ :param proxy_basic_auth:
55
+ Colon-separated username:password string for 'proxy-authorization: basic ...'
56
+ auth header.
57
+
58
+ :param disable_cache:
59
+ If ``True``, adds 'cache-control: no-cache' header.
60
+
61
+ Example::
62
+
63
+ >>> make_headers(keep_alive=True, user_agent="Batman/1.0")
64
+ {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'}
65
+ >>> make_headers(accept_encoding=True)
66
+ {'accept-encoding': 'gzip,deflate'}
67
+ """
68
+ headers = {}
69
+ if accept_encoding:
70
+ if isinstance(accept_encoding, str):
71
+ pass
72
+ elif isinstance(accept_encoding, list):
73
+ accept_encoding = ",".join(accept_encoding)
74
+ else:
75
+ accept_encoding = ACCEPT_ENCODING
76
+ headers["accept-encoding"] = accept_encoding
77
+
78
+ if user_agent:
79
+ headers["user-agent"] = user_agent
80
+
81
+ if keep_alive:
82
+ headers["connection"] = "keep-alive"
83
+
84
+ if basic_auth:
85
+ headers["authorization"] = "Basic " + b64encode(b(basic_auth)).decode("utf-8")
86
+
87
+ if proxy_basic_auth:
88
+ headers["proxy-authorization"] = "Basic " + b64encode(
89
+ b(proxy_basic_auth)
90
+ ).decode("utf-8")
91
+
92
+ if disable_cache:
93
+ headers["cache-control"] = "no-cache"
94
+
95
+ return headers
96
+
97
+
98
+ def set_file_position(body, pos):
99
+ """
100
+ If a position is provided, move file to that point.
101
+ Otherwise, we'll attempt to record a position for future use.
102
+ """
103
+ if pos is not None:
104
+ rewind_body(body, pos)
105
+ elif getattr(body, "tell", None) is not None:
106
+ try:
107
+ pos = body.tell()
108
+ except (IOError, OSError):
109
+ # This differentiates from None, allowing us to catch
110
+ # a failed `tell()` later when trying to rewind the body.
111
+ pos = _FAILEDTELL
112
+
113
+ return pos
114
+
115
+
116
+ def rewind_body(body, body_pos):
117
+ """
118
+ Attempt to rewind body to a certain position.
119
+ Primarily used for request redirects and retries.
120
+
121
+ :param body:
122
+ File-like object that supports seek.
123
+
124
+ :param int pos:
125
+ Position to seek to in file.
126
+ """
127
+ body_seek = getattr(body, "seek", None)
128
+ if body_seek is not None and isinstance(body_pos, integer_types):
129
+ try:
130
+ body_seek(body_pos)
131
+ except (IOError, OSError):
132
+ raise UnrewindableBodyError(
133
+ "An error occurred when rewinding request body for redirect/retry."
134
+ )
135
+ elif body_pos is _FAILEDTELL:
136
+ raise UnrewindableBodyError(
137
+ "Unable to record file position for rewinding "
138
+ "request body during a redirect/retry."
139
+ )
140
+ else:
141
+ raise ValueError(
142
+ "body_pos must be of type integer, instead it was %s." % type(body_pos)
143
+ )
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/response.py ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ from email.errors import MultipartInvariantViolationDefect, StartBoundaryNotFoundDefect
4
+
5
+ from ..exceptions import HeaderParsingError
6
+ from ..packages.six.moves import http_client as httplib
7
+
8
+
9
+ def is_fp_closed(obj):
10
+ """
11
+ Checks whether a given file-like object is closed.
12
+
13
+ :param obj:
14
+ The file-like object to check.
15
+ """
16
+
17
+ try:
18
+ # Check `isclosed()` first, in case Python3 doesn't set `closed`.
19
+ # GH Issue #928
20
+ return obj.isclosed()
21
+ except AttributeError:
22
+ pass
23
+
24
+ try:
25
+ # Check via the official file-like-object way.
26
+ return obj.closed
27
+ except AttributeError:
28
+ pass
29
+
30
+ try:
31
+ # Check if the object is a container for another file-like object that
32
+ # gets released on exhaustion (e.g. HTTPResponse).
33
+ return obj.fp is None
34
+ except AttributeError:
35
+ pass
36
+
37
+ raise ValueError("Unable to determine whether fp is closed.")
38
+
39
+
40
+ def assert_header_parsing(headers):
41
+ """
42
+ Asserts whether all headers have been successfully parsed.
43
+ Extracts encountered errors from the result of parsing headers.
44
+
45
+ Only works on Python 3.
46
+
47
+ :param http.client.HTTPMessage headers: Headers to verify.
48
+
49
+ :raises urllib3.exceptions.HeaderParsingError:
50
+ If parsing errors are found.
51
+ """
52
+
53
+ # This will fail silently if we pass in the wrong kind of parameter.
54
+ # To make debugging easier add an explicit check.
55
+ if not isinstance(headers, httplib.HTTPMessage):
56
+ raise TypeError("expected httplib.Message, got {0}.".format(type(headers)))
57
+
58
+ defects = getattr(headers, "defects", None)
59
+ get_payload = getattr(headers, "get_payload", None)
60
+
61
+ unparsed_data = None
62
+ if get_payload:
63
+ # get_payload is actually email.message.Message.get_payload;
64
+ # we're only interested in the result if it's not a multipart message
65
+ if not headers.is_multipart():
66
+ payload = get_payload()
67
+
68
+ if isinstance(payload, (bytes, str)):
69
+ unparsed_data = payload
70
+ if defects:
71
+ # httplib is assuming a response body is available
72
+ # when parsing headers even when httplib only sends
73
+ # header data to parse_headers() This results in
74
+ # defects on multipart responses in particular.
75
+ # See: https://github.com/urllib3/urllib3/issues/800
76
+
77
+ # So we ignore the following defects:
78
+ # - StartBoundaryNotFoundDefect:
79
+ # The claimed start boundary was never found.
80
+ # - MultipartInvariantViolationDefect:
81
+ # A message claimed to be a multipart but no subparts were found.
82
+ defects = [
83
+ defect
84
+ for defect in defects
85
+ if not isinstance(
86
+ defect, (StartBoundaryNotFoundDefect, MultipartInvariantViolationDefect)
87
+ )
88
+ ]
89
+
90
+ if defects or unparsed_data:
91
+ raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data)
92
+
93
+
94
+ def is_response_to_head(response):
95
+ """
96
+ Checks whether the request of a response has been a HEAD-request.
97
+ Handles the quirks of AppEngine.
98
+
99
+ :param http.client.HTTPResponse response:
100
+ Response to check if the originating request
101
+ used 'HEAD' as a method.
102
+ """
103
+ # FIXME: Can we do this somehow without accessing private httplib _method?
104
+ method = response._method
105
+ if isinstance(method, int): # Platform-specific: Appengine
106
+ return method == 3
107
+ return method.upper() == "HEAD"
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/retry.py ADDED
@@ -0,0 +1,602 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import email
4
+ import logging
5
+ import re
6
+ import time
7
+ import warnings
8
+ from collections import namedtuple
9
+ from itertools import takewhile
10
+
11
+ from ..exceptions import (
12
+ ConnectTimeoutError,
13
+ InvalidHeader,
14
+ MaxRetryError,
15
+ ProtocolError,
16
+ ProxyError,
17
+ ReadTimeoutError,
18
+ ResponseError,
19
+ )
20
+ from ..packages import six
21
+
22
+ log = logging.getLogger(__name__)
23
+
24
+
25
+ # Data structure for representing the metadata of requests that result in a retry.
26
+ RequestHistory = namedtuple(
27
+ "RequestHistory", ["method", "url", "error", "status", "redirect_location"]
28
+ )
29
+
30
+
31
+ # TODO: In v2 we can remove this sentinel and metaclass with deprecated options.
32
+ _Default = object()
33
+
34
+
35
+ class _RetryMeta(type):
36
+ @property
37
+ def DEFAULT_METHOD_WHITELIST(cls):
38
+ warnings.warn(
39
+ "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
40
+ "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
41
+ DeprecationWarning,
42
+ )
43
+ return cls.DEFAULT_ALLOWED_METHODS
44
+
45
+ @DEFAULT_METHOD_WHITELIST.setter
46
+ def DEFAULT_METHOD_WHITELIST(cls, value):
47
+ warnings.warn(
48
+ "Using 'Retry.DEFAULT_METHOD_WHITELIST' is deprecated and "
49
+ "will be removed in v2.0. Use 'Retry.DEFAULT_ALLOWED_METHODS' instead",
50
+ DeprecationWarning,
51
+ )
52
+ cls.DEFAULT_ALLOWED_METHODS = value
53
+
54
+ @property
55
+ def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls):
56
+ warnings.warn(
57
+ "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
58
+ "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
59
+ DeprecationWarning,
60
+ )
61
+ return cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT
62
+
63
+ @DEFAULT_REDIRECT_HEADERS_BLACKLIST.setter
64
+ def DEFAULT_REDIRECT_HEADERS_BLACKLIST(cls, value):
65
+ warnings.warn(
66
+ "Using 'Retry.DEFAULT_REDIRECT_HEADERS_BLACKLIST' is deprecated and "
67
+ "will be removed in v2.0. Use 'Retry.DEFAULT_REMOVE_HEADERS_ON_REDIRECT' instead",
68
+ DeprecationWarning,
69
+ )
70
+ cls.DEFAULT_REMOVE_HEADERS_ON_REDIRECT = value
71
+
72
+
73
+ @six.add_metaclass(_RetryMeta)
74
+ class Retry(object):
75
+ """Retry configuration.
76
+
77
+ Each retry attempt will create a new Retry object with updated values, so
78
+ they can be safely reused.
79
+
80
+ Retries can be defined as a default for a pool::
81
+
82
+ retries = Retry(connect=5, read=2, redirect=5)
83
+ http = PoolManager(retries=retries)
84
+ response = http.request('GET', 'http://example.com/')
85
+
86
+ Or per-request (which overrides the default for the pool)::
87
+
88
+ response = http.request('GET', 'http://example.com/', retries=Retry(10))
89
+
90
+ Retries can be disabled by passing ``False``::
91
+
92
+ response = http.request('GET', 'http://example.com/', retries=False)
93
+
94
+ Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless
95
+ retries are disabled, in which case the causing exception will be raised.
96
+
97
+ :param int total:
98
+ Total number of retries to allow. Takes precedence over other counts.
99
+
100
+ Set to ``None`` to remove this constraint and fall back on other
101
+ counts.
102
+
103
+ Set to ``0`` to fail on the first retry.
104
+
105
+ Set to ``False`` to disable and imply ``raise_on_redirect=False``.
106
+
107
+ :param int connect:
108
+ How many connection-related errors to retry on.
109
+
110
+ These are errors raised before the request is sent to the remote server,
111
+ which we assume has not triggered the server to process the request.
112
+
113
+ Set to ``0`` to fail on the first retry of this type.
114
+
115
+ :param int read:
116
+ How many times to retry on read errors.
117
+
118
+ These errors are raised after the request was sent to the server, so the
119
+ request may have side-effects.
120
+
121
+ Set to ``0`` to fail on the first retry of this type.
122
+
123
+ :param int redirect:
124
+ How many redirects to perform. Limit this to avoid infinite redirect
125
+ loops.
126
+
127
+ A redirect is a HTTP response with a status code 301, 302, 303, 307 or
128
+ 308.
129
+
130
+ Set to ``0`` to fail on the first retry of this type.
131
+
132
+ Set to ``False`` to disable and imply ``raise_on_redirect=False``.
133
+
134
+ :param int status:
135
+ How many times to retry on bad status codes.
136
+
137
+ These are retries made on responses, where status code matches
138
+ ``status_forcelist``.
139
+
140
+ Set to ``0`` to fail on the first retry of this type.
141
+
142
+ :param int other:
143
+ How many times to retry on other errors.
144
+
145
+ Other errors are errors that are not connect, read, redirect or status errors.
146
+ These errors might be raised after the request was sent to the server, so the
147
+ request might have side-effects.
148
+
149
+ Set to ``0`` to fail on the first retry of this type.
150
+
151
+ If ``total`` is not set, it's a good idea to set this to 0 to account
152
+ for unexpected edge cases and avoid infinite retry loops.
153
+
154
+ :param iterable allowed_methods:
155
+ Set of uppercased HTTP method verbs that we should retry on.
156
+
157
+ By default, we only retry on methods which are considered to be
158
+ idempotent (multiple requests with the same parameters end with the
159
+ same state). See :attr:`Retry.DEFAULT_ALLOWED_METHODS`.
160
+
161
+ Set to a ``False`` value to retry on any verb.
162
+
163
+ .. warning::
164
+
165
+ Previously this parameter was named ``method_whitelist``, that
166
+ usage is deprecated in v1.26.0 and will be removed in v2.0.
167
+
168
+ :param iterable status_forcelist:
169
+ A set of integer HTTP status codes that we should force a retry on.
170
+ A retry is initiated if the request method is in ``allowed_methods``
171
+ and the response status code is in ``status_forcelist``.
172
+
173
+ By default, this is disabled with ``None``.
174
+
175
+ :param float backoff_factor:
176
+ A backoff factor to apply between attempts after the second try
177
+ (most errors are resolved immediately by a second try without a
178
+ delay). urllib3 will sleep for::
179
+
180
+ {backoff factor} * (2 ** ({number of total retries} - 1))
181
+
182
+ seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep
183
+ for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer
184
+ than :attr:`Retry.BACKOFF_MAX`.
185
+
186
+ By default, backoff is disabled (set to 0).
187
+
188
+ :param bool raise_on_redirect: Whether, if the number of redirects is
189
+ exhausted, to raise a MaxRetryError, or to return a response with a
190
+ response code in the 3xx range.
191
+
192
+ :param bool raise_on_status: Similar meaning to ``raise_on_redirect``:
193
+ whether we should raise an exception, or return a response,
194
+ if status falls in ``status_forcelist`` range and retries have
195
+ been exhausted.
196
+
197
+ :param tuple history: The history of the request encountered during
198
+ each call to :meth:`~Retry.increment`. The list is in the order
199
+ the requests occurred. Each list item is of class :class:`RequestHistory`.
200
+
201
+ :param bool respect_retry_after_header:
202
+ Whether to respect Retry-After header on status codes defined as
203
+ :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not.
204
+
205
+ :param iterable remove_headers_on_redirect:
206
+ Sequence of headers to remove from the request when a response
207
+ indicating a redirect is returned before firing off the redirected
208
+ request.
209
+ """
210
+
211
+ #: Default methods to be used for ``allowed_methods``
212
+ DEFAULT_ALLOWED_METHODS = frozenset(
213
+ ["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE"]
214
+ )
215
+
216
+ #: Default status codes to be used for ``status_forcelist``
217
+ RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503])
218
+
219
+ #: Default headers to be used for ``remove_headers_on_redirect``
220
+ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"])
221
+
222
+ #: Maximum backoff time.
223
+ BACKOFF_MAX = 120
224
+
225
+ def __init__(
226
+ self,
227
+ total=10,
228
+ connect=None,
229
+ read=None,
230
+ redirect=None,
231
+ status=None,
232
+ other=None,
233
+ allowed_methods=_Default,
234
+ status_forcelist=None,
235
+ backoff_factor=0,
236
+ raise_on_redirect=True,
237
+ raise_on_status=True,
238
+ history=None,
239
+ respect_retry_after_header=True,
240
+ remove_headers_on_redirect=_Default,
241
+ # TODO: Deprecated, remove in v2.0
242
+ method_whitelist=_Default,
243
+ ):
244
+
245
+ if method_whitelist is not _Default:
246
+ if allowed_methods is not _Default:
247
+ raise ValueError(
248
+ "Using both 'allowed_methods' and "
249
+ "'method_whitelist' together is not allowed. "
250
+ "Instead only use 'allowed_methods'"
251
+ )
252
+ warnings.warn(
253
+ "Using 'method_whitelist' with Retry is deprecated and "
254
+ "will be removed in v2.0. Use 'allowed_methods' instead",
255
+ DeprecationWarning,
256
+ stacklevel=2,
257
+ )
258
+ allowed_methods = method_whitelist
259
+ if allowed_methods is _Default:
260
+ allowed_methods = self.DEFAULT_ALLOWED_METHODS
261
+ if remove_headers_on_redirect is _Default:
262
+ remove_headers_on_redirect = self.DEFAULT_REMOVE_HEADERS_ON_REDIRECT
263
+
264
+ self.total = total
265
+ self.connect = connect
266
+ self.read = read
267
+ self.status = status
268
+ self.other = other
269
+
270
+ if redirect is False or total is False:
271
+ redirect = 0
272
+ raise_on_redirect = False
273
+
274
+ self.redirect = redirect
275
+ self.status_forcelist = status_forcelist or set()
276
+ self.allowed_methods = allowed_methods
277
+ self.backoff_factor = backoff_factor
278
+ self.raise_on_redirect = raise_on_redirect
279
+ self.raise_on_status = raise_on_status
280
+ self.history = history or tuple()
281
+ self.respect_retry_after_header = respect_retry_after_header
282
+ self.remove_headers_on_redirect = frozenset(
283
+ [h.lower() for h in remove_headers_on_redirect]
284
+ )
285
+
286
+ def new(self, **kw):
287
+ params = dict(
288
+ total=self.total,
289
+ connect=self.connect,
290
+ read=self.read,
291
+ redirect=self.redirect,
292
+ status=self.status,
293
+ other=self.other,
294
+ status_forcelist=self.status_forcelist,
295
+ backoff_factor=self.backoff_factor,
296
+ raise_on_redirect=self.raise_on_redirect,
297
+ raise_on_status=self.raise_on_status,
298
+ history=self.history,
299
+ remove_headers_on_redirect=self.remove_headers_on_redirect,
300
+ respect_retry_after_header=self.respect_retry_after_header,
301
+ )
302
+
303
+ # TODO: If already given in **kw we use what's given to us
304
+ # If not given we need to figure out what to pass. We decide
305
+ # based on whether our class has the 'method_whitelist' property
306
+ # and if so we pass the deprecated 'method_whitelist' otherwise
307
+ # we use 'allowed_methods'. Remove in v2.0
308
+ if "method_whitelist" not in kw and "allowed_methods" not in kw:
309
+ if "method_whitelist" in self.__dict__:
310
+ warnings.warn(
311
+ "Using 'method_whitelist' with Retry is deprecated and "
312
+ "will be removed in v2.0. Use 'allowed_methods' instead",
313
+ DeprecationWarning,
314
+ )
315
+ params["method_whitelist"] = self.allowed_methods
316
+ else:
317
+ params["allowed_methods"] = self.allowed_methods
318
+
319
+ params.update(kw)
320
+ return type(self)(**params)
321
+
322
+ @classmethod
323
+ def from_int(cls, retries, redirect=True, default=None):
324
+ """Backwards-compatibility for the old retries format."""
325
+ if retries is None:
326
+ retries = default if default is not None else cls.DEFAULT
327
+
328
+ if isinstance(retries, Retry):
329
+ return retries
330
+
331
+ redirect = bool(redirect) and None
332
+ new_retries = cls(retries, redirect=redirect)
333
+ log.debug("Converted retries value: %r -> %r", retries, new_retries)
334
+ return new_retries
335
+
336
+ def get_backoff_time(self):
337
+ """Formula for computing the current backoff
338
+
339
+ :rtype: float
340
+ """
341
+ # We want to consider only the last consecutive errors sequence (Ignore redirects).
342
+ consecutive_errors_len = len(
343
+ list(
344
+ takewhile(lambda x: x.redirect_location is None, reversed(self.history))
345
+ )
346
+ )
347
+ if consecutive_errors_len <= 1:
348
+ return 0
349
+
350
+ backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1))
351
+ return min(self.BACKOFF_MAX, backoff_value)
352
+
353
+ def parse_retry_after(self, retry_after):
354
+ # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4
355
+ if re.match(r"^\s*[0-9]+\s*$", retry_after):
356
+ seconds = int(retry_after)
357
+ else:
358
+ retry_date_tuple = email.utils.parsedate_tz(retry_after)
359
+ if retry_date_tuple is None:
360
+ raise InvalidHeader("Invalid Retry-After header: %s" % retry_after)
361
+ if retry_date_tuple[9] is None: # Python 2
362
+ # Assume UTC if no timezone was specified
363
+ # On Python2.7, parsedate_tz returns None for a timezone offset
364
+ # instead of 0 if no timezone is given, where mktime_tz treats
365
+ # a None timezone offset as local time.
366
+ retry_date_tuple = retry_date_tuple[:9] + (0,) + retry_date_tuple[10:]
367
+
368
+ retry_date = email.utils.mktime_tz(retry_date_tuple)
369
+ seconds = retry_date - time.time()
370
+
371
+ if seconds < 0:
372
+ seconds = 0
373
+
374
+ return seconds
375
+
376
+ def get_retry_after(self, response):
377
+ """Get the value of Retry-After in seconds."""
378
+
379
+ retry_after = response.getheader("Retry-After")
380
+
381
+ if retry_after is None:
382
+ return None
383
+
384
+ return self.parse_retry_after(retry_after)
385
+
386
+ def sleep_for_retry(self, response=None):
387
+ retry_after = self.get_retry_after(response)
388
+ if retry_after:
389
+ time.sleep(retry_after)
390
+ return True
391
+
392
+ return False
393
+
394
+ def _sleep_backoff(self):
395
+ backoff = self.get_backoff_time()
396
+ if backoff <= 0:
397
+ return
398
+ time.sleep(backoff)
399
+
400
+ def sleep(self, response=None):
401
+ """Sleep between retry attempts.
402
+
403
+ This method will respect a server's ``Retry-After`` response header
404
+ and sleep the duration of the time requested. If that is not present, it
405
+ will use an exponential backoff. By default, the backoff factor is 0 and
406
+ this method will return immediately.
407
+ """
408
+
409
+ if self.respect_retry_after_header and response:
410
+ slept = self.sleep_for_retry(response)
411
+ if slept:
412
+ return
413
+
414
+ self._sleep_backoff()
415
+
416
+ def _is_connection_error(self, err):
417
+ """Errors when we're fairly sure that the server did not receive the
418
+ request, so it should be safe to retry.
419
+ """
420
+ if isinstance(err, ProxyError):
421
+ err = err.original_error
422
+ return isinstance(err, ConnectTimeoutError)
423
+
424
+ def _is_read_error(self, err):
425
+ """Errors that occur after the request has been started, so we should
426
+ assume that the server began processing it.
427
+ """
428
+ return isinstance(err, (ReadTimeoutError, ProtocolError))
429
+
430
+ def _is_method_retryable(self, method):
431
+ """Checks if a given HTTP method should be retried upon, depending if
432
+ it is included in the allowed_methods
433
+ """
434
+ # TODO: For now favor if the Retry implementation sets its own method_whitelist
435
+ # property outside of our constructor to avoid breaking custom implementations.
436
+ if "method_whitelist" in self.__dict__:
437
+ warnings.warn(
438
+ "Using 'method_whitelist' with Retry is deprecated and "
439
+ "will be removed in v2.0. Use 'allowed_methods' instead",
440
+ DeprecationWarning,
441
+ )
442
+ allowed_methods = self.method_whitelist
443
+ else:
444
+ allowed_methods = self.allowed_methods
445
+
446
+ if allowed_methods and method.upper() not in allowed_methods:
447
+ return False
448
+ return True
449
+
450
+ def is_retry(self, method, status_code, has_retry_after=False):
451
+ """Is this method/status code retryable? (Based on allowlists and control
452
+ variables such as the number of total retries to allow, whether to
453
+ respect the Retry-After header, whether this header is present, and
454
+ whether the returned status code is on the list of status codes to
455
+ be retried upon on the presence of the aforementioned header)
456
+ """
457
+ if not self._is_method_retryable(method):
458
+ return False
459
+
460
+ if self.status_forcelist and status_code in self.status_forcelist:
461
+ return True
462
+
463
+ return (
464
+ self.total
465
+ and self.respect_retry_after_header
466
+ and has_retry_after
467
+ and (status_code in self.RETRY_AFTER_STATUS_CODES)
468
+ )
469
+
470
+ def is_exhausted(self):
471
+ """Are we out of retries?"""
472
+ retry_counts = (
473
+ self.total,
474
+ self.connect,
475
+ self.read,
476
+ self.redirect,
477
+ self.status,
478
+ self.other,
479
+ )
480
+ retry_counts = list(filter(None, retry_counts))
481
+ if not retry_counts:
482
+ return False
483
+
484
+ return min(retry_counts) < 0
485
+
486
+ def increment(
487
+ self,
488
+ method=None,
489
+ url=None,
490
+ response=None,
491
+ error=None,
492
+ _pool=None,
493
+ _stacktrace=None,
494
+ ):
495
+ """Return a new Retry object with incremented retry counters.
496
+
497
+ :param response: A response object, or None, if the server did not
498
+ return a response.
499
+ :type response: :class:`~urllib3.response.HTTPResponse`
500
+ :param Exception error: An error encountered during the request, or
501
+ None if the response was received successfully.
502
+
503
+ :return: A new ``Retry`` object.
504
+ """
505
+ if self.total is False and error:
506
+ # Disabled, indicate to re-raise the error.
507
+ raise six.reraise(type(error), error, _stacktrace)
508
+
509
+ total = self.total
510
+ if total is not None:
511
+ total -= 1
512
+
513
+ connect = self.connect
514
+ read = self.read
515
+ redirect = self.redirect
516
+ status_count = self.status
517
+ other = self.other
518
+ cause = "unknown"
519
+ status = None
520
+ redirect_location = None
521
+
522
+ if error and self._is_connection_error(error):
523
+ # Connect retry?
524
+ if connect is False:
525
+ raise six.reraise(type(error), error, _stacktrace)
526
+ elif connect is not None:
527
+ connect -= 1
528
+
529
+ elif error and self._is_read_error(error):
530
+ # Read retry?
531
+ if read is False or not self._is_method_retryable(method):
532
+ raise six.reraise(type(error), error, _stacktrace)
533
+ elif read is not None:
534
+ read -= 1
535
+
536
+ elif error:
537
+ # Other retry?
538
+ if other is not None:
539
+ other -= 1
540
+
541
+ elif response and response.get_redirect_location():
542
+ # Redirect retry?
543
+ if redirect is not None:
544
+ redirect -= 1
545
+ cause = "too many redirects"
546
+ redirect_location = response.get_redirect_location()
547
+ status = response.status
548
+
549
+ else:
550
+ # Incrementing because of a server error like a 500 in
551
+ # status_forcelist and the given method is in the allowed_methods
552
+ cause = ResponseError.GENERIC_ERROR
553
+ if response and response.status:
554
+ if status_count is not None:
555
+ status_count -= 1
556
+ cause = ResponseError.SPECIFIC_ERROR.format(status_code=response.status)
557
+ status = response.status
558
+
559
+ history = self.history + (
560
+ RequestHistory(method, url, error, status, redirect_location),
561
+ )
562
+
563
+ new_retry = self.new(
564
+ total=total,
565
+ connect=connect,
566
+ read=read,
567
+ redirect=redirect,
568
+ status=status_count,
569
+ other=other,
570
+ history=history,
571
+ )
572
+
573
+ if new_retry.is_exhausted():
574
+ raise MaxRetryError(_pool, url, error or ResponseError(cause))
575
+
576
+ log.debug("Incremented Retry for (url='%s'): %r", url, new_retry)
577
+
578
+ return new_retry
579
+
580
+ def __repr__(self):
581
+ return (
582
+ "{cls.__name__}(total={self.total}, connect={self.connect}, "
583
+ "read={self.read}, redirect={self.redirect}, status={self.status})"
584
+ ).format(cls=type(self), self=self)
585
+
586
+ def __getattr__(self, item):
587
+ if item == "method_whitelist":
588
+ # TODO: Remove this deprecated alias in v2.0
589
+ warnings.warn(
590
+ "Using 'method_whitelist' with Retry is deprecated and "
591
+ "will be removed in v2.0. Use 'allowed_methods' instead",
592
+ DeprecationWarning,
593
+ )
594
+ return self.allowed_methods
595
+ try:
596
+ return getattr(super(Retry, self), item)
597
+ except AttributeError:
598
+ return getattr(Retry, item)
599
+
600
+
601
+ # For backwards compatibility (equivalent to pre-v1.9):
602
+ Retry.DEFAULT = Retry(3)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssl_.py ADDED
@@ -0,0 +1,495 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import hmac
4
+ import os
5
+ import sys
6
+ import warnings
7
+ from binascii import hexlify, unhexlify
8
+ from hashlib import md5, sha1, sha256
9
+
10
+ from ..exceptions import (
11
+ InsecurePlatformWarning,
12
+ ProxySchemeUnsupported,
13
+ SNIMissingWarning,
14
+ SSLError,
15
+ )
16
+ from ..packages import six
17
+ from .url import BRACELESS_IPV6_ADDRZ_RE, IPV4_RE
18
+
19
+ SSLContext = None
20
+ SSLTransport = None
21
+ HAS_SNI = False
22
+ IS_PYOPENSSL = False
23
+ IS_SECURETRANSPORT = False
24
+ ALPN_PROTOCOLS = ["http/1.1"]
25
+
26
+ # Maps the length of a digest to a possible hash function producing this digest
27
+ HASHFUNC_MAP = {32: md5, 40: sha1, 64: sha256}
28
+
29
+
30
+ def _const_compare_digest_backport(a, b):
31
+ """
32
+ Compare two digests of equal length in constant time.
33
+
34
+ The digests must be of type str/bytes.
35
+ Returns True if the digests match, and False otherwise.
36
+ """
37
+ result = abs(len(a) - len(b))
38
+ for left, right in zip(bytearray(a), bytearray(b)):
39
+ result |= left ^ right
40
+ return result == 0
41
+
42
+
43
+ _const_compare_digest = getattr(hmac, "compare_digest", _const_compare_digest_backport)
44
+
45
+ try: # Test for SSL features
46
+ import ssl
47
+ from ssl import CERT_REQUIRED, wrap_socket
48
+ except ImportError:
49
+ pass
50
+
51
+ try:
52
+ from ssl import HAS_SNI # Has SNI?
53
+ except ImportError:
54
+ pass
55
+
56
+ try:
57
+ from .ssltransport import SSLTransport
58
+ except ImportError:
59
+ pass
60
+
61
+
62
+ try: # Platform-specific: Python 3.6
63
+ from ssl import PROTOCOL_TLS
64
+
65
+ PROTOCOL_SSLv23 = PROTOCOL_TLS
66
+ except ImportError:
67
+ try:
68
+ from ssl import PROTOCOL_SSLv23 as PROTOCOL_TLS
69
+
70
+ PROTOCOL_SSLv23 = PROTOCOL_TLS
71
+ except ImportError:
72
+ PROTOCOL_SSLv23 = PROTOCOL_TLS = 2
73
+
74
+ try:
75
+ from ssl import PROTOCOL_TLS_CLIENT
76
+ except ImportError:
77
+ PROTOCOL_TLS_CLIENT = PROTOCOL_TLS
78
+
79
+
80
+ try:
81
+ from ssl import OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3
82
+ except ImportError:
83
+ OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000
84
+ OP_NO_COMPRESSION = 0x20000
85
+
86
+
87
+ try: # OP_NO_TICKET was added in Python 3.6
88
+ from ssl import OP_NO_TICKET
89
+ except ImportError:
90
+ OP_NO_TICKET = 0x4000
91
+
92
+
93
+ # A secure default.
94
+ # Sources for more information on TLS ciphers:
95
+ #
96
+ # - https://wiki.mozilla.org/Security/Server_Side_TLS
97
+ # - https://www.ssllabs.com/projects/best-practices/index.html
98
+ # - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/
99
+ #
100
+ # The general intent is:
101
+ # - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE),
102
+ # - prefer ECDHE over DHE for better performance,
103
+ # - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and
104
+ # security,
105
+ # - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common,
106
+ # - disable NULL authentication, MD5 MACs, DSS, and other
107
+ # insecure ciphers for security reasons.
108
+ # - NOTE: TLS 1.3 cipher suites are managed through a different interface
109
+ # not exposed by CPython (yet!) and are enabled by default if they're available.
110
+ DEFAULT_CIPHERS = ":".join(
111
+ [
112
+ "ECDHE+AESGCM",
113
+ "ECDHE+CHACHA20",
114
+ "DHE+AESGCM",
115
+ "DHE+CHACHA20",
116
+ "ECDH+AESGCM",
117
+ "DH+AESGCM",
118
+ "ECDH+AES",
119
+ "DH+AES",
120
+ "RSA+AESGCM",
121
+ "RSA+AES",
122
+ "!aNULL",
123
+ "!eNULL",
124
+ "!MD5",
125
+ "!DSS",
126
+ ]
127
+ )
128
+
129
+ try:
130
+ from ssl import SSLContext # Modern SSL?
131
+ except ImportError:
132
+
133
+ class SSLContext(object): # Platform-specific: Python 2
134
+ def __init__(self, protocol_version):
135
+ self.protocol = protocol_version
136
+ # Use default values from a real SSLContext
137
+ self.check_hostname = False
138
+ self.verify_mode = ssl.CERT_NONE
139
+ self.ca_certs = None
140
+ self.options = 0
141
+ self.certfile = None
142
+ self.keyfile = None
143
+ self.ciphers = None
144
+
145
+ def load_cert_chain(self, certfile, keyfile):
146
+ self.certfile = certfile
147
+ self.keyfile = keyfile
148
+
149
+ def load_verify_locations(self, cafile=None, capath=None, cadata=None):
150
+ self.ca_certs = cafile
151
+
152
+ if capath is not None:
153
+ raise SSLError("CA directories not supported in older Pythons")
154
+
155
+ if cadata is not None:
156
+ raise SSLError("CA data not supported in older Pythons")
157
+
158
+ def set_ciphers(self, cipher_suite):
159
+ self.ciphers = cipher_suite
160
+
161
+ def wrap_socket(self, socket, server_hostname=None, server_side=False):
162
+ warnings.warn(
163
+ "A true SSLContext object is not available. This prevents "
164
+ "urllib3 from configuring SSL appropriately and may cause "
165
+ "certain SSL connections to fail. You can upgrade to a newer "
166
+ "version of Python to solve this. For more information, see "
167
+ "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
168
+ "#ssl-warnings",
169
+ InsecurePlatformWarning,
170
+ )
171
+ kwargs = {
172
+ "keyfile": self.keyfile,
173
+ "certfile": self.certfile,
174
+ "ca_certs": self.ca_certs,
175
+ "cert_reqs": self.verify_mode,
176
+ "ssl_version": self.protocol,
177
+ "server_side": server_side,
178
+ }
179
+ return wrap_socket(socket, ciphers=self.ciphers, **kwargs)
180
+
181
+
182
+ def assert_fingerprint(cert, fingerprint):
183
+ """
184
+ Checks if given fingerprint matches the supplied certificate.
185
+
186
+ :param cert:
187
+ Certificate as bytes object.
188
+ :param fingerprint:
189
+ Fingerprint as string of hexdigits, can be interspersed by colons.
190
+ """
191
+
192
+ fingerprint = fingerprint.replace(":", "").lower()
193
+ digest_length = len(fingerprint)
194
+ hashfunc = HASHFUNC_MAP.get(digest_length)
195
+ if not hashfunc:
196
+ raise SSLError("Fingerprint of invalid length: {0}".format(fingerprint))
197
+
198
+ # We need encode() here for py32; works on py2 and p33.
199
+ fingerprint_bytes = unhexlify(fingerprint.encode())
200
+
201
+ cert_digest = hashfunc(cert).digest()
202
+
203
+ if not _const_compare_digest(cert_digest, fingerprint_bytes):
204
+ raise SSLError(
205
+ 'Fingerprints did not match. Expected "{0}", got "{1}".'.format(
206
+ fingerprint, hexlify(cert_digest)
207
+ )
208
+ )
209
+
210
+
211
+ def resolve_cert_reqs(candidate):
212
+ """
213
+ Resolves the argument to a numeric constant, which can be passed to
214
+ the wrap_socket function/method from the ssl module.
215
+ Defaults to :data:`ssl.CERT_REQUIRED`.
216
+ If given a string it is assumed to be the name of the constant in the
217
+ :mod:`ssl` module or its abbreviation.
218
+ (So you can specify `REQUIRED` instead of `CERT_REQUIRED`.
219
+ If it's neither `None` nor a string we assume it is already the numeric
220
+ constant which can directly be passed to wrap_socket.
221
+ """
222
+ if candidate is None:
223
+ return CERT_REQUIRED
224
+
225
+ if isinstance(candidate, str):
226
+ res = getattr(ssl, candidate, None)
227
+ if res is None:
228
+ res = getattr(ssl, "CERT_" + candidate)
229
+ return res
230
+
231
+ return candidate
232
+
233
+
234
+ def resolve_ssl_version(candidate):
235
+ """
236
+ like resolve_cert_reqs
237
+ """
238
+ if candidate is None:
239
+ return PROTOCOL_TLS
240
+
241
+ if isinstance(candidate, str):
242
+ res = getattr(ssl, candidate, None)
243
+ if res is None:
244
+ res = getattr(ssl, "PROTOCOL_" + candidate)
245
+ return res
246
+
247
+ return candidate
248
+
249
+
250
+ def create_urllib3_context(
251
+ ssl_version=None, cert_reqs=None, options=None, ciphers=None
252
+ ):
253
+ """All arguments have the same meaning as ``ssl_wrap_socket``.
254
+
255
+ By default, this function does a lot of the same work that
256
+ ``ssl.create_default_context`` does on Python 3.4+. It:
257
+
258
+ - Disables SSLv2, SSLv3, and compression
259
+ - Sets a restricted set of server ciphers
260
+
261
+ If you wish to enable SSLv3, you can do::
262
+
263
+ from pip._vendor.urllib3.util import ssl_
264
+ context = ssl_.create_urllib3_context()
265
+ context.options &= ~ssl_.OP_NO_SSLv3
266
+
267
+ You can do the same to enable compression (substituting ``COMPRESSION``
268
+ for ``SSLv3`` in the last line above).
269
+
270
+ :param ssl_version:
271
+ The desired protocol version to use. This will default to
272
+ PROTOCOL_SSLv23 which will negotiate the highest protocol that both
273
+ the server and your installation of OpenSSL support.
274
+ :param cert_reqs:
275
+ Whether to require the certificate verification. This defaults to
276
+ ``ssl.CERT_REQUIRED``.
277
+ :param options:
278
+ Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``,
279
+ ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``, and ``ssl.OP_NO_TICKET``.
280
+ :param ciphers:
281
+ Which cipher suites to allow the server to select.
282
+ :returns:
283
+ Constructed SSLContext object with specified options
284
+ :rtype: SSLContext
285
+ """
286
+ # PROTOCOL_TLS is deprecated in Python 3.10
287
+ if not ssl_version or ssl_version == PROTOCOL_TLS:
288
+ ssl_version = PROTOCOL_TLS_CLIENT
289
+
290
+ context = SSLContext(ssl_version)
291
+
292
+ context.set_ciphers(ciphers or DEFAULT_CIPHERS)
293
+
294
+ # Setting the default here, as we may have no ssl module on import
295
+ cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs
296
+
297
+ if options is None:
298
+ options = 0
299
+ # SSLv2 is easily broken and is considered harmful and dangerous
300
+ options |= OP_NO_SSLv2
301
+ # SSLv3 has several problems and is now dangerous
302
+ options |= OP_NO_SSLv3
303
+ # Disable compression to prevent CRIME attacks for OpenSSL 1.0+
304
+ # (issue #309)
305
+ options |= OP_NO_COMPRESSION
306
+ # TLSv1.2 only. Unless set explicitly, do not request tickets.
307
+ # This may save some bandwidth on wire, and although the ticket is encrypted,
308
+ # there is a risk associated with it being on wire,
309
+ # if the server is not rotating its ticketing keys properly.
310
+ options |= OP_NO_TICKET
311
+
312
+ context.options |= options
313
+
314
+ # Enable post-handshake authentication for TLS 1.3, see GH #1634. PHA is
315
+ # necessary for conditional client cert authentication with TLS 1.3.
316
+ # The attribute is None for OpenSSL <= 1.1.0 or does not exist in older
317
+ # versions of Python. We only enable on Python 3.7.4+ or if certificate
318
+ # verification is enabled to work around Python issue #37428
319
+ # See: https://bugs.python.org/issue37428
320
+ if (cert_reqs == ssl.CERT_REQUIRED or sys.version_info >= (3, 7, 4)) and getattr(
321
+ context, "post_handshake_auth", None
322
+ ) is not None:
323
+ context.post_handshake_auth = True
324
+
325
+ def disable_check_hostname():
326
+ if (
327
+ getattr(context, "check_hostname", None) is not None
328
+ ): # Platform-specific: Python 3.2
329
+ # We do our own verification, including fingerprints and alternative
330
+ # hostnames. So disable it here
331
+ context.check_hostname = False
332
+
333
+ # The order of the below lines setting verify_mode and check_hostname
334
+ # matter due to safe-guards SSLContext has to prevent an SSLContext with
335
+ # check_hostname=True, verify_mode=NONE/OPTIONAL. This is made even more
336
+ # complex because we don't know whether PROTOCOL_TLS_CLIENT will be used
337
+ # or not so we don't know the initial state of the freshly created SSLContext.
338
+ if cert_reqs == ssl.CERT_REQUIRED:
339
+ context.verify_mode = cert_reqs
340
+ disable_check_hostname()
341
+ else:
342
+ disable_check_hostname()
343
+ context.verify_mode = cert_reqs
344
+
345
+ # Enable logging of TLS session keys via defacto standard environment variable
346
+ # 'SSLKEYLOGFILE', if the feature is available (Python 3.8+). Skip empty values.
347
+ if hasattr(context, "keylog_filename"):
348
+ sslkeylogfile = os.environ.get("SSLKEYLOGFILE")
349
+ if sslkeylogfile:
350
+ context.keylog_filename = sslkeylogfile
351
+
352
+ return context
353
+
354
+
355
+ def ssl_wrap_socket(
356
+ sock,
357
+ keyfile=None,
358
+ certfile=None,
359
+ cert_reqs=None,
360
+ ca_certs=None,
361
+ server_hostname=None,
362
+ ssl_version=None,
363
+ ciphers=None,
364
+ ssl_context=None,
365
+ ca_cert_dir=None,
366
+ key_password=None,
367
+ ca_cert_data=None,
368
+ tls_in_tls=False,
369
+ ):
370
+ """
371
+ All arguments except for server_hostname, ssl_context, and ca_cert_dir have
372
+ the same meaning as they do when using :func:`ssl.wrap_socket`.
373
+
374
+ :param server_hostname:
375
+ When SNI is supported, the expected hostname of the certificate
376
+ :param ssl_context:
377
+ A pre-made :class:`SSLContext` object. If none is provided, one will
378
+ be created using :func:`create_urllib3_context`.
379
+ :param ciphers:
380
+ A string of ciphers we wish the client to support.
381
+ :param ca_cert_dir:
382
+ A directory containing CA certificates in multiple separate files, as
383
+ supported by OpenSSL's -CApath flag or the capath argument to
384
+ SSLContext.load_verify_locations().
385
+ :param key_password:
386
+ Optional password if the keyfile is encrypted.
387
+ :param ca_cert_data:
388
+ Optional string containing CA certificates in PEM format suitable for
389
+ passing as the cadata parameter to SSLContext.load_verify_locations()
390
+ :param tls_in_tls:
391
+ Use SSLTransport to wrap the existing socket.
392
+ """
393
+ context = ssl_context
394
+ if context is None:
395
+ # Note: This branch of code and all the variables in it are no longer
396
+ # used by urllib3 itself. We should consider deprecating and removing
397
+ # this code.
398
+ context = create_urllib3_context(ssl_version, cert_reqs, ciphers=ciphers)
399
+
400
+ if ca_certs or ca_cert_dir or ca_cert_data:
401
+ try:
402
+ context.load_verify_locations(ca_certs, ca_cert_dir, ca_cert_data)
403
+ except (IOError, OSError) as e:
404
+ raise SSLError(e)
405
+
406
+ elif ssl_context is None and hasattr(context, "load_default_certs"):
407
+ # try to load OS default certs; works well on Windows (require Python3.4+)
408
+ context.load_default_certs()
409
+
410
+ # Attempt to detect if we get the goofy behavior of the
411
+ # keyfile being encrypted and OpenSSL asking for the
412
+ # passphrase via the terminal and instead error out.
413
+ if keyfile and key_password is None and _is_key_file_encrypted(keyfile):
414
+ raise SSLError("Client private key is encrypted, password is required")
415
+
416
+ if certfile:
417
+ if key_password is None:
418
+ context.load_cert_chain(certfile, keyfile)
419
+ else:
420
+ context.load_cert_chain(certfile, keyfile, key_password)
421
+
422
+ try:
423
+ if hasattr(context, "set_alpn_protocols"):
424
+ context.set_alpn_protocols(ALPN_PROTOCOLS)
425
+ except NotImplementedError: # Defensive: in CI, we always have set_alpn_protocols
426
+ pass
427
+
428
+ # If we detect server_hostname is an IP address then the SNI
429
+ # extension should not be used according to RFC3546 Section 3.1
430
+ use_sni_hostname = server_hostname and not is_ipaddress(server_hostname)
431
+ # SecureTransport uses server_hostname in certificate verification.
432
+ send_sni = (use_sni_hostname and HAS_SNI) or (
433
+ IS_SECURETRANSPORT and server_hostname
434
+ )
435
+ # Do not warn the user if server_hostname is an invalid SNI hostname.
436
+ if not HAS_SNI and use_sni_hostname:
437
+ warnings.warn(
438
+ "An HTTPS request has been made, but the SNI (Server Name "
439
+ "Indication) extension to TLS is not available on this platform. "
440
+ "This may cause the server to present an incorrect TLS "
441
+ "certificate, which can cause validation failures. You can upgrade to "
442
+ "a newer version of Python to solve this. For more information, see "
443
+ "https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html"
444
+ "#ssl-warnings",
445
+ SNIMissingWarning,
446
+ )
447
+
448
+ if send_sni:
449
+ ssl_sock = _ssl_wrap_socket_impl(
450
+ sock, context, tls_in_tls, server_hostname=server_hostname
451
+ )
452
+ else:
453
+ ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls)
454
+ return ssl_sock
455
+
456
+
457
+ def is_ipaddress(hostname):
458
+ """Detects whether the hostname given is an IPv4 or IPv6 address.
459
+ Also detects IPv6 addresses with Zone IDs.
460
+
461
+ :param str hostname: Hostname to examine.
462
+ :return: True if the hostname is an IP address, False otherwise.
463
+ """
464
+ if not six.PY2 and isinstance(hostname, bytes):
465
+ # IDN A-label bytes are ASCII compatible.
466
+ hostname = hostname.decode("ascii")
467
+ return bool(IPV4_RE.match(hostname) or BRACELESS_IPV6_ADDRZ_RE.match(hostname))
468
+
469
+
470
+ def _is_key_file_encrypted(key_file):
471
+ """Detects if a key file is encrypted or not."""
472
+ with open(key_file, "r") as f:
473
+ for line in f:
474
+ # Look for Proc-Type: 4,ENCRYPTED
475
+ if "ENCRYPTED" in line:
476
+ return True
477
+
478
+ return False
479
+
480
+
481
+ def _ssl_wrap_socket_impl(sock, ssl_context, tls_in_tls, server_hostname=None):
482
+ if tls_in_tls:
483
+ if not SSLTransport:
484
+ # Import error, ssl is not available.
485
+ raise ProxySchemeUnsupported(
486
+ "TLS in TLS requires support for the 'ssl' module"
487
+ )
488
+
489
+ SSLTransport._validate_ssl_context_for_tls_in_tls(ssl_context)
490
+ return SSLTransport(sock, ssl_context, server_hostname)
491
+
492
+ if server_hostname:
493
+ return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
494
+ else:
495
+ return ssl_context.wrap_socket(sock)
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/ssltransport.py ADDED
@@ -0,0 +1,221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import socket
3
+ import ssl
4
+
5
+ from pip._vendor.urllib3.exceptions import ProxySchemeUnsupported
6
+ from pip._vendor.urllib3.packages import six
7
+
8
+ SSL_BLOCKSIZE = 16384
9
+
10
+
11
+ class SSLTransport:
12
+ """
13
+ The SSLTransport wraps an existing socket and establishes an SSL connection.
14
+
15
+ Contrary to Python's implementation of SSLSocket, it allows you to chain
16
+ multiple TLS connections together. It's particularly useful if you need to
17
+ implement TLS within TLS.
18
+
19
+ The class supports most of the socket API operations.
20
+ """
21
+
22
+ @staticmethod
23
+ def _validate_ssl_context_for_tls_in_tls(ssl_context):
24
+ """
25
+ Raises a ProxySchemeUnsupported if the provided ssl_context can't be used
26
+ for TLS in TLS.
27
+
28
+ The only requirement is that the ssl_context provides the 'wrap_bio'
29
+ methods.
30
+ """
31
+
32
+ if not hasattr(ssl_context, "wrap_bio"):
33
+ if six.PY2:
34
+ raise ProxySchemeUnsupported(
35
+ "TLS in TLS requires SSLContext.wrap_bio() which isn't "
36
+ "supported on Python 2"
37
+ )
38
+ else:
39
+ raise ProxySchemeUnsupported(
40
+ "TLS in TLS requires SSLContext.wrap_bio() which isn't "
41
+ "available on non-native SSLContext"
42
+ )
43
+
44
+ def __init__(
45
+ self, socket, ssl_context, server_hostname=None, suppress_ragged_eofs=True
46
+ ):
47
+ """
48
+ Create an SSLTransport around socket using the provided ssl_context.
49
+ """
50
+ self.incoming = ssl.MemoryBIO()
51
+ self.outgoing = ssl.MemoryBIO()
52
+
53
+ self.suppress_ragged_eofs = suppress_ragged_eofs
54
+ self.socket = socket
55
+
56
+ self.sslobj = ssl_context.wrap_bio(
57
+ self.incoming, self.outgoing, server_hostname=server_hostname
58
+ )
59
+
60
+ # Perform initial handshake.
61
+ self._ssl_io_loop(self.sslobj.do_handshake)
62
+
63
+ def __enter__(self):
64
+ return self
65
+
66
+ def __exit__(self, *_):
67
+ self.close()
68
+
69
+ def fileno(self):
70
+ return self.socket.fileno()
71
+
72
+ def read(self, len=1024, buffer=None):
73
+ return self._wrap_ssl_read(len, buffer)
74
+
75
+ def recv(self, len=1024, flags=0):
76
+ if flags != 0:
77
+ raise ValueError("non-zero flags not allowed in calls to recv")
78
+ return self._wrap_ssl_read(len)
79
+
80
+ def recv_into(self, buffer, nbytes=None, flags=0):
81
+ if flags != 0:
82
+ raise ValueError("non-zero flags not allowed in calls to recv_into")
83
+ if buffer and (nbytes is None):
84
+ nbytes = len(buffer)
85
+ elif nbytes is None:
86
+ nbytes = 1024
87
+ return self.read(nbytes, buffer)
88
+
89
+ def sendall(self, data, flags=0):
90
+ if flags != 0:
91
+ raise ValueError("non-zero flags not allowed in calls to sendall")
92
+ count = 0
93
+ with memoryview(data) as view, view.cast("B") as byte_view:
94
+ amount = len(byte_view)
95
+ while count < amount:
96
+ v = self.send(byte_view[count:])
97
+ count += v
98
+
99
+ def send(self, data, flags=0):
100
+ if flags != 0:
101
+ raise ValueError("non-zero flags not allowed in calls to send")
102
+ response = self._ssl_io_loop(self.sslobj.write, data)
103
+ return response
104
+
105
+ def makefile(
106
+ self, mode="r", buffering=None, encoding=None, errors=None, newline=None
107
+ ):
108
+ """
109
+ Python's httpclient uses makefile and buffered io when reading HTTP
110
+ messages and we need to support it.
111
+
112
+ This is unfortunately a copy and paste of socket.py makefile with small
113
+ changes to point to the socket directly.
114
+ """
115
+ if not set(mode) <= {"r", "w", "b"}:
116
+ raise ValueError("invalid mode %r (only r, w, b allowed)" % (mode,))
117
+
118
+ writing = "w" in mode
119
+ reading = "r" in mode or not writing
120
+ assert reading or writing
121
+ binary = "b" in mode
122
+ rawmode = ""
123
+ if reading:
124
+ rawmode += "r"
125
+ if writing:
126
+ rawmode += "w"
127
+ raw = socket.SocketIO(self, rawmode)
128
+ self.socket._io_refs += 1
129
+ if buffering is None:
130
+ buffering = -1
131
+ if buffering < 0:
132
+ buffering = io.DEFAULT_BUFFER_SIZE
133
+ if buffering == 0:
134
+ if not binary:
135
+ raise ValueError("unbuffered streams must be binary")
136
+ return raw
137
+ if reading and writing:
138
+ buffer = io.BufferedRWPair(raw, raw, buffering)
139
+ elif reading:
140
+ buffer = io.BufferedReader(raw, buffering)
141
+ else:
142
+ assert writing
143
+ buffer = io.BufferedWriter(raw, buffering)
144
+ if binary:
145
+ return buffer
146
+ text = io.TextIOWrapper(buffer, encoding, errors, newline)
147
+ text.mode = mode
148
+ return text
149
+
150
+ def unwrap(self):
151
+ self._ssl_io_loop(self.sslobj.unwrap)
152
+
153
+ def close(self):
154
+ self.socket.close()
155
+
156
+ def getpeercert(self, binary_form=False):
157
+ return self.sslobj.getpeercert(binary_form)
158
+
159
+ def version(self):
160
+ return self.sslobj.version()
161
+
162
+ def cipher(self):
163
+ return self.sslobj.cipher()
164
+
165
+ def selected_alpn_protocol(self):
166
+ return self.sslobj.selected_alpn_protocol()
167
+
168
+ def selected_npn_protocol(self):
169
+ return self.sslobj.selected_npn_protocol()
170
+
171
+ def shared_ciphers(self):
172
+ return self.sslobj.shared_ciphers()
173
+
174
+ def compression(self):
175
+ return self.sslobj.compression()
176
+
177
+ def settimeout(self, value):
178
+ self.socket.settimeout(value)
179
+
180
+ def gettimeout(self):
181
+ return self.socket.gettimeout()
182
+
183
+ def _decref_socketios(self):
184
+ self.socket._decref_socketios()
185
+
186
+ def _wrap_ssl_read(self, len, buffer=None):
187
+ try:
188
+ return self._ssl_io_loop(self.sslobj.read, len, buffer)
189
+ except ssl.SSLError as e:
190
+ if e.errno == ssl.SSL_ERROR_EOF and self.suppress_ragged_eofs:
191
+ return 0 # eof, return 0.
192
+ else:
193
+ raise
194
+
195
+ def _ssl_io_loop(self, func, *args):
196
+ """Performs an I/O loop between incoming/outgoing and the socket."""
197
+ should_loop = True
198
+ ret = None
199
+
200
+ while should_loop:
201
+ errno = None
202
+ try:
203
+ ret = func(*args)
204
+ except ssl.SSLError as e:
205
+ if e.errno not in (ssl.SSL_ERROR_WANT_READ, ssl.SSL_ERROR_WANT_WRITE):
206
+ # WANT_READ, and WANT_WRITE are expected, others are not.
207
+ raise e
208
+ errno = e.errno
209
+
210
+ buf = self.outgoing.read()
211
+ self.socket.sendall(buf)
212
+
213
+ if errno is None:
214
+ should_loop = False
215
+ elif errno == ssl.SSL_ERROR_WANT_READ:
216
+ buf = self.socket.recv(SSL_BLOCKSIZE)
217
+ if buf:
218
+ self.incoming.write(buf)
219
+ else:
220
+ self.incoming.write_eof()
221
+ return ret
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/timeout.py ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import time
4
+
5
+ # The default socket timeout, used by httplib to indicate that no timeout was
6
+ # specified by the user
7
+ from socket import _GLOBAL_DEFAULT_TIMEOUT
8
+
9
+ from ..exceptions import TimeoutStateError
10
+
11
+ # A sentinel value to indicate that no timeout was specified by the user in
12
+ # urllib3
13
+ _Default = object()
14
+
15
+
16
+ # Use time.monotonic if available.
17
+ current_time = getattr(time, "monotonic", time.time)
18
+
19
+
20
+ class Timeout(object):
21
+ """Timeout configuration.
22
+
23
+ Timeouts can be defined as a default for a pool:
24
+
25
+ .. code-block:: python
26
+
27
+ timeout = Timeout(connect=2.0, read=7.0)
28
+ http = PoolManager(timeout=timeout)
29
+ response = http.request('GET', 'http://example.com/')
30
+
31
+ Or per-request (which overrides the default for the pool):
32
+
33
+ .. code-block:: python
34
+
35
+ response = http.request('GET', 'http://example.com/', timeout=Timeout(10))
36
+
37
+ Timeouts can be disabled by setting all the parameters to ``None``:
38
+
39
+ .. code-block:: python
40
+
41
+ no_timeout = Timeout(connect=None, read=None)
42
+ response = http.request('GET', 'http://example.com/, timeout=no_timeout)
43
+
44
+
45
+ :param total:
46
+ This combines the connect and read timeouts into one; the read timeout
47
+ will be set to the time leftover from the connect attempt. In the
48
+ event that both a connect timeout and a total are specified, or a read
49
+ timeout and a total are specified, the shorter timeout will be applied.
50
+
51
+ Defaults to None.
52
+
53
+ :type total: int, float, or None
54
+
55
+ :param connect:
56
+ The maximum amount of time (in seconds) to wait for a connection
57
+ attempt to a server to succeed. Omitting the parameter will default the
58
+ connect timeout to the system default, probably `the global default
59
+ timeout in socket.py
60
+ <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
61
+ None will set an infinite timeout for connection attempts.
62
+
63
+ :type connect: int, float, or None
64
+
65
+ :param read:
66
+ The maximum amount of time (in seconds) to wait between consecutive
67
+ read operations for a response from the server. Omitting the parameter
68
+ will default the read timeout to the system default, probably `the
69
+ global default timeout in socket.py
70
+ <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_.
71
+ None will set an infinite timeout.
72
+
73
+ :type read: int, float, or None
74
+
75
+ .. note::
76
+
77
+ Many factors can affect the total amount of time for urllib3 to return
78
+ an HTTP response.
79
+
80
+ For example, Python's DNS resolver does not obey the timeout specified
81
+ on the socket. Other factors that can affect total request time include
82
+ high CPU load, high swap, the program running at a low priority level,
83
+ or other behaviors.
84
+
85
+ In addition, the read and total timeouts only measure the time between
86
+ read operations on the socket connecting the client and the server,
87
+ not the total amount of time for the request to return a complete
88
+ response. For most requests, the timeout is raised because the server
89
+ has not sent the first byte in the specified time. This is not always
90
+ the case; if a server streams one byte every fifteen seconds, a timeout
91
+ of 20 seconds will not trigger, even though the request will take
92
+ several minutes to complete.
93
+
94
+ If your goal is to cut off any request after a set amount of wall clock
95
+ time, consider having a second "watcher" thread to cut off a slow
96
+ request.
97
+ """
98
+
99
+ #: A sentinel object representing the default timeout value
100
+ DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT
101
+
102
+ def __init__(self, total=None, connect=_Default, read=_Default):
103
+ self._connect = self._validate_timeout(connect, "connect")
104
+ self._read = self._validate_timeout(read, "read")
105
+ self.total = self._validate_timeout(total, "total")
106
+ self._start_connect = None
107
+
108
+ def __repr__(self):
109
+ return "%s(connect=%r, read=%r, total=%r)" % (
110
+ type(self).__name__,
111
+ self._connect,
112
+ self._read,
113
+ self.total,
114
+ )
115
+
116
+ # __str__ provided for backwards compatibility
117
+ __str__ = __repr__
118
+
119
+ @classmethod
120
+ def _validate_timeout(cls, value, name):
121
+ """Check that a timeout attribute is valid.
122
+
123
+ :param value: The timeout value to validate
124
+ :param name: The name of the timeout attribute to validate. This is
125
+ used to specify in error messages.
126
+ :return: The validated and casted version of the given value.
127
+ :raises ValueError: If it is a numeric value less than or equal to
128
+ zero, or the type is not an integer, float, or None.
129
+ """
130
+ if value is _Default:
131
+ return cls.DEFAULT_TIMEOUT
132
+
133
+ if value is None or value is cls.DEFAULT_TIMEOUT:
134
+ return value
135
+
136
+ if isinstance(value, bool):
137
+ raise ValueError(
138
+ "Timeout cannot be a boolean value. It must "
139
+ "be an int, float or None."
140
+ )
141
+ try:
142
+ float(value)
143
+ except (TypeError, ValueError):
144
+ raise ValueError(
145
+ "Timeout value %s was %s, but it must be an "
146
+ "int, float or None." % (name, value)
147
+ )
148
+
149
+ try:
150
+ if value <= 0:
151
+ raise ValueError(
152
+ "Attempted to set %s timeout to %s, but the "
153
+ "timeout cannot be set to a value less "
154
+ "than or equal to 0." % (name, value)
155
+ )
156
+ except TypeError:
157
+ # Python 3
158
+ raise ValueError(
159
+ "Timeout value %s was %s, but it must be an "
160
+ "int, float or None." % (name, value)
161
+ )
162
+
163
+ return value
164
+
165
+ @classmethod
166
+ def from_float(cls, timeout):
167
+ """Create a new Timeout from a legacy timeout value.
168
+
169
+ The timeout value used by httplib.py sets the same timeout on the
170
+ connect(), and recv() socket requests. This creates a :class:`Timeout`
171
+ object that sets the individual timeouts to the ``timeout`` value
172
+ passed to this function.
173
+
174
+ :param timeout: The legacy timeout value.
175
+ :type timeout: integer, float, sentinel default object, or None
176
+ :return: Timeout object
177
+ :rtype: :class:`Timeout`
178
+ """
179
+ return Timeout(read=timeout, connect=timeout)
180
+
181
+ def clone(self):
182
+ """Create a copy of the timeout object
183
+
184
+ Timeout properties are stored per-pool but each request needs a fresh
185
+ Timeout object to ensure each one has its own start/stop configured.
186
+
187
+ :return: a copy of the timeout object
188
+ :rtype: :class:`Timeout`
189
+ """
190
+ # We can't use copy.deepcopy because that will also create a new object
191
+ # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to
192
+ # detect the user default.
193
+ return Timeout(connect=self._connect, read=self._read, total=self.total)
194
+
195
+ def start_connect(self):
196
+ """Start the timeout clock, used during a connect() attempt
197
+
198
+ :raises urllib3.exceptions.TimeoutStateError: if you attempt
199
+ to start a timer that has been started already.
200
+ """
201
+ if self._start_connect is not None:
202
+ raise TimeoutStateError("Timeout timer has already been started.")
203
+ self._start_connect = current_time()
204
+ return self._start_connect
205
+
206
+ def get_connect_duration(self):
207
+ """Gets the time elapsed since the call to :meth:`start_connect`.
208
+
209
+ :return: Elapsed time in seconds.
210
+ :rtype: float
211
+ :raises urllib3.exceptions.TimeoutStateError: if you attempt
212
+ to get duration for a timer that hasn't been started.
213
+ """
214
+ if self._start_connect is None:
215
+ raise TimeoutStateError(
216
+ "Can't get connect duration for timer that has not started."
217
+ )
218
+ return current_time() - self._start_connect
219
+
220
+ @property
221
+ def connect_timeout(self):
222
+ """Get the value to use when setting a connection timeout.
223
+
224
+ This will be a positive float or integer, the value None
225
+ (never timeout), or the default system timeout.
226
+
227
+ :return: Connect timeout.
228
+ :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
229
+ """
230
+ if self.total is None:
231
+ return self._connect
232
+
233
+ if self._connect is None or self._connect is self.DEFAULT_TIMEOUT:
234
+ return self.total
235
+
236
+ return min(self._connect, self.total)
237
+
238
+ @property
239
+ def read_timeout(self):
240
+ """Get the value for the read timeout.
241
+
242
+ This assumes some time has elapsed in the connection timeout and
243
+ computes the read timeout appropriately.
244
+
245
+ If self.total is set, the read timeout is dependent on the amount of
246
+ time taken by the connect timeout. If the connection time has not been
247
+ established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be
248
+ raised.
249
+
250
+ :return: Value to use for the read timeout.
251
+ :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None
252
+ :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect`
253
+ has not yet been called on this object.
254
+ """
255
+ if (
256
+ self.total is not None
257
+ and self.total is not self.DEFAULT_TIMEOUT
258
+ and self._read is not None
259
+ and self._read is not self.DEFAULT_TIMEOUT
260
+ ):
261
+ # In case the connect timeout has not yet been established.
262
+ if self._start_connect is None:
263
+ return self._read
264
+ return max(0, min(self.total - self.get_connect_duration(), self._read))
265
+ elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT:
266
+ return max(0, self.total - self.get_connect_duration())
267
+ else:
268
+ return self._read
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/url.py ADDED
@@ -0,0 +1,432 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import absolute_import
2
+
3
+ import re
4
+ from collections import namedtuple
5
+
6
+ from ..exceptions import LocationParseError
7
+ from ..packages import six
8
+
9
+ url_attrs = ["scheme", "auth", "host", "port", "path", "query", "fragment"]
10
+
11
+ # We only want to normalize urls with an HTTP(S) scheme.
12
+ # urllib3 infers URLs without a scheme (None) to be http.
13
+ NORMALIZABLE_SCHEMES = ("http", "https", None)
14
+
15
+ # Almost all of these patterns were derived from the
16
+ # 'rfc3986' module: https://github.com/python-hyper/rfc3986
17
+ PERCENT_RE = re.compile(r"%[a-fA-F0-9]{2}")
18
+ SCHEME_RE = re.compile(r"^(?:[a-zA-Z][a-zA-Z0-9+-]*:|/)")
19
+ URI_RE = re.compile(
20
+ r"^(?:([a-zA-Z][a-zA-Z0-9+.-]*):)?"
21
+ r"(?://([^\\/?#]*))?"
22
+ r"([^?#]*)"
23
+ r"(?:\?([^#]*))?"
24
+ r"(?:#(.*))?$",
25
+ re.UNICODE | re.DOTALL,
26
+ )
27
+
28
+ IPV4_PAT = r"(?:[0-9]{1,3}\.){3}[0-9]{1,3}"
29
+ HEX_PAT = "[0-9A-Fa-f]{1,4}"
30
+ LS32_PAT = "(?:{hex}:{hex}|{ipv4})".format(hex=HEX_PAT, ipv4=IPV4_PAT)
31
+ _subs = {"hex": HEX_PAT, "ls32": LS32_PAT}
32
+ _variations = [
33
+ # 6( h16 ":" ) ls32
34
+ "(?:%(hex)s:){6}%(ls32)s",
35
+ # "::" 5( h16 ":" ) ls32
36
+ "::(?:%(hex)s:){5}%(ls32)s",
37
+ # [ h16 ] "::" 4( h16 ":" ) ls32
38
+ "(?:%(hex)s)?::(?:%(hex)s:){4}%(ls32)s",
39
+ # [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
40
+ "(?:(?:%(hex)s:)?%(hex)s)?::(?:%(hex)s:){3}%(ls32)s",
41
+ # [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
42
+ "(?:(?:%(hex)s:){0,2}%(hex)s)?::(?:%(hex)s:){2}%(ls32)s",
43
+ # [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
44
+ "(?:(?:%(hex)s:){0,3}%(hex)s)?::%(hex)s:%(ls32)s",
45
+ # [ *4( h16 ":" ) h16 ] "::" ls32
46
+ "(?:(?:%(hex)s:){0,4}%(hex)s)?::%(ls32)s",
47
+ # [ *5( h16 ":" ) h16 ] "::" h16
48
+ "(?:(?:%(hex)s:){0,5}%(hex)s)?::%(hex)s",
49
+ # [ *6( h16 ":" ) h16 ] "::"
50
+ "(?:(?:%(hex)s:){0,6}%(hex)s)?::",
51
+ ]
52
+
53
+ UNRESERVED_PAT = r"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._!\-~"
54
+ IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")"
55
+ ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+"
56
+ IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]"
57
+ REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*"
58
+ TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$")
59
+
60
+ IPV4_RE = re.compile("^" + IPV4_PAT + "$")
61
+ IPV6_RE = re.compile("^" + IPV6_PAT + "$")
62
+ IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT + "$")
63
+ BRACELESS_IPV6_ADDRZ_RE = re.compile("^" + IPV6_ADDRZ_PAT[2:-2] + "$")
64
+ ZONE_ID_RE = re.compile("(" + ZONE_ID_PAT + r")\]$")
65
+
66
+ _HOST_PORT_PAT = ("^(%s|%s|%s)(?::([0-9]{0,5}))?$") % (
67
+ REG_NAME_PAT,
68
+ IPV4_PAT,
69
+ IPV6_ADDRZ_PAT,
70
+ )
71
+ _HOST_PORT_RE = re.compile(_HOST_PORT_PAT, re.UNICODE | re.DOTALL)
72
+
73
+ UNRESERVED_CHARS = set(
74
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-~"
75
+ )
76
+ SUB_DELIM_CHARS = set("!$&'()*+,;=")
77
+ USERINFO_CHARS = UNRESERVED_CHARS | SUB_DELIM_CHARS | {":"}
78
+ PATH_CHARS = USERINFO_CHARS | {"@", "/"}
79
+ QUERY_CHARS = FRAGMENT_CHARS = PATH_CHARS | {"?"}
80
+
81
+
82
+ class Url(namedtuple("Url", url_attrs)):
83
+ """
84
+ Data structure for representing an HTTP URL. Used as a return value for
85
+ :func:`parse_url`. Both the scheme and host are normalized as they are
86
+ both case-insensitive according to RFC 3986.
87
+ """
88
+
89
+ __slots__ = ()
90
+
91
+ def __new__(
92
+ cls,
93
+ scheme=None,
94
+ auth=None,
95
+ host=None,
96
+ port=None,
97
+ path=None,
98
+ query=None,
99
+ fragment=None,
100
+ ):
101
+ if path and not path.startswith("/"):
102
+ path = "/" + path
103
+ if scheme is not None:
104
+ scheme = scheme.lower()
105
+ return super(Url, cls).__new__(
106
+ cls, scheme, auth, host, port, path, query, fragment
107
+ )
108
+
109
+ @property
110
+ def hostname(self):
111
+ """For backwards-compatibility with urlparse. We're nice like that."""
112
+ return self.host
113
+
114
+ @property
115
+ def request_uri(self):
116
+ """Absolute path including the query string."""
117
+ uri = self.path or "/"
118
+
119
+ if self.query is not None:
120
+ uri += "?" + self.query
121
+
122
+ return uri
123
+
124
+ @property
125
+ def netloc(self):
126
+ """Network location including host and port"""
127
+ if self.port:
128
+ return "%s:%d" % (self.host, self.port)
129
+ return self.host
130
+
131
+ @property
132
+ def url(self):
133
+ """
134
+ Convert self into a url
135
+
136
+ This function should more or less round-trip with :func:`.parse_url`. The
137
+ returned url may not be exactly the same as the url inputted to
138
+ :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls
139
+ with a blank port will have : removed).
140
+
141
+ Example: ::
142
+
143
+ >>> U = parse_url('http://google.com/mail/')
144
+ >>> U.url
145
+ 'http://google.com/mail/'
146
+ >>> Url('http', 'username:password', 'host.com', 80,
147
+ ... '/path', 'query', 'fragment').url
148
+ 'http://username:password@host.com:80/path?query#fragment'
149
+ """
150
+ scheme, auth, host, port, path, query, fragment = self
151
+ url = u""
152
+
153
+ # We use "is not None" we want things to happen with empty strings (or 0 port)
154
+ if scheme is not None:
155
+ url += scheme + u"://"
156
+ if auth is not None:
157
+ url += auth + u"@"
158
+ if host is not None:
159
+ url += host
160
+ if port is not None:
161
+ url += u":" + str(port)
162
+ if path is not None:
163
+ url += path
164
+ if query is not None:
165
+ url += u"?" + query
166
+ if fragment is not None:
167
+ url += u"#" + fragment
168
+
169
+ return url
170
+
171
+ def __str__(self):
172
+ return self.url
173
+
174
+
175
+ def split_first(s, delims):
176
+ """
177
+ .. deprecated:: 1.25
178
+
179
+ Given a string and an iterable of delimiters, split on the first found
180
+ delimiter. Return two split parts and the matched delimiter.
181
+
182
+ If not found, then the first part is the full input string.
183
+
184
+ Example::
185
+
186
+ >>> split_first('foo/bar?baz', '?/=')
187
+ ('foo', 'bar?baz', '/')
188
+ >>> split_first('foo/bar?baz', '123')
189
+ ('foo/bar?baz', '', None)
190
+
191
+ Scales linearly with number of delims. Not ideal for large number of delims.
192
+ """
193
+ min_idx = None
194
+ min_delim = None
195
+ for d in delims:
196
+ idx = s.find(d)
197
+ if idx < 0:
198
+ continue
199
+
200
+ if min_idx is None or idx < min_idx:
201
+ min_idx = idx
202
+ min_delim = d
203
+
204
+ if min_idx is None or min_idx < 0:
205
+ return s, "", None
206
+
207
+ return s[:min_idx], s[min_idx + 1 :], min_delim
208
+
209
+
210
+ def _encode_invalid_chars(component, allowed_chars, encoding="utf-8"):
211
+ """Percent-encodes a URI component without reapplying
212
+ onto an already percent-encoded component.
213
+ """
214
+ if component is None:
215
+ return component
216
+
217
+ component = six.ensure_text(component)
218
+
219
+ # Normalize existing percent-encoded bytes.
220
+ # Try to see if the component we're encoding is already percent-encoded
221
+ # so we can skip all '%' characters but still encode all others.
222
+ component, percent_encodings = PERCENT_RE.subn(
223
+ lambda match: match.group(0).upper(), component
224
+ )
225
+
226
+ uri_bytes = component.encode("utf-8", "surrogatepass")
227
+ is_percent_encoded = percent_encodings == uri_bytes.count(b"%")
228
+ encoded_component = bytearray()
229
+
230
+ for i in range(0, len(uri_bytes)):
231
+ # Will return a single character bytestring on both Python 2 & 3
232
+ byte = uri_bytes[i : i + 1]
233
+ byte_ord = ord(byte)
234
+ if (is_percent_encoded and byte == b"%") or (
235
+ byte_ord < 128 and byte.decode() in allowed_chars
236
+ ):
237
+ encoded_component += byte
238
+ continue
239
+ encoded_component.extend(b"%" + (hex(byte_ord)[2:].encode().zfill(2).upper()))
240
+
241
+ return encoded_component.decode(encoding)
242
+
243
+
244
+ def _remove_path_dot_segments(path):
245
+ # See http://tools.ietf.org/html/rfc3986#section-5.2.4 for pseudo-code
246
+ segments = path.split("/") # Turn the path into a list of segments
247
+ output = [] # Initialize the variable to use to store output
248
+
249
+ for segment in segments:
250
+ # '.' is the current directory, so ignore it, it is superfluous
251
+ if segment == ".":
252
+ continue
253
+ # Anything other than '..', should be appended to the output
254
+ elif segment != "..":
255
+ output.append(segment)
256
+ # In this case segment == '..', if we can, we should pop the last
257
+ # element
258
+ elif output:
259
+ output.pop()
260
+
261
+ # If the path starts with '/' and the output is empty or the first string
262
+ # is non-empty
263
+ if path.startswith("/") and (not output or output[0]):
264
+ output.insert(0, "")
265
+
266
+ # If the path starts with '/.' or '/..' ensure we add one more empty
267
+ # string to add a trailing '/'
268
+ if path.endswith(("/.", "/..")):
269
+ output.append("")
270
+
271
+ return "/".join(output)
272
+
273
+
274
+ def _normalize_host(host, scheme):
275
+ if host:
276
+ if isinstance(host, six.binary_type):
277
+ host = six.ensure_str(host)
278
+
279
+ if scheme in NORMALIZABLE_SCHEMES:
280
+ is_ipv6 = IPV6_ADDRZ_RE.match(host)
281
+ if is_ipv6:
282
+ match = ZONE_ID_RE.search(host)
283
+ if match:
284
+ start, end = match.span(1)
285
+ zone_id = host[start:end]
286
+
287
+ if zone_id.startswith("%25") and zone_id != "%25":
288
+ zone_id = zone_id[3:]
289
+ else:
290
+ zone_id = zone_id[1:]
291
+ zone_id = "%" + _encode_invalid_chars(zone_id, UNRESERVED_CHARS)
292
+ return host[:start].lower() + zone_id + host[end:]
293
+ else:
294
+ return host.lower()
295
+ elif not IPV4_RE.match(host):
296
+ return six.ensure_str(
297
+ b".".join([_idna_encode(label) for label in host.split(".")])
298
+ )
299
+ return host
300
+
301
+
302
+ def _idna_encode(name):
303
+ if name and any([ord(x) > 128 for x in name]):
304
+ try:
305
+ from pip._vendor import idna
306
+ except ImportError:
307
+ six.raise_from(
308
+ LocationParseError("Unable to parse URL without the 'idna' module"),
309
+ None,
310
+ )
311
+ try:
312
+ return idna.encode(name.lower(), strict=True, std3_rules=True)
313
+ except idna.IDNAError:
314
+ six.raise_from(
315
+ LocationParseError(u"Name '%s' is not a valid IDNA label" % name), None
316
+ )
317
+ return name.lower().encode("ascii")
318
+
319
+
320
+ def _encode_target(target):
321
+ """Percent-encodes a request target so that there are no invalid characters"""
322
+ path, query = TARGET_RE.match(target).groups()
323
+ target = _encode_invalid_chars(path, PATH_CHARS)
324
+ query = _encode_invalid_chars(query, QUERY_CHARS)
325
+ if query is not None:
326
+ target += "?" + query
327
+ return target
328
+
329
+
330
+ def parse_url(url):
331
+ """
332
+ Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is
333
+ performed to parse incomplete urls. Fields not provided will be None.
334
+ This parser is RFC 3986 compliant.
335
+
336
+ The parser logic and helper functions are based heavily on
337
+ work done in the ``rfc3986`` module.
338
+
339
+ :param str url: URL to parse into a :class:`.Url` namedtuple.
340
+
341
+ Partly backwards-compatible with :mod:`urlparse`.
342
+
343
+ Example::
344
+
345
+ >>> parse_url('http://google.com/mail/')
346
+ Url(scheme='http', host='google.com', port=None, path='/mail/', ...)
347
+ >>> parse_url('google.com:80')
348
+ Url(scheme=None, host='google.com', port=80, path=None, ...)
349
+ >>> parse_url('/foo?bar')
350
+ Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...)
351
+ """
352
+ if not url:
353
+ # Empty
354
+ return Url()
355
+
356
+ source_url = url
357
+ if not SCHEME_RE.search(url):
358
+ url = "//" + url
359
+
360
+ try:
361
+ scheme, authority, path, query, fragment = URI_RE.match(url).groups()
362
+ normalize_uri = scheme is None or scheme.lower() in NORMALIZABLE_SCHEMES
363
+
364
+ if scheme:
365
+ scheme = scheme.lower()
366
+
367
+ if authority:
368
+ auth, _, host_port = authority.rpartition("@")
369
+ auth = auth or None
370
+ host, port = _HOST_PORT_RE.match(host_port).groups()
371
+ if auth and normalize_uri:
372
+ auth = _encode_invalid_chars(auth, USERINFO_CHARS)
373
+ if port == "":
374
+ port = None
375
+ else:
376
+ auth, host, port = None, None, None
377
+
378
+ if port is not None:
379
+ port = int(port)
380
+ if not (0 <= port <= 65535):
381
+ raise LocationParseError(url)
382
+
383
+ host = _normalize_host(host, scheme)
384
+
385
+ if normalize_uri and path:
386
+ path = _remove_path_dot_segments(path)
387
+ path = _encode_invalid_chars(path, PATH_CHARS)
388
+ if normalize_uri and query:
389
+ query = _encode_invalid_chars(query, QUERY_CHARS)
390
+ if normalize_uri and fragment:
391
+ fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS)
392
+
393
+ except (ValueError, AttributeError):
394
+ return six.raise_from(LocationParseError(source_url), None)
395
+
396
+ # For the sake of backwards compatibility we put empty
397
+ # string values for path if there are any defined values
398
+ # beyond the path in the URL.
399
+ # TODO: Remove this when we break backwards compatibility.
400
+ if not path:
401
+ if query is not None or fragment is not None:
402
+ path = ""
403
+ else:
404
+ path = None
405
+
406
+ # Ensure that each part of the URL is a `str` for
407
+ # backwards compatibility.
408
+ if isinstance(url, six.text_type):
409
+ ensure_func = six.ensure_text
410
+ else:
411
+ ensure_func = six.ensure_str
412
+
413
+ def ensure_type(x):
414
+ return x if x is None else ensure_func(x)
415
+
416
+ return Url(
417
+ scheme=ensure_type(scheme),
418
+ auth=ensure_type(auth),
419
+ host=ensure_type(host),
420
+ port=port,
421
+ path=ensure_type(path),
422
+ query=ensure_type(query),
423
+ fragment=ensure_type(fragment),
424
+ )
425
+
426
+
427
+ def get_host(url):
428
+ """
429
+ Deprecated. Use :func:`parse_url` instead.
430
+ """
431
+ p = parse_url(url)
432
+ return p.scheme or "http", p.hostname, p.port
astra_scene_test/Scene_04/.venv/lib/python3.9/site-packages/pip/_vendor/urllib3/util/wait.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import errno
2
+ import select
3
+ import sys
4
+ from functools import partial
5
+
6
+ try:
7
+ from time import monotonic
8
+ except ImportError:
9
+ from time import time as monotonic
10
+
11
+ __all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"]
12
+
13
+
14
+ class NoWayToWaitForSocketError(Exception):
15
+ pass
16
+
17
+
18
+ # How should we wait on sockets?
19
+ #
20
+ # There are two types of APIs you can use for waiting on sockets: the fancy
21
+ # modern stateful APIs like epoll/kqueue, and the older stateless APIs like
22
+ # select/poll. The stateful APIs are more efficient when you have a lots of
23
+ # sockets to keep track of, because you can set them up once and then use them
24
+ # lots of times. But we only ever want to wait on a single socket at a time
25
+ # and don't want to keep track of state, so the stateless APIs are actually
26
+ # more efficient. So we want to use select() or poll().
27
+ #
28
+ # Now, how do we choose between select() and poll()? On traditional Unixes,
29
+ # select() has a strange calling convention that makes it slow, or fail
30
+ # altogether, for high-numbered file descriptors. The point of poll() is to fix
31
+ # that, so on Unixes, we prefer poll().
32
+ #
33
+ # On Windows, there is no poll() (or at least Python doesn't provide a wrapper
34
+ # for it), but that's OK, because on Windows, select() doesn't have this
35
+ # strange calling convention; plain select() works fine.
36
+ #
37
+ # So: on Windows we use select(), and everywhere else we use poll(). We also
38
+ # fall back to select() in case poll() is somehow broken or missing.
39
+
40
+ if sys.version_info >= (3, 5):
41
+ # Modern Python, that retries syscalls by default
42
+ def _retry_on_intr(fn, timeout):
43
+ return fn(timeout)
44
+
45
+
46
+ else:
47
+ # Old and broken Pythons.
48
+ def _retry_on_intr(fn, timeout):
49
+ if timeout is None:
50
+ deadline = float("inf")
51
+ else:
52
+ deadline = monotonic() + timeout
53
+
54
+ while True:
55
+ try:
56
+ return fn(timeout)
57
+ # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7
58
+ except (OSError, select.error) as e:
59
+ # 'e.args[0]' incantation works for both OSError and select.error
60
+ if e.args[0] != errno.EINTR:
61
+ raise
62
+ else:
63
+ timeout = deadline - monotonic()
64
+ if timeout < 0:
65
+ timeout = 0
66
+ if timeout == float("inf"):
67
+ timeout = None
68
+ continue
69
+
70
+
71
+ def select_wait_for_socket(sock, read=False, write=False, timeout=None):
72
+ if not read and not write:
73
+ raise RuntimeError("must specify at least one of read=True, write=True")
74
+ rcheck = []
75
+ wcheck = []
76
+ if read:
77
+ rcheck.append(sock)
78
+ if write:
79
+ wcheck.append(sock)
80
+ # When doing a non-blocking connect, most systems signal success by
81
+ # marking the socket writable. Windows, though, signals success by marked
82
+ # it as "exceptional". We paper over the difference by checking the write
83
+ # sockets for both conditions. (The stdlib selectors module does the same
84
+ # thing.)
85
+ fn = partial(select.select, rcheck, wcheck, wcheck)
86
+ rready, wready, xready = _retry_on_intr(fn, timeout)
87
+ return bool(rready or wready or xready)
88
+
89
+
90
+ def poll_wait_for_socket(sock, read=False, write=False, timeout=None):
91
+ if not read and not write:
92
+ raise RuntimeError("must specify at least one of read=True, write=True")
93
+ mask = 0
94
+ if read:
95
+ mask |= select.POLLIN
96
+ if write:
97
+ mask |= select.POLLOUT
98
+ poll_obj = select.poll()
99
+ poll_obj.register(sock, mask)
100
+
101
+ # For some reason, poll() takes timeout in milliseconds
102
+ def do_poll(t):
103
+ if t is not None:
104
+ t *= 1000
105
+ return poll_obj.poll(t)
106
+
107
+ return bool(_retry_on_intr(do_poll, timeout))
108
+
109
+
110
+ def null_wait_for_socket(*args, **kwargs):
111
+ raise NoWayToWaitForSocketError("no select-equivalent available")
112
+
113
+
114
+ def _have_working_poll():
115
+ # Apparently some systems have a select.poll that fails as soon as you try
116
+ # to use it, either due to strange configuration or broken monkeypatching
117
+ # from libraries like eventlet/greenlet.
118
+ try:
119
+ poll_obj = select.poll()
120
+ _retry_on_intr(poll_obj.poll, 0)
121
+ except (AttributeError, OSError):
122
+ return False
123
+ else:
124
+ return True
125
+
126
+
127
+ def wait_for_socket(*args, **kwargs):
128
+ # We delay choosing which implementation to use until the first time we're
129
+ # called. We could do it at import time, but then we might make the wrong
130
+ # decision if someone goes wild with monkeypatching select.poll after
131
+ # we're imported.
132
+ global wait_for_socket
133
+ if _have_working_poll():
134
+ wait_for_socket = poll_wait_for_socket
135
+ elif hasattr(select, "select"):
136
+ wait_for_socket = select_wait_for_socket
137
+ else: # Platform-specific: Appengine.
138
+ wait_for_socket = null_wait_for_socket
139
+ return wait_for_socket(*args, **kwargs)
140
+
141
+
142
+ def wait_for_read(sock, timeout=None):
143
+ """Waits for reading to be available on a given socket.
144
+ Returns True if the socket is readable, or False if the timeout expired.
145
+ """
146
+ return wait_for_socket(sock, read=True, timeout=timeout)
147
+
148
+
149
+ def wait_for_write(sock, timeout=None):
150
+ """Waits for writing to be available on a given socket.
151
+ Returns True if the socket is readable, or False if the timeout expired.
152
+ """
153
+ return wait_for_socket(sock, write=True, timeout=timeout)