Merge pull request #6115 from ShaharNaveh/update-some-tests-2

Update some tests from 3.13.7
This commit is contained in:
Jeong, YunWon authored and GitHub committed 2025-09-03 00:27:57 +09:00
commit d17dcd817e
15 files changed
+856 -377

No files matched your search

+1 -125
View File
@@ -291,46 +291,7 @@ class TestDecorators(unittest.TestCase):
self.assertEqual(bar(), 42)
self.assertEqual(actions, expected_actions)
def test_wrapped_descriptor_inside_classmethod(self):
class BoundWrapper:
def __init__(self, wrapped):
self.__wrapped__ = wrapped
def __call__(self, *args, **kwargs):
return self.__wrapped__(*args, **kwargs)
class Wrapper:
def __init__(self, wrapped):
self.__wrapped__ = wrapped
def __get__(self, instance, owner):
bound_function = self.__wrapped__.__get__(instance, owner)
return BoundWrapper(bound_function)
def decorator(wrapped):
return Wrapper(wrapped)
class Class:
@decorator
@classmethod
def inner(cls):
# This should already work.
return 'spam'
@classmethod
@decorator
def outer(cls):
# Raised TypeError with a message saying that the 'Wrapper'
# object is not callable.
return 'eggs'
self.assertEqual(Class.inner(), 'spam')
self.assertEqual(Class.outer(), 'eggs')
self.assertEqual(Class().inner(), 'spam')
self.assertEqual(Class().outer(), 'eggs')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_bound_function_inside_classmethod(self):
class A:
def foo(self, cls):
@@ -341,91 +302,6 @@ class TestDecorators(unittest.TestCase):
self.assertEqual(B.bar(), 'spam')
def test_wrapped_classmethod_inside_classmethod(self):
class MyClassMethod1:
def __init__(self, func):
self.func = func
def __call__(self, cls):
if hasattr(self.func, '__get__'):
return self.func.__get__(cls, cls)()
return self.func(cls)
def __get__(self, instance, owner=None):
if owner is None:
owner = type(instance)
return MethodType(self, owner)
class MyClassMethod2:
def __init__(self, func):
if isinstance(func, classmethod):
func = func.__func__
self.func = func
def __call__(self, cls):
return self.func(cls)
def __get__(self, instance, owner=None):
if owner is None:
owner = type(instance)
return MethodType(self, owner)
for myclassmethod in [MyClassMethod1, MyClassMethod2]:
class A:
@myclassmethod
def f1(cls):
return cls
@classmethod
@myclassmethod
def f2(cls):
return cls
@myclassmethod
@classmethod
def f3(cls):
return cls
@classmethod
@classmethod
def f4(cls):
return cls
@myclassmethod
@MyClassMethod1
def f5(cls):
return cls
@myclassmethod
@MyClassMethod2
def f6(cls):
return cls
self.assertIs(A.f1(), A)
self.assertIs(A.f2(), A)
self.assertIs(A.f3(), A)
self.assertIs(A.f4(), A)
self.assertIs(A.f5(), A)
self.assertIs(A.f6(), A)
a = A()
self.assertIs(a.f1(), A)
self.assertIs(a.f2(), A)
self.assertIs(a.f3(), A)
self.assertIs(a.f4(), A)
self.assertIs(a.f5(), A)
self.assertIs(a.f6(), A)
def f(cls):
return cls
self.assertIs(myclassmethod(f).__get__(a)(), A)
self.assertIs(myclassmethod(f).__get__(a, A)(), A)
self.assertIs(myclassmethod(f).__get__(A, A)(), A)
self.assertIs(myclassmethod(f).__get__(A)(), type(A))
self.assertIs(classmethod(f).__get__(a)(), A)
self.assertIs(classmethod(f).__get__(a, A)(), A)
self.assertIs(classmethod(f).__get__(A, A)(), A)
self.assertIs(classmethod(f).__get__(A)(), type(A))
class TestClassDecorators(unittest.TestCase):
+3 -3
View File
@@ -4,7 +4,7 @@ import builtins
import sys
import unittest
from test.support import swap_item, swap_attr
from test.support import swap_item, swap_attr, is_wasi, Py_DEBUG
class RebindBuiltinsTests(unittest.TestCase):
@@ -134,8 +134,8 @@ class RebindBuiltinsTests(unittest.TestCase):
self.assertEqual(foo(), 7)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.skipIf(is_wasi and Py_DEBUG, "requires too much stack")
def test_load_global_specialization_failure_keeps_oparg(self):
# https://github.com/python/cpython/issues/91625
class MyGlobals(dict):
+138 -48
View File
@@ -1,87 +1,177 @@
"""test script for a few new invalid token catches"""
import sys
from test import support
from codecs import BOM_UTF8
from test.support import force_not_colorized
from test.support import os_helper
from test.support import script_helper
from test.support import warnings_helper
import unittest
class EOFTestCase(unittest.TestCase):
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_EOF_single_quote(self):
expect = "unterminated string literal (detected at line 1) (<string>, line 1)"
for quote in ("'", "\""):
try:
with self.assertRaises(SyntaxError) as cm:
eval(f"""{quote}this is a test\
""")
except SyntaxError as msg:
self.assertEqual(str(msg), expect)
self.assertEqual(msg.offset, 1)
else:
raise support.TestFailed
self.assertEqual(str(cm.exception), expect)
self.assertEqual(cm.exception.offset, 1)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_EOFS(self):
expect = ("unterminated triple-quoted string literal (detected at line 1) (<string>, line 1)")
try:
eval("""'''this is a test""")
except SyntaxError as msg:
self.assertEqual(str(msg), expect)
self.assertEqual(msg.offset, 1)
else:
raise support.TestFailed
expect = ("unterminated triple-quoted string literal (detected at line 3) (<string>, line 1)")
with self.assertRaises(SyntaxError) as cm:
eval("""ä = '''thîs is \na \ntest""")
self.assertEqual(str(cm.exception), expect)
self.assertEqual(cm.exception.text, "ä = '''thîs is ")
self.assertEqual(cm.exception.offset, 5)
# TODO: RUSTPYTHON
@unittest.expectedFailure
with self.assertRaises(SyntaxError) as cm:
eval("""ä = '''thîs is \na \ntest""".encode())
self.assertEqual(str(cm.exception), expect)
self.assertEqual(cm.exception.text, "ä = '''thîs is ")
self.assertEqual(cm.exception.offset, 5)
with self.assertRaises(SyntaxError) as cm:
eval(BOM_UTF8 + """ä = '''thîs is \na \ntest""".encode())
self.assertEqual(str(cm.exception), expect)
self.assertEqual(cm.exception.text, "ä = '''thîs is ")
self.assertEqual(cm.exception.offset, 5)
with self.assertRaises(SyntaxError) as cm:
eval("""# coding: latin1\nä = '''thîs is \na \ntest""".encode('latin1'))
self.assertEqual(str(cm.exception), "unterminated triple-quoted string literal (detected at line 4) (<string>, line 2)")
self.assertEqual(cm.exception.text, "ä = '''thîs is ")
self.assertEqual(cm.exception.offset, 5)
@unittest.expectedFailure # TODO: RUSTPYTHON
@force_not_colorized
def test_EOFS_with_file(self):
expect = ("(<string>, line 1)")
with os_helper.temp_dir() as temp_dir:
file_name = script_helper.make_script(temp_dir, 'foo', """'''this is \na \ntest""")
rc, out, err = script_helper.assert_python_failure(file_name)
self.assertIn(b'unterminated triple-quoted string literal (detected at line 3)', err)
file_name = script_helper.make_script(temp_dir, 'foo',
"""ä = '''thîs is \na \ntest""")
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-3:], [
" ä = '''thîs is ",
' ^',
'SyntaxError: unterminated triple-quoted string literal (detected at line 3)'])
# TODO: RUSTPYTHON
@unittest.expectedFailure
file_name = script_helper.make_script(temp_dir, 'foo',
"""ä = '''thîs is \na \ntest""".encode())
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-3:], [
" ä = '''thîs is ",
' ^',
'SyntaxError: unterminated triple-quoted string literal (detected at line 3)'])
file_name = script_helper.make_script(temp_dir, 'foo',
BOM_UTF8 + """ä = '''thîs is \na \ntest""".encode())
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-3:], [
" ä = '''thîs is ",
' ^',
'SyntaxError: unterminated triple-quoted string literal (detected at line 3)'])
file_name = script_helper.make_script(temp_dir, 'foo',
"""# coding: latin1\nä = '''thîs is \na \ntest""".encode('latin1'))
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-3:], [
" ä = '''thîs is ",
' ^',
'SyntaxError: unterminated triple-quoted string literal (detected at line 4)'])
@unittest.expectedFailure # TODO: RUSTPYTHON
@warnings_helper.ignore_warnings(category=SyntaxWarning)
def test_eof_with_line_continuation(self):
expect = "unexpected EOF while parsing (<string>, line 1)"
try:
with self.assertRaises(SyntaxError) as cm:
compile('"\\Xhh" \\', '<string>', 'exec')
except SyntaxError as msg:
self.assertEqual(str(msg), expect)
else:
raise support.TestFailed
self.assertEqual(str(cm.exception), expect)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_line_continuation_EOF(self):
"""A continuation at the end of input must be an error; bpo2180."""
expect = 'unexpected EOF while parsing (<string>, line 1)'
with self.assertRaises(SyntaxError) as excinfo:
exec('x = 5\\')
self.assertEqual(str(excinfo.exception), expect)
with self.assertRaises(SyntaxError) as excinfo:
exec('\\')
self.assertEqual(str(excinfo.exception), expect)
with self.assertRaises(SyntaxError) as cm:
exec('ä = 5\\')
self.assertEqual(str(cm.exception), expect)
self.assertEqual(cm.exception.text, 'ä = 5\\\n')
self.assertEqual(cm.exception.offset, 7)
with self.assertRaises(SyntaxError) as cm:
exec('ä = 5\\'.encode())
self.assertEqual(str(cm.exception), expect)
self.assertEqual(cm.exception.text, 'ä = 5\\\n')
self.assertEqual(cm.exception.offset, 7)
with self.assertRaises(SyntaxError) as cm:
exec('# coding:latin1\nä = 5\\'.encode('latin1'))
self.assertEqual(str(cm.exception),
'unexpected EOF while parsing (<string>, line 2)')
self.assertEqual(cm.exception.text, 'ä = 5\\\n')
self.assertEqual(cm.exception.offset, 7)
with self.assertRaises(SyntaxError) as cm:
exec(BOM_UTF8 + 'ä = 5\\'.encode())
self.assertEqual(str(cm.exception), expect)
self.assertEqual(cm.exception.text, 'ä = 5\\\n')
self.assertEqual(cm.exception.offset, 7)
with self.assertRaises(SyntaxError) as cm:
exec('\\')
self.assertEqual(str(cm.exception), expect)
@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.skipIf(not sys.executable, "sys.executable required")
@force_not_colorized
def test_line_continuation_EOF_from_file_bpo2180(self):
"""Ensure tok_nextc() does not add too many ending newlines."""
with os_helper.temp_dir() as temp_dir:
file_name = script_helper.make_script(temp_dir, 'foo', '\\')
rc, out, err = script_helper.assert_python_failure(file_name)
self.assertIn(b'unexpected EOF while parsing', err)
self.assertIn(b'line 1', err)
self.assertIn(b'\\', err)
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-2:], [
' \\',
'SyntaxError: unexpected EOF while parsing'])
self.assertEqual(err[-3][-8:], ', line 1', err)
file_name = script_helper.make_script(temp_dir, 'foo', 'ä = 6\\')
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-3:], [
' ä = 6\\',
' ^',
'SyntaxError: unexpected EOF while parsing'])
self.assertEqual(err[-4][-8:], ', line 1', err)
file_name = script_helper.make_script(temp_dir, 'foo',
'# coding:latin1\n'
'ä = 7\\'.encode('latin1'))
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-3:], [
' ä = 7\\',
' ^',
'SyntaxError: unexpected EOF while parsing'])
self.assertEqual(err[-4][-8:], ', line 2', err)
file_name = script_helper.make_script(temp_dir, 'foo',
BOM_UTF8 + 'ä = 8\\'.encode())
rc, out, err = script_helper.assert_python_failure('-X', 'utf8', file_name)
err = err.decode().splitlines()
self.assertEqual(err[-3:], [
' ä = 8\\',
' ^',
'SyntaxError: unexpected EOF while parsing'])
self.assertEqual(err[-4][-8:], ', line 1', err)
file_name = script_helper.make_script(temp_dir, 'foo', 'y = 6\\')
rc, out, err = script_helper.assert_python_failure(file_name)
self.assertIn(b'unexpected EOF while parsing', err)
self.assertIn(b'line 1', err)
self.assertIn(b'y = 6\\', err)
if __name__ == "__main__":
unittest.main()
+262
View File
@@ -0,0 +1,262 @@
# Written to test interrupted system calls interfering with our many buffered
# IO implementations. http://bugs.python.org/issue12268
#
# It was suggested that this code could be merged into test_io and the tests
# made to work using the same method as the existing signal tests in test_io.
# I was unable to get single process tests using alarm or setitimer that way
# to reproduce the EINTR problems. This process based test suite reproduces
# the problems prior to the issue12268 patch reliably on Linux and OSX.
# - gregory.p.smith
import os
import select
import signal
import subprocess
import sys
import time
import unittest
from test import support
if not support.has_subprocess_support:
raise unittest.SkipTest("test module requires subprocess")
# Test import all of the things we're about to try testing up front.
import _io
import _pyio
@unittest.skipUnless(os.name == 'posix', 'tests requires a posix system.')
class TestFileIOSignalInterrupt:
def setUp(self):
self._process = None
def tearDown(self):
if self._process and self._process.poll() is None:
try:
self._process.kill()
except OSError:
pass
def _generate_infile_setup_code(self):
"""Returns the infile = ... line of code for the reader process.
subclasseses should override this to test different IO objects.
"""
return ('import %s as io ;'
'infile = io.FileIO(sys.stdin.fileno(), "rb")' %
self.modname)
def fail_with_process_info(self, why, stdout=b'', stderr=b'',
communicate=True):
"""A common way to cleanup and fail with useful debug output.
Kills the process if it is still running, collects remaining output
and fails the test with an error message including the output.
Args:
why: Text to go after "Error from IO process" in the message.
stdout, stderr: standard output and error from the process so
far to include in the error message.
communicate: bool, when True we call communicate() on the process
after killing it to gather additional output.
"""
if self._process.poll() is None:
time.sleep(0.1) # give it time to finish printing the error.
try:
self._process.terminate() # Ensure it dies.
except OSError:
pass
if communicate:
stdout_end, stderr_end = self._process.communicate()
stdout += stdout_end
stderr += stderr_end
self.fail('Error from IO process %s:\nSTDOUT:\n%sSTDERR:\n%s\n' %
(why, stdout.decode(), stderr.decode()))
def _test_reading(self, data_to_write, read_and_verify_code):
"""Generic buffered read method test harness to validate EINTR behavior.
Also validates that Python signal handlers are run during the read.
Args:
data_to_write: String to write to the child process for reading
before sending it a signal, confirming the signal was handled,
writing a final newline and closing the infile pipe.
read_and_verify_code: Single "line" of code to read from a file
object named 'infile' and validate the result. This will be
executed as part of a python subprocess fed data_to_write.
"""
infile_setup_code = self._generate_infile_setup_code()
# Total pipe IO in this function is smaller than the minimum posix OS
# pipe buffer size of 512 bytes. No writer should block.
assert len(data_to_write) < 512, 'data_to_write must fit in pipe buf.'
# Start a subprocess to call our read method while handling a signal.
self._process = subprocess.Popen(
[sys.executable, '-u', '-c',
'import signal, sys ;'
'signal.signal(signal.SIGINT, '
'lambda s, f: sys.stderr.write("$\\n")) ;'
+ infile_setup_code + ' ;' +
'sys.stderr.write("Worm Sign!\\n") ;'
+ read_and_verify_code + ' ;' +
'infile.close()'
],
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# Wait for the signal handler to be installed.
worm_sign = self._process.stderr.read(len(b'Worm Sign!\n'))
if worm_sign != b'Worm Sign!\n': # See also, Dune by Frank Herbert.
self.fail_with_process_info('while awaiting a sign',
stderr=worm_sign)
self._process.stdin.write(data_to_write)
signals_sent = 0
rlist = []
# We don't know when the read_and_verify_code in our child is actually
# executing within the read system call we want to interrupt. This
# loop waits for a bit before sending the first signal to increase
# the likelihood of that. Implementations without correct EINTR
# and signal handling usually fail this test.
while not rlist:
rlist, _, _ = select.select([self._process.stderr], (), (), 0.05)
self._process.send_signal(signal.SIGINT)
signals_sent += 1
if signals_sent > 200:
self._process.kill()
self.fail('reader process failed to handle our signals.')
# This assumes anything unexpected that writes to stderr will also
# write a newline. That is true of the traceback printing code.
signal_line = self._process.stderr.readline()
if signal_line != b'$\n':
self.fail_with_process_info('while awaiting signal',
stderr=signal_line)
# We append a newline to our input so that a readline call can
# end on its own before the EOF is seen and so that we're testing
# the read call that was interrupted by a signal before the end of
# the data stream has been reached.
stdout, stderr = self._process.communicate(input=b'\n')
if self._process.returncode:
self.fail_with_process_info(
'exited rc=%d' % self._process.returncode,
stdout, stderr, communicate=False)
# PASS!
# String format for the read_and_verify_code used by read methods.
_READING_CODE_TEMPLATE = (
'got = infile.{read_method_name}() ;'
'expected = {expected!r} ;'
'assert got == expected, ('
'"{read_method_name} returned wrong data.\\n"'
'"got data %r\\nexpected %r" % (got, expected))'
)
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_readline(self):
"""readline() must handle signals and not lose data."""
self._test_reading(
data_to_write=b'hello, world!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='readline',
expected=b'hello, world!\n'))
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_readlines(self):
"""readlines() must handle signals and not lose data."""
self._test_reading(
data_to_write=b'hello\nworld!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='readlines',
expected=[b'hello\n', b'world!\n']))
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_readall(self):
"""readall() must handle signals and not lose data."""
self._test_reading(
data_to_write=b'hello\nworld!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='readall',
expected=b'hello\nworld!\n'))
# read() is the same thing as readall().
self._test_reading(
data_to_write=b'hello\nworld!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='read',
expected=b'hello\nworld!\n'))
class CTestFileIOSignalInterrupt(TestFileIOSignalInterrupt, unittest.TestCase):
modname = '_io'
class PyTestFileIOSignalInterrupt(TestFileIOSignalInterrupt, unittest.TestCase):
modname = '_pyio'
class TestBufferedIOSignalInterrupt(TestFileIOSignalInterrupt):
def _generate_infile_setup_code(self):
"""Returns the infile = ... line of code to make a BufferedReader."""
return ('import %s as io ;infile = io.open(sys.stdin.fileno(), "rb") ;'
'assert isinstance(infile, io.BufferedReader)' %
self.modname)
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_readall(self):
"""BufferedReader.read() must handle signals and not lose data."""
self._test_reading(
data_to_write=b'hello\nworld!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='read',
expected=b'hello\nworld!\n'))
class CTestBufferedIOSignalInterrupt(TestBufferedIOSignalInterrupt, unittest.TestCase):
modname = '_io'
class PyTestBufferedIOSignalInterrupt(TestBufferedIOSignalInterrupt, unittest.TestCase):
modname = '_pyio'
class TestTextIOSignalInterrupt(TestFileIOSignalInterrupt):
def _generate_infile_setup_code(self):
"""Returns the infile = ... line of code to make a TextIOWrapper."""
return ('import %s as io ;'
'infile = io.open(sys.stdin.fileno(), encoding="utf-8", newline=None) ;'
'assert isinstance(infile, io.TextIOWrapper)' %
self.modname)
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_readline(self):
"""readline() must handle signals and not lose data."""
self._test_reading(
data_to_write=b'hello, world!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='readline',
expected='hello, world!\n'))
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_readlines(self):
"""readlines() must handle signals and not lose data."""
self._test_reading(
data_to_write=b'hello\r\nworld!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='readlines',
expected=['hello\n', 'world!\n']))
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_readall(self):
"""read() must handle signals and not lose data."""
self._test_reading(
data_to_write=b'hello\nworld!',
read_and_verify_code=self._READING_CODE_TEMPLATE.format(
read_method_name='read',
expected="hello\nworld!\n"))
class CTestTextIOSignalInterrupt(TestTextIOSignalInterrupt, unittest.TestCase):
modname = '_io'
class PyTestTextIOSignalInterrupt(TestTextIOSignalInterrupt, unittest.TestCase):
modname = '_pyio'
if __name__ == '__main__':
unittest.main()
+55 -39
View File
@@ -10,10 +10,14 @@ from weakref import proxy
from functools import wraps
from test.support import (
cpython_only, swap_attr, gc_collect, is_emscripten, is_wasi
cpython_only, swap_attr, gc_collect, is_emscripten, is_wasi,
infinite_recursion,
)
from test.support.os_helper import (TESTFN, TESTFN_UNICODE, make_bad_fd)
from test.support.os_helper import (
TESTFN, TESTFN_ASCII, TESTFN_UNICODE, make_bad_fd,
)
from test.support.warnings_helper import check_warnings
from test.support.import_helper import import_module
from collections import UserList
import _io # C implementation of io
@@ -171,6 +175,16 @@ class AutoFileTests:
self.assertEqual(repr(self.f),
"<%s.FileIO [closed]>" % (self.modulename,))
def test_subclass_repr(self):
class TestSubclass(self.FileIO):
pass
f = TestSubclass(TESTFN)
with f:
self.assertIn(TestSubclass.__name__, repr(f))
self.assertIn(TestSubclass.__name__, repr(f))
def testReprNoCloseFD(self):
fd = os.open(TESTFN, os.O_RDONLY)
try:
@@ -181,6 +195,7 @@ class AutoFileTests:
finally:
os.close(fd)
@infinite_recursion(25)
def testRecursiveRepr(self):
# Issue #25455
with swap_attr(self.f, 'name', self.f):
@@ -348,40 +363,34 @@ class CAutoFileTests(AutoFileTests, unittest.TestCase):
FileIO = _io.FileIO
modulename = '_io'
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def testBlksize(self):
super().testBlksize()
return super().testBlksize()
# TODO: RUSTPYTHON
if sys.platform == "win32":
@unittest.expectedFailure
def testErrnoOnClosedTruncate(self):
super().testErrnoOnClosedTruncate()
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
def testErrnoOnClosedTruncate(self):
return super().testErrnoOnClosedTruncate()
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def testMethods(self):
super().testMethods()
# TODO: RUSTPYTHON
@unittest.expectedFailure
def testOpenDirFD(self):
super().testOpenDirFD()
return super().testMethods()
@unittest.expectedFailure # TODO: RUSTPYTHON
def testOpenDirFD(self):
return super().testOpenDirFD()
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_subclass_repr(self):
return super().test_subclass_repr()
@unittest.skipIf(sys.platform == "win32", "TODO: RUSTPYTHON, test setUp errors on Windows")
class PyAutoFileTests(AutoFileTests, unittest.TestCase):
FileIO = _pyio.FileIO
modulename = '_pyio'
def testOpendir(self):
super().testOpendir()
class OtherFileTests:
@unittest.skip("TODO: non-deterministic failures, FileIO.seekable()?")
def testAbles(self):
try:
f = self.FileIO(TESTFN, "w")
@@ -458,18 +467,15 @@ class OtherFileTests:
def testBytesOpen(self):
# Opening a bytes filename
try:
fn = TESTFN.encode("ascii")
except UnicodeEncodeError:
self.skipTest('could not encode %r to ascii' % TESTFN)
fn = TESTFN_ASCII.encode("ascii")
f = self.FileIO(fn, "w")
try:
f.write(b"abc")
f.close()
with open(TESTFN, "rb") as f:
with self.open(TESTFN_ASCII, "rb") as f:
self.assertEqual(f.read(), b"abc")
finally:
os.unlink(TESTFN)
os.unlink(TESTFN_ASCII)
@unittest.skipIf(sys.getfilesystemencoding() != 'utf-8',
"test only works for utf-8 filesystems")
@@ -483,7 +489,7 @@ class OtherFileTests:
try:
f.write(b"abc")
f.close()
with open(TESTFN_UNICODE, "rb") as f:
with self.open(TESTFN_UNICODE, "rb") as f:
self.assertEqual(f.read(), b"abc")
finally:
os.unlink(TESTFN_UNICODE)
@@ -500,6 +506,15 @@ class OtherFileTests:
import msvcrt
self.assertRaises(OSError, msvcrt.get_osfhandle, make_bad_fd())
@unittest.expectedFailure # TODO: RUSTPYTHON
def testBooleanFd(self):
for fd in False, True:
with self.assertWarnsRegex(RuntimeWarning,
'bool is used as a file descriptor') as cm:
f = self.FileIO(fd, closefd=False)
f.close()
self.assertEqual(cm.filename, __file__)
def testBadModeArgument(self):
# verify that we get a sensible error message for bad mode argument
bad_mode = "qwerty"
@@ -530,7 +545,7 @@ class OtherFileTests:
def testTruncateOnWindows(self):
def bug801631():
# SF bug <http://www.python.org/sf/801631>
# SF bug <https://bugs.python.org/issue801631>
# "file.truncate fault on windows"
f = self.FileIO(TESTFN, 'w')
f.write(bytes(range(11)))
@@ -559,13 +574,13 @@ class OtherFileTests:
def testAppend(self):
try:
f = open(TESTFN, 'wb')
f = self.FileIO(TESTFN, 'wb')
f.write(b'spam')
f.close()
f = open(TESTFN, 'ab')
f = self.FileIO(TESTFN, 'ab')
f.write(b'eggs')
f.close()
f = open(TESTFN, 'rb')
f = self.FileIO(TESTFN, 'rb')
d = f.read()
f.close()
self.assertEqual(d, b'spameggs')
@@ -601,16 +616,12 @@ class OtherFileTests:
class COtherFileTests(OtherFileTests, unittest.TestCase):
FileIO = _io.FileIO
modulename = '_io'
# TODO: RUSTPYTHON
@unittest.expectedFailure
def testUnclosedFDOnException(self):
super().testUnclosedFDOnException()
open = _io.open
@cpython_only
def testInvalidFd_overflow(self):
# Issue 15989
import _testcapi
_testcapi = import_module("_testcapi")
self.assertRaises(TypeError, self.FileIO, _testcapi.INT_MAX + 1)
self.assertRaises(TypeError, self.FileIO, _testcapi.INT_MIN - 1)
@@ -623,10 +634,15 @@ class COtherFileTests(OtherFileTests, unittest.TestCase):
actual = f.read()
self.assertEqual(expected, actual)
@unittest.expectedFailure # TODO: RUSTPYTHON
def testUnclosedFDOnException(self):
return super().testUnclosedFDOnException()
class PyOtherFileTests(OtherFileTests, unittest.TestCase):
FileIO = _pyio.FileIO
modulename = '_pyio'
open = _pyio.open
def test_open_code(self):
# Check that the default behaviour of open_code matches
+310 -140
View File
@@ -2,7 +2,7 @@
# This just tests whether the parser accepts them all.
from test.support import check_syntax_error
from test.support.warnings_helper import check_syntax_warning
from test.support import import_helper
import inspect
import unittest
import sys
@@ -12,97 +12,19 @@ from sys import *
# different import patterns to check that __annotations__ does not interfere
# with import machinery
# import test.ann_module as ann_module
import test.typinganndata.ann_module as ann_module
import typing
from collections import ChainMap
# from test import ann_module2
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):
from test.support import check_syntax_error
from test.support.warnings_helper import check_syntax_warning
def test_backslash(self):
# Backslash means line continuation:
@@ -164,7 +86,7 @@ class TokenTests(unittest.TestCase):
x = 3.14
x = 314.
x = 0.314
# XXX x = 000.314
x = 000.314
x = .314
x = 3e14
x = 3E14
@@ -176,8 +98,10 @@ class TokenTests(unittest.TestCase):
def test_float_exponent_tokenization(self):
# See issue 21642.
self.assertEqual(1 if 1else 0, 1)
self.assertEqual(1 if 0else 0, 0)
with warnings.catch_warnings():
warnings.simplefilter('ignore', SyntaxWarning)
self.assertEqual(eval("1 if 1else 0"), 1)
self.assertEqual(eval("1 if 0else 0"), 0)
self.assertRaises(SyntaxError, eval, "0 if 1Else 0")
def test_underscore_literals(self):
@@ -188,8 +112,7 @@ class TokenTests(unittest.TestCase):
# Sanity check: no literal begins with an underscore
self.assertRaises(NameError, eval, "_0")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_bad_numerical_literals(self):
check = self.check_syntax_error
check("0b12", "invalid digit '2' in binary literal")
@@ -212,6 +135,47 @@ class TokenTests(unittest.TestCase):
check("1e2_", "invalid decimal literal")
check("1e+", "invalid decimal literal")
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_end_of_numerical_literals(self):
def check(test, error=False):
with self.subTest(expr=test):
if error:
with warnings.catch_warnings(record=True) as w:
with self.assertRaisesRegex(SyntaxError,
r'invalid \w+ literal'):
compile(test, "<testcase>", "eval")
self.assertEqual(w, [])
else:
self.check_syntax_warning(test,
errtext=r'invalid \w+ literal')
for num in "0xf", "0o7", "0b1", "9", "0", "1.", "1e3", "1j":
compile(num, "<testcase>", "eval")
check(f"{num}and x", error=(num == "0xf"))
check(f"{num}or x", error=(num == "0"))
check(f"{num}in x")
check(f"{num}not in x")
check(f"{num}if x else y")
check(f"x if {num}else y", error=(num == "0xf"))
check(f"[{num}for x in ()]")
check(f"{num}spam", error=True)
# gh-88943: Invalid non-ASCII character following a numerical literal.
with self.assertRaisesRegex(SyntaxError, r"invalid character '⁄' \(U\+2044\)"):
compile(f"{num}⁄7", "<testcase>", "eval")
with self.assertWarnsRegex(SyntaxWarning, r'invalid \w+ literal'):
compile(f"{num}is x", "<testcase>", "eval")
with warnings.catch_warnings():
warnings.simplefilter('error', SyntaxWarning)
with self.assertRaisesRegex(SyntaxError,
r'invalid \w+ literal'):
compile(f"{num}is x", "<testcase>", "eval")
check("[0x1ffor x in ()]")
check("[0x1for x in ()]")
check("[0xfor x in ()]")
def test_string_literals(self):
x = ''; y = ""; self.assertTrue(len(x) == 0 and x == y)
x = '\''; y = "'"; self.assertTrue(len(x) == 1 and x == y and ord(x) == 39)
@@ -257,12 +221,13 @@ the \'lazy\' dog.\n\
self.assertTrue(x is Ellipsis)
self.assertRaises(SyntaxError, eval, ".. .")
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_eof_error(self):
samples = ("def foo(", "\ndef foo(", "def foo(\n")
for s in samples:
with self.assertRaises(SyntaxError) as cm:
compile(s, "<test>", "exec")
self.assertIn("unexpected EOF", str(cm.exception))
self.assertIn("was never closed", str(cm.exception))
var_annot_global: int # a global annotated is necessary for test_var_annot
@@ -281,6 +246,7 @@ class GrammarTests(unittest.TestCase):
from test.support import check_syntax_error
from test.support.warnings_helper import check_syntax_warning
from test.support.warnings_helper import check_no_warnings
# single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
# XXX can't test in a script -- this rule is only used when interactive
@@ -307,14 +273,18 @@ class GrammarTests(unittest.TestCase):
my_lst[one()-1]: int = 5
self.assertEqual(my_lst, [5])
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_var_annot_syntax_errors(self):
# parser pass
check_syntax_error(self, "def f: int")
check_syntax_error(self, "x: int: str")
check_syntax_error(self, "def f():\n"
" nonlocal x: int\n")
check_syntax_error(self, "def f():\n"
" global x: int\n")
check_syntax_error(self, "x: int = y = 1")
check_syntax_error(self, "z = w: int = 1")
check_syntax_error(self, "x: int = y: int = 1")
# AST pass
check_syntax_error(self, "[x, 0]: int\n")
check_syntax_error(self, "f(): int\n")
@@ -328,9 +298,14 @@ class GrammarTests(unittest.TestCase):
check_syntax_error(self, "def f():\n"
" global x\n"
" x: int\n")
check_syntax_error(self, "def f():\n"
" x: int\n"
" nonlocal x\n")
check_syntax_error(self, "def f():\n"
" nonlocal x\n"
" x: int\n")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_var_annot_basic_semantics(self):
# execution order
with self.assertRaises(ZeroDivisionError):
@@ -377,6 +352,28 @@ class GrammarTests(unittest.TestCase):
x: int
x.y: list = []
def test_annotations_inheritance(self):
# Check that annotations are not inherited by derived classes
class A:
attr: int
class B(A):
pass
class C(A):
attr: str
class D:
attr2: int
class E(A, D):
pass
class F(C, A):
pass
self.assertEqual(A.__annotations__, {"attr": int})
self.assertEqual(B.__annotations__, {})
self.assertEqual(C.__annotations__, {"attr" : str})
self.assertEqual(D.__annotations__, {"attr2" : int})
self.assertEqual(E.__annotations__, {})
self.assertEqual(F.__annotations__, {})
def test_var_annot_metaclass_semantics(self):
class CMeta(type):
@classmethod
@@ -386,13 +383,11 @@ class GrammarTests(unittest.TestCase):
XX: 'ANNOT'
self.assertEqual(CC.__annotations__['xx'], 'ANNOT')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_var_annot_module_semantics(self):
with self.assertRaises(AttributeError):
print(test.__annotations__)
self.assertEqual(test.__annotations__, {})
self.assertEqual(ann_module.__annotations__,
{1: 2, 'x': int, 'y': str, 'f': typing.Tuple[int, int]})
{1: 2, 'x': int, 'y': str, 'f': typing.Tuple[int, int], 'u': int | float})
self.assertEqual(ann_module.M.__annotations__,
{'123': 123, 'o': type})
self.assertEqual(ann_module2.__annotations__, {})
@@ -400,13 +395,13 @@ class GrammarTests(unittest.TestCase):
def test_var_annot_in_module(self):
# check that functions fail the same way when executed
# outside of module where they were defined
from test.typinganndata.ann_module3 import f_bad_ann, g_bad_ann, D_bad_ann
ann_module3 = import_helper.import_fresh_module("test.typinganndata.ann_module3")
with self.assertRaises(NameError):
f_bad_ann()
ann_module3.f_bad_ann()
with self.assertRaises(NameError):
g_bad_ann()
ann_module3.g_bad_ann()
with self.assertRaises(NameError):
D_bad_ann(5)
ann_module3.D_bad_ann(5)
def test_var_annot_simple_exec(self):
gns = {}; lns= {}
@@ -417,8 +412,7 @@ class GrammarTests(unittest.TestCase):
with self.assertRaises(KeyError):
gns['__annotations__']
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_var_annot_custom_maps(self):
# tests with custom locals() and __annotations__
ns = {'__annotations__': CNS()}
@@ -440,8 +434,7 @@ class GrammarTests(unittest.TestCase):
exec('x: int = 1', {}, CNS2())
self.assertEqual(nonloc_ns['__annotations__']['x'], int)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_var_annot_refleak(self):
# complex case: custom locals plus custom __annotations__
# this was causing refleak
@@ -459,7 +452,6 @@ class GrammarTests(unittest.TestCase):
exec('X: str', {}, CNS2())
self.assertEqual(nonloc_ns['__annotations__']['x'], str)
def test_var_annot_rhs(self):
ns = {}
exec('x: tuple = 1, 2', ns)
@@ -475,7 +467,7 @@ class GrammarTests(unittest.TestCase):
def test_funcdef(self):
### [decorators] 'def' NAME parameters ['->' test] ':' suite
### decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
### decorator: '@' namedexpr_test NEWLINE
### decorators: decorator+
### parameters: '(' [typedargslist] ')'
### typedargslist: ((tfpdef ['=' test] ',')*
@@ -597,12 +589,14 @@ class GrammarTests(unittest.TestCase):
d22v(1, *(2, 3), **{'d': 4})
# keyword argument type tests
try:
str('x', **{b'foo':1 })
except TypeError:
pass
else:
self.fail('Bytes should not work as keyword argument names')
with warnings.catch_warnings():
warnings.simplefilter('ignore', BytesWarning)
try:
str('x', **{b'foo':1 })
except TypeError:
pass
else:
self.fail('Bytes should not work as keyword argument names')
# keyword only argument tests
def pos0key1(*, key): return key
pos0key1(key=100)
@@ -681,6 +675,20 @@ class GrammarTests(unittest.TestCase):
def f(x) -> list: pass
self.assertEqual(f.__annotations__, {'return': list})
# Test expressions as decorators (PEP 614):
@False or null
def f(x): pass
@d := null
def f(x): pass
@lambda f: null(f)
def f(x): pass
@[..., null, ...][1]
def f(x): pass
@null(null)(null)
def f(x): pass
@[null][0].__call__.__call__
def f(x): pass
# test closures with a variety of opargs
closure = 1
def f(): return closure
@@ -768,10 +776,9 @@ class GrammarTests(unittest.TestCase):
check_syntax_error(self, "x + 1 = 1")
check_syntax_error(self, "a + 1 = b + 2")
# TODO: RUSTPYTHON
@unittest.expectedFailure
# Check the heuristic for print & exec covers significant cases
# As well as placing some limits on false positives
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_former_statements_refer_to_builtins(self):
keywords = "print", "exec"
# Cases where we want the custom error
@@ -804,6 +811,23 @@ class GrammarTests(unittest.TestCase):
del abc
del x, y, (z, xyz)
x, y, z = "xyz"
del x
del y,
del (z)
del ()
a, b, c, d, e, f, g = "abcdefg"
del a, (b, c), (d, (e, f))
a, b, c, d, e, f, g = "abcdefg"
del a, [b, c], (d, [e, f])
abcd = list("abcd")
del abcd[1:2]
compile("del a, (b[0].c, (d.e, f.g[1:2])), [h.i.j], ()", "<testcase>", "exec")
def test_pass_stmt(self):
# 'pass'
pass
@@ -1062,8 +1086,7 @@ class GrammarTests(unittest.TestCase):
self.assertEqual(g2(False), 0)
self.assertEqual(g2(True), ('end', 1))
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_yield(self):
# Allowed as standalone statement
def g(): yield 1
@@ -1103,8 +1126,7 @@ class GrammarTests(unittest.TestCase):
# Check annotation refleak on SyntaxError
check_syntax_error(self, "def g(a:(yield)): pass")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_yield_in_comprehensions(self):
# Check yield in comprehensions
def g(): [x for x in [(yield 1)]]
@@ -1184,11 +1206,9 @@ class GrammarTests(unittest.TestCase):
self.fail("'assert True, msg' should not have "
"raised an AssertionError")
# TODO: RUSTPYTHON
@unittest.expectedFailure
# these tests fail if python is run with -O, so check __debug__
@unittest.skipUnless(__debug__, "Won't work if __debug__ is False")
def testAssert2(self):
def test_assert_failures(self):
try:
assert 0, "msg"
except AssertionError as e:
@@ -1203,11 +1223,38 @@ class GrammarTests(unittest.TestCase):
else:
self.fail("AssertionError not raised by 'assert False'")
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_syntax_warnings(self):
# Ensure that we warn users if they provide a non-zero length tuple as
# the assertion test.
self.check_syntax_warning('assert(x, "msg")',
'assertion is always true')
self.check_syntax_warning('assert(False, "msg")',
'assertion is always true')
self.check_syntax_warning('assert(False,)',
'assertion is always true')
with self.check_no_warnings(category=SyntaxWarning):
compile('assert x, "msg"', '<testcase>', 'exec')
compile('assert False, "msg"', '<testcase>', 'exec')
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_assert_warning_promotes_to_syntax_error(self):
# If SyntaxWarning is configured to be an error, it actually raises a
# SyntaxError.
# https://bugs.python.org/issue35029
with warnings.catch_warnings():
warnings.simplefilter('error', SyntaxWarning)
compile('assert x, "msg"', '<testcase>', 'exec')
try:
compile('assert x, "msg" ', '<testcase>', 'exec')
except SyntaxError:
self.fail('SyntaxError incorrectly raised for \'assert x, "msg"\'')
with self.assertRaises(SyntaxError):
compile('assert(x, "msg")', '<testcase>', 'exec')
with self.assertRaises(SyntaxError):
compile('assert(False, "msg")', '<testcase>', 'exec')
with self.assertRaises(SyntaxError):
compile('assert(False,)', '<testcase>', 'exec')
### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
@@ -1268,10 +1315,16 @@ class GrammarTests(unittest.TestCase):
result.append(x)
self.assertEqual(result, [1, 2, 3])
result = []
a = b = c = [1, 2, 3]
for x in *a, *b, *c:
result.append(x)
self.assertEqual(result, 3 * a)
def test_try(self):
### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite]
### | 'try' ':' suite 'finally' ':' suite
### except_clause: 'except' [expr ['as' expr]]
### except_clause: 'except' [expr ['as' NAME]]
try:
1/0
except ZeroDivisionError:
@@ -1289,6 +1342,36 @@ class GrammarTests(unittest.TestCase):
except (EOFError, TypeError, ZeroDivisionError) as msg: pass
try: pass
finally: pass
with self.assertRaises(SyntaxError):
compile("try:\n pass\nexcept Exception as a.b:\n pass", "?", "exec")
compile("try:\n pass\nexcept Exception as a[b]:\n pass", "?", "exec")
# TODO: RUSTPYTHON
'''
def test_try_star(self):
### try_stmt: 'try': suite (except_star_clause : suite) + ['else' ':' suite]
### except_star_clause: 'except*' expr ['as' NAME]
try:
1/0
except* ZeroDivisionError:
pass
else:
pass
try: 1/0
except* EOFError: pass
except* ZeroDivisionError as msg: pass
else: pass
try: 1/0
except* (EOFError, TypeError, ZeroDivisionError): pass
try: 1/0
except* (EOFError, TypeError, ZeroDivisionError) as msg: pass
try: pass
finally: pass
with self.assertRaises(SyntaxError):
compile("try:\n pass\nexcept* Exception as a.b:\n pass", "?", "exec")
compile("try:\n pass\nexcept* Exception as a[b]:\n pass", "?", "exec")
compile("try:\n pass\nexcept*:\n pass", "?", "exec")
'''
def test_suite(self):
# simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT
@@ -1333,17 +1416,24 @@ class GrammarTests(unittest.TestCase):
if 1 not in (): pass
if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in x is x is not x: pass
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_comparison_is_literal(self):
def check(test, msg='"is" with a literal'):
def check(test, msg):
self.check_syntax_warning(test, msg)
check('x is 1')
check('x is "thing"')
check('1 is x')
check('x is y is 1')
check('x is not 1', '"is not" with a literal')
check('x is 1', '"is" with \'int\' literal')
check('x is "thing"', '"is" with \'str\' literal')
check('1 is x', '"is" with \'int\' literal')
check('x is y is 1', '"is" with \'int\' literal')
check('x is not 1', '"is not" with \'int\' literal')
check('x is not (1, 2)', '"is not" with \'tuple\' literal')
check('(1, 2) is not x', '"is not" with \'tuple\' literal')
check('None is 1', '"is" with \'int\' literal')
check('1 is None', '"is" with \'int\' literal')
check('x == 3 is y', '"is" with \'int\' literal')
check('x == "thing" is y', '"is" with \'str\' literal')
with warnings.catch_warnings():
warnings.simplefilter('error', SyntaxWarning)
@@ -1351,9 +1441,12 @@ class GrammarTests(unittest.TestCase):
compile('x is False', '<testcase>', 'exec')
compile('x is True', '<testcase>', 'exec')
compile('x is ...', '<testcase>', 'exec')
compile('None is x', '<testcase>', 'exec')
compile('False is x', '<testcase>', 'exec')
compile('True is x', '<testcase>', 'exec')
compile('... is x', '<testcase>', 'exec')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_warn_missed_comma(self):
def check(test):
self.check_syntax_warning(test, msg)
@@ -1483,7 +1576,7 @@ class GrammarTests(unittest.TestCase):
s = a[-5:]
s = a[:-1]
s = a[-4:-3]
# A rough test of SF bug 1333982. http://python.org/sf/1333982
# A rough test of SF bug 1333982. https://bugs.python.org/issue1333982
# The testing here is fairly incomplete.
# Test cases should include: commas with 1 and 2 colons
d = {}
@@ -1530,6 +1623,8 @@ class GrammarTests(unittest.TestCase):
### testlist: test (',' test)* [',']
# These have been exercised enough above
# TODO: RUSTPYTHON
'''
def test_classdef(self):
# 'class' NAME ['(' [testlist] ')'] ':' suite
class B: pass
@@ -1542,13 +1637,28 @@ class GrammarTests(unittest.TestCase):
def meth2(self, arg): pass
def meth3(self, a1, a2): pass
# decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE
# decorator: '@' namedexpr_test NEWLINE
# decorators: decorator+
# decorated: decorators (classdef | funcdef)
def class_decorator(x): return x
@class_decorator
class G: pass
# Test expressions as decorators (PEP 614):
@False or class_decorator
class H: pass
@d := class_decorator
class I: pass
@lambda c: class_decorator(c)
class J: pass
@[..., class_decorator, ...][1]
class K: pass
@class_decorator(class_decorator)(class_decorator)
class L: pass
@[class_decorator][0].__call__.__call__
class M: pass
'''
def test_dictcomps(self):
# dictorsetmaker: ( (test ':' test (comp_for |
# (',' test ':' test)* [','])) |
@@ -1693,6 +1803,54 @@ class GrammarTests(unittest.TestCase):
with manager() as x, manager():
pass
with (
manager()
):
pass
with (
manager() as x
):
pass
with (
manager() as (x, y),
manager() as z,
):
pass
with (
manager(),
manager()
):
pass
with (
manager() as x,
manager() as y
):
pass
with (
manager() as x,
manager()
):
pass
with (
manager() as x,
manager() as y,
manager() as z,
):
pass
with (
manager() as x,
manager() as y,
manager(),
):
pass
def test_if_else_expr(self):
# Test ifelse expressions in various cases
def _checkeval(msg, ret):
@@ -1815,6 +1973,18 @@ class GrammarTests(unittest.TestCase):
with self.assertRaises(Done):
foo().send(None)
def test_complex_lambda(self):
def test1(foo, bar):
return ""
def test2():
return f"{test1(
foo=lambda: '、、、、、、、、、、、、、、、、、',
bar=lambda: 'abcdefghijklmnopqrstuvwxyz 123456789 123456789',
)}"
self.assertEqual(test2(), "")
if __name__ == '__main__':
unittest.main()
+1 -3
View File
@@ -352,9 +352,7 @@ def blowstack(fxn, arg, compare_to):
# Make sure that calling isinstance with a deeply nested tuple for its
# argument will raise RecursionError eventually.
tuple_arg = (compare_to,)
# XXX: RUSTPYTHON; support.exceeds_recursion_limit() is not available yet.
import sys
for cnt in range(sys.getrecursionlimit()+5):
for cnt in range(support.exceeds_recursion_limit()):
tuple_arg = (tuple_arg,)
fxn(arg, tuple_arg)
+3 -5
View File
@@ -58,8 +58,7 @@ class KeywordOnlyArgTestCase(unittest.TestCase):
fundef = "def f(*, %s):\n pass\n" % ', '.join('i%d' % i for i in range(300))
compile(fundef, "<test>", "single")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def testTooManyPositionalErrorMessage(self):
def f(a, b=None, *, c=None):
pass
@@ -158,8 +157,7 @@ class KeywordOnlyArgTestCase(unittest.TestCase):
# used to fail with a SystemError.
lambda *, k1=unittest: None
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_mangling(self):
class X:
def f(self, *, __a=42):
@@ -174,7 +172,7 @@ class KeywordOnlyArgTestCase(unittest.TestCase):
pass
self.assertEqual(str(err.exception), "name 'b' is not defined")
with self.assertRaises(NameError) as err:
f = lambda v=a, x=b, *, y=c, z=d: None
g = lambda v=a, x=b, *, y=c, z=d: None
self.assertEqual(str(err.exception), "name 'b' is not defined")
+18
View File
@@ -5,6 +5,7 @@ import errno
import os
import select
import socket
from test import support
import time
import unittest
@@ -256,6 +257,23 @@ class TestKQueue(unittest.TestCase):
self.addCleanup(kqueue.close)
self.assertEqual(os.get_inheritable(kqueue.fileno()), False)
@support.requires_fork()
def test_fork(self):
# gh-110395: kqueue objects must be closed after fork
kqueue = select.kqueue()
if (pid := os.fork()) == 0:
try:
self.assertTrue(kqueue.closed)
with self.assertRaisesRegex(ValueError, "closed kqueue"):
kqueue.fileno()
except:
os._exit(1)
finally:
os._exit(0)
else:
support.wait_process(pid, exitcode=0)
self.assertFalse(kqueue.closed) # child done, we're still open.
if __name__ == "__main__":
unittest.main()
+5 -6
View File
@@ -19,12 +19,11 @@ class PowTest(unittest.TestCase):
self.assertEqual(pow(2, i), pow2)
if i != 30 : pow2 = pow2*2
for othertype in (int,):
for i in list(range(-10, 0)) + list(range(1, 10)):
ii = type(i)
for j in range(1, 11):
jj = -othertype(j)
pow(ii, jj)
for i in list(range(-10, 0)) + list(range(1, 10)):
ii = type(i)
inv = pow(ii, -1) # inverse of ii
for jj in range(-10, 0):
self.assertAlmostEqual(pow(ii, jj), pow(inv, -jj))
for othertype in int, float:
for i in range(1, 100):
+1 -1
View File
@@ -374,7 +374,7 @@ class QueryTestCase(unittest.TestCase):
return super().__new__(Temperature, celsius_degrees)
def __repr__(self):
kelvin_degrees = self + 273.15
return f"{kelvin_degrees}°K"
return f"{kelvin_degrees:.2f}°K"
self.assertEqual(pprint.pformat(Temperature(1000)), '1273.15°K')
def test_sorted_dict(self):
+1
View File
@@ -221,6 +221,7 @@ class MiscTest(unittest.TestCase):
self.assertRaises(Exc, func, Bad())
@support.no_tracing
@support.infinite_recursion(25)
def test_recursion(self):
# Check that comparison for recursive objects fails gracefully
from collections import UserList
-1
View File
@@ -4,7 +4,6 @@ import _pyio as pyio
import unittest
import os
import sys
from test import support
from test.support import os_helper
+6 -1
View File
@@ -1,6 +1,6 @@
# Check every path through every method of UserDict
from test import mapping_tests
from test import mapping_tests, support
import unittest
import collections
@@ -213,6 +213,11 @@ class UserDictTest(mapping_tests.TestHashMappingProtocol):
else:
self.fail("g[42] didn't raise KeyError")
# Decorate existing test with recursion limit, because
# the test is for C structure, but `UserDict` is a Python structure.
test_repr_deep = support.infinite_recursion(25)(
mapping_tests.TestHashMappingProtocol.test_repr_deep,
)
if __name__ == "__main__":
+52 -5
View File
@@ -5,6 +5,7 @@ __author__ = "Mike Bland"
__email__ = "mbland at acm dot org"
import sys
import traceback
import unittest
from collections import deque
from contextlib import _GeneratorContextManager, contextmanager, nullcontext
@@ -79,11 +80,11 @@ class Nested(object):
try:
if mgr.__exit__(*ex):
ex = (None, None, None)
except:
ex = sys.exc_info()
except BaseException as e:
ex = (type(e), e, e.__traceback__)
self.entered = None
if ex is not exc_info:
raise ex[0](ex[1]).with_traceback(ex[2])
raise ex
class MockNested(Nested):
@@ -170,7 +171,10 @@ class FailureTestCase(unittest.TestCase):
def shouldThrow():
ct = EnterThrows()
self.foo = None
with ct as self.foo:
# Ruff complains that we're redefining `self.foo` here,
# but the whole point of the test is to check that `self.foo`
# is *not* redefined (because `__enter__` raises)
with ct as self.foo: # noqa: F811
pass
self.assertRaises(RuntimeError, shouldThrow)
self.assertEqual(self.foo, None)
@@ -251,7 +255,6 @@ class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin):
self.assertAfterWithGeneratorInvariantsNoError(foo)
def testInlineGeneratorBoundToExistingVariable(self):
foo = None
with mock_contextmanager_generator() as foo:
self.assertInWithGeneratorInvariants(foo)
self.assertAfterWithGeneratorInvariantsNoError(foo)
@@ -749,5 +752,49 @@ class NestedWith(unittest.TestCase):
self.assertEqual(10, b1)
self.assertEqual(20, b2)
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'FrameSummary' object has no attribute 'end_lineno'
def testExceptionLocation(self):
# The location of an exception raised from
# __init__, __enter__ or __exit__ of a context
# manager should be just the context manager expression,
# pinpointing the precise context manager in case there
# is more than one.
def init_raises():
try:
with self.Dummy(), self.InitRaises() as cm, self.Dummy() as d:
pass
except Exception as e:
return e
def enter_raises():
try:
with self.EnterRaises(), self.Dummy() as d:
pass
except Exception as e:
return e
def exit_raises():
try:
with self.ExitRaises(), self.Dummy() as d:
pass
except Exception as e:
return e
for func, expected in [(init_raises, "self.InitRaises()"),
(enter_raises, "self.EnterRaises()"),
(exit_raises, "self.ExitRaises()"),
]:
with self.subTest(func):
exc = func()
f = traceback.extract_tb(exc.__traceback__)[0]
indent = 16
co = func.__code__
self.assertEqual(f.lineno, co.co_firstlineno + 2)
self.assertEqual(f.end_lineno, co.co_firstlineno + 2)
self.assertEqual(f.line[f.colno - indent : f.end_colno - indent],
expected)
if __name__ == '__main__':
unittest.main()