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:
import contextlib
import dataclasses
import functools
+import logging
import _opcode
import os
import re
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)
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
--- /dev/null
+# These are shared with test_tokenize and other test modules.
+#
+# Note: since several test cases filter out floats by looking for "e" and ".",
+# don't add hexadecimal literals that contain "e" or "E".
+VALID_UNDERSCORE_LITERALS = [
+ '0_0_0',
+ '4_2',
+ '1_0000_0000',
+ '0b1001_0100',
+ '0xffff_ffff',
+ '0o5_7_7',
+ '1_00_00.5',
+ '1_00_00.5e5',
+ '1_00_00e5_1',
+ '1e1_0',
+ '.1_4',
+ '.1_4e1',
+ '0b_0',
+ '0x_f',
+ '0o_5',
+ '1_00_00j',
+ '1_00_00.5j',
+ '1_00_00e5_1j',
+ '.1_4j',
+ '(1_2.5+3_3j)',
+ '(.5_6j)',
+]
+INVALID_UNDERSCORE_LITERALS = [
+ # Trailing underscores:
+ '0_',
+ '42_',
+ '1.4j_',
+ '0x_',
+ '0b1_',
+ '0xf_',
+ '0o5_',
+ '0 if 1_Else 1',
+ # Underscores in the base selector:
+ '0_b0',
+ '0_xf',
+ '0_o5',
+ # Old-style octal, still disallowed:
+ '0_7',
+ '09_99',
+ # Multiple consecutive underscores:
+ '4_______2',
+ '0.1__4',
+ '0.1__4j',
+ '0b1001__0100',
+ '0xffff__ffff',
+ '0x___',
+ '0o5__77',
+ '1e1__0',
+ '1e1__0j',
+ # Underscore right before a dot:
+ '1_.4',
+ '1_.4j',
+ # Underscore right after a dot:
+ '1._4',
+ '1._4j',
+ '._5',
+ '._5j',
+ # Underscore right after a sign:
+ '1.0e+_1',
+ '1.0e+_1j',
+ # Underscore right before j:
+ '1.4_j',
+ '1.4e5_j',
+ # Underscore right before e:
+ '1_e1',
+ '1.4_e1',
+ '1.4_e1j',
+ # Underscore right after e:
+ '1e_1',
+ '1.4e_1',
+ '1.4e_1j',
+ # Complex cases with parens:
+ '(1+1.5_j_)',
+ '(1+1.5_j)',
+]
import collections.abc
import contextlib
import errno
+import logging
import os
import re
import stat
# 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,
+ stack_info=True,
+ stacklevel=4,
+ )
def _unlink(filename):
_waitfor(os.unlink, filename)
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)
+ logging.getLogger(__name__).warning(
+ "tests may fail, unable to create temporary directory %r: %s",
+ path,
+ exc,
+ exc_info=exc,
+ stack_info=True,
+ stacklevel=3,
+ )
if dir_created:
pid = os.getpid()
try:
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,
+ stack_info=True,
+ stacklevel=3,
+ )
try:
yield os.getcwd()
finally:
import sys
from test import support
from test.support.testcase import ComplexesAreIdenticalMixin
-from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
- INVALID_UNDERSCORE_LITERALS)
+from test.support.numbers import (
+ VALID_UNDERSCORE_LITERALS,
+ INVALID_UNDERSCORE_LITERALS,
+)
from random import random
from math import isnan, copysign
with the corresponding argument.
"""
+import logging
import math
import os, sys
import operator
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'].")
from test import support
from test.support.testcase import FloatsAreIdenticalMixin
-from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
- INVALID_UNDERSCORE_LITERALS)
+from test.support.numbers import (
+ VALID_UNDERSCORE_LITERALS,
+ INVALID_UNDERSCORE_LITERALS,
+)
from math import isinf, isnan, copysign, ldexp
import math
import typing
from test.typinganndata import ann_module2
import test
-
-# These are shared with test_tokenize and other test modules.
-#
-# Note: since several test cases filter out floats by looking for "e" and ".",
-# don't add hexadecimal literals that contain "e" or "E".
-VALID_UNDERSCORE_LITERALS = [
- '0_0_0',
- '4_2',
- '1_0000_0000',
- '0b1001_0100',
- '0xffff_ffff',
- '0o5_7_7',
- '1_00_00.5',
- '1_00_00.5e5',
- '1_00_00e5_1',
- '1e1_0',
- '.1_4',
- '.1_4e1',
- '0b_0',
- '0x_f',
- '0o_5',
- '1_00_00j',
- '1_00_00.5j',
- '1_00_00e5_1j',
- '.1_4j',
- '(1_2.5+3_3j)',
- '(.5_6j)',
-]
-INVALID_UNDERSCORE_LITERALS = [
- # Trailing underscores:
- '0_',
- '42_',
- '1.4j_',
- '0x_',
- '0b1_',
- '0xf_',
- '0o5_',
- '0 if 1_Else 1',
- # Underscores in the base selector:
- '0_b0',
- '0_xf',
- '0_o5',
- # Old-style octal, still disallowed:
- '0_7',
- '09_99',
- # Multiple consecutive underscores:
- '4_______2',
- '0.1__4',
- '0.1__4j',
- '0b1001__0100',
- '0xffff__ffff',
- '0x___',
- '0o5__77',
- '1e1__0',
- '1e1__0j',
- # Underscore right before a dot:
- '1_.4',
- '1_.4j',
- # Underscore right after a dot:
- '1._4',
- '1._4j',
- '._5',
- '._5j',
- # Underscore right after a sign:
- '1.0e+_1',
- '1.0e+_1j',
- # Underscore right before j:
- '1.4_j',
- '1.4e5_j',
- # Underscore right before e:
- '1_e1',
- '1.4_e1',
- '1.4_e1j',
- # Underscore right after e:
- '1e_1',
- '1.4e_1',
- '1.4e_1j',
- # Complex cases with parens:
- '(1+1.5_j_)',
- '(1+1.5_j)',
-]
-
+from test.support.numbers import (
+ VALID_UNDERSCORE_LITERALS,
+ INVALID_UNDERSCORE_LITERALS,
+)
class TokenTests(unittest.TestCase):
import importlib
import io
import itertools
+import logging
import os
import sys
import sysconfig
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):
import unittest
from unittest import mock
from test import support
-from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
- INVALID_UNDERSCORE_LITERALS)
+from test.support.numbers import (
+ VALID_UNDERSCORE_LITERALS,
+ INVALID_UNDERSCORE_LITERALS,
+)
try:
import _pylong
import contextlib
import json
import io
+import logging
import os
import os.path
import pickle
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)
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:
import threading
import time
import traceback
+import warnings
from weakref import proxy
try:
import multiprocessing
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="received malformed or improperly-truncated ancillary data",
+ category=RuntimeWarning,
+ )
+ yield
+
+
HAVE_SOCKET_CAN = _have_socket_can()
HAVE_SOCKET_CAN_ISOTP = _have_socket_can_isotp()
# 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)
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)
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)
+import contextlib
import errno
import importlib
import io
+import logging
import os
import shutil
import socket
from test.support import script_helper
from test.support import socket_helper
from test.support import warnings_helper
+from test.support.testcase import ExtraAssertions
TESTFN = os_helper.TESTFN
-class TestSupport(unittest.TestCase):
+class LogCaptureHandler(logging.StreamHandler):
+ # Inspired by pytest's caplog
+ def __init__(self):
+ super().__init__(io.StringIO())
+ self.records = []
+
+ def emit(self, record) -> None:
+ self.records.append(record)
+ super().emit(record)
+
+ def handleError(self, record):
+ raise
+
+
+@contextlib.contextmanager
+def _caplog():
+ handler = LogCaptureHandler()
+ root_logger = logging.getLogger()
+ root_logger.addHandler(handler)
+ try:
+ yield handler
+ finally:
+ root_logger.removeHandler(handler)
+
+
+class TestSupport(unittest.TestCase, ExtraAssertions):
@classmethod
def setUpClass(cls):
orig_filter_len = len(warnings.filters)
path = os.path.realpath(path)
try:
- with warnings_helper.check_warnings() as recorder:
+ with warnings_helper.check_warnings() as recorder, _caplog() as caplog:
with os_helper.temp_dir(path, quiet=True) as temp_path:
self.assertEqual(path, temp_path)
warnings = [str(w.message) for w in recorder.warnings]
finally:
shutil.rmtree(path)
- self.assertEqual(len(warnings), 1, warnings)
- warn = warnings[0]
- self.assertTrue(warn.startswith(f'tests may fail, unable to create '
- f'temporary directory {path!r}: '),
- warn)
+ self.assertListEqual(warnings, [])
+ self.assertEqual(len(caplog.records), 1)
+ record = caplog.records[0]
+ self.assertStartsWith(
+ record.getMessage(),
+ f'tests may fail, unable to create '
+ f'temporary directory {path!r}: '
+ )
@support.requires_fork()
def test_temp_dir__forked_child(self):
with os_helper.temp_dir() as parent_dir:
bad_dir = os.path.join(parent_dir, 'does_not_exist')
- with warnings_helper.check_warnings() as recorder:
+ with warnings_helper.check_warnings() as recorder, _caplog() as caplog:
with os_helper.change_cwd(bad_dir, quiet=True) as new_cwd:
self.assertEqual(new_cwd, original_cwd)
self.assertEqual(os.getcwd(), new_cwd)
warnings = [str(w.message) for w in recorder.warnings]
- self.assertEqual(len(warnings), 1, warnings)
- warn = warnings[0]
- self.assertTrue(warn.startswith(f'tests may fail, unable to change '
- f'the current working directory '
- f'to {bad_dir!r}: '),
- warn)
+ self.assertListEqual(warnings, [])
+ self.assertEqual(len(caplog.records), 1)
+ record = caplog.records[0]
+ self.assertStartsWith(
+ record.getMessage(),
+ f'tests may fail, unable to change '
+ f'the current working directory '
+ f'to {bad_dir!r}: '
+ )
# Tests for change_cwd()
def test_change_cwd__chdir_warning(self):
"""Check the warning message when os.chdir() fails."""
path = TESTFN + '_does_not_exist'
- with warnings_helper.check_warnings() as recorder:
+ with warnings_helper.check_warnings() as recorder, _caplog() as caplog:
with os_helper.change_cwd(path=path, quiet=True):
pass
messages = [str(w.message) for w in recorder.warnings]
- self.assertEqual(len(messages), 1, messages)
- msg = messages[0]
- self.assertTrue(msg.startswith(f'tests may fail, unable to change '
- f'the current working directory '
- f'to {path!r}: '),
- msg)
+ self.assertListEqual(messages, [])
+ self.assertEqual(len(caplog.records), 1)
+ record = caplog.records[0]
+ self.assertStartsWith(
+ record.getMessage(),
+ f'tests may fail, unable to change '
+ f'the current working directory '
+ f'to {path!r}: ',
+ )
# Tests for temp_cwd()
from textwrap import dedent
from unittest import TestCase, mock
from test import support
-from test.test_grammar import (VALID_UNDERSCORE_LITERALS,
- INVALID_UNDERSCORE_LITERALS)
from test.support import os_helper
from test.support.script_helper import run_test_script, make_script, run_python_until_end
+from test.support.numbers import (
+ VALID_UNDERSCORE_LITERALS,
+ INVALID_UNDERSCORE_LITERALS,
+)
+
# Converts a source string into a list of textual representation
# of the tokens such as: