summaryrefslogtreecommitdiff
path: root/Lib/test
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2021-10-20 20:55:46 -0700
committerGitHub <noreply@github.com>2021-10-20 20:55:46 -0700
commitc52338fc42353e8d0c6214e4c22427807439dfd5 (patch)
tree6da4bf5da5eb739aa48eab1850218d5726c45b10 /Lib/test
parent8f05ffb0534c2343fc45ad0e1d91ae1dc2d92b64 (diff)
parent2a9ab75af32b1ee9f210ae2a0718990687d0f79d (diff)
downloadcpython-git-enum-private-310.tar.gz
Merge branch '3.10' into enum-private-310enum-private-310
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_codecs.py85
-rw-r--r--Lib/test/test_dbm.py114
-rw-r--r--Lib/test/test_doctest.py20
-rw-r--r--Lib/test/test_doctest2.py21
-rw-r--r--Lib/test/test_enum.py162
-rw-r--r--Lib/test/test_exceptions.py4
-rw-r--r--Lib/test/test_functools.py42
-rw-r--r--Lib/test/test_http_cookiejar.py11
-rw-r--r--Lib/test/test_tempfile.py19
-rw-r--r--Lib/test/test_traceback.py10
10 files changed, 369 insertions, 119 deletions
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index 328a47b2e3..f7310fbb14 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -114,7 +114,7 @@ class ReadTest(MixInCheckStateHandling):
q = Queue(b"")
r = codecs.getreader(self.encoding)(q)
result = ""
- for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+ for (c, partialresult) in zip(input.encode(self.encoding), partialresults, strict=True):
q.write(bytes([c]))
result += r.read()
self.assertEqual(result, partialresult)
@@ -125,7 +125,7 @@ class ReadTest(MixInCheckStateHandling):
# do the check again, this time using an incremental decoder
d = codecs.getincrementaldecoder(self.encoding)()
result = ""
- for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+ for (c, partialresult) in zip(input.encode(self.encoding), partialresults, strict=True):
result += d.decode(bytes([c]))
self.assertEqual(result, partialresult)
# check that there's nothing left in the buffers
@@ -135,7 +135,7 @@ class ReadTest(MixInCheckStateHandling):
# Check whether the reset method works properly
d.reset()
result = ""
- for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
+ for (c, partialresult) in zip(input.encode(self.encoding), partialresults, strict=True):
result += d.decode(bytes([c]))
self.assertEqual(result, partialresult)
# check that there's nothing left in the buffers
@@ -2341,7 +2341,11 @@ class TypesTest(unittest.TestCase):
(r"\x5c\x55\x30\x30\x31\x31\x30\x30\x30\x30", 10))
-class UnicodeEscapeTest(unittest.TestCase):
+class UnicodeEscapeTest(ReadTest, unittest.TestCase):
+ encoding = "unicode-escape"
+
+ test_lone_surrogates = None
+
def test_empty(self):
self.assertEqual(codecs.unicode_escape_encode(""), (b"", 0))
self.assertEqual(codecs.unicode_escape_decode(b""), ("", 0))
@@ -2428,8 +2432,50 @@ class UnicodeEscapeTest(unittest.TestCase):
self.assertEqual(decode(br"\U00110000", "ignore"), ("", 10))
self.assertEqual(decode(br"\U00110000", "replace"), ("\ufffd", 10))
+ def test_partial(self):
+ self.check_partial(
+ "\x00\t\n\r\\\xff\uffff\U00010000",
+ [
+ '',
+ '',
+ '',
+ '\x00',
+ '\x00',
+ '\x00\t',
+ '\x00\t',
+ '\x00\t\n',
+ '\x00\t\n',
+ '\x00\t\n\r',
+ '\x00\t\n\r',
+ '\x00\t\n\r\\',
+ '\x00\t\n\r\\',
+ '\x00\t\n\r\\',
+ '\x00\t\n\r\\',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff\U00010000',
+ ]
+ )
+
+class RawUnicodeEscapeTest(ReadTest, unittest.TestCase):
+ encoding = "raw-unicode-escape"
+
+ test_lone_surrogates = None
-class RawUnicodeEscapeTest(unittest.TestCase):
def test_empty(self):
self.assertEqual(codecs.raw_unicode_escape_encode(""), (b"", 0))
self.assertEqual(codecs.raw_unicode_escape_decode(b""), ("", 0))
@@ -2478,6 +2524,35 @@ class RawUnicodeEscapeTest(unittest.TestCase):
self.assertEqual(decode(br"\U00110000", "ignore"), ("", 10))
self.assertEqual(decode(br"\U00110000", "replace"), ("\ufffd", 10))
+ def test_partial(self):
+ self.check_partial(
+ "\x00\t\n\r\\\xff\uffff\U00010000",
+ [
+ '\x00',
+ '\x00\t',
+ '\x00\t\n',
+ '\x00\t\n\r',
+ '\x00\t\n\r',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff',
+ '\x00\t\n\r\\\xff\uffff\U00010000',
+ ]
+ )
+
class EscapeEncodeTest(unittest.TestCase):
diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py
index e02d1e16ae..16a023084e 100644
--- a/Lib/test/test_dbm.py
+++ b/Lib/test/test_dbm.py
@@ -1,23 +1,21 @@
"""Test script for the dbm.open function based on testdumbdbm.py"""
import unittest
-import glob
+import dbm
+import os
from test.support import import_helper
from test.support import os_helper
-# Skip tests if dbm module doesn't exist.
-dbm = import_helper.import_module('dbm')
-
try:
from dbm import ndbm
except ImportError:
ndbm = None
-_fname = os_helper.TESTFN
+dirname = os_helper.TESTFN
+_fname = os.path.join(dirname, os_helper.TESTFN)
#
-# Iterates over every database module supported by dbm currently available,
-# setting dbm to use each in turn, and yielding that module
+# Iterates over every database module supported by dbm currently available.
#
def dbm_iterator():
for name in dbm._names:
@@ -31,11 +29,12 @@ def dbm_iterator():
#
# Clean up all scratch databases we might have created during testing
#
-def delete_files():
- # we don't know the precise name the underlying database uses
- # so we use glob to locate all names
- for f in glob.glob(glob.escape(_fname) + "*"):
- os_helper.unlink(f)
+def cleaunup_test_dir():
+ os_helper.rmtree(dirname)
+
+def setup_test_dir():
+ cleaunup_test_dir()
+ os.mkdir(dirname)
class AnyDBMTestCase:
@@ -134,80 +133,67 @@ class AnyDBMTestCase:
for key in self._dict:
self.assertEqual(self._dict[key], f[key.encode("ascii")])
- def tearDown(self):
- delete_files()
+ def test_keys(self):
+ with dbm.open(_fname, 'c') as d:
+ self.assertEqual(d.keys(), [])
+ a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')]
+ for k, v in a:
+ d[k] = v
+ self.assertEqual(sorted(d.keys()), sorted(k for (k, v) in a))
+ for k, v in a:
+ self.assertIn(k, d)
+ self.assertEqual(d[k], v)
+ self.assertNotIn(b'xxx', d)
+ self.assertRaises(KeyError, lambda: d[b'xxx'])
def setUp(self):
+ self.addCleanup(setattr, dbm, '_defaultmod', dbm._defaultmod)
dbm._defaultmod = self.module
- delete_files()
+ self.addCleanup(cleaunup_test_dir)
+ setup_test_dir()
class WhichDBTestCase(unittest.TestCase):
def test_whichdb(self):
+ self.addCleanup(setattr, dbm, '_defaultmod', dbm._defaultmod)
for module in dbm_iterator():
# Check whether whichdb correctly guesses module name
# for databases opened with "module" module.
- # Try with empty files first
name = module.__name__
- if name == 'dbm.dumb':
- continue # whichdb can't support dbm.dumb
- delete_files()
- f = module.open(_fname, 'c')
- f.close()
+ setup_test_dir()
+ dbm._defaultmod = module
+ # Try with empty files first
+ with module.open(_fname, 'c'): pass
self.assertEqual(name, self.dbm.whichdb(_fname))
# Now add a key
- f = module.open(_fname, 'w')
- f[b"1"] = b"1"
- # and test that we can find it
- self.assertIn(b"1", f)
- # and read it
- self.assertEqual(f[b"1"], b"1")
- f.close()
+ with module.open(_fname, 'w') as f:
+ f[b"1"] = b"1"
+ # and test that we can find it
+ self.assertIn(b"1", f)
+ # and read it
+ self.assertEqual(f[b"1"], b"1")
self.assertEqual(name, self.dbm.whichdb(_fname))
@unittest.skipUnless(ndbm, reason='Test requires ndbm')
def test_whichdb_ndbm(self):
# Issue 17198: check that ndbm which is referenced in whichdb is defined
- db_file = '{}_ndbm.db'.format(_fname)
- with open(db_file, 'w'):
- self.addCleanup(os_helper.unlink, db_file)
- self.assertIsNone(self.dbm.whichdb(db_file[:-3]))
-
- def tearDown(self):
- delete_files()
+ with open(_fname + '.db', 'wb'): pass
+ self.assertIsNone(self.dbm.whichdb(_fname))
def setUp(self):
- delete_files()
- self.filename = os_helper.TESTFN
- self.d = dbm.open(self.filename, 'c')
- self.d.close()
+ self.addCleanup(cleaunup_test_dir)
+ setup_test_dir()
self.dbm = import_helper.import_fresh_module('dbm')
- def test_keys(self):
- self.d = dbm.open(self.filename, 'c')
- self.assertEqual(self.d.keys(), [])
- a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')]
- for k, v in a:
- self.d[k] = v
- self.assertEqual(sorted(self.d.keys()), sorted(k for (k, v) in a))
- for k, v in a:
- self.assertIn(k, self.d)
- self.assertEqual(self.d[k], v)
- self.assertNotIn(b'xxx', self.d)
- self.assertRaises(KeyError, lambda: self.d[b'xxx'])
- self.d.close()
-
-
-def load_tests(loader, tests, pattern):
- classes = []
- for mod in dbm_iterator():
- classes.append(type("TestCase-" + mod.__name__,
- (AnyDBMTestCase, unittest.TestCase),
- {'module': mod}))
- suites = [unittest.makeSuite(c) for c in classes]
-
- tests.addTests(suites)
- return tests
+
+for mod in dbm_iterator():
+ assert mod.__name__.startswith('dbm.')
+ suffix = mod.__name__[4:]
+ testname = f'TestCase_{suffix}'
+ globals()[testname] = type(testname,
+ (AnyDBMTestCase, unittest.TestCase),
+ {'module': mod})
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py
index 828a0ff567..7f8ccd3896 100644
--- a/Lib/test/test_doctest.py
+++ b/Lib/test/test_doctest.py
@@ -3110,20 +3110,11 @@ def test_no_trailing_whitespace_stripping():
patches that contain trailing whitespace. More info on Issue 24746.
"""
-######################################################################
-## Main
-######################################################################
-
-def test_main():
- # Check the doctest cases in doctest itself:
- ret = support.run_doctest(doctest, verbosity=True)
- # Check the doctest cases defined here:
- from test import test_doctest
- support.run_doctest(test_doctest, verbosity=True)
-
- # Run unittests
- support.run_unittest(__name__)
+def load_tests(loader, tests, pattern):
+ tests.addTest(doctest.DocTestSuite(doctest))
+ tests.addTest(doctest.DocTestSuite())
+ return tests
def test_coverage(coverdir):
@@ -3136,8 +3127,9 @@ def test_coverage(coverdir):
r.write_results(show_missing=True, summary=True,
coverdir=coverdir)
+
if __name__ == '__main__':
if '-c' in sys.argv:
test_coverage('/tmp/doctest.cover')
else:
- test_main()
+ unittest.main()
diff --git a/Lib/test/test_doctest2.py b/Lib/test/test_doctest2.py
index 347a143641..ab8a069673 100644
--- a/Lib/test/test_doctest2.py
+++ b/Lib/test/test_doctest2.py
@@ -13,7 +13,6 @@ the example. It should be ignored:
import sys
import unittest
-from test import support
if sys.flags.optimize >= 2:
raise unittest.SkipTest("Cannot test docstrings with -O2")
@@ -107,17 +106,21 @@ class C(object):
"""
return val
-def test_main():
- from test import test_doctest2
- EXPECTED = 19
- f, t = support.run_doctest(test_doctest2)
- if t != EXPECTED:
- raise support.TestFailed("expected %d tests to run, not %d" %
- (EXPECTED, t))
+
+class Test(unittest.TestCase):
+ def test_testmod(self):
+ import doctest, sys
+ EXPECTED = 19
+ f, t = doctest.testmod(sys.modules[__name__])
+ if f:
+ self.fail("%d of %d doctests failed" % (f, t))
+ if t != EXPECTED:
+ self.fail("expected %d tests to run, not %d" % (EXPECTED, t))
+
# Pollute the namespace with a bunch of imported functions and classes,
# to make sure they don't get tested.
from doctest import *
if __name__ == '__main__':
- test_main()
+ unittest.main()
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index eb1266b960..03cf3533fc 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -11,6 +11,7 @@ from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL
from test.support import ALWAYS_EQ, check__all__, threading_helper
from datetime import timedelta
+python_version = sys.version_info[:2]
# for pickle tests
try:
@@ -347,17 +348,38 @@ class TestEnum(unittest.TestCase):
self.assertTrue(IntLogic.true)
self.assertFalse(IntLogic.false)
- def test_contains(self):
+ @unittest.skipIf(
+ python_version >= (3, 12),
+ '__contains__ now returns True/False for all inputs',
+ )
+ def test_contains_er(self):
Season = self.Season
self.assertIn(Season.AUTUMN, Season)
with self.assertRaises(TypeError):
- 3 in Season
+ with self.assertWarns(DeprecationWarning):
+ 3 in Season
with self.assertRaises(TypeError):
- 'AUTUMN' in Season
-
+ with self.assertWarns(DeprecationWarning):
+ 'AUTUMN' in Season
val = Season(3)
self.assertIn(val, Season)
+ #
+ class OtherEnum(Enum):
+ one = 1; two = 2
+ self.assertNotIn(OtherEnum.two, Season)
+ @unittest.skipIf(
+ python_version < (3, 12),
+ '__contains__ only works with enum memmbers before 3.12',
+ )
+ def test_contains_tf(self):
+ Season = self.Season
+ self.assertIn(Season.AUTUMN, Season)
+ self.assertTrue(3 in Season)
+ self.assertFalse('AUTUMN' in Season)
+ val = Season(3)
+ self.assertIn(val, Season)
+ #
class OtherEnum(Enum):
one = 1; two = 2
self.assertNotIn(OtherEnum.two, Season)
@@ -1932,6 +1954,38 @@ class TestEnum(unittest.TestCase):
else:
raise Exception('Exception not raised.')
+ def test_missing_exceptions_reset(self):
+ import weakref
+ #
+ class TestEnum(enum.Enum):
+ VAL1 = 'val1'
+ VAL2 = 'val2'
+ #
+ class Class1:
+ def __init__(self):
+ # Gracefully handle an exception of our own making
+ try:
+ raise ValueError()
+ except ValueError:
+ pass
+ #
+ class Class2:
+ def __init__(self):
+ # Gracefully handle an exception of Enum's making
+ try:
+ TestEnum('invalid_value')
+ except ValueError:
+ pass
+ # No strong refs here so these are free to die.
+ class_1_ref = weakref.ref(Class1())
+ class_2_ref = weakref.ref(Class2())
+ #
+ # The exception raised by Enum creates a reference loop and thus
+ # Class2 instances will stick around until the next gargage collection
+ # cycle, unlike Class1.
+ self.assertIs(class_1_ref(), None)
+ self.assertIs(class_2_ref(), None)
+
def test_multiple_mixin(self):
class MaxMixin:
@classproperty
@@ -2085,7 +2139,7 @@ class TestEnum(unittest.TestCase):
exec(code, global_ns, local_ls)
@unittest.skipUnless(
- sys.version_info[:2] == (3, 9),
+ python_version == (3, 9),
'private variables are now normal attributes',
)
def test_warning_for_private_variables(self):
@@ -2390,19 +2444,42 @@ class TestFlag(unittest.TestCase):
test_pickle_dump_load(self.assertIs, FlagStooges.CURLY|FlagStooges.MOE)
test_pickle_dump_load(self.assertIs, FlagStooges)
- def test_contains(self):
+ @unittest.skipIf(
+ python_version >= (3, 12),
+ '__contains__ now returns True/False for all inputs',
+ )
+ def test_contains_er(self):
Open = self.Open
Color = self.Color
self.assertFalse(Color.BLACK in Open)
self.assertFalse(Open.RO in Color)
with self.assertRaises(TypeError):
- 'BLACK' in Color
+ with self.assertWarns(DeprecationWarning):
+ 'BLACK' in Color
with self.assertRaises(TypeError):
- 'RO' in Open
+ with self.assertWarns(DeprecationWarning):
+ 'RO' in Open
with self.assertRaises(TypeError):
- 1 in Color
+ with self.assertWarns(DeprecationWarning):
+ 1 in Color
with self.assertRaises(TypeError):
- 1 in Open
+ with self.assertWarns(DeprecationWarning):
+ 1 in Open
+
+ @unittest.skipIf(
+ python_version < (3, 12),
+ '__contains__ only works with enum memmbers before 3.12',
+ )
+ def test_contains_tf(self):
+ Open = self.Open
+ Color = self.Color
+ self.assertFalse(Color.BLACK in Open)
+ self.assertFalse(Open.RO in Color)
+ self.assertFalse('BLACK' in Color)
+ self.assertFalse('RO' in Open)
+ self.assertTrue(1 in Color)
+ self.assertTrue(1 in Open)
+
def test_member_contains(self):
Perm = self.Perm
@@ -2883,7 +2960,11 @@ class TestIntFlag(unittest.TestCase):
self.assertEqual(len(lst), len(Thing))
self.assertEqual(len(Thing), 0, Thing)
- def test_contains(self):
+ @unittest.skipIf(
+ python_version >= (3, 12),
+ '__contains__ now returns True/False for all inputs',
+ )
+ def test_contains_er(self):
Open = self.Open
Color = self.Color
self.assertTrue(Color.GREEN in Color)
@@ -2891,13 +2972,33 @@ class TestIntFlag(unittest.TestCase):
self.assertFalse(Color.GREEN in Open)
self.assertFalse(Open.RW in Color)
with self.assertRaises(TypeError):
- 'GREEN' in Color
+ with self.assertWarns(DeprecationWarning):
+ 'GREEN' in Color
with self.assertRaises(TypeError):
- 'RW' in Open
+ with self.assertWarns(DeprecationWarning):
+ 'RW' in Open
with self.assertRaises(TypeError):
- 2 in Color
+ with self.assertWarns(DeprecationWarning):
+ 2 in Color
with self.assertRaises(TypeError):
- 2 in Open
+ with self.assertWarns(DeprecationWarning):
+ 2 in Open
+
+ @unittest.skipIf(
+ python_version < (3, 12),
+ '__contains__ only works with enum memmbers before 3.12',
+ )
+ def test_contains_tf(self):
+ Open = self.Open
+ Color = self.Color
+ self.assertTrue(Color.GREEN in Color)
+ self.assertTrue(Open.RW in Open)
+ self.assertTrue(Color.GREEN in Open)
+ self.assertTrue(Open.RW in Color)
+ self.assertFalse('GREEN' in Color)
+ self.assertFalse('RW' in Open)
+ self.assertTrue(2 in Color)
+ self.assertTrue(2 in Open)
def test_member_contains(self):
Perm = self.Perm
@@ -3267,7 +3368,7 @@ class TestIntEnumConvert(unittest.TestCase):
if name[0:2] not in ('CO', '__')],
[], msg='Names other than CONVERT_TEST_* found.')
- @unittest.skipUnless(sys.version_info[:2] == (3, 8),
+ @unittest.skipUnless(python_version == (3, 8),
'_convert was deprecated in 3.8')
def test_convert_warn(self):
with self.assertWarns(DeprecationWarning):
@@ -3276,7 +3377,7 @@ class TestIntEnumConvert(unittest.TestCase):
('test.test_enum', '__main__')[__name__=='__main__'],
filter=lambda x: x.startswith('CONVERT_TEST_'))
- @unittest.skipUnless(sys.version_info >= (3, 9),
+ @unittest.skipUnless(python_version >= (3, 9),
'_convert was removed in 3.9')
def test_convert_raise(self):
with self.assertRaises(AttributeError):
@@ -3285,6 +3386,33 @@ class TestIntEnumConvert(unittest.TestCase):
('test.test_enum', '__main__')[__name__=='__main__'],
filter=lambda x: x.startswith('CONVERT_TEST_'))
+class TestHelpers(unittest.TestCase):
+
+ sunder_names = '_bad_', '_good_', '_what_ho_'
+ dunder_names = '__mal__', '__bien__', '__que_que__'
+ private_names = '_MyEnum__private', '_MyEnum__still_private'
+ private_and_sunder_names = '_MyEnum__private_', '_MyEnum__also_private_'
+ random_names = 'okay', '_semi_private', '_weird__', '_MyEnum__'
+
+ def test_sunder(self):
+ for name in self.sunder_names + self.private_and_sunder_names:
+ self.assertTrue(enum._is_sunder(name), '%r is a not sunder name?' % name)
+ for name in self.dunder_names + self.private_names + self.random_names:
+ self.assertFalse(enum._is_sunder(name), '%r is a sunder name?' % name)
+
+ def test_dunder(self):
+ for name in self.dunder_names:
+ self.assertTrue(enum._is_dunder(name), '%r is a not dunder name?' % name)
+ for name in self.sunder_names + self.private_names + self.private_and_sunder_names + self.random_names:
+ self.assertFalse(enum._is_dunder(name), '%r is a dunder name?' % name)
+
+ def test_is_private(self):
+ for name in self.private_names + self.private_and_sunder_names:
+ self.assertTrue(enum._is_private('MyEnum', name), '%r is a not private name?')
+ for name in self.sunder_names + self.dunder_names + self.random_names:
+ self.assertFalse(enum._is_private('MyEnum', name), '%r is a private name?')
+
if __name__ == '__main__':
unittest.main()
+
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 4213dabfd8..4930c57d3f 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -209,6 +209,10 @@ class ExceptionTests(unittest.TestCase):
src = src.decode(encoding, 'replace')
line = src.split('\n')[lineno-1]
self.assertIn(line, cm.exception.text)
+
+ def test_error_offset_continuation_characters(self):
+ check = self.check
+ check('"\\\n"(1 for c in I,\\\n\\', 2, 2)
def testSyntaxErrorOffset(self):
check = self.check
diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py
index fece8256a3..bdb4ddcc60 100644
--- a/Lib/test/test_functools.py
+++ b/Lib/test/test_functools.py
@@ -2437,6 +2437,48 @@ class TestSingleDispatch(unittest.TestCase):
self.assertEqual(a.t(''), "str")
self.assertEqual(a.t(0.0), "base")
+ def test_staticmethod_type_ann_register(self):
+ class A:
+ @functools.singledispatchmethod
+ @staticmethod
+ def t(arg):
+ return arg
+ @t.register
+ @staticmethod
+ def _(arg: int):
+ return isinstance(arg, int)
+ @t.register
+ @staticmethod
+ def _(arg: str):
+ return isinstance(arg, str)
+ a = A()
+
+ self.assertTrue(A.t(0))
+ self.assertTrue(A.t(''))
+ self.assertEqual(A.t(0.0), 0.0)
+
+ def test_classmethod_type_ann_register(self):
+ class A:
+ def __init__(self, arg):
+ self.arg = arg
+
+ @functools.singledispatchmethod
+ @classmethod
+ def t(cls, arg):
+ return cls("base")
+ @t.register
+ @classmethod
+ def _(cls, arg: int):
+ return cls("int")
+ @t.register
+ @classmethod
+ def _(cls, arg: str):
+ return cls("str")
+
+ self.assertEqual(A.t(0).arg, "int")
+ self.assertEqual(A.t('').arg, "str")
+ self.assertEqual(A.t(0.0).arg, "base")
+
def test_invalid_registrations(self):
msg_prefix = "Invalid first argument to `register()`: "
msg_suffix = (
diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py
index fdf15efde1..9450104d0b 100644
--- a/Lib/test/test_http_cookiejar.py
+++ b/Lib/test/test_http_cookiejar.py
@@ -1920,14 +1920,5 @@ class LWPCookieTests(unittest.TestCase):
self.assertNotEqual(counter["session_before"], 0)
-def test_main(verbose=None):
- test.support.run_unittest(
- DateTimeTests,
- HeaderTests,
- CookieTests,
- FileCookieJarTests,
- LWPCookieTests,
- )
-
if __name__ == "__main__":
- test_main(verbose=True)
+ unittest.main()
diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py
index 96946a281a..2b0ec46a10 100644
--- a/Lib/test/test_tempfile.py
+++ b/Lib/test/test_tempfile.py
@@ -62,6 +62,25 @@ class TestLowLevelInternals(unittest.TestCase):
def test_infer_return_type_pathlib(self):
self.assertIs(str, tempfile._infer_return_type(pathlib.Path('/')))
+ def test_infer_return_type_pathlike(self):
+ class Path:
+ def __init__(self, path):
+ self.path = path
+
+ def __fspath__(self):
+ return self.path
+
+ self.assertIs(str, tempfile._infer_return_type(Path('/')))
+ self.assertIs(bytes, tempfile._infer_return_type(Path(b'/')))
+ self.assertIs(str, tempfile._infer_return_type('', Path('')))
+ self.assertIs(bytes, tempfile._infer_return_type(b'', Path(b'')))
+ self.assertIs(bytes, tempfile._infer_return_type(None, Path(b'')))
+ self.assertIs(str, tempfile._infer_return_type(None, Path('')))
+
+ with self.assertRaises(TypeError):
+ tempfile._infer_return_type('', Path(b''))
+ with self.assertRaises(TypeError):
+ tempfile._infer_return_type(b'', Path(''))
# Common functionality.
diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py
index fabe5d01a9..ba03ce4629 100644
--- a/Lib/test/test_traceback.py
+++ b/Lib/test/test_traceback.py
@@ -51,6 +51,9 @@ class TracebackCases(unittest.TestCase):
def syntax_error_bad_indentation2(self):
compile(" print(2)", "?", "exec")
+ def tokenizer_error_with_caret_range(self):
+ compile("blech ( ", "?", "exec")
+
def test_caret(self):
err = self.get_exception_format(self.syntax_error_with_caret,
SyntaxError)
@@ -81,6 +84,13 @@ class TracebackCases(unittest.TestCase):
self.assertEqual(err[1].find("y"), err[2].find("^")) # in the right place
self.assertEqual(err[2].count("^"), len("y for y in range(30)"))
+ err = self.get_exception_format(self.tokenizer_error_with_caret_range,
+ SyntaxError)
+ self.assertIn("^", err[2]) # third line has caret
+ self.assertEqual(err[2].count('\n'), 1) # and no additional newline
+ self.assertEqual(err[1].find("("), err[2].find("^")) # in the right place
+ self.assertEqual(err[2].count("^"), 1)
+
def test_nocaret(self):
exc = SyntaxError("error", ("x.py", 23, None, "bad syntax"))
err = traceback.format_exception_only(SyntaxError, exc)