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

gh-128770: raise warnings as errors in test suite - except for test_socket which still logs warnings, and internal test warnings that are now logged #128973

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
4 changes: 2 additions & 2 deletions Lib/test/libregrtest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -642,9 +642,9 @@ def _add_ci_python_opts(self, python_opts, keep_environ):
if not sys.stdout.write_through:
python_opts.append('-u')

# Add warnings filter 'default'
# Add warnings filter 'error'
if 'default' not in sys.warnoptions:
python_opts.extend(('-W', 'default'))
python_opts.extend(('-W', 'error'))

# Error on bytes/str comparison
if sys.flags.bytes_warning < 2:
Expand Down
6 changes: 3 additions & 3 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import types
import unittest
import warnings
import logging


__all__ = [
Expand Down Expand Up @@ -387,7 +388,7 @@ def skip_if_buildbot(reason=None):
try:
isbuildbot = getpass.getuser().lower() == 'buildbot'
except (KeyError, OSError) as err:
warnings.warn(f'getpass.getuser() failed {err}.', RuntimeWarning)
logging.getLogger(__name__).warning('getpass.getuser() failed %s.', err, exc_info=err)
isbuildbot = False
return unittest.skipIf(isbuildbot, reason)

Expand Down Expand Up @@ -1066,8 +1067,7 @@ def start(self):
try:
f = open(self.procfile, 'r')
except OSError as e:
warnings.warn('/proc not available for stats: {}'.format(e),
RuntimeWarning)
logging.getLogger(__name__).warning('/proc not available for stats: %s', e, exc_info=e)
sys.stderr.flush()
return

Expand Down
23 changes: 15 additions & 8 deletions Lib/test/support/os_helper.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import collections.abc
import contextlib
import errno
Expand Down Expand Up @@ -378,8 +379,7 @@ def _waitfor(func, pathname, waitall=False):
# Increase the timeout and try again
time.sleep(timeout)
timeout *= 2
warnings.warn('tests may fail, delete still pending for ' + pathname,
RuntimeWarning, stacklevel=4)
logging.getLogger(__name__).warning('tests may fail, delete still pending for %s', pathname)
graingert marked this conversation as resolved.
Show resolved Hide resolved

def _unlink(filename):
_waitfor(os.unlink, filename)
Expand Down Expand Up @@ -494,9 +494,12 @@ def temp_dir(path=None, quiet=False):
except OSError as exc:
if not quiet:
raise
warnings.warn(f'tests may fail, unable to create '
f'temporary directory {path!r}: {exc}',
RuntimeWarning, stacklevel=3)
logger.getLogger(__name__).warning(
graingert marked this conversation as resolved.
Show resolved Hide resolved
"tests may fail, unable to create temporary directory %r: %s",
path,
exc,
exc_info=exc,
graingert marked this conversation as resolved.
Show resolved Hide resolved
)
if dir_created:
pid = os.getpid()
try:
Expand Down Expand Up @@ -527,9 +530,13 @@ def change_cwd(path, quiet=False):
except OSError as exc:
if not quiet:
raise
warnings.warn(f'tests may fail, unable to change the current working '
f'directory to {path!r}: {exc}',
RuntimeWarning, stacklevel=3)
logging.getLogger(__name__).warning(
'tests may fail, unable to change the current working directory '
'to %r: %s',
path,
exc,
exc_info=exc,
graingert marked this conversation as resolved.
Show resolved Hide resolved
)
try:
yield os.getcwd()
finally:
Expand Down
7 changes: 4 additions & 3 deletions Lib/test/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
you're working through IDLE, you can import this test module and call test()
with the corresponding argument.
"""

import logging
import math
import os, sys
import operator
Expand Down Expand Up @@ -5946,8 +5946,9 @@ def tearDownModule():
if C: C.setcontext(ORIGINAL_CONTEXT[C].copy())
P.setcontext(ORIGINAL_CONTEXT[P].copy())
if not C:
warnings.warn('C tests skipped: no module named _decimal.',
UserWarning)
logging.getLogger(__name__).warning(
'C tests skipped: no module named _decimal.'
)
if not orig_sys_decimal is sys.modules['decimal']:
raise TestFailed("Internal error: unbalanced number of changes to "
"sys.modules['decimal'].")
Expand Down
7 changes: 6 additions & 1 deletion Lib/test/test_hashlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Licensed to PSF under a Contributor Agreement.
#

import logging
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you order the import (namely put it after import itertools)? Thanks in advance.

Copy link
Contributor Author

@graingert graingert Jan 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add it as a ruff lint rule for just this file?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, we have a ruff config for tests? I think the other import statements are also sorted so I think my comment applies to other files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there's only one rule at the moment, they have to be added one at a time

import array
from binascii import unhexlify
import hashlib
Expand Down Expand Up @@ -113,7 +114,11 @@ def _conditional_import_module(self, module_name):
return importlib.import_module(module_name)
except ModuleNotFoundError as error:
if self._warn_on_extension_import and module_name in builtin_hashes:
warnings.warn(f'Did a C extension fail to compile? {error}')
logging.getLogger(__name__).warning(
'Did a C extension fail to compile? %s',
error,
exc_info=error,
)
return None

def __init__(self, *args, **kwargs):
Expand Down
5 changes: 3 additions & 2 deletions Lib/test/test_interpreters/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
from collections import namedtuple
import contextlib
import json
Expand Down Expand Up @@ -66,8 +67,8 @@ def pack_exception(exc=None):
def unpack_exception(packed):
try:
data = json.loads(packed)
except json.decoder.JSONDecodeError:
warnings.warn('incomplete exception data', RuntimeWarning)
except json.decoder.JSONDecodeError as e:
logging.getLogger(__name__).warning('incomplete exception data', exc_info=e)
print(packed if isinstance(packed, str) else packed.decode('utf-8'))
return None
exc = types.SimpleNamespace(**data)
Expand Down
6 changes: 4 additions & 2 deletions Lib/test/test_pty.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,10 @@ def test_openpty(self):
new_dim = tty.tcgetwinsize(pty.STDIN_FILENO)
self.assertEqual(new_dim, target_dim,
"pty.STDIN_FILENO window size unchanged")
except OSError:
warnings.warn("Failed to set pty.STDIN_FILENO window size.")
except OSError as e:
logging.getLogger(__name__).warning(
"Failed to set pty.STDIN_FILENO window size.", exc_info=e,
)
pass

try:
Expand Down
31 changes: 15 additions & 16 deletions Lib/test/test_pyrepl/test_pyrepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1324,22 +1324,21 @@ def test_readline_history_file(self):
if readline.backend != "editline":
self.skipTest("GNU readline is not affected by this issue")

hfile = tempfile.NamedTemporaryFile()
self.addCleanup(unlink, hfile.name)
env = os.environ.copy()
env["PYTHON_HISTORY"] = hfile.name

env["PYTHON_BASIC_REPL"] = "1"
output, exit_code = self.run_repl("spam \nexit()\n", env=env)
self.assertEqual(exit_code, 0)
self.assertIn("spam ", output)
self.assertNotEqual(pathlib.Path(hfile.name).stat().st_size, 0)
self.assertIn("spam\\040", pathlib.Path(hfile.name).read_text())

env.pop("PYTHON_BASIC_REPL", None)
output, exit_code = self.run_repl("exit\n", env=env)
self.assertEqual(exit_code, 0)
self.assertNotIn("\\040", pathlib.Path(hfile.name).read_text())
with tempfile.NamedTemporaryFile() as hfile:
env = os.environ.copy()
env["PYTHON_HISTORY"] = hfile.name

env["PYTHON_BASIC_REPL"] = "1"
output, exit_code = self.run_repl("spam \nexit()\n", env=env)
self.assertEqual(exit_code, 0)
self.assertIn("spam ", output)
self.assertNotEqual(pathlib.Path(hfile.name).stat().st_size, 0)
self.assertIn("spam\\040", pathlib.Path(hfile.name).read_text())

env.pop("PYTHON_BASIC_REPL", None)
output, exit_code = self.run_repl("exit\n", env=env)
self.assertEqual(exit_code, 0)
self.assertNotIn("\\040", pathlib.Path(hfile.name).read_text())

def test_keyboard_interrupt_after_isearch(self):
output, exit_code = self.run_repl(["\x12", "\x03", "exit"])
Expand Down
38 changes: 30 additions & 8 deletions Lib/test/test_socket.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import unittest
import warnings
from test import support
from test.support import (
is_apple, os_helper, refleak_helper, socket_helper, threading_helper
is_apple, os_helper, refleak_helper, socket_helper, threading_helper,
)
import _thread as thread
import array
Expand Down Expand Up @@ -198,6 +199,24 @@ def socket_setdefaulttimeout(timeout):
socket.setdefaulttimeout(old_timeout)


@contextlib.contextmanager
def downgrade_malformed_data_warning():
# This warning happens on macos and win, but does not always happen on linux.
if sys.platform not in {"win32", "darwin"}:
yield
return

with warnings.catch_warnings():
# TODO: gh-110012, we should investigate why this warning is happening
# and fix it properly.
warnings.filterwarnings(
action="always",
message=r"received malformed or improperly-truncated ancillary data",
category=RuntimeWarning,
)
yield


HAVE_SOCKET_CAN = _have_socket_can()

HAVE_SOCKET_CAN_ISOTP = _have_socket_can_isotp()
Expand Down Expand Up @@ -3946,8 +3965,9 @@ def checkTruncatedArray(self, ancbuf, maxdata, mindata=0):
# mindata and maxdata bytes when received with buffer size
# ancbuf, and that any complete file descriptor numbers are
# valid.
msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock,
len(MSG), ancbuf)
with downgrade_malformed_data_warning(): # TODO: gh-110012
msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock,
len(MSG), ancbuf)
self.assertEqual(msg, MSG)
self.checkRecvmsgAddress(addr, self.cli_addr)
self.checkFlags(flags, eor=True, checkset=socket.MSG_CTRUNC)
Expand Down Expand Up @@ -4298,8 +4318,9 @@ def testSingleCmsgTruncInData(self):
self.serv_sock.setsockopt(socket.IPPROTO_IPV6,
socket.IPV6_RECVHOPLIMIT, 1)
self.misc_event.set()
msg, ancdata, flags, addr = self.doRecvmsg(
self.serv_sock, len(MSG), socket.CMSG_LEN(SIZEOF_INT) - 1)
with downgrade_malformed_data_warning(): # TODO: gh-110012
msg, ancdata, flags, addr = self.doRecvmsg(
self.serv_sock, len(MSG), socket.CMSG_LEN(SIZEOF_INT) - 1)

self.assertEqual(msg, MSG)
self.checkRecvmsgAddress(addr, self.cli_addr)
Expand Down Expand Up @@ -4402,9 +4423,10 @@ def testSecondCmsgTruncInData(self):
self.serv_sock.setsockopt(socket.IPPROTO_IPV6,
socket.IPV6_RECVTCLASS, 1)
self.misc_event.set()
msg, ancdata, flags, addr = self.doRecvmsg(
self.serv_sock, len(MSG),
socket.CMSG_SPACE(SIZEOF_INT) + socket.CMSG_LEN(SIZEOF_INT) - 1)
with downgrade_malformed_data_warning(): # TODO: gh-110012
msg, ancdata, flags, addr = self.doRecvmsg(
self.serv_sock, len(MSG),
socket.CMSG_SPACE(SIZEOF_INT) + socket.CMSG_LEN(SIZEOF_INT) - 1)

self.assertEqual(msg, MSG)
self.checkRecvmsgAddress(addr, self.cli_addr)
Expand Down
Loading