diff options
Diffstat (limited to 'django/utils')
| -rw-r--r-- | django/utils/autoreload.py | 8 | ||||
| -rw-r--r-- | django/utils/http.py | 74 | ||||
| -rw-r--r-- | django/utils/module_loading.py | 5 | ||||
| -rw-r--r-- | django/utils/version.py | 2 |
4 files changed, 5 insertions, 84 deletions
diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py index faa3252c71..3847252632 100644 --- a/django/utils/autoreload.py +++ b/django/utils/autoreload.py @@ -231,15 +231,11 @@ def get_child_arguments(): exe_entrypoint = py_script.with_suffix('.exe') if exe_entrypoint.exists(): # Should be executed directly, ignoring sys.executable. - # TODO: Remove str() when dropping support for PY37. - # args parameter accepts path-like on Windows from Python 3.8. - return [str(exe_entrypoint), *sys.argv[1:]] + return [exe_entrypoint, *sys.argv[1:]] script_entrypoint = py_script.with_name('%s-script.py' % py_script.name) if script_entrypoint.exists(): # Should be executed as usual. - # TODO: Remove str() when dropping support for PY37. - # args parameter accepts path-like on Windows from Python 3.8. - return [*args, str(script_entrypoint), *sys.argv[1:]] + return [*args, script_entrypoint, *sys.argv[1:]] raise RuntimeError('Script %s does not exist.' % py_script) else: args += sys.argv diff --git a/django/utils/http.py b/django/utils/http.py index 962716eb00..5397bb8190 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -7,7 +7,7 @@ from binascii import Error as BinasciiError from email.utils import formatdate from urllib.parse import ( ParseResult, SplitResult, _coerce_args, _splitnetloc, _splitparams, - scheme_chars, unquote, urlencode as original_urlencode, uses_params, + scheme_chars, urlencode as original_urlencode, uses_params, ) from django.utils.datastructures import MultiValueDict @@ -343,78 +343,6 @@ def _url_has_allowed_host_and_scheme(url, allowed_hosts, require_https=False): (not scheme or scheme in valid_schemes)) -# TODO: Remove when dropping support for PY37. -def parse_qsl( - qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', - errors='replace', max_num_fields=None, -): - """ - Return a list of key/value tuples parsed from query string. - - Backport of urllib.parse.parse_qsl() from Python 3.8. - Copyright (C) 2020 Python Software Foundation (see LICENSE.python). - - ---- - - Parse a query given as a string argument. - - Arguments: - - qs: percent-encoded query string to be parsed - - keep_blank_values: flag indicating whether blank values in - percent-encoded queries should be treated as blank strings. A - true value indicates that blanks should be retained as blank - strings. The default false value indicates that blank values - are to be ignored and treated as if they were not included. - - strict_parsing: flag indicating what to do with parsing errors. If false - (the default), errors are silently ignored. If true, errors raise a - ValueError exception. - - encoding and errors: specify how to decode percent-encoded sequences - into Unicode characters, as accepted by the bytes.decode() method. - - max_num_fields: int. If set, then throws a ValueError if there are more - than n fields read by parse_qsl(). - - Returns a list, as G-d intended. - """ - qs, _coerce_result = _coerce_args(qs) - - # If max_num_fields is defined then check that the number of fields is less - # than max_num_fields. This prevents a memory exhaustion DOS attack via - # post bodies with many fields. - if max_num_fields is not None: - num_fields = 1 + qs.count('&') + qs.count(';') - if max_num_fields < num_fields: - raise ValueError('Max number of fields exceeded') - - pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] - r = [] - for name_value in pairs: - if not name_value and not strict_parsing: - continue - nv = name_value.split('=', 1) - if len(nv) != 2: - if strict_parsing: - raise ValueError("bad query field: %r" % (name_value,)) - # Handle case of a control-name with no equal sign. - if keep_blank_values: - nv.append('') - else: - continue - if len(nv[1]) or keep_blank_values: - name = nv[0].replace('+', ' ') - name = unquote(name, encoding=encoding, errors=errors) - name = _coerce_result(name) - value = nv[1].replace('+', ' ') - value = unquote(value, encoding=encoding, errors=errors) - value = _coerce_result(value) - r.append((name, value)) - return r - - def escape_leading_slashes(url): """ If redirecting to an absolute path (two leading slashes), a slash must be diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py index df8e65098d..9f58c06856 100644 --- a/django/utils/module_loading.py +++ b/django/utils/module_loading.py @@ -72,10 +72,9 @@ def module_has_submodule(package, module_name): full_module_name = package_name + '.' + module_name try: return importlib_find(full_module_name, package_path) is not None - except (ModuleNotFoundError, AttributeError): + except ModuleNotFoundError: # When module_name is an invalid dotted path, Python raises - # ModuleNotFoundError. AttributeError is raised on PY36 (fixed in PY37) - # if the penultimate part of the path is not a package. + # ModuleNotFoundError. return False diff --git a/django/utils/version.py b/django/utils/version.py index 4b26586b36..68708df7aa 100644 --- a/django/utils/version.py +++ b/django/utils/version.py @@ -9,8 +9,6 @@ from distutils.version import LooseVersion # or later". So that third-party apps can use these values, each constant # should remain as long as the oldest supported Django version supports that # Python version. -PY36 = sys.version_info >= (3, 6) -PY37 = sys.version_info >= (3, 7) PY38 = sys.version_info >= (3, 8) PY39 = sys.version_info >= (3, 9) |
