lazily load idna library

This commit is contained in:
Moin
2017-01-17 20:34:15 +05:30
parent 580b45dd3c
commit fae3f92c34
3 changed files with 28 additions and 17 deletions
+1
View File
@@ -175,3 +175,4 @@ Patches and Suggestions
- Hussain Tamboli <hussaintamboli18@gmail.com> (`@hussaintamboli <https://github.com/hussaintamboli>`_)
- Casey Davidson (`@davidsoncasey <https://github.com/davidsoncasey>`_)
- Andrii Soldatenko (`@a_soldatenko <https://github.com/andriisoldatenko>`_)
- Moinuddin Quadri <moin18@gmail.com> (`@moin18 <https://github.com/moin18>`_)
+27 -11
View File
@@ -9,6 +9,7 @@ This module contains the primary objects that power Requests.
import collections
import datetime
import sys
# Import encoding now, to avoid implicit import later.
# Implicit import within threads may cause LookupError when standard library is in a ZIP,
@@ -21,7 +22,6 @@ from .structures import CaseInsensitiveDict
from .auth import HTTPBasicAuth
from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar
from .packages import idna
from .packages.urllib3.fields import RequestField
from .packages.urllib3.filepost import encode_multipart_formdata
from .packages.urllib3.util import parse_url
@@ -331,6 +331,22 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
if self.method is not None:
self.method = to_native_string(self.method.upper())
@staticmethod
def _get_idna_encoded_host(host):
try:
from .packages import idna
except ImportError:
# tolerate the possibility of downstream repackagers unvendoring `requests`
# For more information, read: packages/__init__.py
import idna
sys.modules['requests.packages.idna'] = idna
try:
host = idna.encode(host, uts46=True).decode('utf-8')
except idna.IDNAError:
raise UnicodeError
return host
def prepare_url(self, url, params):
"""Prepares the given HTTP URL."""
#: Accept objects that have string representations.
@@ -368,17 +384,17 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
if not host:
raise InvalidURL("Invalid URL %r: No host supplied" % url)
# In general, we want to try IDNA encoding every hostname, as that
# allows users to automatically get the correct behaviour. However,
# were quite strict about IDNA encoding, so certain valid hostnames
# may fail to encode. On failure, we verify the hostname meets a
# minimum standard of only containing ASCII characters, and not starting
# with a wildcard (*), before allowing the unencoded hostname through.
try:
host = idna.encode(host, uts46=True).decode('utf-8')
except (UnicodeError, idna.IDNAError):
if not unicode_is_ascii(host) or host.startswith(u'*'):
# In general, we want to try IDNA encoding the hostname if the string contains
# non-ASCII characters. This allows users to automatically get the correct IDNA
# behaviour. For strings containing only ASCII characters, we need to also verify
# it doesn't start with a wildcard (*), before allowing the unencoded hostname.
if not unicode_is_ascii(host):
try:
host = self._get_idna_encoded_host(host)
except UnicodeError:
raise InvalidURL('URL has an invalid label.')
elif host.startswith(u'*'):
raise InvalidURL('URL has an invalid label.')
# Carefully reconstruct the network location
netloc = auth or ''
-6
View File
@@ -34,9 +34,3 @@ try:
except ImportError:
import chardet
sys.modules['%s.chardet' % __name__] = chardet
try:
from . import idna
except ImportError:
import idna
sys.modules['%s.idna' % __name__] = idna