mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Sync selected Python 3.15 core library tests and repr type errors (#9321)
* Sync Python 3.15 core library tests and repr type errors Synchronize ten selected library paths from CPython 3.15.0 at d220409a13b77de7a6c30abe16ea90db01528edc using the canonical updater, retaining existing RustPython adapters and failure markers. Match generic __repr__ invalid-result errors to the qualified type-name format required by the canonical ExceptionGroup regression, preserving string results and exceptions raised by the implementation. Implementation, source review, and validation were AI-assisted. The model version identifier is unavailable; automated checks are not human verification. Bounded validation covers 43 passes and one canonical skip, not the full repository suites. Assisted-by: OpenAI Codex:model version unavailable * Preserve original escape decoder consumed length after callbacks Keep the original input length as consumed after successful unicode-escape and raw-unicode-escape decoding, including error-handler input replacement. Only report the current cursor when a non-final decode stops on incomplete input, matching CPython's codec wrappers and incomplete exits. Fix the canonical Unicode escape mutation regression that failed CI on Linux, macOS and Windows. Preserve all Lib tests and existing assertions. Bounded Linux validation: 55 passes and one canonical skip, CLI build and strict common/VM Clippy passed. Full repository suites were not run. Implementation, source review, and validation were AI-assisted. The model version identifier is unavailable; automated checks are not human verification. Assisted-by: OpenAI Codex:model version unavailable --------- Co-authored-by: youknowdot <336763669+youknowdot@users.noreply.github.com>
This commit is contained in:
1 parent
afe5d9030a
commit
c70e9b8443
13 files changed
+198
-126
No files matched your search
Vendored
+21
-90
@@ -29,7 +29,7 @@
|
||||
#
|
||||
# History:
|
||||
#
|
||||
# <see CVS and SVN checkin messages for history>
|
||||
# <see checkin messages for history>
|
||||
#
|
||||
# 1.0.9 - added invalidate_caches() function to invalidate cached values
|
||||
# 1.0.8 - changed Windows support to read version from kernel32.dll
|
||||
@@ -110,8 +110,6 @@ __copyright__ = """
|
||||
|
||||
"""
|
||||
|
||||
__version__ = '1.0.9'
|
||||
|
||||
import collections
|
||||
import os
|
||||
import re
|
||||
@@ -129,7 +127,7 @@ except ImportError:
|
||||
# Based on the description of the PHP's version_compare():
|
||||
# http://php.net/manual/en/function.version-compare.php
|
||||
|
||||
_ver_stages = {
|
||||
_ver_stages = frozendict({
|
||||
# any string not found in this dict, will get 0 assigned
|
||||
'dev': 10,
|
||||
'alpha': 20, 'a': 20,
|
||||
@@ -138,7 +136,7 @@ _ver_stages = {
|
||||
'RC': 50, 'rc': 50,
|
||||
# number, will get 100 assigned
|
||||
'pl': 200, 'p': 200,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
def _comparable_version(version):
|
||||
@@ -307,8 +305,7 @@ def _syscmd_ver(system='', release='', version='',
|
||||
text=True,
|
||||
encoding="locale",
|
||||
shell=True)
|
||||
except (OSError, subprocess.CalledProcessError) as why:
|
||||
#print('Command %s failed: %s' % (cmd, why))
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
continue
|
||||
else:
|
||||
break
|
||||
@@ -539,53 +536,6 @@ def ios_ver(system="", release="", model="", is_simulator=False):
|
||||
return IOSVersionInfo(system, release, model, is_simulator)
|
||||
|
||||
|
||||
def _java_getprop(name, default):
|
||||
"""This private helper is deprecated in 3.13 and will be removed in 3.15"""
|
||||
from java.lang import System
|
||||
try:
|
||||
value = System.getProperty(name)
|
||||
if value is None:
|
||||
return default
|
||||
return value
|
||||
except AttributeError:
|
||||
return default
|
||||
|
||||
def java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', '')):
|
||||
|
||||
""" Version interface for Jython.
|
||||
|
||||
Returns a tuple (release, vendor, vminfo, osinfo) with vminfo being
|
||||
a tuple (vm_name, vm_release, vm_vendor) and osinfo being a
|
||||
tuple (os_name, os_version, os_arch).
|
||||
|
||||
Values which cannot be determined are set to the defaults
|
||||
given as parameters (which all default to '').
|
||||
|
||||
"""
|
||||
import warnings
|
||||
warnings._deprecated('java_ver', remove=(3, 15))
|
||||
# Import the needed APIs
|
||||
try:
|
||||
import java.lang # noqa: F401
|
||||
except ImportError:
|
||||
return release, vendor, vminfo, osinfo
|
||||
|
||||
vendor = _java_getprop('java.vendor', vendor)
|
||||
release = _java_getprop('java.version', release)
|
||||
vm_name, vm_release, vm_vendor = vminfo
|
||||
vm_name = _java_getprop('java.vm.name', vm_name)
|
||||
vm_vendor = _java_getprop('java.vm.vendor', vm_vendor)
|
||||
vm_release = _java_getprop('java.vm.version', vm_release)
|
||||
vminfo = vm_name, vm_release, vm_vendor
|
||||
os_name, os_version, os_arch = osinfo
|
||||
os_arch = _java_getprop('java.os.arch', os_arch)
|
||||
os_name = _java_getprop('java.os.name', os_name)
|
||||
os_version = _java_getprop('java.os.version', os_version)
|
||||
osinfo = os_name, os_version, os_arch
|
||||
|
||||
return release, vendor, vminfo, osinfo
|
||||
|
||||
|
||||
AndroidVer = collections.namedtuple(
|
||||
"AndroidVer", "release api_level manufacturer model device is_emulator")
|
||||
|
||||
@@ -670,6 +620,9 @@ def system_alias(system, release, version):
|
||||
|
||||
### Various internal helpers
|
||||
|
||||
# Table for cleaning up characters in filenames.
|
||||
_SIMPLE_SUBSTITUTIONS = str.maketrans(r' /\:;"()', r'_-------')
|
||||
|
||||
def _platform(*args):
|
||||
|
||||
""" Helper to format the platform string in a filename
|
||||
@@ -679,28 +632,13 @@ def _platform(*args):
|
||||
platform = '-'.join(x.strip() for x in filter(len, args))
|
||||
|
||||
# Cleanup some possible filename obstacles...
|
||||
platform = platform.replace(' ', '_')
|
||||
platform = platform.replace('/', '-')
|
||||
platform = platform.replace('\\', '-')
|
||||
platform = platform.replace(':', '-')
|
||||
platform = platform.replace(';', '-')
|
||||
platform = platform.replace('"', '-')
|
||||
platform = platform.replace('(', '-')
|
||||
platform = platform.replace(')', '-')
|
||||
platform = platform.translate(_SIMPLE_SUBSTITUTIONS)
|
||||
|
||||
# No need to report 'unknown' information...
|
||||
platform = platform.replace('unknown', '')
|
||||
|
||||
# Fold '--'s and remove trailing '-'
|
||||
while True:
|
||||
cleaned = platform.replace('--', '-')
|
||||
if cleaned == platform:
|
||||
break
|
||||
platform = cleaned
|
||||
while platform and platform[-1] == '-':
|
||||
platform = platform[:-1]
|
||||
|
||||
return platform
|
||||
return re.sub(r'-{2,}', '-', platform).rstrip('-')
|
||||
|
||||
def _node(default=''):
|
||||
|
||||
@@ -767,11 +705,11 @@ def _syscmd_file(target, default=''):
|
||||
|
||||
# Default values for architecture; non-empty strings override the
|
||||
# defaults given as parameters
|
||||
_default_architecture = {
|
||||
_default_architecture = frozendict({
|
||||
'win32': ('', 'WindowsPE'),
|
||||
'win16': ('', 'Windows'),
|
||||
'dos': ('', 'MSDOS'),
|
||||
}
|
||||
})
|
||||
|
||||
def architecture(executable=sys.executable, bits='', linkage=''):
|
||||
|
||||
@@ -1045,13 +983,6 @@ def uname():
|
||||
version = '16bit'
|
||||
system = 'Windows'
|
||||
|
||||
elif system[:4] == 'java':
|
||||
release, vendor, vminfo, osinfo = java_ver()
|
||||
system = 'Java'
|
||||
version = ', '.join(vminfo)
|
||||
if not version:
|
||||
version = vendor
|
||||
|
||||
# System specific extensions
|
||||
if system == 'OpenVMS':
|
||||
# OpenVMS seems to have release and version mixed up
|
||||
@@ -1386,15 +1317,6 @@ def platform(aliased=False, terse=False):
|
||||
platform = _platform(system, release, machine, processor,
|
||||
'with',
|
||||
libcname+libcversion)
|
||||
elif system == 'Java':
|
||||
# Java platforms
|
||||
r, v, vminfo, (os_name, os_version, os_arch) = java_ver()
|
||||
if terse or not os_name:
|
||||
platform = _platform(system, release, version)
|
||||
else:
|
||||
platform = _platform(system, release, version,
|
||||
'on',
|
||||
os_name, os_version, os_arch)
|
||||
|
||||
else:
|
||||
# Generic handler
|
||||
@@ -1483,7 +1405,7 @@ def invalidate_caches():
|
||||
def _parse_args(args: list[str] | None):
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(color=True)
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("args", nargs="*", choices=["nonaliased", "terse"])
|
||||
parser.add_argument(
|
||||
"--terse",
|
||||
@@ -1516,5 +1438,14 @@ def _main(args: list[str] | None = None):
|
||||
print(platform(aliased, terse))
|
||||
|
||||
|
||||
def __getattr__(name):
|
||||
if name == "__version__":
|
||||
from warnings import _deprecated
|
||||
|
||||
_deprecated("__version__", remove=(3, 20))
|
||||
return "1.1.0" # Do not change
|
||||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
_main()
|
||||
Vendored
+66
-8
@@ -1,3 +1,4 @@
|
||||
from _codecs import _unregister_error as _codecs_unregister_error
|
||||
import codecs
|
||||
import html.entities
|
||||
import itertools
|
||||
@@ -754,8 +755,7 @@ class CodecCallbackTest(unittest.TestCase):
|
||||
(s[:1], 1 + n)
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_badhandlerresults(self):
|
||||
results = ( 42, "foo", (1,2,3), ("foo", 1, 3), ("foo", None), ("foo",), ("foo", 1, 3), ("foo", None), ("foo",) )
|
||||
encs = ("ascii", "latin-1", "iso-8859-1", "iso-8859-15")
|
||||
@@ -798,8 +798,7 @@ class CodecCallbackTest(unittest.TestCase):
|
||||
codecs.lookup_error("namereplace")
|
||||
)
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_encode_nonascii_replacement(self):
|
||||
def handle(exc):
|
||||
if isinstance(exc, UnicodeEncodeError):
|
||||
@@ -1041,8 +1040,7 @@ class CodecCallbackTest(unittest.TestCase):
|
||||
self.assertRaises(ValueError, codecs.charmap_encode, "\xff", err, D())
|
||||
self.assertRaises(TypeError, codecs.charmap_encode, "\xff", err, {0xff: 300})
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
@unittest.expectedFailure # TODO: RUSTPYTHON
|
||||
def test_decodehelper_bug36819(self):
|
||||
handler = RepeatedPosReturn("x")
|
||||
codecs.register_error("test.bug36819", handler.handle)
|
||||
@@ -1130,7 +1128,7 @@ class CodecCallbackTest(unittest.TestCase):
|
||||
text = 'abc<def>ghi'*n
|
||||
text.translate(charmap)
|
||||
|
||||
def test_mutatingdecodehandler(self):
|
||||
def test_mutating_decode_handler(self):
|
||||
baddata = [
|
||||
("ascii", b"\xff"),
|
||||
("utf-7", b"++"),
|
||||
@@ -1165,6 +1163,42 @@ class CodecCallbackTest(unittest.TestCase):
|
||||
for (encoding, data) in baddata:
|
||||
self.assertEqual(data.decode(encoding, "test.mutating"), "\u4242")
|
||||
|
||||
def test_mutating_decode_handler_unicode_escape(self):
|
||||
decode = codecs.unicode_escape_decode
|
||||
def mutating(exc):
|
||||
if isinstance(exc, UnicodeDecodeError):
|
||||
r = data.get(exc.object[:exc.end])
|
||||
if r is not None:
|
||||
exc.object = r[0] + exc.object[exc.end:]
|
||||
return ('\u0404', r[1])
|
||||
raise AssertionError("don't know how to handle %r" % exc)
|
||||
|
||||
codecs.register_error('test.mutating2', mutating)
|
||||
data = {
|
||||
br'\x0': (b'\\', 0),
|
||||
br'\x3': (b'xxx\\', 3),
|
||||
br'\x5': (b'x\\', 1),
|
||||
}
|
||||
def check(input, expected, msg):
|
||||
with self.assertWarns(DeprecationWarning) as cm:
|
||||
self.assertEqual(decode(input, 'test.mutating2'), (expected, len(input)))
|
||||
self.assertIn(msg, str(cm.warning))
|
||||
|
||||
check(br'\x0n\z', '\u0404\n\\z', r'"\z" is an invalid escape sequence')
|
||||
check(br'\x0n\501', '\u0404\n\u0141', r'"\501" is an invalid octal escape sequence')
|
||||
check(br'\x0z', '\u0404\\z', r'"\z" is an invalid escape sequence')
|
||||
|
||||
check(br'\x3n\zr', '\u0404\n\\zr', r'"\z" is an invalid escape sequence')
|
||||
check(br'\x3zr', '\u0404\\zr', r'"\z" is an invalid escape sequence')
|
||||
check(br'\x3z5', '\u0404\\z5', r'"\z" is an invalid escape sequence')
|
||||
check(memoryview(br'\x3z5x')[:-1], '\u0404\\z5', r'"\z" is an invalid escape sequence')
|
||||
check(memoryview(br'\x3z5xy')[:-2], '\u0404\\z5', r'"\z" is an invalid escape sequence')
|
||||
|
||||
check(br'\x5n\z', '\u0404\n\\z', r'"\z" is an invalid escape sequence')
|
||||
check(br'\x5n\501', '\u0404\n\u0141', r'"\501" is an invalid octal escape sequence')
|
||||
check(br'\x5z', '\u0404\\z', r'"\z" is an invalid escape sequence')
|
||||
check(memoryview(br'\x5zy')[:-1], '\u0404\\z', r'"\z" is an invalid escape sequence')
|
||||
|
||||
# issue32583
|
||||
def test_crashing_decode_handler(self):
|
||||
# better generating one more character to fill the extra space slot
|
||||
@@ -1216,7 +1250,6 @@ class CodecCallbackTest(unittest.TestCase):
|
||||
'\ufffd\x00\x00'
|
||||
)
|
||||
|
||||
|
||||
def test_fake_error_class(self):
|
||||
handlers = [
|
||||
codecs.strict_errors,
|
||||
@@ -1241,6 +1274,31 @@ class CodecCallbackTest(unittest.TestCase):
|
||||
with self.assertRaises((TypeError, FakeUnicodeError)):
|
||||
handler(FakeUnicodeError())
|
||||
|
||||
def test_reject_unregister_builtin_error_handler(self):
|
||||
for name in [
|
||||
'strict', 'ignore', 'replace', 'backslashreplace', 'namereplace',
|
||||
'xmlcharrefreplace', 'surrogateescape', 'surrogatepass',
|
||||
]:
|
||||
with self.subTest(name):
|
||||
self.assertRaises(ValueError, _codecs_unregister_error, name)
|
||||
|
||||
def test_unregister_custom_error_handler(self):
|
||||
def custom_handler(exc):
|
||||
raise exc
|
||||
|
||||
custom_name = 'test.test_unregister_custom_error_handler'
|
||||
self.assertRaises(LookupError, codecs.lookup_error, custom_name)
|
||||
codecs.register_error(custom_name, custom_handler)
|
||||
self.assertIs(codecs.lookup_error(custom_name), custom_handler)
|
||||
self.assertTrue(_codecs_unregister_error(custom_name))
|
||||
self.assertRaises(LookupError, codecs.lookup_error, custom_name)
|
||||
|
||||
def test_unregister_custom_unknown_error_handler(self):
|
||||
unknown_name = 'test.test_unregister_custom_unknown_error_handler'
|
||||
self.assertRaises(LookupError, codecs.lookup_error, unknown_name)
|
||||
self.assertFalse(_codecs_unregister_error(unknown_name))
|
||||
self.assertRaises(LookupError, codecs.lookup_error, unknown_name)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Vendored
+18
-2
@@ -1,7 +1,9 @@
|
||||
import collections
|
||||
import types
|
||||
import unittest
|
||||
from test.support import skip_emscripten_stack_overflow, skip_wasi_stack_overflow, exceeds_recursion_limit
|
||||
from test.support import (skip_emscripten_stack_overflow,
|
||||
skip_wasi_stack_overflow, skip_if_huge_c_stack,
|
||||
exceeds_recursion_limit)
|
||||
|
||||
class TestExceptionGroupTypeHierarchy(unittest.TestCase):
|
||||
def test_exception_group_types(self):
|
||||
@@ -234,6 +236,18 @@ class StrAndReprTests(unittest.TestCase):
|
||||
"ExceptionGroup('test', deque([ValueError(1), TypeError(2)]))"
|
||||
)
|
||||
|
||||
def test_repr_small_size_args(self):
|
||||
eg = ExceptionGroup("msg", [ValueError()])
|
||||
eg.args = ()
|
||||
# repr of the ExceptionGroup with empty args should not crash
|
||||
self.assertEqual(repr(eg), "ExceptionGroup('msg', (ValueError(),))")
|
||||
|
||||
eg.args = (1,)
|
||||
# repr of the ExceptionGroup with 1-size args should not crash
|
||||
self.assertEqual(repr(eg), "ExceptionGroup('msg', (ValueError(),))")
|
||||
|
||||
|
||||
|
||||
def test_repr_raises(self):
|
||||
class MySeq(collections.abc.Sequence):
|
||||
def __init__(self, raises):
|
||||
@@ -255,7 +269,7 @@ class StrAndReprTests(unittest.TestCase):
|
||||
seq = MySeq(None)
|
||||
with self.assertRaisesRegex(
|
||||
TypeError,
|
||||
r"__repr__ returned non-string \(type NoneType\)"
|
||||
r".*MySeq\.__repr__\(\) must return a str, not NoneType"
|
||||
):
|
||||
ExceptionGroup("test", seq)
|
||||
|
||||
@@ -535,6 +549,7 @@ class DeepRecursionInSplitAndSubgroup(unittest.TestCase):
|
||||
e = ExceptionGroup('eg', [e])
|
||||
return e
|
||||
|
||||
@skip_if_huge_c_stack()
|
||||
@skip_emscripten_stack_overflow()
|
||||
@skip_wasi_stack_overflow()
|
||||
def test_deep_split(self):
|
||||
@@ -542,6 +557,7 @@ class DeepRecursionInSplitAndSubgroup(unittest.TestCase):
|
||||
with self.assertRaises(RecursionError):
|
||||
e.split(TypeError)
|
||||
|
||||
@skip_if_huge_c_stack()
|
||||
@skip_emscripten_stack_overflow()
|
||||
@skip_wasi_stack_overflow()
|
||||
def test_deep_subgroup(self):
|
||||
|
||||
Vendored
+18
@@ -460,6 +460,24 @@ class BuiltinFunctionPropertiesTest(unittest.TestCase):
|
||||
# XXX Not sure where this should really go since I can't find a
|
||||
# test module specifically for builtin_function_or_method.
|
||||
|
||||
def test_builtin__module__(self):
|
||||
import math
|
||||
|
||||
# builtin function:
|
||||
self.assertEqual(len.__module__, 'builtins')
|
||||
self.assertEqual(math.sin.__module__, 'math')
|
||||
|
||||
# instance method:
|
||||
self.assertRaises(AttributeError, getattr, int.to_bytes, '__module__')
|
||||
self.assertEqual(int.to_bytes.__objclass__.__module__, 'builtins')
|
||||
|
||||
# builtin classmethod:
|
||||
self.assertEqual(int.from_bytes.__module__, None)
|
||||
self.assertEqual(int.from_bytes.__self__.__module__, 'builtins')
|
||||
|
||||
# builtin staticmethod:
|
||||
self.assertEqual(bytes.maketrans.__module__, 'builtins')
|
||||
|
||||
def test_builtin__qualname__(self):
|
||||
import time
|
||||
|
||||
|
||||
Vendored
+10
@@ -49,6 +49,16 @@ class TestCTest(CTest):
|
||||
'_json')
|
||||
|
||||
|
||||
class TestModule(unittest.TestCase):
|
||||
def test_deprecated__version__(self):
|
||||
with self.assertWarnsRegex(
|
||||
DeprecationWarning,
|
||||
"'__version__' is deprecated and slated for removal in Python 3.20",
|
||||
) as cm:
|
||||
getattr(json, "__version__")
|
||||
self.assertEqual(cm.filename, __file__)
|
||||
|
||||
|
||||
def load_tests(loader, _, pattern):
|
||||
suite = unittest.TestSuite()
|
||||
for mod in (json, json.encoder, json.decoder):
|
||||
|
||||
Vendored
+7
@@ -146,6 +146,13 @@ class TestFail:
|
||||
('"', 'Unterminated string starting at', 0),
|
||||
('"spam', 'Unterminated string starting at', 0),
|
||||
]
|
||||
# A complete \uXXXX escape at end of input leaves it unterminated.
|
||||
test_cases += [
|
||||
(r'"\u0041', 'Unterminated string starting at', 0),
|
||||
(r'"\ud834', 'Unterminated string starting at', 0),
|
||||
(r'"\ud834\udd1e', 'Unterminated string starting at', 0),
|
||||
(r'{"a": "\u0041', 'Unterminated string starting at', 6),
|
||||
]
|
||||
for data, msg, idx in test_cases:
|
||||
with self.assertRaises(self.JSONDecodeError) as cm:
|
||||
self.loads(data)
|
||||
|
||||
+3
@@ -139,6 +139,9 @@ class TestScanstring:
|
||||
'"\\ud834\\u-123"',
|
||||
'"\\ud834\\u+123"',
|
||||
'"\\ud834\\u1_23"',
|
||||
# Truncated or non-hex \uXXXX escape at end of input.
|
||||
'"\\u004',
|
||||
'"\\uXYZW',
|
||||
]
|
||||
for s in bad_escapes:
|
||||
with self.assertRaises(self.JSONDecodeError, msg=s):
|
||||
|
||||
Vendored
+22
-14
@@ -11,7 +11,7 @@ import unittest
|
||||
from unittest import mock
|
||||
|
||||
from test import support
|
||||
from test.support import os_helper
|
||||
from test.support import os_helper, warnings_helper
|
||||
|
||||
try:
|
||||
# Some of the iOS tests need ctypes to operate.
|
||||
@@ -133,6 +133,22 @@ class PlatformTest(unittest.TestCase):
|
||||
for terse in (False, True):
|
||||
res = platform.platform(aliased, terse)
|
||||
|
||||
def test__platform(self):
|
||||
for src, res in [
|
||||
('foo bar', 'foo_bar'),
|
||||
(
|
||||
'1/2\\3:4;5"6(7)8(7)6"5;4:3\\2/1',
|
||||
'1-2-3-4-5-6-7-8-7-6-5-4-3-2-1'
|
||||
),
|
||||
('--', ''),
|
||||
('-f', '-f'),
|
||||
('-foo----', '-foo'),
|
||||
('--foo---', '-foo'),
|
||||
('---foo--', '-foo'),
|
||||
]:
|
||||
with self.subTest(src=src):
|
||||
self.assertEqual(platform._platform(src), res)
|
||||
|
||||
def test_system(self):
|
||||
res = platform.system()
|
||||
|
||||
@@ -383,15 +399,6 @@ class PlatformTest(unittest.TestCase):
|
||||
finally:
|
||||
platform._uname_cache = None
|
||||
|
||||
def test_java_ver(self):
|
||||
import re
|
||||
msg = re.escape(
|
||||
"'java_ver' is deprecated and slated for removal in Python 3.15"
|
||||
)
|
||||
with self.assertWarnsRegex(DeprecationWarning, msg):
|
||||
res = platform.java_ver()
|
||||
self.assertEqual(len(res), 4)
|
||||
|
||||
@unittest.skipUnless(support.MS_WINDOWS, 'This test only makes sense on Windows')
|
||||
def test_win32_ver(self):
|
||||
release1, version1, csd1, ptype1 = 'a', 'b', 'c', 'd'
|
||||
@@ -458,7 +465,7 @@ class PlatformTest(unittest.TestCase):
|
||||
else:
|
||||
self.assertEqual(res[2], 'PowerPC')
|
||||
|
||||
|
||||
@warnings_helper.ignore_fork_in_thread_deprecation_warnings()
|
||||
@unittest.skipUnless(sys.platform == 'darwin', "OSX only test")
|
||||
def test_mac_ver_with_fork(self):
|
||||
# Issue7895: platform.mac_ver() crashes when using fork without exec
|
||||
@@ -527,7 +534,7 @@ class PlatformTest(unittest.TestCase):
|
||||
|
||||
def test_libc_ver(self):
|
||||
if support.is_emscripten:
|
||||
assert platform.libc_ver() == ("emscripten", "4.0.12")
|
||||
assert platform.libc_ver() == ("emscripten", "4.0.19")
|
||||
return
|
||||
# check that libc_ver(executable) doesn't raise an exception
|
||||
if os.path.isdir(sys.executable) and \
|
||||
@@ -769,13 +776,14 @@ class CommandLineTest(unittest.TestCase):
|
||||
platform._main(args=flags)
|
||||
return output.getvalue()
|
||||
|
||||
@support.force_not_colorized
|
||||
def test_unknown_flag(self):
|
||||
output = io.StringIO()
|
||||
with self.assertRaises(SystemExit):
|
||||
output = io.StringIO()
|
||||
# suppress argparse error message
|
||||
with contextlib.redirect_stderr(output):
|
||||
_ = self.invoke_platform('--unknown')
|
||||
self.assertStartsWith(output, "usage: ")
|
||||
self.assertStartsWith(output.getvalue(), "usage: ")
|
||||
|
||||
def test_invocation(self):
|
||||
flags = (
|
||||
|
||||
Vendored
+13
-2
@@ -188,7 +188,10 @@ class TestJointOps:
|
||||
self.assertEqual(type(i), self.basetype)
|
||||
self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru())
|
||||
self.assertRaises(TypeError, self.s.symmetric_difference, [[]])
|
||||
for C in set, frozenset, dict.fromkeys, str, list, tuple:
|
||||
constructors = (set, frozenset,
|
||||
dict.fromkeys, frozendict.fromkeys,
|
||||
str, list, tuple)
|
||||
for C in constructors:
|
||||
self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd'))
|
||||
self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg'))
|
||||
self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a'))
|
||||
@@ -670,7 +673,7 @@ class TestSet(TestJointOps, unittest.TestCase):
|
||||
with check_unhashable_element():
|
||||
myset.discard(elem)
|
||||
|
||||
# Only TypeError exception is overriden,
|
||||
# Only TypeError exception is overridden,
|
||||
# other exceptions are left unchanged.
|
||||
class HashError:
|
||||
def __hash__(self):
|
||||
@@ -1596,6 +1599,14 @@ class TestOnlySetsDict(TestOnlySetsInBinaryOps, unittest.TestCase):
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
class TestOnlySetsFrozenDict(TestOnlySetsInBinaryOps, unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.set = set((1, 2, 3))
|
||||
self.other = frozendict({1:2, 3:4})
|
||||
self.otherIsIterable = True
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
class TestOnlySetsOperator(TestOnlySetsInBinaryOps, unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.set = set((1, 2, 3))
|
||||
|
||||
Vendored
+2
-2
@@ -245,7 +245,7 @@ class UserDictTest(mapping_tests.TestHashMappingProtocol):
|
||||
test_repr_deep = mapping_tests.TestHashMappingProtocol.test_repr_deep
|
||||
|
||||
def test_mixed_or(self):
|
||||
for t in UserDict, dict, types.MappingProxyType:
|
||||
for t in UserDict, dict, frozendict, types.MappingProxyType:
|
||||
with self.subTest(t.__name__):
|
||||
u = UserDict({0: 'a', 1: 'b'}) | t({1: 'c', 2: 'd'})
|
||||
self.assertEqual(u, {0: 'a', 1: 'c', 2: 'd'})
|
||||
@@ -276,7 +276,7 @@ class UserDictTest(mapping_tests.TestHashMappingProtocol):
|
||||
self.assertIs(type(u), UserDictSubclass)
|
||||
|
||||
def test_mixed_ior(self):
|
||||
for t in UserDict, dict, types.MappingProxyType:
|
||||
for t in UserDict, dict, frozendict, types.MappingProxyType:
|
||||
with self.subTest(t.__name__):
|
||||
u = u2 = UserDict({0: 'a', 1: 'b'})
|
||||
u |= t({1: 'c', 2: 'd'})
|
||||
|
||||
@@ -41,6 +41,7 @@ where
|
||||
E: DecodeErrorHandler<Ctx>,
|
||||
{
|
||||
let mut out = Wtf8Buf::new();
|
||||
let mut consumed = ctx.full_data().len();
|
||||
loop {
|
||||
let rest = ctx.remaining_data();
|
||||
if rest.is_empty() {
|
||||
@@ -62,6 +63,7 @@ where
|
||||
let escape_start = ctx.position();
|
||||
let digits_start = 2;
|
||||
if !final_decode && rest.len() < digits_start + want {
|
||||
consumed = ctx.position();
|
||||
break;
|
||||
}
|
||||
let available = (digits_start + want).min(rest.len());
|
||||
@@ -99,6 +101,7 @@ where
|
||||
continue;
|
||||
}
|
||||
if kind.is_none() && !final_decode {
|
||||
consumed = ctx.position();
|
||||
break;
|
||||
}
|
||||
out.push_char(b as char);
|
||||
@@ -108,5 +111,5 @@ where
|
||||
ctx.advance(1);
|
||||
}
|
||||
}
|
||||
Ok((out, ctx.position()))
|
||||
Ok((out, consumed))
|
||||
}
|
||||
@@ -68,6 +68,7 @@ where
|
||||
{
|
||||
let mut out = Wtf8Buf::new();
|
||||
let mut warning = None;
|
||||
let mut consumed = ctx.full_data().len();
|
||||
loop {
|
||||
let rest = ctx.remaining_data();
|
||||
if rest.is_empty() {
|
||||
@@ -84,6 +85,7 @@ where
|
||||
let escape_start = ctx.position();
|
||||
if rest.len() == 1 {
|
||||
if !final_decode {
|
||||
consumed = ctx.position();
|
||||
break;
|
||||
}
|
||||
let end = ctx.full_data().len();
|
||||
@@ -163,6 +165,7 @@ where
|
||||
_ => (8usize, "truncated \\UXXXXXXXX escape"),
|
||||
};
|
||||
if !final_decode && rest.len() < 2 + digits {
|
||||
consumed = ctx.position();
|
||||
break;
|
||||
}
|
||||
ctx.advance(2);
|
||||
@@ -194,6 +197,7 @@ where
|
||||
}
|
||||
b'N' => {
|
||||
if rest.len() == 2 && !final_decode {
|
||||
consumed = ctx.position();
|
||||
break;
|
||||
}
|
||||
if rest.len() >= 3 && rest[2] == b'{' {
|
||||
@@ -204,6 +208,7 @@ where
|
||||
}
|
||||
if look >= rest.len() {
|
||||
if !final_decode {
|
||||
consumed = ctx.position();
|
||||
break;
|
||||
}
|
||||
let start = escape_start;
|
||||
@@ -268,5 +273,5 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok((out, ctx.position(), warning))
|
||||
Ok((out, consumed, warning))
|
||||
}
|
||||
@@ -575,12 +575,14 @@ fn sequence_contains_wrapper(
|
||||
|
||||
fn repr_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
|
||||
let ret = vm.call_special_method(zelf, identifier!(vm, __repr__), ())?;
|
||||
ret.downcast::<PyStr>().map_err(|obj| {
|
||||
vm.new_type_error(format!(
|
||||
"__repr__ returned non-string (type {})",
|
||||
obj.class()
|
||||
))
|
||||
})
|
||||
match ret.downcast::<PyStr>() {
|
||||
Ok(value) => Ok(value),
|
||||
Err(obj) => Err(vm.new_type_error(format!(
|
||||
"{}.__repr__() must return a str, not {}",
|
||||
zelf.class().fully_qualified_name(vm)?,
|
||||
obj.class().fully_qualified_name(vm)?
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
fn str_wrapper(zelf: &PyObject, vm: &VirtualMachine) -> PyResult<PyRef<PyStr>> {
|
||||
|
||||
Reference in new issue
Block a user