Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix remaining warnings in the suite. #236

Merged
merged 10 commits into from
Mar 2, 2024
6 changes: 2 additions & 4 deletions distutils/ccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -888,8 +887,7 @@ def has_function( # noqa: C901
"""
% funcname
)
finally:
f.close()

try:
objects = self.compile([fname], include_dirs=include_dirs)
except CompileError:
Expand Down
20 changes: 5 additions & 15 deletions distutils/command/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"""

import os
import pathlib
import re

from ..core import Command
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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'))
22 changes: 11 additions & 11 deletions distutils/command/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand All @@ -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
Expand Down Expand Up @@ -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('#')
23 changes: 17 additions & 6 deletions distutils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""

import os
import email.message
from configparser import RawConfigParser

from .cmd import Command
Expand Down Expand Up @@ -42,7 +43,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
Expand All @@ -53,7 +55,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
Expand Down Expand Up @@ -120,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."""
Expand All @@ -138,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')
18 changes: 10 additions & 8 deletions distutils/cygwinccompiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

import os
import pathlib
import re
import sys
import copy
Expand Down Expand Up @@ -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}")

Expand Down
2 changes: 1 addition & 1 deletion distutils/dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 2 additions & 6 deletions distutils/file_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
2 changes: 1 addition & 1 deletion distutils/text_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading