mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Update some tests to 3.14.5 (#7990)
* Update `test_embed.py` to 3.14.5 * Update `test_cmd_line*` to 3.14.5 * Update unicode related tests * Update `test_script_helper.py` * Update `test_gc.py`
This commit is contained in:
1 parent
024201c050
commit
620faab734
13 files changed
+2672
-222
No files matched your search
Vendored
+62
@@ -0,0 +1,62 @@
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
|
||||
|
||||
# bpo-46417: Test that structseq types used by the sys module are still
|
||||
# valid when Py_Finalize()/Py_Initialize() are called multiple times.
|
||||
class TestStructSeq(unittest.TestCase):
|
||||
# test PyTypeObject members
|
||||
def check_structseq(self, obj_type):
|
||||
# ob_refcnt
|
||||
self.assertGreaterEqual(sys.getrefcount(obj_type), 1)
|
||||
# tp_base
|
||||
self.assertIsSubclass(obj_type, tuple)
|
||||
# tp_bases
|
||||
self.assertEqual(obj_type.__bases__, (tuple,))
|
||||
# tp_dict
|
||||
self.assertIsInstance(obj_type.__dict__, types.MappingProxyType)
|
||||
# tp_mro
|
||||
self.assertEqual(obj_type.__mro__, (obj_type, tuple, object))
|
||||
# tp_name
|
||||
self.assertIsInstance(type.__name__, str)
|
||||
# tp_subclasses
|
||||
self.assertEqual(obj_type.__subclasses__(), [])
|
||||
|
||||
def test_sys_attrs(self):
|
||||
for attr_name in (
|
||||
'flags', # FlagsType
|
||||
'float_info', # FloatInfoType
|
||||
'hash_info', # Hash_InfoType
|
||||
'int_info', # Int_InfoType
|
||||
'thread_info', # ThreadInfoType
|
||||
'version_info', # VersionInfoType
|
||||
):
|
||||
with self.subTest(attr=attr_name):
|
||||
attr = getattr(sys, attr_name)
|
||||
self.check_structseq(type(attr))
|
||||
|
||||
def test_sys_funcs(self):
|
||||
func_names = ['get_asyncgen_hooks'] # AsyncGenHooksType
|
||||
if hasattr(sys, 'getwindowsversion'):
|
||||
func_names.append('getwindowsversion') # WindowsVersionType
|
||||
for func_name in func_names:
|
||||
with self.subTest(func=func_name):
|
||||
func = getattr(sys, func_name)
|
||||
obj = func()
|
||||
self.check_structseq(type(obj))
|
||||
|
||||
|
||||
try:
|
||||
unittest.main(
|
||||
module=(
|
||||
'__main__'
|
||||
if __name__ == '__main__'
|
||||
# Avoiding a circular import:
|
||||
else sys.modules['test._test_embed_structseq']
|
||||
)
|
||||
)
|
||||
except SystemExit as exc:
|
||||
if exc.args[0] != 0:
|
||||
raise
|
||||
print("Tests passed")
|
||||
Vendored
+408
-65
@@ -3,17 +3,23 @@
|
||||
# See test_cmd_line_script.py for testing of script execution
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import sysconfig
|
||||
import tempfile
|
||||
import textwrap
|
||||
import unittest
|
||||
from test import support
|
||||
from test.support import os_helper
|
||||
from test.support import force_not_colorized
|
||||
from test.support import threading_helper
|
||||
from test.support.script_helper import (
|
||||
spawn_python, kill_python, assert_python_ok, assert_python_failure,
|
||||
interpreter_requires_environment
|
||||
)
|
||||
from textwrap import dedent
|
||||
|
||||
|
||||
if not support.has_subprocess_support:
|
||||
raise unittest.SkipTest("test module requires subprocess")
|
||||
@@ -33,11 +39,13 @@ class CmdLineTest(unittest.TestCase):
|
||||
|
||||
def verify_valid_flag(self, cmd_line):
|
||||
rc, out, err = assert_python_ok(cmd_line)
|
||||
self.assertTrue(out == b'' or out.endswith(b'\n'))
|
||||
if out != b'':
|
||||
self.assertEndsWith(out, b'\n')
|
||||
self.assertNotIn(b'Traceback', out)
|
||||
self.assertNotIn(b'Traceback', err)
|
||||
return out
|
||||
|
||||
@support.cpython_only
|
||||
def test_help(self):
|
||||
self.verify_valid_flag('-h')
|
||||
self.verify_valid_flag('-?')
|
||||
@@ -48,20 +56,28 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertNotIn(b'-X dev', out)
|
||||
self.assertLess(len(lines), 50)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@support.cpython_only
|
||||
def test_help_env(self):
|
||||
out = self.verify_valid_flag('--help-env')
|
||||
self.assertIn(b'PYTHONHOME', out)
|
||||
# Env vars in each section should be sorted alphabetically
|
||||
# (ignoring underscores so PYTHON_FOO and PYTHONFOO intermix naturally)
|
||||
sort_key = lambda name: name.replace(b'_', b'').lower()
|
||||
sections = out.split(b'These variables have equivalent')
|
||||
for section in sections:
|
||||
envvars = re.findall(rb'^(PYTHON\w+)', section, re.MULTILINE)
|
||||
self.assertEqual(envvars, sorted(envvars, key=sort_key),
|
||||
"env vars should be sorted alphabetically")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@support.cpython_only
|
||||
def test_help_xoptions(self):
|
||||
out = self.verify_valid_flag('--help-xoptions')
|
||||
self.assertIn(b'-X dev', out)
|
||||
options = re.findall(rb'^-X (\w+)', out, re.MULTILINE)
|
||||
self.assertEqual(options, sorted(options),
|
||||
"options should be sorted alphabetically")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@support.cpython_only
|
||||
def test_help_all(self):
|
||||
out = self.verify_valid_flag('--help-all')
|
||||
lines = out.splitlines()
|
||||
@@ -80,12 +96,13 @@ class CmdLineTest(unittest.TestCase):
|
||||
def test_site_flag(self):
|
||||
self.verify_valid_flag('-S')
|
||||
|
||||
@support.cpython_only
|
||||
def test_version(self):
|
||||
version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
|
||||
for switch in '-V', '--version', '-VV':
|
||||
rc, out, err = assert_python_ok(switch)
|
||||
self.assertFalse(err.startswith(version))
|
||||
self.assertTrue(out.startswith(version))
|
||||
self.assertNotStartsWith(err, version)
|
||||
self.assertStartsWith(out, version)
|
||||
|
||||
def test_verbose(self):
|
||||
# -v causes imports to write to stderr. If the write to
|
||||
@@ -145,8 +162,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
else:
|
||||
self.assertEqual(err, b'')
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@support.cpython_only
|
||||
def test_xoption_frozen_modules(self):
|
||||
tests = {
|
||||
('=on', 'FrozenImporter'),
|
||||
@@ -161,6 +177,18 @@ class CmdLineTest(unittest.TestCase):
|
||||
res = assert_python_ok(*cmd)
|
||||
self.assertRegex(res.out.decode('utf-8'), expected)
|
||||
|
||||
@support.cpython_only
|
||||
def test_env_var_frozen_modules(self):
|
||||
tests = {
|
||||
('on', 'FrozenImporter'),
|
||||
('off', 'SourceFileLoader'),
|
||||
}
|
||||
for raw, expected in tests:
|
||||
cmd = ['-c', 'import os; print(os.__spec__.loader, end="")']
|
||||
with self.subTest(raw):
|
||||
res = assert_python_ok(*cmd, PYTHON_FROZEN_MODULES=raw)
|
||||
self.assertRegex(res.out.decode('utf-8'), expected)
|
||||
|
||||
def test_run_module(self):
|
||||
# Test expected operation of the '-m' switch
|
||||
# Switch needs an argument
|
||||
@@ -173,6 +201,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
# All good if module is located and run successfully
|
||||
assert_python_ok('-m', 'timeit', '-n', '1')
|
||||
|
||||
@unittest.expectedFailureIf(support.is_android, "TODO: RUSTPYTHON")
|
||||
def test_run_module_bug1764407(self):
|
||||
# -m and -i need to play well together
|
||||
# Runs the timeit module and checks the __main__
|
||||
@@ -184,6 +213,14 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertTrue(data.find(b'1 loop') != -1)
|
||||
self.assertTrue(data.find(b'__main__.Timer') != -1)
|
||||
|
||||
@support.cpython_only
|
||||
def test_null_byte_in_interactive_mode(self):
|
||||
# gh-140594: Fix an out of bounds read when a single NUL character
|
||||
# is read from the standard input in interactive mode.
|
||||
proc = spawn_python('-i')
|
||||
proc.communicate(b'\x00', timeout=support.SHORT_TIMEOUT)
|
||||
self.assertEqual(proc.returncode, 0)
|
||||
|
||||
def test_relativedir_bug46421(self):
|
||||
# Test `python -m unittest` with a relative directory beginning with ./
|
||||
# Note: We have to switch to the project's top module's directory, as per
|
||||
@@ -222,8 +259,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
# command line, but how subprocess does decode bytes to unicode. Python
|
||||
# doesn't decode the command line because Windows provides directly the
|
||||
# arguments as unicode (using wmain() instead of main()).
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
@unittest.skipIf(sys.platform == 'win32',
|
||||
'Windows has a native unicode API')
|
||||
def test_undecodable_code(self):
|
||||
@@ -259,8 +295,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
if not stdout.startswith(pattern):
|
||||
raise AssertionError("%a doesn't start with %a" % (stdout, pattern))
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
@unittest.skipIf(sys.platform == 'win32',
|
||||
'Windows has a native unicode API')
|
||||
def test_invalid_utf8_arg(self):
|
||||
@@ -272,12 +307,10 @@ class CmdLineTest(unittest.TestCase):
|
||||
# Test with default config, in the C locale, in the Python UTF-8 Mode.
|
||||
code = 'import sys, os; s=os.fsencode(sys.argv[1]); print(ascii(s))'
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
def run_default(arg):
|
||||
cmd = [sys.executable, '-c', code, arg]
|
||||
return subprocess.run(cmd, stdout=subprocess.PIPE, text=True)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
def run_c_locale(arg):
|
||||
cmd = [sys.executable, '-c', code, arg]
|
||||
env = dict(os.environ)
|
||||
@@ -285,7 +318,6 @@ class CmdLineTest(unittest.TestCase):
|
||||
return subprocess.run(cmd, stdout=subprocess.PIPE,
|
||||
text=True, env=env)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
def run_utf8_mode(arg):
|
||||
cmd = [sys.executable, '-X', 'utf8', '-c', code, arg]
|
||||
return subprocess.run(cmd, stdout=subprocess.PIPE, text=True)
|
||||
@@ -330,6 +362,8 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(stdout, expected)
|
||||
self.assertEqual(p.returncode, 0)
|
||||
|
||||
@unittest.skipIf(os.environ.get("PYTHONUNBUFFERED", "0") != "0",
|
||||
"Python stdio buffering is disabled.")
|
||||
def test_non_interactive_output_buffering(self):
|
||||
code = textwrap.dedent("""
|
||||
import sys
|
||||
@@ -369,7 +403,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
p.stdin.flush()
|
||||
data, rc = _kill_python_and_exit_code(p)
|
||||
self.assertEqual(rc, 0)
|
||||
self.assertTrue(data.startswith(b'x'), data)
|
||||
self.assertStartsWith(data, b'x')
|
||||
|
||||
def test_large_PYTHONPATH(self):
|
||||
path1 = "ABCDE" * 100
|
||||
@@ -406,8 +440,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
# for empty and unset PYTHONPATH
|
||||
self.assertEqual(out1, out2)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_displayhook_unencodable(self):
|
||||
for encoding in ('ascii', 'latin-1', 'utf-8'):
|
||||
env = os.environ.copy()
|
||||
@@ -475,6 +508,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertRegex(err.decode('ascii', 'ignore'), 'SyntaxError')
|
||||
self.assertEqual(b'', out)
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_stdout_flush_at_shutdown(self):
|
||||
# Issue #5319: if stdout.flush() fails at shutdown, an error should
|
||||
# be printed out.
|
||||
@@ -486,8 +520,9 @@ class CmdLineTest(unittest.TestCase):
|
||||
rc, out, err = assert_python_failure('-c', code)
|
||||
self.assertEqual(b'', out)
|
||||
self.assertEqual(120, rc)
|
||||
self.assertRegex(err.decode('ascii', 'ignore'),
|
||||
'Exception ignored in.*\nOSError: .*')
|
||||
self.assertIn(b'Exception ignored while flushing sys.stdout:\n'
|
||||
b'OSError: '.replace(b'\n', os.linesep.encode()),
|
||||
err)
|
||||
|
||||
def test_closed_stdout(self):
|
||||
# Issue #13444: if stdout has been explicitly closed, we should
|
||||
@@ -525,23 +560,19 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(err, b'')
|
||||
self.assertEqual(p.returncode, 42)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_no_stdin(self):
|
||||
self._test_no_stdio(['stdin'])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_no_stdout(self):
|
||||
self._test_no_stdio(['stdout'])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_no_stderr(self):
|
||||
self._test_no_stdio(['stderr'])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_no_std_streams(self):
|
||||
self._test_no_stdio(['stdin', 'stdout', 'stderr'])
|
||||
|
||||
@@ -593,8 +624,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
print("del sys.modules['__main__']", file=script)
|
||||
assert_python_ok(filename)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@support.cpython_only
|
||||
def test_unknown_options(self):
|
||||
rc, out, err = assert_python_failure('-E', '-z')
|
||||
self.assertIn(b'Unknown option: -z', err)
|
||||
@@ -641,6 +671,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
cwd=tmpdir)
|
||||
self.assertEqual(out.strip(), b"ok")
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_sys_flags_set(self):
|
||||
# Issue 31845: a startup refactoring broke reading flags from env vars
|
||||
for value, expected in (("", 0), ("1", 1), ("text", 1), ("2", 2)):
|
||||
@@ -650,22 +681,19 @@ class CmdLineTest(unittest.TestCase):
|
||||
PYTHONDONTWRITEBYTECODE=value,
|
||||
PYTHONVERBOSE=value,
|
||||
)
|
||||
dont_write_bytecode = int(bool(value))
|
||||
expected_bool = int(bool(value))
|
||||
code = (
|
||||
"import sys; "
|
||||
"sys.stderr.write(str(sys.flags)); "
|
||||
f"""sys.exit(not (
|
||||
sys.flags.debug == sys.flags.optimize ==
|
||||
sys.flags.verbose ==
|
||||
{expected}
|
||||
and sys.flags.dont_write_bytecode == {dont_write_bytecode}
|
||||
sys.flags.optimize == sys.flags.verbose == {expected}
|
||||
and sys.flags.debug == sys.flags.dont_write_bytecode == {expected_bool}
|
||||
))"""
|
||||
)
|
||||
with self.subTest(envar_value=value):
|
||||
assert_python_ok('-c', code, **env_vars)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_set_pycache_prefix(self):
|
||||
# sys.pycache_prefix can be set from either -X pycache_prefix or
|
||||
# PYTHONPYCACHEPREFIX env var, with the former taking precedence.
|
||||
@@ -711,6 +739,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(proc.returncode, 0, proc)
|
||||
return proc.stdout.rstrip()
|
||||
|
||||
@support.cpython_only
|
||||
def test_xdev(self):
|
||||
# sys.flags.dev_mode
|
||||
code = "import sys; print(sys.flags.dev_mode)"
|
||||
@@ -747,22 +776,24 @@ class CmdLineTest(unittest.TestCase):
|
||||
|
||||
# Memory allocator debug hooks
|
||||
try:
|
||||
import _testcapi
|
||||
import _testinternalcapi # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
code = "import _testcapi; print(_testcapi.pymem_getallocatorsname())"
|
||||
code = "import _testinternalcapi; print(_testinternalcapi.pymem_getallocatorsname())"
|
||||
with support.SuppressCrashReport():
|
||||
out = self.run_xdev("-c", code, check_exitcode=False)
|
||||
if support.with_pymalloc():
|
||||
alloc_name = "pymalloc_debug"
|
||||
elif support.Py_GIL_DISABLED:
|
||||
alloc_name = "mimalloc_debug"
|
||||
else:
|
||||
alloc_name = "malloc_debug"
|
||||
self.assertEqual(out, alloc_name)
|
||||
|
||||
# Faulthandler
|
||||
try:
|
||||
import faulthandler
|
||||
import faulthandler # noqa: F401
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
@@ -791,8 +822,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(proc.returncode, 0, proc)
|
||||
return proc.stdout.rstrip()
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_warnings_filter_precedence(self):
|
||||
expected_filters = ("error::BytesWarning "
|
||||
"once::UserWarning "
|
||||
@@ -815,7 +845,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(out, expected_filters)
|
||||
|
||||
def check_pythonmalloc(self, env_var, name):
|
||||
code = 'import _testcapi; print(_testcapi.pymem_getallocatorsname())'
|
||||
code = 'import _testinternalcapi; print(_testinternalcapi.pymem_getallocatorsname())'
|
||||
env = dict(os.environ)
|
||||
env.pop('PYTHONDEVMODE', None)
|
||||
if env_var is not None:
|
||||
@@ -831,12 +861,16 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(proc.stdout.rstrip(), name)
|
||||
self.assertEqual(proc.returncode, 0)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@support.cpython_only
|
||||
def test_pythonmalloc(self):
|
||||
# Test the PYTHONMALLOC environment variable
|
||||
malloc = not support.Py_GIL_DISABLED
|
||||
pymalloc = support.with_pymalloc()
|
||||
if pymalloc:
|
||||
mimalloc = support.with_mimalloc()
|
||||
if support.Py_GIL_DISABLED:
|
||||
default_name = 'mimalloc_debug' if support.Py_DEBUG else 'mimalloc'
|
||||
default_name_debug = 'mimalloc_debug'
|
||||
elif pymalloc:
|
||||
default_name = 'pymalloc_debug' if support.Py_DEBUG else 'pymalloc'
|
||||
default_name_debug = 'pymalloc_debug'
|
||||
else:
|
||||
@@ -846,21 +880,28 @@ class CmdLineTest(unittest.TestCase):
|
||||
tests = [
|
||||
(None, default_name),
|
||||
('debug', default_name_debug),
|
||||
('malloc', 'malloc'),
|
||||
('malloc_debug', 'malloc_debug'),
|
||||
]
|
||||
if malloc:
|
||||
tests.extend([
|
||||
('malloc', 'malloc'),
|
||||
('malloc_debug', 'malloc_debug'),
|
||||
])
|
||||
if pymalloc:
|
||||
tests.extend((
|
||||
('pymalloc', 'pymalloc'),
|
||||
('pymalloc_debug', 'pymalloc_debug'),
|
||||
))
|
||||
if mimalloc:
|
||||
tests.extend((
|
||||
('mimalloc', 'mimalloc'),
|
||||
('mimalloc_debug', 'mimalloc_debug'),
|
||||
))
|
||||
|
||||
for env_var, name in tests:
|
||||
with self.subTest(env_var=env_var, name=name):
|
||||
self.check_pythonmalloc(env_var, name)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_pythondevmode_env(self):
|
||||
# Test the PYTHONDEVMODE environment variable
|
||||
code = "import sys; print(sys.flags.dev_mode)"
|
||||
@@ -879,6 +920,138 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(proc.stdout.rstrip(), 'True')
|
||||
self.assertEqual(proc.returncode, 0, proc)
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_python_gil(self):
|
||||
cases = [
|
||||
# (env, opt, expected, msg)
|
||||
('1', None, '1', "PYTHON_GIL=1"),
|
||||
(None, '1', '1', "-X gil=1"),
|
||||
]
|
||||
|
||||
if support.Py_GIL_DISABLED:
|
||||
cases.extend(
|
||||
[
|
||||
(None, None, 'None', "no options set"),
|
||||
('0', None, '0', "PYTHON_GIL=0"),
|
||||
('1', '0', '0', "-X gil=0 overrides PYTHON_GIL=1"),
|
||||
(None, '0', '0', "-X gil=0"),
|
||||
]
|
||||
)
|
||||
else:
|
||||
cases.extend(
|
||||
[
|
||||
(None, None, '1', '-X gil=0 (unsupported by this build)'),
|
||||
('1', None, '1', 'PYTHON_GIL=0 (unsupported by this build)'),
|
||||
]
|
||||
)
|
||||
code = "import sys; print(sys.flags.gil)"
|
||||
environ = dict(os.environ)
|
||||
|
||||
for env, opt, expected, msg in cases:
|
||||
with self.subTest(msg, env=env, opt=opt):
|
||||
environ.pop('PYTHON_GIL', None)
|
||||
if env is not None:
|
||||
environ['PYTHON_GIL'] = env
|
||||
extra_args = []
|
||||
if opt is not None:
|
||||
extra_args = ['-X', f'gil={opt}']
|
||||
|
||||
proc = subprocess.run([sys.executable, *extra_args, '-c', code],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True, env=environ)
|
||||
self.assertEqual(proc.returncode, 0, proc)
|
||||
self.assertEqual(proc.stdout.rstrip(), expected)
|
||||
self.assertEqual(proc.stderr, '')
|
||||
|
||||
def test_python_asyncio_debug(self):
|
||||
code = "import asyncio; print(asyncio.new_event_loop().get_debug())"
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHONASYNCIODEBUG='1')
|
||||
self.assertIn(b'True', out)
|
||||
|
||||
@unittest.skipUnless(sysconfig.get_config_var('Py_TRACE_REFS'), "Requires --with-trace-refs build option")
|
||||
def test_python_dump_refs(self):
|
||||
code = 'import sys; sys._clear_internal_caches()'
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHONDUMPREFS='1')
|
||||
self.assertEqual(rc, 0)
|
||||
|
||||
@unittest.skipUnless(sysconfig.get_config_var('Py_TRACE_REFS'), "Requires --with-trace-refs build option")
|
||||
def test_python_dump_refs_file(self):
|
||||
with tempfile.NamedTemporaryFile() as dump_file:
|
||||
code = 'import sys; sys._clear_internal_caches()'
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHONDUMPREFSFILE=dump_file.name)
|
||||
self.assertEqual(rc, 0)
|
||||
with open(dump_file.name, 'r') as file:
|
||||
contents = file.read()
|
||||
self.assertIn('Remaining objects', contents)
|
||||
|
||||
@unittest.expectedFailureIf(sys.platform == "darwin", "TODO: RUSTPYTHON")
|
||||
@unittest.skipUnless(sys.platform == 'darwin', 'PYTHONEXECUTABLE only works on macOS')
|
||||
def test_python_executable(self):
|
||||
code = 'import sys; print(sys.executable)'
|
||||
expected = "/busr/bbin/bpython"
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHONEXECUTABLE=expected)
|
||||
self.assertIn(expected.encode(), out)
|
||||
|
||||
@unittest.expectedFailureIf(support.MS_WINDOWS, "TODO: RUSTPYTHON")
|
||||
@unittest.skipUnless(support.MS_WINDOWS, 'Test only applicable on Windows')
|
||||
def test_python_legacy_windows_fs_encoding(self):
|
||||
code = "import sys; print(sys.getfilesystemencoding())"
|
||||
expected = 'mbcs'
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHONLEGACYWINDOWSFSENCODING='1')
|
||||
self.assertIn(expected.encode(), out)
|
||||
|
||||
@unittest.expectedFailureIf(support.MS_WINDOWS, "TODO: RUSTPYTHON")
|
||||
@unittest.skipUnless(support.MS_WINDOWS, 'Test only applicable on Windows')
|
||||
def test_python_legacy_windows_stdio(self):
|
||||
# Test that _WindowsConsoleIO is used when PYTHONLEGACYWINDOWSSTDIO
|
||||
# is not set.
|
||||
# We cannot use PIPE becase it prevents creating new console.
|
||||
# So we use exit code.
|
||||
code = "import sys; sys.exit(type(sys.stdout.buffer.raw).__name__ != '_WindowsConsoleIO')"
|
||||
env = os.environ.copy()
|
||||
env["PYTHONLEGACYWINDOWSSTDIO"] = ""
|
||||
p = subprocess.run([sys.executable, "-c", code],
|
||||
creationflags=subprocess.CREATE_NEW_CONSOLE,
|
||||
env=env)
|
||||
self.assertEqual(p.returncode, 0)
|
||||
|
||||
# Then test that FIleIO is used when PYTHONLEGACYWINDOWSSTDIO is set.
|
||||
code = "import sys; sys.exit(type(sys.stdout.buffer.raw).__name__ != 'FileIO')"
|
||||
env["PYTHONLEGACYWINDOWSSTDIO"] = "1"
|
||||
p = subprocess.run([sys.executable, "-c", code],
|
||||
creationflags=subprocess.CREATE_NEW_CONSOLE,
|
||||
env=env)
|
||||
self.assertEqual(p.returncode, 0)
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
@unittest.skipIf("-fsanitize" in sysconfig.get_config_vars().get('PY_CFLAGS', ()),
|
||||
"PYTHONMALLOCSTATS doesn't work with ASAN")
|
||||
def test_python_malloc_stats(self):
|
||||
code = "pass"
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHONMALLOCSTATS='1')
|
||||
self.assertIn(b'Small block threshold', err)
|
||||
|
||||
def test_python_user_base(self):
|
||||
code = "import site; print(site.USER_BASE)"
|
||||
expected = "/custom/userbase"
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHONUSERBASE=expected)
|
||||
self.assertIn(expected.encode(), out)
|
||||
|
||||
def test_python_basic_repl(self):
|
||||
# Currently this only tests that the env var is set. See test_pyrepl.test_python_basic_repl.
|
||||
code = "import os; print('PYTHON_BASIC_REPL' in os.environ)"
|
||||
expected = "True"
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHON_BASIC_REPL='1')
|
||||
self.assertIn(expected.encode(), out)
|
||||
|
||||
@unittest.skipUnless(sysconfig.get_config_var('HAVE_PERF_TRAMPOLINE'), "Requires HAVE_PERF_TRAMPOLINE support")
|
||||
def test_python_perf_jit_support(self):
|
||||
code = "import sys; print(sys.is_stack_trampoline_active())"
|
||||
expected = "True"
|
||||
rc, out, err = assert_python_ok('-c', code, PYTHON_PERF_JIT_SUPPORT='1')
|
||||
self.assertIn(expected.encode(), out)
|
||||
|
||||
@unittest.skipUnless(sys.platform == 'win32',
|
||||
'bpo-32457 only applies on Windows')
|
||||
def test_argv0_normalization(self):
|
||||
@@ -891,16 +1064,15 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(proc.returncode, 0, proc)
|
||||
self.assertEqual(proc.stdout.strip(), b'0')
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@support.cpython_only
|
||||
def test_parsing_error(self):
|
||||
args = [sys.executable, '-I', '--unknown-option']
|
||||
proc = subprocess.run(args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True)
|
||||
err_msg = "unknown option --unknown-option\nusage: "
|
||||
self.assertTrue(proc.stderr.startswith(err_msg), proc.stderr)
|
||||
err_msg = "Unknown option: --unknown-option\nusage: "
|
||||
self.assertStartsWith(proc.stderr, err_msg)
|
||||
self.assertNotEqual(proc.returncode, 0)
|
||||
|
||||
def test_int_max_str_digits(self):
|
||||
@@ -915,11 +1087,8 @@ class CmdLineTest(unittest.TestCase):
|
||||
assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='foo')
|
||||
assert_python_failure('-c', code, PYTHONINTMAXSTRDIGITS='100')
|
||||
|
||||
def res2int(res):
|
||||
out = res.out.strip().decode("utf-8")
|
||||
return tuple(int(i) for i in out.split())
|
||||
|
||||
res = assert_python_ok('-c', code)
|
||||
res2int = self.res2int
|
||||
current_max = sys.get_int_max_str_digits()
|
||||
self.assertEqual(res2int(res), (current_max, current_max))
|
||||
res = assert_python_ok('-X', 'int_max_str_digits=0', '-c', code)
|
||||
@@ -939,6 +1108,181 @@ class CmdLineTest(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(res2int(res), (6000, 6000))
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_cmd_dedent(self):
|
||||
# test that -c auto-dedents its arguments
|
||||
test_cases = [
|
||||
(
|
||||
"""
|
||||
print('space-auto-dedent')
|
||||
""",
|
||||
"space-auto-dedent",
|
||||
),
|
||||
(
|
||||
dedent(
|
||||
"""
|
||||
^^^print('tab-auto-dedent')
|
||||
"""
|
||||
).replace("^", "\t"),
|
||||
"tab-auto-dedent",
|
||||
),
|
||||
(
|
||||
dedent(
|
||||
"""
|
||||
^^if 1:
|
||||
^^^^print('mixed-auto-dedent-1')
|
||||
^^print('mixed-auto-dedent-2')
|
||||
"""
|
||||
).replace("^", "\t \t"),
|
||||
"mixed-auto-dedent-1\nmixed-auto-dedent-2",
|
||||
),
|
||||
(
|
||||
'''
|
||||
data = """$
|
||||
|
||||
this data has an empty newline above and a newline with spaces below $
|
||||
$
|
||||
"""$
|
||||
if 1: $
|
||||
print(repr(data))$
|
||||
'''.replace(
|
||||
"$", ""
|
||||
),
|
||||
# Note: entirely blank lines are normalized to \n, even if they
|
||||
# are part of a data string. This is consistent with
|
||||
# textwrap.dedent behavior, but might not be intuitive.
|
||||
"'\\n\\nthis data has an empty newline above and a newline with spaces below \\n\\n'",
|
||||
),
|
||||
(
|
||||
'',
|
||||
'',
|
||||
),
|
||||
(
|
||||
' \t\n\t\n \t\t\t \t\t \t\n\t\t \n\n\n\t\t\t ',
|
||||
'',
|
||||
),
|
||||
]
|
||||
for code, expected in test_cases:
|
||||
# Run the auto-dedent case
|
||||
args1 = sys.executable, '-c', code
|
||||
proc1 = subprocess.run(args1, stdout=subprocess.PIPE)
|
||||
self.assertEqual(proc1.returncode, 0, proc1)
|
||||
output1 = proc1.stdout.strip().decode(encoding='utf-8')
|
||||
|
||||
# Manually dedent beforehand, check the result is the same.
|
||||
args2 = sys.executable, '-c', dedent(code)
|
||||
proc2 = subprocess.run(args2, stdout=subprocess.PIPE)
|
||||
self.assertEqual(proc2.returncode, 0, proc2)
|
||||
output2 = proc2.stdout.strip().decode(encoding='utf-8')
|
||||
|
||||
self.assertEqual(output1, output2)
|
||||
self.assertEqual(output1.replace('\r\n', '\n'), expected)
|
||||
|
||||
def test_cmd_dedent_failcase(self):
|
||||
# Mixing tabs and spaces is not allowed
|
||||
from textwrap import dedent
|
||||
template = dedent(
|
||||
'''
|
||||
-+if 1:
|
||||
+-++ print('will fail')
|
||||
''')
|
||||
code = template.replace('-', ' ').replace('+', '\t')
|
||||
assert_python_failure('-c', code)
|
||||
code = template.replace('-', '\t').replace('+', ' ')
|
||||
assert_python_failure('-c', code)
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_cpu_count(self):
|
||||
code = "import os; print(os.cpu_count(), os.process_cpu_count())"
|
||||
res = assert_python_ok('-X', 'cpu_count=4321', '-c', code)
|
||||
self.assertEqual(self.res2int(res), (4321, 4321))
|
||||
res = assert_python_ok('-c', code, PYTHON_CPU_COUNT='1234')
|
||||
self.assertEqual(self.res2int(res), (1234, 1234))
|
||||
|
||||
def test_cpu_count_default(self):
|
||||
code = "import os; print(os.cpu_count(), os.process_cpu_count())"
|
||||
res = assert_python_ok('-X', 'cpu_count=default', '-c', code)
|
||||
self.assertEqual(self.res2int(res), (os.cpu_count(), os.process_cpu_count()))
|
||||
res = assert_python_ok('-X', 'cpu_count=default', '-c', code, PYTHON_CPU_COUNT='1234')
|
||||
self.assertEqual(self.res2int(res), (os.cpu_count(), os.process_cpu_count()))
|
||||
res = assert_python_ok('-c', code, PYTHON_CPU_COUNT='default')
|
||||
self.assertEqual(self.res2int(res), (os.cpu_count(), os.process_cpu_count()))
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_import_time(self):
|
||||
# os is not imported at startup
|
||||
code = 'import os; import os'
|
||||
|
||||
for case in 'importtime', 'importtime=1', 'importtime=true':
|
||||
res = assert_python_ok('-X', case, '-c', code)
|
||||
res_err = res.err.decode('utf-8')
|
||||
self.assertRegex(res_err, r'import time: \s*\d+ \| \s*\d+ \| \s*os')
|
||||
self.assertNotRegex(res_err, r'import time: cached\s* \| cached\s* \| os')
|
||||
|
||||
res = assert_python_ok('-X', 'importtime=2', '-c', code)
|
||||
res_err = res.err.decode('utf-8')
|
||||
self.assertRegex(res_err, r'import time: \s*\d+ \| \s*\d+ \| \s*os')
|
||||
self.assertRegex(res_err, r'import time: cached\s* \| cached\s* \| os')
|
||||
|
||||
assert_python_failure('-X', 'importtime=-1', '-c', code)
|
||||
assert_python_failure('-X', 'importtime=3', '-c', code)
|
||||
|
||||
def res2int(self, res):
|
||||
out = res.out.strip().decode("utf-8")
|
||||
return tuple(int(i) for i in out.split())
|
||||
|
||||
@unittest.skipUnless(support.Py_GIL_DISABLED,
|
||||
"PYTHON_TLBC and -X tlbc"
|
||||
" only supported in Py_GIL_DISABLED builds")
|
||||
@threading_helper.requires_working_threading()
|
||||
def test_disable_thread_local_bytecode(self):
|
||||
code = """if 1:
|
||||
import threading
|
||||
def test(x, y):
|
||||
return x + y
|
||||
t = threading.Thread(target=test, args=(1,2))
|
||||
t.start()
|
||||
t.join()"""
|
||||
assert_python_ok("-W", "always", "-X", "tlbc=0", "-c", code)
|
||||
assert_python_ok("-W", "always", "-c", code, PYTHON_TLBC="0")
|
||||
|
||||
@unittest.skipUnless(support.Py_GIL_DISABLED,
|
||||
"PYTHON_TLBC and -X tlbc"
|
||||
" only supported in Py_GIL_DISABLED builds")
|
||||
@threading_helper.requires_working_threading()
|
||||
def test_enable_thread_local_bytecode(self):
|
||||
code = """if 1:
|
||||
import threading
|
||||
def test(x, y):
|
||||
return x + y
|
||||
t = threading.Thread(target=test, args=(1,2))
|
||||
t.start()
|
||||
t.join()"""
|
||||
# The functionality of thread-local bytecode is tested more extensively
|
||||
# in test_thread_local_bytecode
|
||||
assert_python_ok("-W", "always", "-X", "tlbc=1", "-c", code)
|
||||
assert_python_ok("-W", "always", "-c", code, PYTHON_TLBC="1")
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
@unittest.skipUnless(support.Py_GIL_DISABLED,
|
||||
"PYTHON_TLBC and -X tlbc"
|
||||
" only supported in Py_GIL_DISABLED builds")
|
||||
def test_invalid_thread_local_bytecode(self):
|
||||
rc, out, err = assert_python_failure("-X", "tlbc")
|
||||
self.assertIn(b"tlbc=n: n is missing or invalid", err)
|
||||
rc, out, err = assert_python_failure("-X", "tlbc=foo")
|
||||
self.assertIn(b"tlbc=n: n is missing or invalid", err)
|
||||
rc, out, err = assert_python_failure("-X", "tlbc=-1")
|
||||
self.assertIn(b"tlbc=n: n is missing or invalid", err)
|
||||
rc, out, err = assert_python_failure("-X", "tlbc=2")
|
||||
self.assertIn(b"tlbc=n: n is missing or invalid", err)
|
||||
rc, out, err = assert_python_failure(PYTHON_TLBC="foo")
|
||||
self.assertIn(b"PYTHON_TLBC=N: N is missing or invalid", err)
|
||||
rc, out, err = assert_python_failure(PYTHON_TLBC="-1")
|
||||
self.assertIn(b"PYTHON_TLBC=N: N is missing or invalid", err)
|
||||
rc, out, err = assert_python_failure(PYTHON_TLBC="2")
|
||||
self.assertIn(b"PYTHON_TLBC=N: N is missing or invalid", err)
|
||||
|
||||
|
||||
@unittest.skipIf(interpreter_requires_environment(),
|
||||
'Cannot run -I tests when PYTHON env vars are required.')
|
||||
@@ -979,6 +1323,7 @@ class IgnoreEnvironmentTest(unittest.TestCase):
|
||||
|
||||
|
||||
class SyntaxErrorTests(unittest.TestCase):
|
||||
@force_not_colorized
|
||||
def check_string(self, code):
|
||||
proc = subprocess.run([sys.executable, "-"], input=code,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
@@ -986,13 +1331,11 @@ class SyntaxErrorTests(unittest.TestCase):
|
||||
self.assertNotEqual(proc.stderr, None)
|
||||
self.assertIn(b"\nSyntaxError", proc.stderr)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailureIf(not support.is_android, "TODO: RUSTPYTHON")
|
||||
def test_tokenizer_error_with_stdin(self):
|
||||
self.check_string(b"(1+2+3")
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailureIf(not support.is_android, "TODO: RUSTPYTHON")
|
||||
def test_decoding_error_at_the_end_of_the_line(self):
|
||||
self.check_string(br"'\u1f'")
|
||||
|
||||
|
||||
Vendored
+56
-36
@@ -14,8 +14,7 @@ import io
|
||||
|
||||
import textwrap
|
||||
from test import support
|
||||
from test.support import import_helper
|
||||
from test.support import os_helper
|
||||
from test.support import import_helper, is_apple, os_helper
|
||||
from test.support.script_helper import (
|
||||
make_pkg, make_script, make_zip_pkg, make_zip_script,
|
||||
assert_python_ok, assert_python_failure, spawn_python, kill_python)
|
||||
@@ -89,6 +88,8 @@ def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename,
|
||||
importlib.invalidate_caches()
|
||||
return to_return
|
||||
|
||||
|
||||
@support.force_not_colorized_test_class
|
||||
class CmdLineTest(unittest.TestCase):
|
||||
def _check_output(self, script_name, exit_code, data,
|
||||
expected_file, expected_argv0,
|
||||
@@ -152,15 +153,13 @@ class CmdLineTest(unittest.TestCase):
|
||||
print('Expected output: %r' % expected_msg)
|
||||
self.assertIn(expected_msg.encode('utf-8'), err)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_dash_c_loader(self):
|
||||
rc, out, err = assert_python_ok("-c", "print(__loader__)")
|
||||
expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
|
||||
self.assertIn(expected, out)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_stdin_loader(self):
|
||||
# Unfortunately, there's no way to automatically test the fully
|
||||
# interactive REPL, since that code path only gets executed when
|
||||
@@ -207,21 +206,23 @@ class CmdLineTest(unittest.TestCase):
|
||||
stderr = p.stderr if separate_stderr else p.stdout
|
||||
self.assertIn(b'Traceback ', stderr.readline())
|
||||
self.assertIn(b'File "<stdin>"', stderr.readline())
|
||||
self.assertIn(b'1/0', stderr.readline())
|
||||
self.assertIn(b' ~^~', stderr.readline())
|
||||
self.assertIn(b'ZeroDivisionError', stderr.readline())
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON, test hang in middle")
|
||||
@unittest.skip("TODO: RUSTPYTHON; test hang in middle")
|
||||
def test_repl_stdout_flush(self):
|
||||
self.check_repl_stdout_flush()
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON, test hang in middle")
|
||||
@unittest.skip("TODO: RUSTPYTHON; test hang in middle")
|
||||
def test_repl_stdout_flush_separate_stderr(self):
|
||||
self.check_repl_stdout_flush(True)
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON, test hang in middle")
|
||||
@unittest.skip("TODO: RUSTPYTHON; test hang in middle")
|
||||
def test_repl_stderr_flush(self):
|
||||
self.check_repl_stderr_flush()
|
||||
|
||||
@unittest.skip("TODO: RUSTPYTHON, test hang in middle")
|
||||
@unittest.skip("TODO: RUSTPYTHON; test hang in middle")
|
||||
def test_repl_stderr_flush_separate_stderr(self):
|
||||
self.check_repl_stderr_flush(True)
|
||||
|
||||
@@ -233,8 +234,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
importlib.machinery.SourceFileLoader,
|
||||
expected_cwd=script_dir)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_script_abspath(self):
|
||||
# pass the script using the relative path, expect the absolute path
|
||||
# in __file__
|
||||
@@ -390,8 +390,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
"be directly executed")
|
||||
self._check_import_error(["-m", "test_pkg"], msg, cwd=script_dir)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_issue8202(self):
|
||||
# Make sure package __init__ modules see "-m" in sys.argv0 while
|
||||
# searching for the module to execute
|
||||
@@ -554,7 +553,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
script = textwrap.dedent("""\
|
||||
try:
|
||||
raise ValueError
|
||||
except:
|
||||
except ValueError:
|
||||
raise NameError from None
|
||||
""")
|
||||
with os_helper.temp_dir() as script_dir:
|
||||
@@ -562,18 +561,23 @@ class CmdLineTest(unittest.TestCase):
|
||||
exitcode, stdout, stderr = assert_python_failure(script_name)
|
||||
text = stderr.decode('ascii').split('\n')
|
||||
self.assertEqual(len(text), 5)
|
||||
self.assertTrue(text[0].startswith('Traceback'))
|
||||
self.assertTrue(text[1].startswith(' File '))
|
||||
self.assertTrue(text[3].startswith('NameError'))
|
||||
self.assertStartsWith(text[0], 'Traceback')
|
||||
self.assertStartsWith(text[1], ' File ')
|
||||
self.assertStartsWith(text[3], 'NameError')
|
||||
|
||||
@unittest.expectedFailureIf(sys.platform == "linux", "TODO: RUSTPYTHON")
|
||||
@unittest.expectedFailureIf(sys.platform in ("android", "linux"), "TODO: RUSTPYTHON")
|
||||
def test_non_ascii(self):
|
||||
# Mac OS X denies the creation of a file with an invalid UTF-8 name.
|
||||
# Apple platforms deny the creation of a file with an invalid UTF-8 name.
|
||||
# Windows allows creating a name with an arbitrary bytes name, but
|
||||
# Python cannot a undecodable bytes argument to a subprocess.
|
||||
# WASI does not permit invalid UTF-8 names.
|
||||
if (os_helper.TESTFN_UNDECODABLE
|
||||
and sys.platform not in ('win32', 'darwin', 'emscripten', 'wasi')):
|
||||
# Emscripten/WASI does not permit invalid UTF-8 names.
|
||||
if (
|
||||
os_helper.TESTFN_UNDECODABLE
|
||||
and sys.platform not in {
|
||||
"win32", "emscripten", "wasi"
|
||||
}
|
||||
and not is_apple
|
||||
):
|
||||
name = os.fsdecode(os_helper.TESTFN_UNDECODABLE)
|
||||
elif os_helper.TESTFN_NONASCII:
|
||||
name = os_helper.TESTFN_NONASCII
|
||||
@@ -641,8 +645,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertNotIn("\f", text)
|
||||
self.assertIn("\n 1 + 1 = 2\n ^^^^^\n", text)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_syntaxerror_multi_line_fstring(self):
|
||||
script = 'foo = f"""{}\nfoo"""\n'
|
||||
with os_helper.temp_dir() as script_dir:
|
||||
@@ -657,8 +660,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
],
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_syntaxerror_invalid_escape_sequence_multi_line(self):
|
||||
script = 'foo = """\\q"""\n'
|
||||
with os_helper.temp_dir() as script_dir:
|
||||
@@ -669,13 +671,13 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertEqual(
|
||||
stderr.splitlines()[-3:],
|
||||
[ b' foo = """\\q"""',
|
||||
b' ^^^^^^^^',
|
||||
b'SyntaxError: invalid escape sequence \'\\q\''
|
||||
b' ^^',
|
||||
b'SyntaxError: "\\q" is an invalid escape sequence. '
|
||||
b'Did you mean "\\\\q"? A raw string is also an option.'
|
||||
],
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_syntaxerror_null_bytes(self):
|
||||
script = "x = '\0' nothing to see here\n';import os;os.system('echo pwnd')\n"
|
||||
with os_helper.temp_dir() as script_dir:
|
||||
@@ -688,8 +690,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
],
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_syntaxerror_null_bytes_in_multiline_string(self):
|
||||
scripts = ["\n'''\nmultilinestring\0\n'''", "\nf'''\nmultilinestring\0\n'''"] # Both normal and f-strings
|
||||
with os_helper.temp_dir() as script_dir:
|
||||
@@ -703,6 +704,26 @@ class CmdLineTest(unittest.TestCase):
|
||||
]
|
||||
)
|
||||
|
||||
def test_source_lines_are_shown_when_running_source(self):
|
||||
_, _, stderr = assert_python_failure("-c", "1/0")
|
||||
expected_lines = [
|
||||
b'Traceback (most recent call last):',
|
||||
b' File "<string>", line 1, in <module>',
|
||||
b' 1/0',
|
||||
b' ~^~',
|
||||
b'ZeroDivisionError: division by zero']
|
||||
self.assertEqual(stderr.splitlines(), expected_lines)
|
||||
|
||||
def test_syntaxerror_does_not_crash(self):
|
||||
script = "nonlocal x\n"
|
||||
with os_helper.temp_dir() as script_dir:
|
||||
script_name = _make_test_script(script_dir, 'script', script)
|
||||
exitcode, stdout, stderr = assert_python_failure(script_name)
|
||||
text = io.TextIOWrapper(io.BytesIO(stderr), 'ascii').read()
|
||||
# It used to crash in https://github.com/python/cpython/issues/111132
|
||||
self.assertEndsWith(text,
|
||||
'SyntaxError: nonlocal declaration not allowed at module level\n')
|
||||
|
||||
def test_consistent_sys_path_for_direct_execution(self):
|
||||
# This test case ensures that the following all give the same
|
||||
# sys.path configuration:
|
||||
@@ -771,8 +792,7 @@ class CmdLineTest(unittest.TestCase):
|
||||
traceback_lines = stderr.decode().splitlines()
|
||||
self.assertIn("No module named script_pkg", traceback_lines[-1])
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_nonexisting_script(self):
|
||||
# bpo-34783: "./python script.py" must not crash
|
||||
# if the script file doesn't exist.
|
||||
@@ -788,11 +808,11 @@ class CmdLineTest(unittest.TestCase):
|
||||
self.assertIn(": can't open file ", err)
|
||||
self.assertNotEqual(proc.returncode, 0)
|
||||
|
||||
@unittest.skipIf(sys.platform.startswith("darwin"), "TODO: RUSTPYTHON; Problems with Mac os descriptor")
|
||||
@unittest.skipUnless(os.path.exists('/dev/fd/0'), 'requires /dev/fd platform')
|
||||
@unittest.skipIf(sys.platform.startswith("freebsd") and
|
||||
os.stat("/dev").st_dev == os.stat("/dev/fd").st_dev,
|
||||
"Requires fdescfs mounted on /dev/fd on FreeBSD")
|
||||
@unittest.skipIf(sys.platform.startswith("darwin"), "TODO: RUSTPYTHON Problems with Mac os descriptor")
|
||||
def test_script_as_dev_fd(self):
|
||||
# GH-87235: On macOS passing a non-trivial script to /dev/fd/N can cause
|
||||
# problems because all open /dev/fd/N file descriptors share the same
|
||||
|
||||
Vendored
+2032
File diff suppressed because it is too large.
Load diff
Vendored
+71
-106
@@ -7,7 +7,7 @@ from test.support import (verbose, refcount_test,
|
||||
Py_GIL_DISABLED)
|
||||
from test.support.import_helper import import_module
|
||||
from test.support.os_helper import temp_dir, TESTFN, unlink
|
||||
from test.support.script_helper import assert_python_ok, make_script, run_test_script
|
||||
from test.support.script_helper import assert_python_ok, make_script
|
||||
from test.support import threading_helper, gc_threshold
|
||||
|
||||
import gc
|
||||
@@ -236,8 +236,7 @@ class GCTests(unittest.TestCase):
|
||||
# is 3 because it includes f's code object.
|
||||
self.assertIn(gc.collect(), (2, 3))
|
||||
|
||||
# TODO: RUSTPYTHON - weakref clear ordering differs from 3.15+
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON; - weakref clear ordering differs from 3.15+
|
||||
def test_function_tp_clear_leaves_consistent_state(self):
|
||||
# https://github.com/python/cpython/issues/91636
|
||||
code = """if 1:
|
||||
@@ -311,28 +310,6 @@ class GCTests(unittest.TestCase):
|
||||
self.assertRegex(stdout, rb"""\A\s*func=None""")
|
||||
self.assertFalse(stderr)
|
||||
|
||||
# TODO: RUSTPYTHON - _datetime module not available
|
||||
@unittest.expectedFailure
|
||||
def test_datetime_weakref_cycle(self):
|
||||
# https://github.com/python/cpython/issues/132413
|
||||
# If the weakref used by the datetime extension gets cleared by the GC (due to being
|
||||
# in an unreachable cycle) then datetime functions would crash (get_module_state()
|
||||
# was returning a NULL pointer). This bug is fixed by clearing weakrefs without
|
||||
# callbacks *after* running finalizers.
|
||||
code = """if 1:
|
||||
import _datetime
|
||||
class C:
|
||||
def __del__(self):
|
||||
print('__del__ called')
|
||||
_datetime.timedelta(days=1) # crash?
|
||||
|
||||
l = [C()]
|
||||
l.append(l)
|
||||
"""
|
||||
rc, stdout, stderr = assert_python_ok("-c", code)
|
||||
self.assertEqual(rc, 0)
|
||||
self.assertEqual(stdout.strip(), b'__del__ called')
|
||||
|
||||
@refcount_test
|
||||
def test_frame(self):
|
||||
def f():
|
||||
@@ -423,11 +400,19 @@ class GCTests(unittest.TestCase):
|
||||
# each call to collect(N)
|
||||
x = []
|
||||
gc.collect(0)
|
||||
# x is now in the old gen
|
||||
# x is now in gen 1
|
||||
a, b, c = gc.get_count()
|
||||
# We don't check a since its exact values depends on
|
||||
gc.collect(1)
|
||||
# x is now in gen 2
|
||||
d, e, f = gc.get_count()
|
||||
gc.collect(2)
|
||||
# x is now in gen 3
|
||||
g, h, i = gc.get_count()
|
||||
# We don't check a, d, g since their exact values depends on
|
||||
# internal implementation details of the interpreter.
|
||||
self.assertEqual((b, c), (1, 0))
|
||||
self.assertEqual((e, f), (0, 1))
|
||||
self.assertEqual((h, i), (0, 0))
|
||||
|
||||
def test_trashcan(self):
|
||||
class Ouch:
|
||||
@@ -682,8 +667,9 @@ class GCTests(unittest.TestCase):
|
||||
gc.collect()
|
||||
self.assertEqual(len(ouch), 2) # else the callbacks didn't run
|
||||
for x in ouch:
|
||||
# The weakref should be cleared before executing the callback.
|
||||
self.assertIsNone(x)
|
||||
# If the callback resurrected one of these guys, the instance
|
||||
# would be damaged, with an empty __dict__.
|
||||
self.assertEqual(x, None)
|
||||
|
||||
def test_bug21435(self):
|
||||
# This is a poor test - its only virtue is that it happened to
|
||||
@@ -845,20 +831,17 @@ class GCTests(unittest.TestCase):
|
||||
rc, out, err = assert_python_ok(TESTFN)
|
||||
self.assertEqual(out.strip(), b'__del__ called')
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_get_stats(self):
|
||||
stats = gc.get_stats()
|
||||
self.assertEqual(len(stats), 3)
|
||||
for st in stats:
|
||||
self.assertIsInstance(st, dict)
|
||||
self.assertEqual(
|
||||
set(st),
|
||||
{"collected", "collections", "uncollectable", "candidates", "duration"}
|
||||
)
|
||||
self.assertEqual(set(st),
|
||||
{"collected", "collections", "uncollectable"})
|
||||
self.assertGreaterEqual(st["collected"], 0)
|
||||
self.assertGreaterEqual(st["collections"], 0)
|
||||
self.assertGreaterEqual(st["uncollectable"], 0)
|
||||
self.assertGreaterEqual(st["candidates"], 0)
|
||||
self.assertGreaterEqual(st["duration"], 0)
|
||||
# Check that collection counts are incremented correctly
|
||||
if gc.isenabled():
|
||||
self.addCleanup(gc.enable)
|
||||
@@ -869,25 +852,11 @@ class GCTests(unittest.TestCase):
|
||||
self.assertEqual(new[0]["collections"], old[0]["collections"] + 1)
|
||||
self.assertEqual(new[1]["collections"], old[1]["collections"])
|
||||
self.assertEqual(new[2]["collections"], old[2]["collections"])
|
||||
self.assertGreater(new[0]["duration"], old[0]["duration"])
|
||||
self.assertEqual(new[1]["duration"], old[1]["duration"])
|
||||
self.assertEqual(new[2]["duration"], old[2]["duration"])
|
||||
for stat in ["collected", "uncollectable", "candidates"]:
|
||||
self.assertGreaterEqual(new[0][stat], old[0][stat])
|
||||
self.assertEqual(new[1][stat], old[1][stat])
|
||||
self.assertEqual(new[2][stat], old[2][stat])
|
||||
gc.collect(2)
|
||||
old, new = new, gc.get_stats()
|
||||
self.assertEqual(new[0]["collections"], old[0]["collections"])
|
||||
new = gc.get_stats()
|
||||
self.assertEqual(new[0]["collections"], old[0]["collections"] + 1)
|
||||
self.assertEqual(new[1]["collections"], old[1]["collections"])
|
||||
self.assertEqual(new[2]["collections"], old[2]["collections"] + 1)
|
||||
self.assertEqual(new[0]["duration"], old[0]["duration"])
|
||||
self.assertEqual(new[1]["duration"], old[1]["duration"])
|
||||
self.assertGreater(new[2]["duration"], old[2]["duration"])
|
||||
for stat in ["collected", "uncollectable", "candidates"]:
|
||||
self.assertEqual(new[0][stat], old[0][stat])
|
||||
self.assertEqual(new[1][stat], old[1][stat])
|
||||
self.assertGreaterEqual(new[2][stat], old[2][stat])
|
||||
|
||||
def test_freeze(self):
|
||||
gc.freeze()
|
||||
@@ -911,10 +880,42 @@ class GCTests(unittest.TestCase):
|
||||
self.assertTrue(
|
||||
any(l is element for element in gc.get_objects(generation=0))
|
||||
)
|
||||
gc.collect()
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=1))
|
||||
)
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=2))
|
||||
)
|
||||
gc.collect(generation=0)
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=0))
|
||||
)
|
||||
self.assertTrue(
|
||||
any(l is element for element in gc.get_objects(generation=1))
|
||||
)
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=2))
|
||||
)
|
||||
gc.collect(generation=1)
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=0))
|
||||
)
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=1))
|
||||
)
|
||||
self.assertTrue(
|
||||
any(l is element for element in gc.get_objects(generation=2))
|
||||
)
|
||||
gc.collect(generation=2)
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=0))
|
||||
)
|
||||
self.assertFalse(
|
||||
any(l is element for element in gc.get_objects(generation=1))
|
||||
)
|
||||
self.assertTrue(
|
||||
any(l is element for element in gc.get_objects(generation=2))
|
||||
)
|
||||
del l
|
||||
gc.collect()
|
||||
|
||||
@@ -1203,37 +1204,6 @@ class GCTests(unittest.TestCase):
|
||||
""")
|
||||
assert_python_ok("-c", source)
|
||||
|
||||
def test_do_not_cleanup_type_subclasses_before_finalization(self):
|
||||
# See https://github.com/python/cpython/issues/135552
|
||||
# If we cleanup weakrefs for tp_subclasses before calling
|
||||
# the finalizer (__del__) then the line `fail = BaseNode.next.next`
|
||||
# should fail because we are trying to access a subclass
|
||||
# attribute. But subclass type cache was not properly invalidated.
|
||||
code = """
|
||||
class BaseNode:
|
||||
def __del__(self):
|
||||
BaseNode.next = BaseNode.next.next
|
||||
fail = BaseNode.next.next
|
||||
|
||||
class Node(BaseNode):
|
||||
pass
|
||||
|
||||
BaseNode.next = Node()
|
||||
BaseNode.next.next = Node()
|
||||
"""
|
||||
# this test checks garbage collection while interp
|
||||
# finalization
|
||||
assert_python_ok("-c", textwrap.dedent(code))
|
||||
|
||||
code_inside_function = textwrap.dedent(F"""
|
||||
def test():
|
||||
{textwrap.indent(code, ' ')}
|
||||
|
||||
test()
|
||||
""")
|
||||
# this test checks regular garbage collection
|
||||
assert_python_ok("-c", code_inside_function)
|
||||
|
||||
|
||||
@unittest.skipUnless(Py_GIL_DISABLED, "requires free-threaded GC")
|
||||
@unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi")
|
||||
@@ -1252,16 +1222,14 @@ class GCTests(unittest.TestCase):
|
||||
# Use n // 2 just in case some other objects were collected.
|
||||
self.assertTrue(new_count - count > (n // 2))
|
||||
|
||||
|
||||
class IncrementalGCTests(unittest.TestCase):
|
||||
@requires_gil_enabled('need generational GC')
|
||||
@unittest.skipIf(_testinternalcapi is None, "requires _testinternalcapi")
|
||||
@requires_gil_enabled("Free threading does not support incremental GC")
|
||||
def test_incremental_gc_handles_fast_cycle_creation(self):
|
||||
# Run this test in a fresh process. The number of alive objects (which can
|
||||
# be from unit tests run before this one) can influence how quickly cyclic
|
||||
# garbage is found.
|
||||
script = support.findfile("_test_gc_fast_cycles.py")
|
||||
run_test_script(script)
|
||||
def test_heap_size(self):
|
||||
count = _testinternalcapi.get_tracked_heap_size()
|
||||
l = []
|
||||
self.assertEqual(count + 1, _testinternalcapi.get_tracked_heap_size())
|
||||
del l
|
||||
self.assertEqual(count, _testinternalcapi.get_tracked_heap_size())
|
||||
|
||||
|
||||
class GCCallbackTests(unittest.TestCase):
|
||||
@@ -1338,11 +1306,9 @@ class GCCallbackTests(unittest.TestCase):
|
||||
# Check that we got the right info dict for all callbacks
|
||||
for v in self.visit:
|
||||
info = v[2]
|
||||
self.assertIn("generation", info)
|
||||
self.assertIn("collected", info)
|
||||
self.assertIn("uncollectable", info)
|
||||
self.assertIn("candidates", info)
|
||||
self.assertIn("duration", info)
|
||||
self.assertTrue("generation" in info)
|
||||
self.assertTrue("collected" in info)
|
||||
self.assertTrue("uncollectable" in info)
|
||||
|
||||
def test_collect_generation(self):
|
||||
self.preclean()
|
||||
@@ -1518,8 +1484,8 @@ class GCTogglingTests(unittest.TestCase):
|
||||
assert not detector.gc_happened
|
||||
while not detector.gc_happened:
|
||||
i += 1
|
||||
if i > 100000:
|
||||
self.fail("gc didn't happen after 100000 iterations")
|
||||
if i > 10000:
|
||||
self.fail("gc didn't happen after 10000 iterations")
|
||||
self.assertEqual(len(ouch), 0)
|
||||
junk.append([]) # this will eventually trigger gc
|
||||
|
||||
@@ -1530,7 +1496,6 @@ class GCTogglingTests(unittest.TestCase):
|
||||
self.assertEqual(x, None)
|
||||
|
||||
@gc_threshold(1000, 0, 0)
|
||||
@unittest.skipIf(Py_GIL_DISABLED, "requires GC generations or increments")
|
||||
def test_bug1055820d(self):
|
||||
# Corresponds to temp2d.py in the bug report. This is very much like
|
||||
# test_bug1055820c, but uses a __del__ method instead of a weakref
|
||||
@@ -1591,8 +1556,8 @@ class GCTogglingTests(unittest.TestCase):
|
||||
gc.collect()
|
||||
while not detector.gc_happened:
|
||||
i += 1
|
||||
if i > 50000:
|
||||
self.fail("gc didn't happen after 50000 iterations")
|
||||
if i > 10000:
|
||||
self.fail("gc didn't happen after 10000 iterations")
|
||||
self.assertEqual(len(ouch), 0)
|
||||
junk.append([]) # this will eventually trigger gc
|
||||
|
||||
@@ -1609,8 +1574,8 @@ class GCTogglingTests(unittest.TestCase):
|
||||
detector = GC_Detector()
|
||||
while not detector.gc_happened:
|
||||
i += 1
|
||||
if i > 100000:
|
||||
self.fail("gc didn't happen after 100000 iterations")
|
||||
if i > 10000:
|
||||
self.fail("gc didn't happen after 10000 iterations")
|
||||
junk.append([]) # this will eventually trigger gc
|
||||
|
||||
try:
|
||||
@@ -1620,11 +1585,11 @@ class GCTogglingTests(unittest.TestCase):
|
||||
detector = GC_Detector()
|
||||
while not detector.gc_happened:
|
||||
i += 1
|
||||
if i > 100000:
|
||||
if i > 10000:
|
||||
break
|
||||
junk.append([]) # this may eventually trigger gc (if it is enabled)
|
||||
|
||||
self.assertEqual(i, 100001)
|
||||
self.assertEqual(i, 10001)
|
||||
finally:
|
||||
gc.enable()
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
-1
@@ -1 +0,0 @@
|
||||
|
||||
Vendored
+3
-3
@@ -3,7 +3,7 @@
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from test.support import script_helper
|
||||
from test.support import script_helper, requires_subprocess
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
@@ -69,12 +69,12 @@ class TestScriptHelper(unittest.TestCase):
|
||||
self.assertNotIn('-E', popen_command)
|
||||
|
||||
|
||||
@requires_subprocess()
|
||||
class TestScriptHelperEnvironment(unittest.TestCase):
|
||||
"""Code coverage for interpreter_requires_environment()."""
|
||||
|
||||
def setUp(self):
|
||||
self.assertTrue(
|
||||
hasattr(script_helper, '__cached_interp_requires_environment'))
|
||||
self.assertHasAttr(script_helper, '__cached_interp_requires_environment')
|
||||
# Reset the private cached state.
|
||||
script_helper.__dict__['__cached_interp_requires_environment'] = None
|
||||
|
||||
|
||||
Vendored
+36
-3
@@ -88,6 +88,9 @@ class UnicodeNamesTest(unittest.TestCase):
|
||||
self.checkletter("HANGUL SYLLABLE HWEOK", "\ud6f8")
|
||||
self.checkletter("HANGUL SYLLABLE HIH", "\ud7a3")
|
||||
|
||||
self.checkletter("haNGul SYllABle WAe", '\uc65c')
|
||||
self.checkletter("HAngUL syLLabLE waE", '\uc65c')
|
||||
|
||||
self.assertRaises(ValueError, unicodedata.name, "\ud7a4")
|
||||
|
||||
def test_cjk_unified_ideographs(self):
|
||||
@@ -103,6 +106,36 @@ class UnicodeNamesTest(unittest.TestCase):
|
||||
self.checkletter("CJK UNIFIED IDEOGRAPH-2B81D", "\U0002B81D")
|
||||
self.checkletter("CJK UNIFIED IDEOGRAPH-3134A", "\U0003134A")
|
||||
|
||||
self.checkletter("cjK UniFIeD idEogRAph-3aBc", "\u3abc")
|
||||
self.checkletter("CJk uNIfiEd IDeOGraPH-3AbC", "\u3abc")
|
||||
self.checkletter("cjK UniFIeD idEogRAph-2aBcD", "\U0002abcd")
|
||||
self.checkletter("CJk uNIfiEd IDeOGraPH-2AbCd", "\U0002abcd")
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError: got unexpected unicode
|
||||
def test_tangut_ideographs(self):
|
||||
self.checkletter("TANGUT IDEOGRAPH-17000", "\U00017000")
|
||||
self.checkletter("TANGUT IDEOGRAPH-187F7", "\U000187f7")
|
||||
self.checkletter("TANGUT IDEOGRAPH-18D00", "\U00018D00")
|
||||
self.checkletter("TANGUT IDEOGRAPH-18D08", "\U00018d08")
|
||||
self.checkletter("tangut ideograph-18d08", "\U00018d08")
|
||||
|
||||
def test_egyptian_hieroglyphs(self):
|
||||
self.checkletter("EGYPTIAN HIEROGLYPH-13460", "\U00013460")
|
||||
self.checkletter("EGYPTIAN HIEROGLYPH-143FA", "\U000143fa")
|
||||
self.checkletter("egyptian hieroglyph-143fa", "\U000143fa")
|
||||
|
||||
def test_khitan_small_script_characters(self):
|
||||
self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18B00", "\U00018b00")
|
||||
self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18CD5", "\U00018cd5")
|
||||
self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18CFF", "\U00018cff")
|
||||
self.checkletter("KHITAN SMALL SCRIPT CHARACTER-18CFF", "\U00018cff")
|
||||
self.checkletter("khitan small script character-18cff", "\U00018cff")
|
||||
|
||||
def test_nushu_characters(self):
|
||||
self.checkletter("NUSHU CHARACTER-1B170", "\U0001b170")
|
||||
self.checkletter("NUSHU CHARACTER-1B2FB", "\U0001b2fb")
|
||||
self.checkletter("nushu character-1b2fb", "\U0001b2fb")
|
||||
|
||||
def test_bmp_characters(self):
|
||||
for code in range(0x10000):
|
||||
char = chr(code)
|
||||
@@ -116,7 +149,7 @@ class UnicodeNamesTest(unittest.TestCase):
|
||||
self.checkletter("HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK", "\uFF9F")
|
||||
self.checkletter("FULLWIDTH LATIN SMALL LETTER A", "\uFF41")
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_aliases(self):
|
||||
# Check that the aliases defined in the NameAliases.txt file work.
|
||||
# This should be updated when new aliases are added or the file
|
||||
@@ -157,7 +190,7 @@ class UnicodeNamesTest(unittest.TestCase):
|
||||
unicodedata.name(chr(cp))
|
||||
self.assertEqual(str(cm.exception), 'no such name')
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_named_sequences_sample(self):
|
||||
# Check a few named sequences. See #12753.
|
||||
sequences = [
|
||||
@@ -174,7 +207,7 @@ class UnicodeNamesTest(unittest.TestCase):
|
||||
with self.assertRaises(KeyError):
|
||||
unicodedata.ucd_3_2_0.lookup(seqname)
|
||||
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_named_sequences_full(self):
|
||||
# Check all the named sequences
|
||||
def check_version(testfile):
|
||||
|
||||
+2
-2
@@ -125,8 +125,8 @@ class UnicodeFileTests(unittest.TestCase):
|
||||
# open(), os.stat(), etc. don't raise any exception.
|
||||
@unittest.skipIf(is_apple, 'irrelevant test on Apple platforms')
|
||||
@unittest.skipIf(
|
||||
support.is_emscripten or support.is_wasi,
|
||||
"test fails on Emscripten/WASI when host platform is macOS."
|
||||
support.is_wasi,
|
||||
"test fails on WASI when host platform is macOS."
|
||||
)
|
||||
def test_normalize(self):
|
||||
files = set(self.files)
|
||||
|
||||
Vendored
+2
-3
@@ -17,11 +17,10 @@ class PEP3131Test(unittest.TestCase):
|
||||
𝔘𝔫𝔦𝔠𝔬𝔡𝔢 = 1
|
||||
self.assertIn("Unicode", dir())
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_invalid(self):
|
||||
try:
|
||||
from test.tokenizedata import badsyntax_3131
|
||||
from test.tokenizedata import badsyntax_3131 # noqa: F401
|
||||
except SyntaxError as err:
|
||||
self.assertEqual(str(err),
|
||||
"invalid character '€' (U+20AC) (badsyntax_3131.py, line 2)")
|
||||
|
||||
Reference in new issue
Block a user