From 4fd512859b234179879cd9a213bd6288363ff26f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 15:31:22 -0500 Subject: [PATCH 01/10] Address EncodingWarning in ccompiler. Ref pypa/distutils#232. --- distutils/ccompiler.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/distutils/ccompiler.py b/distutils/ccompiler.py index 6faf546c..bcf9580c 100644 --- a/distutils/ccompiler.py +++ b/distutils/ccompiler.py @@ -858,8 +858,7 @@ def has_function( # noqa: C901 if library_dirs is None: library_dirs = [] fd, fname = tempfile.mkstemp(".c", funcname, text=True) - f = os.fdopen(fd, "w") - try: + with os.fdopen(fd, "w", encoding='utf-8') as f: for incl in includes: f.write("""#include "%s"\n""" % incl) if not includes: @@ -888,8 +887,7 @@ def has_function( # noqa: C901 """ % funcname ) - finally: - f.close() + try: objects = self.compile([fname], include_dirs=include_dirs) except CompileError: From 03ec237712b26d926362a349f837f9cc65e3b547 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 15:38:01 -0500 Subject: [PATCH 02/10] Fix EncodingWarnings in distutils/command/config.py. Ref pypa/distutils#232. --- distutils/command/config.py | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/distutils/command/config.py b/distutils/command/config.py index 494d97d1..573741d7 100644 --- a/distutils/command/config.py +++ b/distutils/command/config.py @@ -10,6 +10,7 @@ """ import os +import pathlib import re from ..core import Command @@ -102,7 +103,7 @@ def _check_compiler(self): def _gen_temp_sourcefile(self, body, headers, lang): filename = "_configtest" + LANG_EXT[lang] - with open(filename, "w") as file: + with open(filename, "w", encoding='utf-8') as file: if headers: for header in headers: file.write("#include <%s>\n" % header) @@ -199,15 +200,8 @@ def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, lang=" if isinstance(pattern, str): pattern = re.compile(pattern) - with open(out) as file: - match = False - while True: - line = file.readline() - if line == '': - break - if pattern.search(line): - match = True - break + with open(out, encoding='utf-8') as file: + match = any(pattern.search(line) for line in file) self._clean() return match @@ -369,8 +363,4 @@ def dump_file(filename, head=None): log.info('%s', filename) else: log.info(head) - file = open(filename) - try: - log.info(file.read()) - finally: - file.close() + log.info(pathlib.Path(filename).read_text(encoding='utf-8')) From b894d6f341b626b289c4d50dc00909606d1bd164 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 15:40:06 -0500 Subject: [PATCH 03/10] Fix EncodingWarnings in distutils/config.py. Ref pypa/distutils#232. --- distutils/config.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/distutils/config.py b/distutils/config.py index a55951ed..f92ecb96 100644 --- a/distutils/config.py +++ b/distutils/config.py @@ -42,7 +42,8 @@ def _get_rc_file(self): def _store_pypirc(self, username, password): """Creates a default .pypirc file.""" rc = self._get_rc_file() - with os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f: + raw = os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600) + with os.fdopen(raw, 'w', encoding='utf-8') as f: f.write(DEFAULT_PYPIRC % (username, password)) def _read_pypirc(self): # noqa: C901 @@ -53,7 +54,7 @@ def _read_pypirc(self): # noqa: C901 repository = self.repository or self.DEFAULT_REPOSITORY config = RawConfigParser() - config.read(rc) + config.read(rc, encoding='utf-8') sections = config.sections() if 'distutils' in sections: # let's get the list of servers From f0692cf4ccdec21debcfef57202f4af97043f135 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 15:47:35 -0500 Subject: [PATCH 04/10] Fix EncodingWarnings in sdist.py. Ref pypa/distutils#232. --- distutils/command/sdist.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/distutils/command/sdist.py b/distutils/command/sdist.py index ac489726..b76cb9bc 100644 --- a/distutils/command/sdist.py +++ b/distutils/command/sdist.py @@ -6,6 +6,7 @@ import sys from glob import glob from warnings import warn +from itertools import filterfalse from ..core import Command from distutils import dir_util @@ -429,11 +430,8 @@ def _manifest_is_not_generated(self): if not os.path.isfile(self.manifest): return False - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() + with open(self.manifest, encoding='utf-8') as fp: + first_line = next(fp) return first_line != '# file GENERATED by distutils, do NOT edit\n' def read_manifest(self): @@ -442,13 +440,11 @@ def read_manifest(self): distribution. """ log.info("reading manifest file '%s'", self.manifest) - with open(self.manifest) as manifest: - for line in manifest: + with open(self.manifest, encoding='utf-8') as lines: + self.filelist.extend( # ignore comments and blank lines - line = line.strip() - if line.startswith('#') or not line: - continue - self.filelist.append(line) + filter(None, filterfalse(is_comment, map(str.strip, lines))) + ) def make_release_tree(self, base_dir, files): """Create the directory tree that will become the source @@ -528,3 +524,7 @@ def get_archive_files(self): was run, or None if the command hasn't run yet. """ return self.archive_files + + +def is_comment(line): + return line.startswith('#') From b420f2dd8ed44251faa2880e791c113f8ea7823c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 15:49:07 -0500 Subject: [PATCH 05/10] Fix EncodingWarnings in text_file.py. Ref pypa/distutils#232. --- distutils/text_file.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distutils/text_file.py b/distutils/text_file.py index 36f947e5..6f90cfe2 100644 --- a/distutils/text_file.py +++ b/distutils/text_file.py @@ -115,7 +115,7 @@ def open(self, filename): """Open a new file named 'filename'. This overrides both the 'filename' and 'file' arguments to the constructor.""" self.filename = filename - self.file = open(self.filename, errors=self.errors) + self.file = open(self.filename, errors=self.errors, encoding='utf-8') self.current_line = 0 def close(self): From 559a4f355fadc8017a9ebdf31afed06ce4e03445 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 15:50:06 -0500 Subject: [PATCH 06/10] Fix EncodingWarnings in dist.py. Ref pypa/distutils#232. --- distutils/dist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/distutils/dist.py b/distutils/dist.py index 65958394..c4d2a45d 100644 --- a/distutils/dist.py +++ b/distutils/dist.py @@ -395,7 +395,7 @@ def parse_config_files(self, filenames=None): # noqa: C901 for filename in filenames: if DEBUG: self.announce(" reading %s" % filename) - parser.read(filename) + parser.read(filename, encoding='utf-8') for section in parser.sections(): options = parser.options(section) opt_dict = self.get_option_dict(section) From 61d103fba380d5e56a4081b11a6680a4a0ba319a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 15:59:16 -0500 Subject: [PATCH 07/10] Fix EncodingWarning in cygwinccompiler. Ref pypa/distutils#232. --- distutils/cygwinccompiler.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/distutils/cygwinccompiler.py b/distutils/cygwinccompiler.py index 84151b7e..20609504 100644 --- a/distutils/cygwinccompiler.py +++ b/distutils/cygwinccompiler.py @@ -7,6 +7,7 @@ """ import os +import pathlib import re import sys import copy @@ -329,14 +330,15 @@ def check_config_h(): # let's see if __GNUC__ is mentioned in python.h fn = sysconfig.get_config_h_filename() try: - config_h = open(fn) - try: - if "__GNUC__" in config_h.read(): - return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn - else: - return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn - finally: - config_h.close() + config_h = pathlib.Path(fn).read_text(encoding='utf-8') + substring = '__GNUC__' + if substring in config_h: + code = CONFIG_H_OK + mention_inflected = 'mentions' + else: + code = CONFIG_H_NOTOK + mention_inflected = 'does not mention' + return code, f"{fn!r} {mention_inflected} {substring!r}" except OSError as exc: return (CONFIG_H_UNCERTAIN, f"couldn't read '{fn}': {exc.strerror}") From 2b93ccc7e3b7561ef90bac952f52de33ad46735e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 16:06:30 -0500 Subject: [PATCH 08/10] Fix EncodingWarning in file_util. Ref pypa/distutils#232. --- distutils/file_util.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/distutils/file_util.py b/distutils/file_util.py index 8ebd2a79..0eb9b861 100644 --- a/distutils/file_util.py +++ b/distutils/file_util.py @@ -230,9 +230,5 @@ def write_file(filename, contents): """Create a file with the specified name and write 'contents' (a sequence of strings without line terminators) to it. """ - f = open(filename, "w") - try: - for line in contents: - f.write(line + "\n") - finally: - f.close() + with open(filename, 'w', encoding='utf-8') as f: + f.writelines(line + '\n' for line in contents) From 9508489953a84a1412ad24e6613650351369462c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 16:10:53 -0500 Subject: [PATCH 09/10] Suppress EncodingWarnings in pyfakefs. Ref pypa/distutils#232. Workaround for pytest-dev/pyfakefs#957. --- pytest.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pytest.ini b/pytest.ini index 3ee2f886..42820fc7 100644 --- a/pytest.ini +++ b/pytest.ini @@ -34,3 +34,7 @@ filterwarnings= # suppress well know deprecation warning ignore:distutils.log.Log is deprecated + + # pytest-dev/pyfakefs#957 + ignore:UTF-8 Mode affects locale.getpreferredencoding::pyfakefs.fake_file + ignore:'encoding' argument not specified::pyfakefs.helpers From 57d567de0ab8798d418e0b2e48d4048bb86713b8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 2 Mar 2024 16:19:04 -0500 Subject: [PATCH 10/10] Replaced deprecated cgi module with email module. Ref pypa/distutils#232. --- distutils/config.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/distutils/config.py b/distutils/config.py index f92ecb96..e0defd77 100644 --- a/distutils/config.py +++ b/distutils/config.py @@ -5,6 +5,7 @@ """ import os +import email.message from configparser import RawConfigParser from .cmd import Command @@ -121,11 +122,8 @@ def _read_pypirc(self): # noqa: C901 def _read_pypi_response(self, response): """Read and decode a PyPI HTTP response.""" - import cgi - content_type = response.getheader('content-type', 'text/plain') - encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii') - return response.read().decode(encoding) + return response.read().decode(_extract_encoding(content_type)) def initialize_options(self): """Initialize options.""" @@ -139,3 +137,15 @@ def finalize_options(self): self.repository = self.DEFAULT_REPOSITORY if self.realm is None: self.realm = self.DEFAULT_REALM + + +def _extract_encoding(content_type): + """ + >>> _extract_encoding('text/plain') + 'ascii' + >>> _extract_encoding('text/html; charset="utf8"') + 'utf8' + """ + msg = email.message.EmailMessage() + msg['content-type'] = content_type + return msg['content-type'].params.get('charset', 'ascii')