aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib
diff options
context:
space:
mode:
Diffstat (limited to 'Lib')
-rw-r--r--Lib/compression/zstd/__init__.py12
-rw-r--r--Lib/compression/zstd/_zstdfile.py1
-rw-r--r--Lib/html/parser.py6
-rw-r--r--Lib/inspect.py4
-rw-r--r--Lib/sqlite3/__main__.py35
-rw-r--r--Lib/test/datetimetester.py3
-rw-r--r--Lib/test/test_ast/test_ast.py9
-rw-r--r--Lib/test/test_codeop.py2
-rw-r--r--Lib/test/test_htmlparser.py91
-rw-r--r--Lib/test/test_inspect/test_inspect.py31
-rw-r--r--Lib/test/test_pdb.py4
-rw-r--r--Lib/test/test_positional_only_arg.py12
-rw-r--r--Lib/test/test_pyrepl/test_interact.py2
-rw-r--r--Lib/test/test_repl.py2
-rw-r--r--Lib/test/test_sqlite3/test_cli.py13
-rw-r--r--Lib/test/test_syntax.py56
-rw-r--r--Lib/test/test_xml_etree.py44
-rw-r--r--Lib/test/test_zstd.py38
18 files changed, 265 insertions, 100 deletions
diff --git a/Lib/compression/zstd/__init__.py b/Lib/compression/zstd/__init__.py
index a1054adb641..e7b2f427164 100644
--- a/Lib/compression/zstd/__init__.py
+++ b/Lib/compression/zstd/__init__.py
@@ -71,7 +71,7 @@ def get_frame_info(frame_buffer):
the frame may or may not need a dictionary to be decoded,
and the ID of such a dictionary is not specified.
"""
- return FrameInfo(*_zstd._get_frame_info(frame_buffer))
+ return FrameInfo(*_zstd.get_frame_info(frame_buffer))
def train_dict(samples, dict_size):
@@ -91,7 +91,7 @@ def train_dict(samples, dict_size):
chunk_sizes = tuple(_nbytes(sample) for sample in samples)
if not chunks:
raise ValueError("samples contained no data; can't train dictionary.")
- dict_content = _zstd._train_dict(chunks, chunk_sizes, dict_size)
+ dict_content = _zstd.train_dict(chunks, chunk_sizes, dict_size)
return ZstdDict(dict_content)
@@ -127,7 +127,7 @@ def finalize_dict(zstd_dict, /, samples, dict_size, level):
if not chunks:
raise ValueError("The samples are empty content, can't finalize the"
"dictionary.")
- dict_content = _zstd._finalize_dict(zstd_dict.dict_content,
+ dict_content = _zstd.finalize_dict(zstd_dict.dict_content,
chunks, chunk_sizes,
dict_size, level)
return ZstdDict(dict_content)
@@ -201,7 +201,7 @@ class CompressionParameter(enum.IntEnum):
Both the lower and upper bounds are inclusive.
"""
- return _zstd._get_param_bounds(self.value, is_compress=True)
+ return _zstd.get_param_bounds(self.value, is_compress=True)
class DecompressionParameter(enum.IntEnum):
@@ -214,7 +214,7 @@ class DecompressionParameter(enum.IntEnum):
Both the lower and upper bounds are inclusive.
"""
- return _zstd._get_param_bounds(self.value, is_compress=False)
+ return _zstd.get_param_bounds(self.value, is_compress=False)
class Strategy(enum.IntEnum):
@@ -237,4 +237,4 @@ class Strategy(enum.IntEnum):
# Check validity of the CompressionParameter & DecompressionParameter types
-_zstd._set_parameter_types(CompressionParameter, DecompressionParameter)
+_zstd.set_parameter_types(CompressionParameter, DecompressionParameter)
diff --git a/Lib/compression/zstd/_zstdfile.py b/Lib/compression/zstd/_zstdfile.py
index 1ff24996569..0086c13d3c1 100644
--- a/Lib/compression/zstd/_zstdfile.py
+++ b/Lib/compression/zstd/_zstdfile.py
@@ -89,7 +89,6 @@ class ZstdFile(_streams.BaseStream):
raw = _streams.DecompressReader(
self._fp,
ZstdDecompressor,
- trailing_error=ZstdError,
zstd_dict=zstd_dict,
options=options,
)
diff --git a/Lib/html/parser.py b/Lib/html/parser.py
index 0a1dd3b7d3b..1e30956fe24 100644
--- a/Lib/html/parser.py
+++ b/Lib/html/parser.py
@@ -260,7 +260,7 @@ class HTMLParser(_markupbase.ParserBase):
else:
assert 0, "interesting.search() lied"
# end while
- if end and i < n and not self.cdata_elem:
+ if end and i < n:
if self.convert_charrefs and not self.cdata_elem:
self.handle_data(unescape(rawdata[i:n]))
else:
@@ -278,7 +278,7 @@ class HTMLParser(_markupbase.ParserBase):
if rawdata[i:i+4] == '<!--':
# this case is actually already handled in goahead()
return self.parse_comment(i)
- elif rawdata[i:i+3] == '<![':
+ elif rawdata[i:i+9] == '<![CDATA[':
return self.parse_marked_section(i)
elif rawdata[i:i+9].lower() == '<!doctype':
# find the closing >
@@ -295,7 +295,7 @@ class HTMLParser(_markupbase.ParserBase):
def parse_bogus_comment(self, i, report=1):
rawdata = self.rawdata
assert rawdata[i:i+2] in ('<!', '</'), ('unexpected call to '
- 'parse_comment()')
+ 'parse_bogus_comment()')
pos = rawdata.find('>', i+2)
if pos == -1:
return -1
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 52c9bb05b31..183e67fabf9 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -2074,13 +2074,11 @@ def _signature_is_functionlike(obj):
code = getattr(obj, '__code__', None)
defaults = getattr(obj, '__defaults__', _void) # Important to use _void ...
kwdefaults = getattr(obj, '__kwdefaults__', _void) # ... and not None here
- annotations = getattr(obj, '__annotations__', None)
return (isinstance(code, types.CodeType) and
isinstance(name, str) and
(defaults is None or isinstance(defaults, tuple)) and
- (kwdefaults is None or isinstance(kwdefaults, dict)) and
- (isinstance(annotations, (dict)) or annotations is None) )
+ (kwdefaults is None or isinstance(kwdefaults, dict)))
def _signature_strip_non_python_syntax(signature):
diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py
index 4ccf292ddf2..c2fa23c46cf 100644
--- a/Lib/sqlite3/__main__.py
+++ b/Lib/sqlite3/__main__.py
@@ -10,9 +10,10 @@ import sys
from argparse import ArgumentParser
from code import InteractiveConsole
from textwrap import dedent
+from _colorize import get_theme, theme_no_color
-def execute(c, sql, suppress_errors=True):
+def execute(c, sql, suppress_errors=True, theme=theme_no_color):
"""Helper that wraps execution of SQL code.
This is used both by the REPL and by direct execution from the CLI.
@@ -25,11 +26,15 @@ def execute(c, sql, suppress_errors=True):
for row in c.execute(sql):
print(row)
except sqlite3.Error as e:
+ t = theme.traceback
tp = type(e).__name__
try:
- print(f"{tp} ({e.sqlite_errorname}): {e}", file=sys.stderr)
+ tp += f" ({e.sqlite_errorname})"
except AttributeError:
- print(f"{tp}: {e}", file=sys.stderr)
+ pass
+ print(
+ f"{t.type}{tp}{t.reset}: {t.message}{e}{t.reset}", file=sys.stderr
+ )
if not suppress_errors:
sys.exit(1)
@@ -37,10 +42,11 @@ def execute(c, sql, suppress_errors=True):
class SqliteInteractiveConsole(InteractiveConsole):
"""A simple SQLite REPL."""
- def __init__(self, connection):
+ def __init__(self, connection, use_color=False):
super().__init__()
self._con = connection
self._cur = connection.cursor()
+ self._use_color = use_color
def runsource(self, source, filename="<input>", symbol="single"):
"""Override runsource, the core of the InteractiveConsole REPL.
@@ -48,6 +54,8 @@ class SqliteInteractiveConsole(InteractiveConsole):
Return True if more input is needed; buffering is done automatically.
Return False if input is a complete statement ready for execution.
"""
+ theme = get_theme(force_no_color=not self._use_color)
+
if not source or source.isspace():
return False
if source[0] == ".":
@@ -61,12 +69,13 @@ class SqliteInteractiveConsole(InteractiveConsole):
case "":
pass
case _ as unknown:
- self.write("Error: unknown command or invalid arguments:"
- f' "{unknown}".\n')
+ t = theme.traceback
+ self.write(f'{t.type}Error{t.reset}:{t.message} unknown'
+ f'command or invalid arguments: "{unknown}".\n{t.reset}')
else:
if not sqlite3.complete_statement(source):
return True
- execute(self._cur, source)
+ execute(self._cur, source, theme=theme)
return False
@@ -113,17 +122,21 @@ def main(*args):
Each command will be run using execute() on the cursor.
Type ".help" for more information; type ".quit" or {eofkey} to quit.
""").strip()
- sys.ps1 = "sqlite> "
- sys.ps2 = " ... "
+
+ theme = get_theme()
+ s = theme.syntax
+
+ sys.ps1 = f"{s.prompt}sqlite> {s.reset}"
+ sys.ps2 = f"{s.prompt} ... {s.reset}"
con = sqlite3.connect(args.filename, isolation_level=None)
try:
if args.sql:
# SQL statement provided on the command-line; execute it directly.
- execute(con, args.sql, suppress_errors=False)
+ execute(con, args.sql, suppress_errors=False, theme=theme)
else:
# No SQL provided; start the REPL.
- console = SqliteInteractiveConsole(con)
+ console = SqliteInteractiveConsole(con, use_color=True)
try:
import readline # noqa: F401
except ImportError:
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index 55844ec35a9..d1882a310bb 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -773,6 +773,9 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
microseconds=999999)),
"999999999 days, 23:59:59.999999")
+ # test the Doc/library/datetime.rst recipe
+ eq(f'-({-td(hours=-1)!s})', "-(1:00:00)")
+
def test_repr(self):
name = 'datetime.' + self.theclass.__name__
self.assertEqual(repr(self.theclass(1)),
diff --git a/Lib/test/test_ast/test_ast.py b/Lib/test/test_ast/test_ast.py
index 02628868db0..0776559b900 100644
--- a/Lib/test/test_ast/test_ast.py
+++ b/Lib/test/test_ast/test_ast.py
@@ -1315,6 +1315,15 @@ class CopyTests(unittest.TestCase):
self.assertIs(repl.id, 'y')
self.assertIs(repl.ctx, context)
+ def test_replace_accept_missing_field_with_default(self):
+ node = ast.FunctionDef(name="foo", args=ast.arguments())
+ self.assertIs(node.returns, None)
+ self.assertEqual(node.decorator_list, [])
+ node2 = copy.replace(node, name="bar")
+ self.assertEqual(node2.name, "bar")
+ self.assertIs(node2.returns, None)
+ self.assertEqual(node2.decorator_list, [])
+
def test_replace_reject_known_custom_instance_fields_commits(self):
node = ast.parse('x').body[0].value
node.extra = extra = object() # add instance 'extra' field
diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py
index 0eefc22d11b..ed10bd3dcb6 100644
--- a/Lib/test/test_codeop.py
+++ b/Lib/test/test_codeop.py
@@ -322,7 +322,7 @@ class CodeopTests(unittest.TestCase):
dedent("""\
def foo(x,x):
pass
- """), "duplicate argument 'x' in function definition")
+ """), "duplicate parameter 'x' in function definition")
diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py
index 4fdba06cf4c..61fa24fab57 100644
--- a/Lib/test/test_htmlparser.py
+++ b/Lib/test/test_htmlparser.py
@@ -317,6 +317,16 @@ text
("endtag", element_lower)],
collector=Collector(convert_charrefs=False))
+ def test_EOF_in_cdata(self):
+ content = """<!-- not a comment --> &not-an-entity-ref;
+ <a href="" /> </p><p> <span></span></style>
+ '</script' + '>'"""
+ s = f'<script>{content}'
+ self._run_check(s, [
+ ("starttag", 'script', []),
+ ("data", content)
+ ])
+
def test_comments(self):
html = ("<!-- I'm a valid comment -->"
'<!--me too!-->'
@@ -566,12 +576,33 @@ text
for html, expected in data:
self._run_check(html, expected)
- def test_broken_comments(self):
+ def test_EOF_in_comments_or_decls(self):
+ data = [
+ ('<!', [('data', '<!')]),
+ ('<!-', [('data', '<!-')]),
+ ('<!--', [('data', '<!--')]),
+ ('<![', [('data', '<![')]),
+ ('<![CDATA[', [('data', '<![CDATA[')]),
+ ('<![CDATA[x', [('data', '<![CDATA[x')]),
+ ('<!DOCTYPE', [('data', '<!DOCTYPE')]),
+ ('<!DOCTYPE HTML', [('data', '<!DOCTYPE HTML')]),
+ ]
+ for html, expected in data:
+ self._run_check(html, expected)
+ def test_bogus_comments(self):
html = ('<! not really a comment >'
'<! not a comment either -->'
'<! -- close enough -->'
'<!><!<-- this was an empty comment>'
- '<!!! another bogus comment !!!>')
+ '<!!! another bogus comment !!!>'
+ # see #32876
+ '<![with square brackets]!>'
+ '<![\nmultiline\nbogusness\n]!>'
+ '<![more brackets]-[and a hyphen]!>'
+ '<![cdata[should be uppercase]]>'
+ '<![CDATA [whitespaces are not ignored]]>'
+ '<![CDATA]]>' # required '[' after CDATA
+ )
expected = [
('comment', ' not really a comment '),
('comment', ' not a comment either --'),
@@ -579,39 +610,65 @@ text
('comment', ''),
('comment', '<-- this was an empty comment'),
('comment', '!! another bogus comment !!!'),
+ ('comment', '[with square brackets]!'),
+ ('comment', '[\nmultiline\nbogusness\n]!'),
+ ('comment', '[more brackets]-[and a hyphen]!'),
+ ('comment', '[cdata[should be uppercase]]'),
+ ('comment', '[CDATA [whitespaces are not ignored]]'),
+ ('comment', '[CDATA]]'),
]
self._run_check(html, expected)
def test_broken_condcoms(self):
# these condcoms are missing the '--' after '<!' and before the '>'
+ # and they are considered bogus comments according to
+ # "8.2.4.42. Markup declaration open state"
html = ('<![if !(IE)]>broken condcom<![endif]>'
'<![if ! IE]><link href="favicon.tiff"/><![endif]>'
'<![if !IE 6]><img src="firefox.png" /><![endif]>'
'<![if !ie 6]><b>foo</b><![endif]>'
'<![if (!IE)|(lt IE 9)]><img src="mammoth.bmp" /><![endif]>')
- # According to the HTML5 specs sections "8.2.4.44 Bogus comment state"
- # and "8.2.4.45 Markup declaration open state", comment tokens should
- # be emitted instead of 'unknown decl', but calling unknown_decl
- # provides more flexibility.
- # See also Lib/_markupbase.py:parse_declaration
expected = [
- ('unknown decl', 'if !(IE)'),
+ ('comment', '[if !(IE)]'),
('data', 'broken condcom'),
- ('unknown decl', 'endif'),
- ('unknown decl', 'if ! IE'),
+ ('comment', '[endif]'),
+ ('comment', '[if ! IE]'),
('startendtag', 'link', [('href', 'favicon.tiff')]),
- ('unknown decl', 'endif'),
- ('unknown decl', 'if !IE 6'),
+ ('comment', '[endif]'),
+ ('comment', '[if !IE 6]'),
('startendtag', 'img', [('src', 'firefox.png')]),
- ('unknown decl', 'endif'),
- ('unknown decl', 'if !ie 6'),
+ ('comment', '[endif]'),
+ ('comment', '[if !ie 6]'),
('starttag', 'b', []),
('data', 'foo'),
('endtag', 'b'),
- ('unknown decl', 'endif'),
- ('unknown decl', 'if (!IE)|(lt IE 9)'),
+ ('comment', '[endif]'),
+ ('comment', '[if (!IE)|(lt IE 9)]'),
('startendtag', 'img', [('src', 'mammoth.bmp')]),
- ('unknown decl', 'endif')
+ ('comment', '[endif]')
+ ]
+ self._run_check(html, expected)
+
+ def test_cdata_declarations(self):
+ # More tests should be added. See also "8.2.4.42. Markup
+ # declaration open state", "8.2.4.69. CDATA section state",
+ # and issue 32876
+ html = ('<![CDATA[just some plain text]]>')
+ expected = [('unknown decl', 'CDATA[just some plain text')]
+ self._run_check(html, expected)
+
+ def test_cdata_declarations_multiline(self):
+ html = ('<code><![CDATA['
+ ' if (a < b && a > b) {'
+ ' printf("[<marquee>How?</marquee>]");'
+ ' }'
+ ']]></code>')
+ expected = [
+ ('starttag', 'code', []),
+ ('unknown decl',
+ 'CDATA[ if (a < b && a > b) { '
+ 'printf("[<marquee>How?</marquee>]"); }'),
+ ('endtag', 'code')
]
self._run_check(html, expected)
diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py
index bc112982707..1c325c0d507 100644
--- a/Lib/test/test_inspect/test_inspect.py
+++ b/Lib/test/test_inspect/test_inspect.py
@@ -4997,6 +4997,37 @@ class TestSignatureObject(unittest.TestCase):
with self.assertRaisesRegex(NameError, "undefined"):
signature_func(ida.f)
+ def test_signature_deferred_annotations(self):
+ def f(x: undef):
+ pass
+
+ class C:
+ x: undef
+
+ def __init__(self, x: undef):
+ self.x = x
+
+ sig = inspect.signature(f, annotation_format=Format.FORWARDREF)
+ self.assertEqual(list(sig.parameters), ['x'])
+ sig = inspect.signature(C, annotation_format=Format.FORWARDREF)
+ self.assertEqual(list(sig.parameters), ['x'])
+
+ class CallableWrapper:
+ def __init__(self, func):
+ self.func = func
+ self.__annotate__ = func.__annotate__
+
+ def __call__(self, *args, **kwargs):
+ return self.func(*args, **kwargs)
+
+ @property
+ def __annotations__(self):
+ return self.__annotate__(Format.VALUE)
+
+ cw = CallableWrapper(f)
+ sig = inspect.signature(cw, annotation_format=Format.FORWARDREF)
+ self.assertEqual(list(sig.parameters), ['args', 'kwargs'])
+
def test_signature_none_annotation(self):
class funclike:
# Has to be callable, and have correct
diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py
index 68c2b508fa6..6b74e21ad73 100644
--- a/Lib/test/test_pdb.py
+++ b/Lib/test/test_pdb.py
@@ -4749,7 +4749,9 @@ class TestREPLSession(unittest.TestCase):
@support.force_not_colorized_test_class
@support.requires_subprocess()
class PdbTestReadline(unittest.TestCase):
- def setUpClass():
+
+ @classmethod
+ def setUpClass(cls):
# Ensure that the readline module is loaded
# If this fails, the test is skipped because SkipTest will be raised
readline = import_module('readline')
diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py
index eea0625012d..e412cb1d58d 100644
--- a/Lib/test/test_positional_only_arg.py
+++ b/Lib/test/test_positional_only_arg.py
@@ -37,8 +37,8 @@ class PositionalOnlyTestCase(unittest.TestCase):
check_syntax_error(self, "def f(/): pass")
check_syntax_error(self, "def f(*, a, /): pass")
check_syntax_error(self, "def f(*, /, a): pass")
- check_syntax_error(self, "def f(a, /, a): pass", "duplicate argument 'a' in function definition")
- check_syntax_error(self, "def f(a, /, *, a): pass", "duplicate argument 'a' in function definition")
+ check_syntax_error(self, "def f(a, /, a): pass", "duplicate parameter 'a' in function definition")
+ check_syntax_error(self, "def f(a, /, *, a): pass", "duplicate parameter 'a' in function definition")
check_syntax_error(self, "def f(a, b/2, c): pass")
check_syntax_error(self, "def f(a, /, c, /): pass")
check_syntax_error(self, "def f(a, /, c, /, d): pass")
@@ -59,8 +59,8 @@ class PositionalOnlyTestCase(unittest.TestCase):
check_syntax_error(self, "async def f(/): pass")
check_syntax_error(self, "async def f(*, a, /): pass")
check_syntax_error(self, "async def f(*, /, a): pass")
- check_syntax_error(self, "async def f(a, /, a): pass", "duplicate argument 'a' in function definition")
- check_syntax_error(self, "async def f(a, /, *, a): pass", "duplicate argument 'a' in function definition")
+ check_syntax_error(self, "async def f(a, /, a): pass", "duplicate parameter 'a' in function definition")
+ check_syntax_error(self, "async def f(a, /, *, a): pass", "duplicate parameter 'a' in function definition")
check_syntax_error(self, "async def f(a, b/2, c): pass")
check_syntax_error(self, "async def f(a, /, c, /): pass")
check_syntax_error(self, "async def f(a, /, c, /, d): pass")
@@ -247,8 +247,8 @@ class PositionalOnlyTestCase(unittest.TestCase):
check_syntax_error(self, "lambda /: None")
check_syntax_error(self, "lambda *, a, /: None")
check_syntax_error(self, "lambda *, /, a: None")
- check_syntax_error(self, "lambda a, /, a: None", "duplicate argument 'a' in function definition")
- check_syntax_error(self, "lambda a, /, *, a: None", "duplicate argument 'a' in function definition")
+ check_syntax_error(self, "lambda a, /, a: None", "duplicate parameter 'a' in function definition")
+ check_syntax_error(self, "lambda a, /, *, a: None", "duplicate parameter 'a' in function definition")
check_syntax_error(self, "lambda a, /, b, /: None")
check_syntax_error(self, "lambda a, /, b, /, c: None")
check_syntax_error(self, "lambda a, /, b, /, c, *, d: None")
diff --git a/Lib/test/test_pyrepl/test_interact.py b/Lib/test/test_pyrepl/test_interact.py
index a20719033fc..8c0eeab6dca 100644
--- a/Lib/test/test_pyrepl/test_interact.py
+++ b/Lib/test/test_pyrepl/test_interact.py
@@ -113,7 +113,7 @@ class TestSimpleInteract(unittest.TestCase):
r = """
def f(x, x): ...
^
-SyntaxError: duplicate argument 'x' in function definition"""
+SyntaxError: duplicate parameter 'x' in function definition"""
self.assertIn(r, f.getvalue())
def test_runsource_shows_syntax_error_for_failed_compilation(self):
diff --git a/Lib/test/test_repl.py b/Lib/test/test_repl.py
index 27f16f1ba96..f4a4634fc62 100644
--- a/Lib/test/test_repl.py
+++ b/Lib/test/test_repl.py
@@ -197,7 +197,7 @@ class TestInteractiveInterpreter(unittest.TestCase):
expected_lines = [
' def f(x, x): ...',
' ^',
- "SyntaxError: duplicate argument 'x' in function definition"
+ "SyntaxError: duplicate parameter 'x' in function definition"
]
self.assertEqual(output.splitlines()[4:-1], expected_lines)
diff --git a/Lib/test/test_sqlite3/test_cli.py b/Lib/test/test_sqlite3/test_cli.py
index a03d7cbe16b..37e0f74f688 100644
--- a/Lib/test/test_sqlite3/test_cli.py
+++ b/Lib/test/test_sqlite3/test_cli.py
@@ -8,10 +8,11 @@ from test.support import (
captured_stdout,
captured_stderr,
captured_stdin,
- force_not_colorized,
+ force_not_colorized_test_class,
)
+@force_not_colorized_test_class
class CommandLineInterface(unittest.TestCase):
def _do_test(self, *args, expect_success=True):
@@ -37,7 +38,6 @@ class CommandLineInterface(unittest.TestCase):
self.assertEqual(out, "")
return err
- @force_not_colorized
def test_cli_help(self):
out = self.expect_success("-h")
self.assertIn("usage: ", out)
@@ -69,6 +69,7 @@ class CommandLineInterface(unittest.TestCase):
self.assertIn("(0,)", out)
+@force_not_colorized_test_class
class InteractiveSession(unittest.TestCase):
MEMORY_DB_MSG = "Connected to a transient in-memory database"
PS1 = "sqlite> "
@@ -190,6 +191,14 @@ class InteractiveSession(unittest.TestCase):
out, _ = self.run_cli(TESTFN, commands=("SELECT count(t) FROM t;",))
self.assertIn("(0,)\n", out)
+ def test_color(self):
+ with unittest.mock.patch("_colorize.can_colorize", return_value=True):
+ out, err = self.run_cli(commands="TEXT\n")
+ self.assertIn("\x1b[1;35msqlite> \x1b[0m", out)
+ self.assertIn("\x1b[1;35m ... \x1b[0m\x1b", out)
+ out, err = self.run_cli(commands=("sel;",))
+ self.assertIn('\x1b[1;35mOperationalError (SQLITE_ERROR)\x1b[0m: '
+ '\x1b[35mnear "sel": syntax error\x1b[0m', err)
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py
index 0ee17849e28..0eccf03a1a9 100644
--- a/Lib/test/test_syntax.py
+++ b/Lib/test/test_syntax.py
@@ -419,7 +419,7 @@ SyntaxError: invalid syntax
>>> def foo(/,a,b=,c):
... pass
Traceback (most recent call last):
-SyntaxError: at least one argument must precede /
+SyntaxError: at least one parameter must precede /
>>> def foo(a,/,/,b,c):
... pass
@@ -454,67 +454,67 @@ SyntaxError: / must be ahead of *
>>> def foo(a,*b=3,c):
... pass
Traceback (most recent call last):
-SyntaxError: var-positional argument cannot have default value
+SyntaxError: var-positional parameter cannot have default value
>>> def foo(a,*b: int=,c):
... pass
Traceback (most recent call last):
-SyntaxError: var-positional argument cannot have default value
+SyntaxError: var-positional parameter cannot have default value
>>> def foo(a,**b=3):
... pass
Traceback (most recent call last):
-SyntaxError: var-keyword argument cannot have default value
+SyntaxError: var-keyword parameter cannot have default value
>>> def foo(a,**b: int=3):
... pass
Traceback (most recent call last):
-SyntaxError: var-keyword argument cannot have default value
+SyntaxError: var-keyword parameter cannot have default value
>>> def foo(a,*a, b, **c, d):
... pass
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> def foo(a,*a, b, **c, d=4):
... pass
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> def foo(a,*a, b, **c, *d):
... pass
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> def foo(a,*a, b, **c, **d):
... pass
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> def foo(a=1,/,**b,/,c):
... pass
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> def foo(*b,*d):
... pass
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> def foo(a,*b,c,*d,*e,c):
... pass
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> def foo(a,b,/,c,*b,c,*d,*e,c):
... pass
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> def foo(a,b,/,c,*b,c,*d,**e):
... pass
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> def foo(a=1,/*,b,c):
... pass
@@ -538,7 +538,7 @@ SyntaxError: expected default value expression
>>> lambda /,a,b,c: None
Traceback (most recent call last):
-SyntaxError: at least one argument must precede /
+SyntaxError: at least one parameter must precede /
>>> lambda a,/,/,b,c: None
Traceback (most recent call last):
@@ -570,47 +570,47 @@ SyntaxError: expected comma between / and *
>>> lambda a,*b=3,c: None
Traceback (most recent call last):
-SyntaxError: var-positional argument cannot have default value
+SyntaxError: var-positional parameter cannot have default value
>>> lambda a,**b=3: None
Traceback (most recent call last):
-SyntaxError: var-keyword argument cannot have default value
+SyntaxError: var-keyword parameter cannot have default value
>>> lambda a, *a, b, **c, d: None
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> lambda a,*a, b, **c, d=4: None
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> lambda a,*a, b, **c, *d: None
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> lambda a,*a, b, **c, **d: None
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> lambda a=1,/,**b,/,c: None
Traceback (most recent call last):
-SyntaxError: arguments cannot follow var-keyword argument
+SyntaxError: parameters cannot follow var-keyword parameter
>>> lambda *b,*d: None
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> lambda a,*b,c,*d,*e,c: None
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> lambda a,b,/,c,*b,c,*d,*e,c: None
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> lambda a,b,/,c,*b,c,*d,**e: None
Traceback (most recent call last):
-SyntaxError: * argument may appear only once
+SyntaxError: * may appear only once
>>> lambda a=1,d=,c: None
Traceback (most recent call last):
@@ -1304,7 +1304,7 @@ Missing parens after function definition
Traceback (most recent call last):
SyntaxError: expected '('
-Parenthesized arguments in function definitions
+Parenthesized parameters in function definitions
>>> def f(x, (y, z), w):
... pass
@@ -2178,7 +2178,7 @@ Corner-cases that used to fail to raise the correct error:
>>> with (lambda *:0): pass
Traceback (most recent call last):
- SyntaxError: named arguments must follow bare *
+ SyntaxError: named parameters must follow bare *
Corner-cases that used to crash:
diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py
index 5fe9d688410..8f277952007 100644
--- a/Lib/test/test_xml_etree.py
+++ b/Lib/test/test_xml_etree.py
@@ -2960,6 +2960,50 @@ class BadElementTest(ElementTestCase, unittest.TestCase):
del b
gc_collect()
+ def test_deepcopy_clear(self):
+ # Prevent crashes when __deepcopy__() clears the children list.
+ # See https://github.com/python/cpython/issues/133009.
+ class X(ET.Element):
+ def __deepcopy__(self, memo):
+ root.clear()
+ return self
+
+ root = ET.Element('a')
+ evil = X('x')
+ root.extend([evil, ET.Element('y')])
+ if is_python_implementation():
+ # Mutating a list over which we iterate raises an error.
+ self.assertRaises(RuntimeError, copy.deepcopy, root)
+ else:
+ c = copy.deepcopy(root)
+ # In the C implementation, we can still copy the evil element.
+ self.assertListEqual(list(c), [evil])
+
+ def test_deepcopy_grow(self):
+ # Prevent crashes when __deepcopy__() mutates the children list.
+ # See https://github.com/python/cpython/issues/133009.
+ a = ET.Element('a')
+ b = ET.Element('b')
+ c = ET.Element('c')
+
+ class X(ET.Element):
+ def __deepcopy__(self, memo):
+ root.append(a)
+ root.append(b)
+ return self
+
+ root = ET.Element('top')
+ evil1, evil2 = X('1'), X('2')
+ root.extend([evil1, c, evil2])
+ children = list(copy.deepcopy(root))
+ # mock deep copies
+ self.assertIs(children[0], evil1)
+ self.assertIs(children[2], evil2)
+ # true deep copies
+ self.assertEqual(children[1].tag, c.tag)
+ self.assertEqual([c.tag for c in children[3:]],
+ [a.tag, b.tag, a.tag, b.tag])
+
class MutationDeleteElementPath(str):
def __new__(cls, elem, *args):
diff --git a/Lib/test/test_zstd.py b/Lib/test/test_zstd.py
index cd65c1a6637..713294c4c27 100644
--- a/Lib/test/test_zstd.py
+++ b/Lib/test/test_zstd.py
@@ -1174,43 +1174,43 @@ class ZstdDictTestCase(unittest.TestCase):
def test_train_dict_c(self):
# argument wrong type
with self.assertRaises(TypeError):
- _zstd._train_dict({}, (), 100)
+ _zstd.train_dict({}, (), 100)
with self.assertRaises(TypeError):
- _zstd._train_dict(b'', 99, 100)
+ _zstd.train_dict(b'', 99, 100)
with self.assertRaises(TypeError):
- _zstd._train_dict(b'', (), 100.1)
+ _zstd.train_dict(b'', (), 100.1)
# size > size_t
with self.assertRaises(ValueError):
- _zstd._train_dict(b'', (2**64+1,), 100)
+ _zstd.train_dict(b'', (2**64+1,), 100)
# dict_size <= 0
with self.assertRaises(ValueError):
- _zstd._train_dict(b'', (), 0)
+ _zstd.train_dict(b'', (), 0)
def test_finalize_dict_c(self):
with self.assertRaises(TypeError):
- _zstd._finalize_dict(1, 2, 3, 4, 5)
+ _zstd.finalize_dict(1, 2, 3, 4, 5)
# argument wrong type
with self.assertRaises(TypeError):
- _zstd._finalize_dict({}, b'', (), 100, 5)
+ _zstd.finalize_dict({}, b'', (), 100, 5)
with self.assertRaises(TypeError):
- _zstd._finalize_dict(TRAINED_DICT.dict_content, {}, (), 100, 5)
+ _zstd.finalize_dict(TRAINED_DICT.dict_content, {}, (), 100, 5)
with self.assertRaises(TypeError):
- _zstd._finalize_dict(TRAINED_DICT.dict_content, b'', 99, 100, 5)
+ _zstd.finalize_dict(TRAINED_DICT.dict_content, b'', 99, 100, 5)
with self.assertRaises(TypeError):
- _zstd._finalize_dict(TRAINED_DICT.dict_content, b'', (), 100.1, 5)
+ _zstd.finalize_dict(TRAINED_DICT.dict_content, b'', (), 100.1, 5)
with self.assertRaises(TypeError):
- _zstd._finalize_dict(TRAINED_DICT.dict_content, b'', (), 100, 5.1)
+ _zstd.finalize_dict(TRAINED_DICT.dict_content, b'', (), 100, 5.1)
# size > size_t
with self.assertRaises(ValueError):
- _zstd._finalize_dict(TRAINED_DICT.dict_content, b'', (2**64+1,), 100, 5)
+ _zstd.finalize_dict(TRAINED_DICT.dict_content, b'', (2**64+1,), 100, 5)
# dict_size <= 0
with self.assertRaises(ValueError):
- _zstd._finalize_dict(TRAINED_DICT.dict_content, b'', (), 0, 5)
+ _zstd.finalize_dict(TRAINED_DICT.dict_content, b'', (), 0, 5)
def test_train_buffer_protocol_samples(self):
def _nbytes(dat):
@@ -1232,19 +1232,19 @@ class ZstdDictTestCase(unittest.TestCase):
# wrong size list
with self.assertRaisesRegex(ValueError,
"The samples size tuple doesn't match the concatenation's size"):
- _zstd._train_dict(concatenation, tuple(wrong_size_lst), 100*_1K)
+ _zstd.train_dict(concatenation, tuple(wrong_size_lst), 100*_1K)
# correct size list
- _zstd._train_dict(concatenation, tuple(correct_size_lst), 3*_1K)
+ _zstd.train_dict(concatenation, tuple(correct_size_lst), 3*_1K)
# wrong size list
with self.assertRaisesRegex(ValueError,
"The samples size tuple doesn't match the concatenation's size"):
- _zstd._finalize_dict(TRAINED_DICT.dict_content,
+ _zstd.finalize_dict(TRAINED_DICT.dict_content,
concatenation, tuple(wrong_size_lst), 300*_1K, 5)
# correct size list
- _zstd._finalize_dict(TRAINED_DICT.dict_content,
+ _zstd.finalize_dict(TRAINED_DICT.dict_content,
concatenation, tuple(correct_size_lst), 300*_1K, 5)
def test_as_prefix(self):
@@ -1682,10 +1682,10 @@ class FileTestCase(unittest.TestCase):
# Trailing data isn't a valid compressed stream
with ZstdFile(io.BytesIO(self.FRAME_42 + b'12345')) as f:
- self.assertEqual(f.read(), self.DECOMPRESSED_42)
+ self.assertRaises(ZstdError, f.read)
with ZstdFile(io.BytesIO(SKIPPABLE_FRAME + b'12345')) as f:
- self.assertEqual(f.read(), b'')
+ self.assertRaises(ZstdError, f.read)
def test_read_truncated(self):
# Drop stream epilogue: 4 bytes checksum