Vendoring Updates for Jan 2020 (#7618)

This commit is contained in:
Pradyun Gedam 2020-01-21 15:15:29 +05:30 committed by GitHub
commit bd02564af2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 456 additions and 167 deletions

1
news/CacheControl.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade CacheControl to 0.12.5

1
news/certifi.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade certifi to 2019.9.11

1
news/colorama.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade colorama to 0.4.1

1
news/distlib.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade distlib to 0.2.9.post0

1
news/ipaddress.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade ipaddress to 1.0.22

View File

@ -0,0 +1 @@
Upgrade pkg_resources (via setuptools) to 44.0.0

1
news/pyparsing.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade pyparsing to 2.4.2

1
news/six.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade six to 1.12.0

1
news/urllib3.vendor Normal file
View File

@ -0,0 +1 @@
Upgrade urllib3 to 1.25.6

View File

@ -4,7 +4,7 @@ Make it easy to import from cachecontrol without long namespaces.
"""
__author__ = "Eric Larson"
__email__ = "eric@ionrock.org"
__version__ = "0.12.5"
__version__ = "0.12.6"
from .wrapper import CacheControl
from .adapter import CacheControlAdapter

View File

@ -24,7 +24,7 @@ class CacheControlAdapter(HTTPAdapter):
**kw
):
super(CacheControlAdapter, self).__init__(*args, **kw)
self.cache = cache or DictCache()
self.cache = DictCache() if cache is None else cache
self.heuristic = heuristic
self.cacheable_methods = cacheable_methods or ("GET",)

View File

@ -34,7 +34,7 @@ class CacheController(object):
def __init__(
self, cache=None, cache_etags=True, serializer=None, status_codes=None
):
self.cache = cache or DictCache()
self.cache = DictCache() if cache is None else cache
self.cache_etags = cache_etags
self.serializer = serializer or Serializer()
self.cacheable_status_codes = status_codes or (200, 203, 300, 301)
@ -293,6 +293,15 @@ class CacheController(object):
if no_store:
return
# https://tools.ietf.org/html/rfc7234#section-4.1:
# A Vary header field-value of "*" always fails to match.
# Storing such a response leads to a deserialization warning
# during cache lookup and is not allowed to ever be served,
# so storing it can be avoided.
if "*" in response_headers.get("vary", ""):
logger.debug('Response header has "Vary: *"')
return
# If we've been given an etag, then keep the response
if self.cache_etags and "etag" in response_headers:
logger.debug("Caching due to etag")

View File

@ -107,6 +107,8 @@ class Serializer(object):
"""
# Special case the '*' Vary value as it means we cannot actually
# determine if the cached response is suitable for this request.
# This case is also handled in the controller code when creating
# a cache entry, but is left here for backwards compatibility.
if "*" in cached.get("vary", {}):
return
@ -179,7 +181,7 @@ class Serializer(object):
def _loads_v4(self, request, data):
try:
cached = msgpack.loads(data, encoding="utf-8")
cached = msgpack.loads(data, raw=False)
except ValueError:
return

View File

@ -13,7 +13,7 @@ def CacheControl(
cacheable_methods=None,
):
cache = cache or DictCache()
cache = DictCache() if cache is None else cache
adapter_class = adapter_class or CacheControlAdapter
adapter = adapter_class(
cache,

View File

@ -1,3 +1,3 @@
from .core import where
__version__ = "2019.09.11"
__version__ = "2019.11.28"

View File

@ -4556,3 +4556,47 @@ L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa
LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG
mpv0
-----END CERTIFICATE-----
# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only
# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only
# Label: "Entrust Root Certification Authority - G4"
# Serial: 289383649854506086828220374796556676440
# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88
# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01
# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88
-----BEGIN CERTIFICATE-----
MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw
gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL
Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg
MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw
BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0
MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1
c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ
bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg
Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ
2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E
T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j
5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM
C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T
DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX
wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A
2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm
nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8
dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl
N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj
c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS
5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS
Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr
hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/
B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI
AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw
H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+
b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk
2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol
IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk
5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY
n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==
-----END CERTIFICATE-----

View File

@ -3,4 +3,4 @@ from .initialise import init, deinit, reinit, colorama_text
from .ansi import Fore, Back, Style, Cursor
from .ansitowin32 import AnsiToWin32
__version__ = '0.4.1'
__version__ = '0.4.3'

View File

@ -6,7 +6,7 @@
#
import logging
__version__ = '0.2.9.post0'
__version__ = '0.3.0'
class DistlibException(Exception):
pass

View File

@ -119,11 +119,9 @@ def _expand_globals(config):
#_expand_globals(_SCHEMES)
# FIXME don't rely on sys.version here, its format is an implementation detail
# of CPython, use sys.version_info or sys.hexversion
_PY_VERSION = sys.version.split()[0]
_PY_VERSION_SHORT = sys.version[:3]
_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2]
_PY_VERSION = '%s.%s.%s' % sys.version_info[:3]
_PY_VERSION_SHORT = '%s.%s' % sys.version_info[:2]
_PY_VERSION_SHORT_NO_DOT = '%s%s' % sys.version_info[:2]
_PREFIX = os.path.normpath(sys.prefix)
_EXEC_PREFIX = os.path.normpath(sys.exec_prefix)
_CONFIG_VARS = None

View File

@ -567,7 +567,7 @@ class InstalledDistribution(BaseInstalledDistribution):
p = os.path.join(path, 'top_level.txt')
if os.path.exists(p):
with open(p, 'rb') as f:
data = f.read()
data = f.read().decode('utf-8')
self.modules = data.splitlines()
def __repr__(self):

View File

@ -304,18 +304,25 @@ class Locator(object):
def _get_digest(self, info):
"""
Get a digest from a dictionary by looking at keys of the form
'algo_digest'.
Get a digest from a dictionary by looking at a "digests" dictionary
or keys of the form 'algo_digest'.
Returns a 2-tuple (algo, digest) if found, else None. Currently
looks only for SHA256, then MD5.
"""
result = None
for algo in ('sha256', 'md5'):
key = '%s_digest' % algo
if key in info:
result = (algo, info[key])
break
if 'digests' in info:
digests = info['digests']
for algo in ('sha256', 'md5'):
if algo in digests:
result = (algo, digests[algo])
break
if not result:
for algo in ('sha256', 'md5'):
key = '%s_digest' % algo
if key in info:
result = (algo, info[key])
break
return result
def _update_version_data(self, result, info):

View File

@ -172,8 +172,16 @@ class ScriptMaker(object):
if sys.platform.startswith('java'): # pragma: no cover
executable = self._fix_jython_executable(executable)
# Normalise case for Windows
executable = os.path.normcase(executable)
# Normalise case for Windows - COMMENTED OUT
# executable = os.path.normcase(executable)
# N.B. The normalising operation above has been commented out: See
# issue #124. Although paths in Windows are generally case-insensitive,
# they aren't always. For example, a path containing a ẞ (which is a
# LATIN CAPITAL LETTER SHARP S - U+1E9E) is normcased to ß (which is a
# LATIN SMALL LETTER SHARP S' - U+00DF). The two are not considered by
# Windows as equivalent in path names.
# If the user didn't specify an executable, it may be necessary to
# cater for executable paths with spaces (not uncommon on Windows)
if enquote:
@ -285,9 +293,10 @@ class ScriptMaker(object):
if '' in self.variants:
scriptnames.add(name)
if 'X' in self.variants:
scriptnames.add('%s%s' % (name, sys.version[0]))
scriptnames.add('%s%s' % (name, sys.version_info[0]))
if 'X.Y' in self.variants:
scriptnames.add('%s-%s' % (name, sys.version[:3]))
scriptnames.add('%s-%s.%s' % (name, sys.version_info[0],
sys.version_info[1]))
if options and options.get('gui', False):
ext = 'pyw'
else:
@ -367,8 +376,12 @@ class ScriptMaker(object):
# Issue 31: don't hardcode an absolute package name, but
# determine it relative to the current package
distlib_package = __name__.rsplit('.', 1)[0]
result = finder(distlib_package).find(name).bytes
return result
resource = finder(distlib_package).find(name)
if not resource:
msg = ('Unable to find resource %s in package %s' % (name,
distlib_package))
raise ValueError(msg)
return resource.bytes
# Public API follows

Binary file not shown.

Binary file not shown.

View File

@ -703,7 +703,7 @@ class ExportEntry(object):
ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+)
\s*=\s*(?P<callable>(\w+)([:\.]\w+)*)
\s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])?
\s*(\[\s*(?P<flags>[\w-]+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])?
''', re.VERBOSE)
def get_export_entry(specification):
@ -1438,7 +1438,8 @@ if ssl:
ca_certs=self.ca_certs)
else: # pragma: no cover
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.options |= ssl.OP_NO_SSLv2
if hasattr(ssl, 'OP_NO_SSLv2'):
context.options |= ssl.OP_NO_SSLv2
if self.cert_file:
context.load_cert_chain(self.cert_file, self.key_file)
kwargs = {}

Binary file not shown.

Binary file not shown.

View File

@ -684,7 +684,7 @@ class Wheel(object):
if cache is None:
# Use native string to avoid issues on 2.x: see Python #20140.
base = os.path.join(get_cache_base(), str('dylib-cache'),
sys.version[:3])
'%s.%s' % sys.version_info[:2])
cache = Cache(base)
return cache

View File

@ -14,7 +14,7 @@ from __future__ import unicode_literals
import itertools
import struct
__version__ = '1.0.22'
__version__ = '1.0.23'
# Compatibility functions
_compat_int_types = (int,)
@ -1103,7 +1103,8 @@ class _BaseNetwork(_IPAddressBase):
try:
# Always false if one is v4 and the other is v6.
if a._version != b._version:
raise TypeError("%s and %s are not of the same version" (a, b))
raise TypeError(
"%s and %s are not of the same version" % (a, b))
return (b.network_address <= a.network_address and
b.broadcast_address >= a.broadcast_address)
except AttributeError:

View File

@ -88,8 +88,8 @@ __import__('pip._vendor.packaging.markers')
__metaclass__ = type
if (3, 0) < sys.version_info < (3, 4):
raise RuntimeError("Python 3.4 or later is required")
if (3, 0) < sys.version_info < (3, 5):
raise RuntimeError("Python 3.5 or later is required")
if six.PY2:
# Those builtin exceptions are only defined in Python 3
@ -333,7 +333,7 @@ class UnknownExtra(ResolutionError):
_provider_factories = {}
PY_MAJOR = sys.version[:3]
PY_MAJOR = '{}.{}'.format(*sys.version_info)
EGG_DIST = 3
BINARY_DIST = 2
SOURCE_DIST = 1
@ -3109,6 +3109,7 @@ class Requirement(packaging.requirements.Requirement):
self.extras = tuple(map(safe_extra, self.extras))
self.hashCmp = (
self.key,
self.url,
self.specifier,
frozenset(self.extras),
str(self.marker) if self.marker else None,

View File

@ -95,8 +95,8 @@ classes inherit from. Use the docstrings for examples of how to:
namespace class
"""
__version__ = "2.4.2"
__versionTime__ = "29 Jul 2019 02:58 UTC"
__version__ = "2.4.6"
__versionTime__ = "24 Dec 2019 04:27 UTC"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
import string
@ -114,6 +114,7 @@ from datetime import datetime
from operator import itemgetter
import itertools
from functools import wraps
from contextlib import contextmanager
try:
# Python 3
@ -184,8 +185,15 @@ __diag__.warn_ungrouped_named_tokens_in_collection = False
__diag__.warn_name_set_on_empty_Forward = False
__diag__.warn_on_multiple_string_args_to_oneof = False
__diag__.enable_debug_on_named_expressions = False
__diag__._all_names = [nm for nm in vars(__diag__) if nm.startswith("enable_") or nm.startswith("warn_")]
def _enable_all_warnings():
__diag__.warn_multiple_tokens_in_named_alternation = True
__diag__.warn_ungrouped_named_tokens_in_collection = True
__diag__.warn_name_set_on_empty_Forward = True
__diag__.warn_on_multiple_string_args_to_oneof = True
__diag__.enable_all_warnings = _enable_all_warnings
# ~ sys.stderr.write("testing pyparsing module, version %s, %s\n" % (__version__, __versionTime__))
__all__ = ['__version__', '__versionTime__', '__author__', '__compat__', '__diag__',
'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty',
@ -206,7 +214,7 @@ __all__ = ['__version__', '__versionTime__', '__author__', '__compat__', '__diag
'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute',
'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation', 'locatedExpr', 'withClass',
'CloseMatch', 'tokenMap', 'pyparsing_common', 'pyparsing_unicode', 'unicode_set',
'conditionAsParseAction',
'conditionAsParseAction', 're',
]
system_version = tuple(sys.version_info)[:3]
@ -2561,15 +2569,13 @@ class ParserElement(object):
raise exc
def __eq__(self, other):
if isinstance(other, ParserElement):
if PY_3:
self is other or super(ParserElement, self).__eq__(other)
else:
return self is other or vars(self) == vars(other)
if self is other:
return True
elif isinstance(other, basestring):
return self.matches(other)
else:
return super(ParserElement, self) == other
elif isinstance(other, ParserElement):
return vars(self) == vars(other)
return False
def __ne__(self, other):
return not (self == other)
@ -3252,14 +3258,23 @@ class Regex(Token):
If the given regex contains named groups (defined using ``(?P<name>...)``),
these will be preserved as named parse results.
If instead of the Python stdlib re module you wish to use a different RE module
(such as the `regex` module), you can replace it by either building your
Regex object with a compiled RE that was compiled using regex:
Example::
realnum = Regex(r"[+-]?\d+\.\d*")
date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)')
# ref: https://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
roman = Regex(r"M{0,4}(CM|CD|D?{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
# use regex module instead of stdlib re module to construct a Regex using
# a compiled regular expression
import regex
parser = pp.Regex(regex.compile(r'[0-9]'))
"""
compiledREtype = type(re.compile("[A-Z]"))
def __init__(self, pattern, flags=0, asGroupList=False, asMatch=False):
"""The parameters ``pattern`` and ``flags`` are passed
to the ``re.compile()`` function as-is. See the Python
@ -3284,13 +3299,13 @@ class Regex(Token):
SyntaxWarning, stacklevel=2)
raise
elif isinstance(pattern, Regex.compiledREtype):
elif hasattr(pattern, 'pattern') and hasattr(pattern, 'match'):
self.re = pattern
self.pattern = self.reString = str(pattern)
self.pattern = self.reString = pattern.pattern
self.flags = flags
else:
raise ValueError("Regex may only be constructed with a string or a compiled RE object")
raise TypeError("Regex may only be constructed with a string or a compiled RE object")
self.re_match = self.re.match
@ -3617,24 +3632,24 @@ class White(Token):
'\n': '<LF>',
'\r': '<CR>',
'\f': '<FF>',
'u\00A0': '<NBSP>',
'u\1680': '<OGHAM_SPACE_MARK>',
'u\180E': '<MONGOLIAN_VOWEL_SEPARATOR>',
'u\2000': '<EN_QUAD>',
'u\2001': '<EM_QUAD>',
'u\2002': '<EN_SPACE>',
'u\2003': '<EM_SPACE>',
'u\2004': '<THREE-PER-EM_SPACE>',
'u\2005': '<FOUR-PER-EM_SPACE>',
'u\2006': '<SIX-PER-EM_SPACE>',
'u\2007': '<FIGURE_SPACE>',
'u\2008': '<PUNCTUATION_SPACE>',
'u\2009': '<THIN_SPACE>',
'u\200A': '<HAIR_SPACE>',
'u\200B': '<ZERO_WIDTH_SPACE>',
'u\202F': '<NNBSP>',
'u\205F': '<MMSP>',
'u\3000': '<IDEOGRAPHIC_SPACE>',
u'\u00A0': '<NBSP>',
u'\u1680': '<OGHAM_SPACE_MARK>',
u'\u180E': '<MONGOLIAN_VOWEL_SEPARATOR>',
u'\u2000': '<EN_QUAD>',
u'\u2001': '<EM_QUAD>',
u'\u2002': '<EN_SPACE>',
u'\u2003': '<EM_SPACE>',
u'\u2004': '<THREE-PER-EM_SPACE>',
u'\u2005': '<FOUR-PER-EM_SPACE>',
u'\u2006': '<SIX-PER-EM_SPACE>',
u'\u2007': '<FIGURE_SPACE>',
u'\u2008': '<PUNCTUATION_SPACE>',
u'\u2009': '<THIN_SPACE>',
u'\u200A': '<HAIR_SPACE>',
u'\u200B': '<ZERO_WIDTH_SPACE>',
u'\u202F': '<NNBSP>',
u'\u205F': '<MMSP>',
u'\u3000': '<IDEOGRAPHIC_SPACE>',
}
def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
super(White, self).__init__()
@ -4566,6 +4581,7 @@ class PrecededBy(ParseElementEnhance):
self.retreat = retreat
self.errmsg = "not preceded by " + str(expr)
self.skipWhitespace = False
self.parseAction.append(lambda s, l, t: t.__delitem__(slice(None, None)))
def parseImpl(self, instring, loc=0, doActions=True):
if self.exact:
@ -4576,19 +4592,18 @@ class PrecededBy(ParseElementEnhance):
else:
# retreat specified a maximum lookbehind window, iterate
test_expr = self.expr + StringEnd()
instring_slice = instring[:loc]
instring_slice = instring[max(0, loc - self.retreat):loc]
last_expr = ParseException(instring, loc, self.errmsg)
for offset in range(1, min(loc, self.retreat + 1)):
for offset in range(1, min(loc, self.retreat + 1)+1):
try:
_, ret = test_expr._parse(instring_slice, loc - offset)
# print('trying', offset, instring_slice, repr(instring_slice[loc - offset:]))
_, ret = test_expr._parse(instring_slice, len(instring_slice) - offset)
except ParseBaseException as pbe:
last_expr = pbe
else:
break
else:
raise last_expr
# return empty list of tokens, but preserve any defined results names
del ret[:]
return loc, ret
@ -6051,7 +6066,7 @@ def infixNotation(baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')')):
matchExpr = _FB(lastExpr + lastExpr) + Group(lastExpr + OneOrMore(lastExpr))
elif arity == 3:
matchExpr = (_FB(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr)
+ Group(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr))
+ Group(lastExpr + OneOrMore(opExpr1 + lastExpr + opExpr2 + lastExpr)))
else:
raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
elif rightLeftAssoc == opAssoc.RIGHT:
@ -6305,18 +6320,18 @@ def indentedBlock(blockStatementExpr, indentStack, indent=True):
if curCol < indentStack[-1]:
indentStack.pop()
NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress())
NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress(), stopOn=StringEnd())
INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT')
PEER = Empty().setParseAction(checkPeerIndent).setName('')
UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT')
if indent:
smExpr = Group(Optional(NL)
+ INDENT
+ OneOrMore(PEER + Group(blockStatementExpr) + Optional(NL))
+ OneOrMore(PEER + Group(blockStatementExpr) + Optional(NL), stopOn=StringEnd())
+ UNDENT)
else:
smExpr = Group(Optional(NL)
+ OneOrMore(PEER + Group(blockStatementExpr) + Optional(NL))
+ OneOrMore(PEER + Group(blockStatementExpr) + Optional(NL), stopOn=StringEnd())
+ UNDENT)
smExpr.setFailAction(lambda a, b, c, d: reset_stack())
blockStatementExpr.ignore(_bslash + LineEnd())
@ -6822,6 +6837,187 @@ if PY_3:
setattr(pyparsing_unicode, u"देवनागरी", pyparsing_unicode.Devanagari)
class pyparsing_test:
"""
namespace class for classes useful in writing unit tests
"""
class reset_pyparsing_context:
"""
Context manager to be used when writing unit tests that modify pyparsing config values:
- packrat parsing
- default whitespace characters.
- default keyword characters
- literal string auto-conversion class
- __diag__ settings
Example:
with reset_pyparsing_context():
# test that literals used to construct a grammar are automatically suppressed
ParserElement.inlineLiteralsUsing(Suppress)
term = Word(alphas) | Word(nums)
group = Group('(' + term[...] + ')')
# assert that the '()' characters are not included in the parsed tokens
self.assertParseAndCheckLisst(group, "(abc 123 def)", ['abc', '123', 'def'])
# after exiting context manager, literals are converted to Literal expressions again
"""
def __init__(self):
self._save_context = {}
def save(self):
self._save_context["default_whitespace"] = ParserElement.DEFAULT_WHITE_CHARS
self._save_context["default_keyword_chars"] = Keyword.DEFAULT_KEYWORD_CHARS
self._save_context[
"literal_string_class"
] = ParserElement._literalStringClass
self._save_context["packrat_enabled"] = ParserElement._packratEnabled
self._save_context["packrat_parse"] = ParserElement._parse
self._save_context["__diag__"] = {
name: getattr(__diag__, name) for name in __diag__._all_names
}
self._save_context["__compat__"] = {
"collect_all_And_tokens": __compat__.collect_all_And_tokens
}
return self
def restore(self):
# reset pyparsing global state
if (
ParserElement.DEFAULT_WHITE_CHARS
!= self._save_context["default_whitespace"]
):
ParserElement.setDefaultWhitespaceChars(
self._save_context["default_whitespace"]
)
Keyword.DEFAULT_KEYWORD_CHARS = self._save_context["default_keyword_chars"]
ParserElement.inlineLiteralsUsing(
self._save_context["literal_string_class"]
)
for name, value in self._save_context["__diag__"].items():
setattr(__diag__, name, value)
ParserElement._packratEnabled = self._save_context["packrat_enabled"]
ParserElement._parse = self._save_context["packrat_parse"]
__compat__.collect_all_And_tokens = self._save_context["__compat__"]
def __enter__(self):
return self.save()
def __exit__(self, *args):
return self.restore()
class TestParseResultsAsserts:
"""
A mixin class to add parse results assertion methods to normal unittest.TestCase classes.
"""
def assertParseResultsEquals(
self, result, expected_list=None, expected_dict=None, msg=None
):
"""
Unit test assertion to compare a ParseResults object with an optional expected_list,
and compare any defined results names with an optional expected_dict.
"""
if expected_list is not None:
self.assertEqual(expected_list, result.asList(), msg=msg)
if expected_dict is not None:
self.assertEqual(expected_dict, result.asDict(), msg=msg)
def assertParseAndCheckList(
self, expr, test_string, expected_list, msg=None, verbose=True
):
"""
Convenience wrapper assert to test a parser element and input string, and assert that
the resulting ParseResults.asList() is equal to the expected_list.
"""
result = expr.parseString(test_string, parseAll=True)
if verbose:
print(result.dump())
self.assertParseResultsEquals(result, expected_list=expected_list, msg=msg)
def assertParseAndCheckDict(
self, expr, test_string, expected_dict, msg=None, verbose=True
):
"""
Convenience wrapper assert to test a parser element and input string, and assert that
the resulting ParseResults.asDict() is equal to the expected_dict.
"""
result = expr.parseString(test_string, parseAll=True)
if verbose:
print(result.dump())
self.assertParseResultsEquals(result, expected_dict=expected_dict, msg=msg)
def assertRunTestResults(
self, run_tests_report, expected_parse_results=None, msg=None
):
"""
Unit test assertion to evaluate output of ParserElement.runTests(). If a list of
list-dict tuples is given as the expected_parse_results argument, then these are zipped
with the report tuples returned by runTests and evaluated using assertParseResultsEquals.
Finally, asserts that the overall runTests() success value is True.
:param run_tests_report: tuple(bool, [tuple(str, ParseResults or Exception)]) returned from runTests
:param expected_parse_results (optional): [tuple(str, list, dict, Exception)]
"""
run_test_success, run_test_results = run_tests_report
if expected_parse_results is not None:
merged = [
(rpt[0], rpt[1], expected)
for rpt, expected in zip(run_test_results, expected_parse_results)
]
for test_string, result, expected in merged:
# expected should be a tuple containing a list and/or a dict or an exception,
# and optional failure message string
# an empty tuple will skip any result validation
fail_msg = next(
(exp for exp in expected if isinstance(exp, str)), None
)
expected_exception = next(
(
exp
for exp in expected
if isinstance(exp, type) and issubclass(exp, Exception)
),
None,
)
if expected_exception is not None:
with self.assertRaises(
expected_exception=expected_exception, msg=fail_msg or msg
):
if isinstance(result, Exception):
raise result
else:
expected_list = next(
(exp for exp in expected if isinstance(exp, list)), None
)
expected_dict = next(
(exp for exp in expected if isinstance(exp, dict)), None
)
if (expected_list, expected_dict) != (None, None):
self.assertParseResultsEquals(
result,
expected_list=expected_list,
expected_dict=expected_dict,
msg=fail_msg or msg,
)
else:
# warning here maybe?
print("no validation for {!r}".format(test_string))
# do this last, in case some specific test results can be reported instead
self.assertTrue(
run_test_success, msg=msg if msg is not None else "failed runTests"
)
@contextmanager
def assertRaisesParseException(self, exc_type=ParseException, msg=None):
with self.assertRaises(exc_type, msg=msg):
yield
if __name__ == "__main__":
selectToken = CaselessLiteral("select")

View File

@ -1,4 +1,4 @@
Copyright (c) 2010-2018 Benjamin Peterson
Copyright (c) 2010-2020 Benjamin Peterson
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in

View File

@ -1,4 +1,4 @@
# Copyright (c) 2010-2018 Benjamin Peterson
# Copyright (c) 2010-2020 Benjamin Peterson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@ -29,7 +29,7 @@ import sys
import types
__author__ = "Benjamin Peterson <benjamin@python.org>"
__version__ = "1.12.0"
__version__ = "1.14.0"
# Useful for very coarse version differentiation.
@ -255,9 +255,11 @@ _moved_attributes = [
MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
MovedModule("builtins", "__builtin__"),
MovedModule("configparser", "ConfigParser"),
MovedModule("collections_abc", "collections", "collections.abc" if sys.version_info >= (3, 3) else "collections"),
MovedModule("copyreg", "copy_reg"),
MovedModule("dbm_gnu", "gdbm", "dbm.gnu"),
MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"),
MovedModule("dbm_ndbm", "dbm", "dbm.ndbm"),
MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread" if sys.version_info < (3, 9) else "_thread"),
MovedModule("http_cookiejar", "cookielib", "http.cookiejar"),
MovedModule("http_cookies", "Cookie", "http.cookies"),
MovedModule("html_entities", "htmlentitydefs", "html.entities"),
@ -637,13 +639,16 @@ if PY3:
import io
StringIO = io.StringIO
BytesIO = io.BytesIO
del io
_assertCountEqual = "assertCountEqual"
if sys.version_info[1] <= 1:
_assertRaisesRegex = "assertRaisesRegexp"
_assertRegex = "assertRegexpMatches"
_assertNotRegex = "assertNotRegexpMatches"
else:
_assertRaisesRegex = "assertRaisesRegex"
_assertRegex = "assertRegex"
_assertNotRegex = "assertNotRegex"
else:
def b(s):
return s
@ -665,6 +670,7 @@ else:
_assertCountEqual = "assertItemsEqual"
_assertRaisesRegex = "assertRaisesRegexp"
_assertRegex = "assertRegexpMatches"
_assertNotRegex = "assertNotRegexpMatches"
_add_doc(b, """Byte literal""")
_add_doc(u, """Text literal""")
@ -681,6 +687,10 @@ def assertRegex(self, *args, **kwargs):
return getattr(self, _assertRegex)(*args, **kwargs)
def assertNotRegex(self, *args, **kwargs):
return getattr(self, _assertNotRegex)(*args, **kwargs)
if PY3:
exec_ = getattr(moves.builtins, "exec")
@ -716,16 +726,7 @@ else:
""")
if sys.version_info[:2] == (3, 2):
exec_("""def raise_from(value, from_value):
try:
if from_value is None:
raise value
raise value from from_value
finally:
value = None
""")
elif sys.version_info[:2] > (3, 2):
if sys.version_info[:2] > (3,):
exec_("""def raise_from(value, from_value):
try:
raise value from from_value
@ -805,13 +806,33 @@ if sys.version_info[:2] < (3, 3):
_add_doc(reraise, """Reraise an exception.""")
if sys.version_info[0:2] < (3, 4):
# This does exactly the same what the :func:`py3:functools.update_wrapper`
# function does on Python versions after 3.2. It sets the ``__wrapped__``
# attribute on ``wrapper`` object and it doesn't raise an error if any of
# the attributes mentioned in ``assigned`` and ``updated`` are missing on
# ``wrapped`` object.
def _update_wrapper(wrapper, wrapped,
assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES):
for attr in assigned:
try:
value = getattr(wrapped, attr)
except AttributeError:
continue
else:
setattr(wrapper, attr, value)
for attr in updated:
getattr(wrapper, attr).update(getattr(wrapped, attr, {}))
wrapper.__wrapped__ = wrapped
return wrapper
_update_wrapper.__doc__ = functools.update_wrapper.__doc__
def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS,
updated=functools.WRAPPER_UPDATES):
def wrapper(f):
f = functools.wraps(wrapped, assigned, updated)(f)
f.__wrapped__ = wrapped
return f
return wrapper
return functools.partial(_update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
wraps.__doc__ = functools.wraps.__doc__
else:
wraps = functools.wraps
@ -824,7 +845,15 @@ def with_metaclass(meta, *bases):
class metaclass(type):
def __new__(cls, name, this_bases, d):
return meta(name, bases, d)
if sys.version_info[:2] >= (3, 7):
# This version introduced PEP 560 that requires a bit
# of extra care (we mimic what is done by __build_class__).
resolved_bases = types.resolve_bases(bases)
if resolved_bases is not bases:
d['__orig_bases__'] = bases
else:
resolved_bases = bases
return meta(name, resolved_bases, d)
@classmethod
def __prepare__(cls, name, this_bases):
@ -908,10 +937,9 @@ def ensure_text(s, encoding='utf-8', errors='strict'):
raise TypeError("not expecting type '%s'" % type(s))
def python_2_unicode_compatible(klass):
"""
A decorator that defines __unicode__ and __str__ methods under Python 2.
A class decorator that defines __unicode__ and __str__ methods under Python 2.
Under Python 3 it does nothing.
To support Python 2 and 3 with a single code base, define a __str__ method

View File

@ -22,7 +22,7 @@ from logging import NullHandler
__author__ = "Andrey Petrov (andrey.petrov@shazow.net)"
__license__ = "MIT"
__version__ = "1.25.6"
__version__ = "1.25.7"
__all__ = (
"HTTPConnectionPool",

View File

@ -412,7 +412,7 @@ class VerifiedHTTPSConnection(HTTPSConnection):
(
"Certificate for {0} has no `subjectAltName`, falling back to check for a "
"`commonName` for now. This feature is being removed by major browsers and "
"deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 "
"deprecated by RFC 2818. (See https://github.com/urllib3/urllib3/issues/497 "
"for details.)".format(hostname)
),
SubjectAltNameWarning,
@ -430,7 +430,7 @@ def _match_hostname(cert, asserted_hostname):
match_hostname(cert, asserted_hostname)
except CertificateError as e:
log.warning(
"Certificate did not match expected hostname: %s. " "Certificate: %s",
"Certificate did not match expected hostname: %s. Certificate: %s",
asserted_hostname,
cert,
)

View File

@ -257,7 +257,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
if self.block:
raise EmptyPoolError(
self,
"Pool reached maximum size and no more " "connections are allowed.",
"Pool reached maximum size and no more connections are allowed.",
)
pass # Oh well, we'll create a new connection then
@ -626,7 +626,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
#
# See issue #651 [1] for details.
#
# [1] <https://github.com/shazow/urllib3/issues/651>
# [1] <https://github.com/urllib3/urllib3/issues/651>
release_this_conn = release_conn
# Merge the proxy headers. Only do this in HTTP. We have to copy the
@ -742,10 +742,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
if not conn:
# Try again
log.warning(
"Retrying (%r) after connection " "broken by '%r': %s",
retries,
err,
url,
"Retrying (%r) after connection broken by '%r': %s", retries, err, url
)
return self.urlopen(
method,
@ -758,6 +755,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
timeout=timeout,
pool_timeout=pool_timeout,
release_conn=release_conn,
chunked=chunked,
body_pos=body_pos,
**response_kw
)
@ -809,6 +807,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
timeout=timeout,
pool_timeout=pool_timeout,
release_conn=release_conn,
chunked=chunked,
body_pos=body_pos,
**response_kw
)
@ -842,6 +841,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
timeout=timeout,
pool_timeout=pool_timeout,
release_conn=release_conn,
chunked=chunked,
body_pos=body_pos,
**response_kw
)
@ -961,7 +961,7 @@ class HTTPSConnectionPool(HTTPConnectionPool):
if not self.ConnectionCls or self.ConnectionCls is DummyConnection:
raise SSLError(
"Can't connect to HTTPS URL because the SSL " "module is not available."
"Can't connect to HTTPS URL because the SSL module is not available."
)
actual_host = self.host

View File

@ -6,27 +6,31 @@ import os
def is_appengine():
return is_local_appengine() or is_prod_appengine() or is_prod_appengine_mvms()
return "APPENGINE_RUNTIME" in os.environ
def is_appengine_sandbox():
return is_appengine() and not is_prod_appengine_mvms()
"""Reports if the app is running in the first generation sandbox.
The second generation runtimes are technically still in a sandbox, but it
is much less restrictive, so generally you shouldn't need to check for it.
see https://cloud.google.com/appengine/docs/standard/runtimes
"""
return is_appengine() and os.environ["APPENGINE_RUNTIME"] == "python27"
def is_local_appengine():
return (
"APPENGINE_RUNTIME" in os.environ
and "Development/" in os.environ["SERVER_SOFTWARE"]
return is_appengine() and os.environ.get("SERVER_SOFTWARE", "").startswith(
"Development/"
)
def is_prod_appengine():
return (
"APPENGINE_RUNTIME" in os.environ
and "Google App Engine/" in os.environ["SERVER_SOFTWARE"]
and not is_prod_appengine_mvms()
return is_appengine() and os.environ.get("SERVER_SOFTWARE", "").startswith(
"Google App Engine/"
)
def is_prod_appengine_mvms():
return os.environ.get("GAE_VM", False) == "true"
"""Deprecated."""
return False

View File

@ -415,6 +415,7 @@ class SecurityConst(object):
kTLSProtocol1 = 4
kTLSProtocol11 = 7
kTLSProtocol12 = 8
# SecureTransport does not support TLS 1.3 even if there's a constant for it
kTLSProtocol13 = 10
kTLSProtocolMaxSupported = 999

View File

@ -108,13 +108,6 @@ class AppEngineManager(RequestMethods):
"URLFetch is not available in this environment."
)
if is_prod_appengine_mvms():
raise AppEnginePlatformError(
"Use normal urllib3.PoolManager instead of AppEngineManager"
"on Managed VMs, as using URLFetch is not necessary in "
"this environment."
)
warnings.warn(
"urllib3 is using URLFetch on Google App Engine sandbox instead "
"of sockets. To use sockets directly instead of URLFetch see "

View File

@ -96,9 +96,7 @@ class NTLMConnectionPool(HTTPSConnectionPool):
log.debug("Response data: %s [...]", res.read()[:100])
if res.status != 200:
if res.status == 401:
raise Exception(
"Server rejected request: wrong " "username or password"
)
raise Exception("Server rejected request: wrong username or password")
raise Exception("Wrong server response: %s %s" % (res.status, res.reason))
res.fp = None

View File

@ -144,13 +144,10 @@ CIPHER_SUITES = [
]
# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of
# TLSv1 and a high of TLSv1.3. For everything else, we pin to that version.
# TLSv1 to 1.2 are supported on macOS 10.8+ and TLSv1.3 is macOS 10.13+
# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version.
# TLSv1 to 1.2 are supported on macOS 10.8+
_protocol_to_min_max = {
util.PROTOCOL_TLS: (
SecurityConst.kTLSProtocol1,
SecurityConst.kTLSProtocolMaxSupported,
)
util.PROTOCOL_TLS: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12)
}
if hasattr(ssl, "PROTOCOL_SSLv2"):
@ -488,15 +485,7 @@ class WrappedSocket(object):
result = Security.SSLSetProtocolVersionMin(self.context, min_version)
_assert_no_error(result)
# TLS 1.3 isn't necessarily enabled by the OS
# so we have to detect when we error out and try
# setting TLS 1.3 if it's allowed. kTLSProtocolMaxSupported
# was added in macOS 10.13 along with kTLSProtocol13.
result = Security.SSLSetProtocolVersionMax(self.context, max_version)
if result != 0 and max_version == SecurityConst.kTLSProtocolMaxSupported:
result = Security.SSLSetProtocolVersionMax(
self.context, SecurityConst.kTLSProtocol12
)
_assert_no_error(result)
# If there's a trust DB, we need to use it. We do that by telling
@ -707,7 +696,7 @@ class WrappedSocket(object):
)
_assert_no_error(result)
if protocol.value == SecurityConst.kTLSProtocol13:
return "TLSv1.3"
raise ssl.SSLError("SecureTransport does not support TLS 1.3")
elif protocol.value == SecurityConst.kTLSProtocol12:
return "TLSv1.2"
elif protocol.value == SecurityConst.kTLSProtocol11:

View File

@ -222,7 +222,7 @@ class IncompleteRead(HTTPError, httplib_IncompleteRead):
super(IncompleteRead, self).__init__(partial, expected)
def __repr__(self):
return "IncompleteRead(%i bytes read, " "%i more expected)" % (
return "IncompleteRead(%i bytes read, %i more expected)" % (
self.partial,
self.expected,
)

View File

@ -153,10 +153,8 @@ def match_hostname(cert, hostname):
"doesn't match either of %s" % (hostname, ", ".join(map(repr, dnsnames)))
)
elif len(dnsnames) == 1:
raise CertificateError(
"hostname %r " "doesn't match %r" % (hostname, dnsnames[0])
)
raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0]))
else:
raise CertificateError(
"no appropriate commonName or " "subjectAltName fields were found"
"no appropriate commonName or subjectAltName fields were found"
)

View File

@ -121,7 +121,7 @@ def _has_ipv6(host):
# has_ipv6 returns true if cPython was compiled with IPv6 support.
# It does not tell us if the system has IPv6 support enabled. To
# determine that we must bind to an IPv6 address.
# https://github.com/shazow/urllib3/pull/611
# https://github.com/urllib3/urllib3/pull/611
# https://bugs.python.org/issue658327
try:
sock = socket.socket(socket.AF_INET6)

View File

@ -122,7 +122,7 @@ def rewind_body(body, body_pos):
body_seek(body_pos)
except (IOError, OSError):
raise UnrewindableBodyError(
"An error occurred when rewinding request " "body for redirect/retry."
"An error occurred when rewinding request body for redirect/retry."
)
elif body_pos is _FAILEDTELL:
raise UnrewindableBodyError(
@ -131,5 +131,5 @@ def rewind_body(body, body_pos):
)
else:
raise ValueError(
"body_pos must be of type integer, " "instead it was %s." % type(body_pos)
"body_pos must be of type integer, instead it was %s." % type(body_pos)
)

View File

@ -203,7 +203,7 @@ class Timeout(object):
"""
if self._start_connect is None:
raise TimeoutStateError(
"Can't get connect duration for timer " "that has not started."
"Can't get connect duration for timer that has not started."
)
return current_time() - self._start_connect

View File

@ -55,7 +55,7 @@ IPV6_PAT = "(?:" + "|".join([x % _subs for x in _variations]) + ")"
ZONE_ID_PAT = "(?:%25|%)(?:[" + UNRESERVED_PAT + "]|%[a-fA-F0-9]{2})+"
IPV6_ADDRZ_PAT = r"\[" + IPV6_PAT + r"(?:" + ZONE_ID_PAT + r")?\]"
REG_NAME_PAT = r"(?:[^\[\]%:/?#]|%[a-fA-F0-9]{2})*"
TARGET_RE = re.compile(r"^(/[^?]*)(?:\?([^#]+))?(?:#(.*))?$")
TARGET_RE = re.compile(r"^(/[^?#]*)(?:\?([^#]*))?(?:#.*)?$")
IPV4_RE = re.compile("^" + IPV4_PAT + "$")
IPV6_RE = re.compile("^" + IPV6_PAT + "$")
@ -325,14 +325,11 @@ def _encode_target(target):
if not target.startswith("/"):
return target
path, query, fragment = TARGET_RE.match(target).groups()
path, query = TARGET_RE.match(target).groups()
target = _encode_invalid_chars(path, PATH_CHARS)
query = _encode_invalid_chars(query, QUERY_CHARS)
fragment = _encode_invalid_chars(fragment, FRAGMENT_CHARS)
if query is not None:
target += "?" + query
if fragment is not None:
target += "#" + target
return target

View File

@ -1,23 +1,23 @@
appdirs==1.4.3
CacheControl==0.12.5
colorama==0.4.1
CacheControl==0.12.6
colorama==0.4.3
contextlib2==0.6.0
distlib==0.2.9.post0
distlib==0.3.0
distro==1.4.0
html5lib==1.0.1
ipaddress==1.0.22 # Only needed on 2.6 and 2.7
ipaddress==1.0.23 # Only needed on 2.6 and 2.7
msgpack==0.6.2
packaging==20.0
pep517==0.7.0
progress==1.5
pyparsing==2.4.2
pyparsing==2.4.6
pytoml==0.1.21
requests==2.22.0
certifi==2019.9.11
certifi==2019.11.28
chardet==3.0.4
idna==2.8
urllib3==1.25.6
urllib3==1.25.7
retrying==1.3.3
setuptools==41.4.0
six==1.12.0
setuptools==44.0.0
six==1.14.0
webencodings==0.5.1