mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Merge pull request #6115 from ShaharNaveh/update-some-tests-2
Update some tests from 3.13.7
This commit is contained in:
15 files changed
+856
-377
No files matched your search
Vendored
+1
-125
@@ -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):
|
||||
|
||||
|
||||
Vendored
+3
-3
@@ -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):
|
||||
|
||||
Vendored
+138
-48
@@ -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()
|
||||
Vendored
+262
@@ -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()
|
||||
Vendored
+55
-39
@@ -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
|
||||
|
||||
Vendored
+310
-140
@@ -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()
|
||||
Vendored
+1
-3
@@ -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)
|
||||
|
||||
|
||||
Vendored
+3
-5
@@ -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")
|
||||
|
||||
|
||||
|
||||
Vendored
+18
@@ -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()
|
||||
Vendored
+5
-6
@@ -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):
|
||||
|
||||
Vendored
+1
-1
@@ -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):
|
||||
|
||||
Vendored
+1
@@ -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
|
||||
|
||||
Vendored
-1
@@ -4,7 +4,6 @@ import _pyio as pyio
|
||||
import unittest
|
||||
import os
|
||||
import sys
|
||||
from test import support
|
||||
from test.support import os_helper
|
||||
|
||||
|
||||
|
||||
Vendored
+6
-1
@@ -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__":
|
||||
|
||||
Vendored
+52
-5
@@ -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()
|
||||
Reference in new issue
Block a user