From d8cf70ee1a954b2971a4484a0c7643191b1d74cd Mon Sep 17 00:00:00 2001 From: Ash Berlin-Taylor Date: Thu, 22 Apr 2021 09:31:30 +0100 Subject: [PATCH] fixup! Switch LGPL'd chardet for MIT licensed charset_normalizer --- HISTORY.md | 5 +++-- requests/__init__.py | 32 +++++++++++++++++++++++--------- requests/packages.py | 14 +++++++++++--- setup.py | 3 ++- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d31dbe05a4..f7dea52f27 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -8,8 +8,9 @@ dev **Dependencies** -- Switch chardet for the MIT-licensed charset_normalizer to remove license - ambiguity for projects bundling requests. +- Switch chardet for the MIT-licensed charset_normalizer for Python3 to remove license + ambiguity for projects bundling requests. Python2 still depends upon the + LGPL'd module. 2.25.1 (2020-12-16) ------------------- diff --git a/requests/__init__.py b/requests/__init__.py index 9085319cc2..5bdf88b812 100644 --- a/requests/__init__.py +++ b/requests/__init__.py @@ -41,12 +41,20 @@ """ import urllib3 -import charset_normalizer import warnings from .exceptions import RequestsDependencyWarning +try: + from charset_normalizer import __version__ as charset_normalizer_version +except ImportError: + charset_normalizer_version = None + +try: + from chardet import __version__ as chardet_version +except ImportError: + chardet_version = None -def check_compatibility(urllib3_version, charset_normalizer_version): +def check_compatibility(urllib3_version, chardet_version, charset_normalizer_version): urllib3_version = urllib3_version.split('.') assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. @@ -63,10 +71,16 @@ def check_compatibility(urllib3_version, charset_normalizer_version): assert minor <= 26 # Check charset_normalizer for compatibility. - major, minor, patch = charset_normalizer_version.split('.')[:3] - major, minor, patch = int(major), int(minor), int(patch) - # charset_normalizer >= 3.0.2, < 5.0.0 - assert (1, 3, 5) <= (major, minor, patch) < (2, 0, 0) + if chardet_version: + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet_version >= 3.0.2, < 5.0.0 + assert (3, 0, 2) <= (major, minor, patch) < (5, 0, 0) + else: + major, minor, patch = charset_normalizer_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # charset_normalizer >= 1.3.5, < 2.0.0 + assert (1, 3, 5) <= (major, minor, patch) < (2, 0, 0) def _check_cryptography(cryptography_version): @@ -82,10 +96,10 @@ def _check_cryptography(cryptography_version): # Check imported dependencies for compatibility. try: - check_compatibility(urllib3.__version__, charset_normalizer.__version__) + check_compatibility(urllib3.__version__, chardet_version, charset_normalizer_version) except (AssertionError, ValueError): - warnings.warn("urllib3 ({}) or charset_normalizer ({}) doesn't match a supported " - "version!".format(urllib3.__version__, charset_normalizer.__version__), + warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported " + "version!".format(urllib3.__version__, chardet_version, charset_normalizer_version), RequestsDependencyWarning) # Attempt to enable urllib3's fallback for SNI support diff --git a/requests/packages.py b/requests/packages.py index 9da77d70dd..082b48749b 100644 --- a/requests/packages.py +++ b/requests/packages.py @@ -1,15 +1,23 @@ import sys +try: + import chardet +except ImportError: + import charset_normalizer as chardet + # This code exists for backwards compatibility reasons. # I don't like it either. Just look the other way. :) -for package, alias in (('urllib3', 'urllib3'), ('idna', 'idna'), ('charset_normalizer', 'chardet')): +for package in ('urllib3', 'idna'): locals()[package] = __import__(package) - locals()[alias] = locals()[package] # This traversal is apparently necessary such that the identities are # preserved (requests.packages.urllib3.* is urllib3.*) for mod in list(sys.modules): if mod == package or mod.startswith(package + '.'): - sys.modules['requests.packages.' + mod.replace(package, alias)] = sys.modules[mod] + sys.modules['requests.packages.' + mod] = sys.modules[mod] +target = chardet.__name__ +for mod in list(sys.modules): + if mod == target or mod.startswith(target + '.'): + sys.modules['requests.packages.' + target.replace(target, 'chardet')] = sys.modules[mod] # Kinda cool, though, right? diff --git a/setup.py b/setup.py index 3a890ae718..8416450303 100755 --- a/setup.py +++ b/setup.py @@ -41,7 +41,8 @@ def run_tests(self): packages = ['requests'] requires = [ - 'charset_normalizer>=1.3.5,<2', + 'charset_normalizer>=1.3.5,<2; python_version >= "3"', + 'chardet>=3.0.2,<5; python_version < "3"', 'idna>=2.5,<3', 'urllib3>=1.21.1,<1.27', 'certifi>=2017.4.17'