Use ast.unparse for generating patches with lib_updater.py (#6142)

* Use `ast.unparse` for decorator generation and every ut_method

* Ensure ut_method type for external patches

* use textwrap

* Apply patches to `test_os.py`

* Apoly on `test_xml_etree.py`

* Run on some test files

* Update `test_str.py`

* Update `test_logging.py` from 3.13.7
This commit is contained in:
Shahar Naveh authored and GitHub committed 2025-09-11 22:42:19 +09:00
1 parent 0c3d14affc
commit f429ac4939
7 files changed
+414 -778

No files matched your search

+109 -220
View File
@@ -72,8 +72,7 @@ class AST_Tests(unittest.TestCase):
# "ast.AST constructor takes 0 positional arguments"
ast.AST(2)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_AST_fields_NULL_check(self):
# See: https://github.com/python/cpython/issues/126105
old_value = ast.AST._fields
@@ -91,8 +90,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaisesRegex(AttributeError, msg):
ast.AST()
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_AST_garbage_collection(self):
class X:
pass
@@ -105,8 +103,7 @@ class AST_Tests(unittest.TestCase):
support.gc_collect()
self.assertIsNone(ref())
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_snippets(self):
for input, output, kind in (
(exec_tests, exec_results, "exec"),
@@ -121,8 +118,7 @@ class AST_Tests(unittest.TestCase):
with self.subTest(action="compiling", input=i, kind=kind):
compile(ast_tree, "?", kind)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_ast_validation(self):
# compile() is the only function that calls PyAST_Validate
snippets_to_validate = exec_tests + single_tests + eval_tests
@@ -130,8 +126,7 @@ class AST_Tests(unittest.TestCase):
tree = ast.parse(snippet)
compile(tree, "<string>", "exec")
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_optimization_levels__debug__(self):
cases = [(-1, "__debug__"), (0, "__debug__"), (1, False), (2, False)]
for optval, expected in cases:
@@ -147,8 +142,7 @@ class AST_Tests(unittest.TestCase):
self.assertIsInstance(res.body[0].value, ast.Name)
self.assertEqual(res.body[0].value.id, expected)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_optimization_levels_const_folding(self):
folded = ("Expr", (1, 0, 1, 5), ("Constant", (1, 0, 1, 5), 3, None))
not_folded = (
@@ -172,8 +166,7 @@ class AST_Tests(unittest.TestCase):
res = to_tuple(tree.body[0])
self.assertEqual(res, expected)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_invalid_position_information(self):
invalid_linenos = [(10, 1), (-10, -11), (10, -11), (-5, -2), (-5, 1)]
@@ -198,8 +191,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaises(ValueError):
compile(tree, "<string>", "exec")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_compilation_of_ast_nodes_with_default_end_position_values(self):
tree = ast.Module(
body=[
@@ -220,8 +212,7 @@ class AST_Tests(unittest.TestCase):
# Check that compilation doesn't crash. Note: this may crash explicitly only on debug mode.
compile(tree, "<string>", "exec")
# TODO: RUSTPYTHON; TypeError: required field "end_lineno" missing from alias
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: required field "end_lineno" missing from alias
def test_negative_locations_for_compile(self):
# See https://github.com/python/cpython/issues/130775
alias = ast.alias(name='traceback', lineno=0, col_offset=0)
@@ -328,8 +319,7 @@ class AST_Tests(unittest.TestCase):
if isinstance(x, ast.AST):
self.assertIs(type(x._fields), tuple)
# TODO: RUSTPYTHON; type object 'Module' has no attribute '__annotations__'
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; type object 'Module' has no attribute '__annotations__'
def test_field_attr_existence(self):
for name, item in ast.__dict__.items():
# These emit DeprecationWarnings
@@ -356,8 +346,7 @@ class AST_Tests(unittest.TestCase):
kwargs[name] = self._construct_ast_class(typ)
return cls(**kwargs)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_arguments(self):
x = ast.arguments()
self.assertEqual(
@@ -406,8 +395,7 @@ class AST_Tests(unittest.TestCase):
x._fields = 666
self.assertEqual(x._fields, 666)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_classattrs_deprecated(self):
with warnings.catch_warnings():
warnings.filterwarnings("ignore", "", DeprecationWarning)
@@ -499,8 +487,7 @@ class AST_Tests(unittest.TestCase):
],
)
# TODO: RUSTPYTHON; DeprecationWarning not triggered
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; DeprecationWarning not triggered
def test_classattrs(self):
with self.assertWarns(DeprecationWarning):
x = ast.Constant()
@@ -706,8 +693,7 @@ class AST_Tests(unittest.TestCase):
with assertNumDeprecated():
self.assertNotIsInstance(Constant(S("42")), Num)
# TODO: RUSTPYTHON; will be removed in Python 3.14
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; will be removed in Python 3.14
def test_constant_subclasses_deprecated(self):
with warnings.catch_warnings():
warnings.filterwarnings("ignore", "", DeprecationWarning)
@@ -774,8 +760,7 @@ class AST_Tests(unittest.TestCase):
x = ast.Module(body, [])
self.assertEqual(x.body, body)
# TODO: RUSTPYTHON; DeprecationWarning not triggered
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; DeprecationWarning not triggered
def test_nodeclasses(self):
# Zero arguments constructor explicitly allowed (but deprecated)
with self.assertWarns(DeprecationWarning):
@@ -827,8 +812,7 @@ class AST_Tests(unittest.TestCase):
x = ast.Sub()
self.assertEqual(x._fields, ())
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_invalid_sum(self):
pos = dict(lineno=2, col_offset=3)
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
@@ -836,8 +820,7 @@ class AST_Tests(unittest.TestCase):
compile(m, "<test>", "exec")
self.assertIn("but got <ast.expr", str(cm.exception))
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_invalid_identifier(self):
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
ast.fix_missing_locations(m)
@@ -852,8 +835,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaisesRegex(TypeError, "invalid type in Constant: type"):
compile(e, "<test>", "eval")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_empty_yield_from(self):
# Issue 16546: yield from value is not optional.
empty_yield_from = ast.parse("def f():\n yield from g()")
@@ -910,8 +892,7 @@ class AST_Tests(unittest.TestCase):
attr_b = tree.body[0].decorator_list[0].value
self.assertEqual(attr_b.end_col_offset, 4)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_ast_asdl_signature(self):
self.assertEqual(
ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)"
@@ -926,8 +907,7 @@ class AST_Tests(unittest.TestCase):
expressions[0] = f"expr = {ast.expr.__subclasses__()[0].__doc__}"
self.assertCountEqual(ast.expr.__doc__.split("\n"), expressions)
# TODO: RUSTPYTHON; SyntaxError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError not raised
def test_positional_only_feature_version(self):
ast.parse("def foo(x, /): ...", feature_version=(3, 8))
ast.parse("def bar(x=1, /): ...", feature_version=(3, 8))
@@ -943,8 +923,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaises(SyntaxError):
ast.parse("lambda x=1, /: ...", feature_version=(3, 7))
# TODO: RUSTPYTHON; SyntaxError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError not raised
def test_assignment_expression_feature_version(self):
ast.parse("(x := 0)", feature_version=(3, 8))
with self.assertRaises(SyntaxError):
@@ -954,8 +933,7 @@ class AST_Tests(unittest.TestCase):
# regression test for gh-115881
ast.parse("with (x() if y else z()): ...", feature_version=(3, 8))
# TODO: RUSTPYTHON; SyntaxError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError not raised
def test_exception_groups_feature_version(self):
code = dedent("""
try: ...
@@ -965,8 +943,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaises(SyntaxError):
ast.parse(code, feature_version=(3, 10))
# TODO: RUSTPYTHON; SyntaxError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError not raised
def test_type_params_feature_version(self):
samples = [
"type X = int",
@@ -979,8 +956,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaises(SyntaxError):
ast.parse(sample, feature_version=(3, 11))
# TODO: RUSTPYTHON; SyntaxError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError not raised
def test_type_params_default_feature_version(self):
samples = [
"type X[*Ts=int] = int",
@@ -999,8 +975,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaises(ValueError):
ast.parse("pass", feature_version=(4, 0))
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_constant_as_name(self):
for constant in "True", "False", "None":
expr = ast.Expression(ast.Name(constant, ast.Load()))
@@ -1010,8 +985,7 @@ class AST_Tests(unittest.TestCase):
):
compile(expr, "<test>", "eval")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_constant_as_unicode_name(self):
constants = [
("True", b"Tru\xe1\xb5\x89"),
@@ -1023,8 +997,7 @@ class AST_Tests(unittest.TestCase):
f"identifier field can't represent '{constant[0]}' constant"):
ast.parse(constant[1], mode="eval")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_precedence_enum(self):
class _Precedence(enum.IntEnum):
"""Precedence table that originated from python grammar."""
@@ -1101,8 +1074,7 @@ class AST_Tests(unittest.TestCase):
with self.assertRaisesRegex(ValueError, f"^{e}$"):
compile(tree, "<test>", "exec")
# TODO: RUSTPYTHON; TypeError: expected some sort of expr, but got None
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: expected some sort of expr, but got None
def test_none_checks(self) -> None:
tests = [
(ast.alias, "name", "import spam as SPAM"),
@@ -1120,8 +1092,7 @@ class AST_Tests(unittest.TestCase):
class CopyTests(unittest.TestCase):
"""Test copying and pickling AST nodes."""
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_pickling(self):
import pickle
@@ -1202,8 +1173,7 @@ class CopyTests(unittest.TestCase):
class ASTHelpers_Test(unittest.TestCase):
maxDiff = None
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_parse(self):
a = ast.parse("foo(1 + 1)")
b = compile("foo(1 + 1)", "<unknown>", "exec", ast.PyCF_ONLY_AST)
@@ -1217,8 +1187,7 @@ class ASTHelpers_Test(unittest.TestCase):
ast.literal_eval(r"'\U'")
self.assertIsNotNone(e.exception.__context__)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_dump(self):
node = ast.parse('spam(eggs, "and cheese")')
self.assertEqual(
@@ -1242,8 +1211,7 @@ class ASTHelpers_Test(unittest.TestCase):
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)])",
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_dump_indent(self):
node = ast.parse('spam(eggs, "and cheese")')
self.assertEqual(
@@ -1308,8 +1276,7 @@ Module(
end_col_offset=24)])""",
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_dump_incomplete(self):
node = ast.Raise(lineno=3, col_offset=4)
self.assertEqual(ast.dump(node), "Raise()")
@@ -1377,8 +1344,7 @@ Module(
"ClassDef('T', [], [keyword('a', Constant(None))], [], [Name('dataclass', Load())])",
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_dump_show_empty(self):
def check_node(node, empty, full, **kwargs):
with self.subTest(show_empty=False):
@@ -1469,8 +1435,7 @@ Module(
full="Module(body=[Import(names=[alias(name='_ast', asname='ast')]), ImportFrom(module='module', names=[alias(name='sub')], level=0)], type_ignores=[])",
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_copy_location(self):
src = ast.parse("1 + 1", mode="eval")
src.body.right = ast.copy_location(ast.Constant(2), src.body.right)
@@ -1491,8 +1456,7 @@ Module(
self.assertEqual(new.lineno, 1)
self.assertEqual(new.col_offset, 1)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_fix_missing_locations(self):
src = ast.parse('write("spam")')
src.body.append(
@@ -1514,8 +1478,7 @@ Module(
"end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)])",
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_increment_lineno(self):
src = ast.parse("1 + 1", mode="eval")
self.assertEqual(ast.increment_lineno(src, n=3), src)
@@ -1542,8 +1505,7 @@ Module(
self.assertEqual(ast.increment_lineno(src).lineno, 2)
self.assertIsNone(ast.increment_lineno(src).end_lineno)
# TODO: RUSTPYTHON; IndexError: index out of range
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; IndexError: index out of range
def test_increment_lineno_on_module(self):
src = ast.parse(
dedent("""\
@@ -1565,8 +1527,7 @@ Module(
self.assertEqual(d.pop("func").id, "foo")
self.assertEqual(d, {"keywords": [], "args": []})
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_iter_child_nodes(self):
node = ast.parse("spam(23, 42, eggs='leek')", mode="eval")
self.assertEqual(len(list(ast.iter_child_nodes(node.body))), 4)
@@ -1681,8 +1642,7 @@ Module(
self.assertRaises(ValueError, ast.literal_eval, "+True")
self.assertRaises(ValueError, ast.literal_eval, "2+3")
# TODO: RUSTPYTHON; SyntaxError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError not raised
def test_literal_eval_str_int_limit(self):
with support.adjust_int_max_str_digits(4000):
ast.literal_eval("3" * 4000) # no error
@@ -1722,8 +1682,7 @@ Module(
)
self.assertRaises(ValueError, ast.literal_eval, malformed)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_literal_eval_trailing_ws(self):
self.assertEqual(ast.literal_eval(" -1"), -1)
self.assertEqual(ast.literal_eval("\t\t-1"), -1)
@@ -1741,8 +1700,7 @@ Module(
with self.assertRaisesRegex(ValueError, msg):
ast.literal_eval(node)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_literal_eval_syntax_errors(self):
with self.assertRaisesRegex(SyntaxError, "unexpected indent"):
ast.literal_eval(r"""
@@ -1750,8 +1708,7 @@ Module(
(\
\ """)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_bad_integer(self):
# issue13436: Bad error message with invalid numeric values
body = [
@@ -1768,8 +1725,7 @@ Module(
compile(mod, "test", "exec")
self.assertIn("invalid integer value: None", str(cm.exception))
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_level_as_none(self):
body = [
ast.ImportFrom(
@@ -1786,8 +1742,7 @@ Module(
exec(code, ns)
self.assertIn("sleep", ns)
# TODO: RUSTPYTHON
@unittest.skip("TODO: RUSTPYTHON; crash")
@unittest.skip('TODO: RUSTPYTHON; crash')
def test_recursion_direct(self):
e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0, operand=ast.Constant(1))
e.operand = e
@@ -1795,8 +1750,7 @@ Module(
with support.infinite_recursion():
compile(ast.Expression(e), "<test>", "eval")
# TODO: RUSTPYTHON
@unittest.skip("TODO: RUSTPYTHON; crash")
@unittest.skip('TODO: RUSTPYTHON; crash')
def test_recursion_indirect(self):
e = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0, operand=ast.Constant(1))
f = ast.UnaryOp(op=ast.Not(), lineno=0, col_offset=0, operand=ast.Constant(1))
@@ -1826,8 +1780,7 @@ class ASTValidatorTests(unittest.TestCase):
mod = ast.Module([stmt], [])
self.mod(mod, msg)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_module(self):
m = ast.Interactive([ast.Expr(ast.Name("x", ast.Store()))])
self.mod(m, "must have Load context", "single")
@@ -1884,8 +1837,7 @@ class ASTValidatorTests(unittest.TestCase):
"must have Load context",
)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_funcdef(self):
a = ast.arguments([], [], None, [], [], None, [])
f = ast.FunctionDef("x", a, [], [], None, None, [])
@@ -1906,8 +1858,7 @@ class ASTValidatorTests(unittest.TestCase):
self._check_arguments(fac, self.stmt)
# TODO: RUSTPYTHON; called `Result::unwrap()` on an `Err` value: StackUnderflow
'''
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: class pattern defines no positional sub-patterns (__match_args__ missing)
def test_funcdef_pattern_matching(self):
# gh-104799: New fields on FunctionDef should be added at the end
def matcher(node):
@@ -1932,10 +1883,8 @@ class ASTValidatorTests(unittest.TestCase):
funcdef = source.body[0]
self.assertIsInstance(funcdef, ast.FunctionDef)
self.assertTrue(matcher(funcdef))
'''
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_classdef(self):
def cls(
bases=None, keywords=None, body=None, decorator_list=None, type_params=None
@@ -1965,15 +1914,13 @@ class ASTValidatorTests(unittest.TestCase):
cls(decorator_list=[ast.Name("x", ast.Store())]), "must have Load context"
)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_delete(self):
self.stmt(ast.Delete([]), "empty targets on Delete")
self.stmt(ast.Delete([None]), "None disallowed")
self.stmt(ast.Delete([ast.Name("x", ast.Load())]), "must have Del context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_assign(self):
self.stmt(ast.Assign([], ast.Constant(3)), "empty targets on Assign")
self.stmt(ast.Assign([None], ast.Constant(3)), "None disallowed")
@@ -1986,8 +1933,7 @@ class ASTValidatorTests(unittest.TestCase):
"must have Load context",
)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_augassign(self):
aug = ast.AugAssign(
ast.Name("x", ast.Load()), ast.Add(), ast.Name("y", ast.Load())
@@ -1998,8 +1944,7 @@ class ASTValidatorTests(unittest.TestCase):
)
self.stmt(aug, "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_for(self):
x = ast.Name("x", ast.Store())
y = ast.Name("y", ast.Load())
@@ -2015,8 +1960,7 @@ class ASTValidatorTests(unittest.TestCase):
self.stmt(ast.For(x, y, [e], []), "must have Load context")
self.stmt(ast.For(x, y, [p], [e]), "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_while(self):
self.stmt(ast.While(ast.Constant(3), [], []), "empty body on While")
self.stmt(
@@ -2030,8 +1974,7 @@ class ASTValidatorTests(unittest.TestCase):
"must have Load context",
)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_if(self):
self.stmt(ast.If(ast.Constant(3), [], []), "empty body on If")
i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], [])
@@ -2043,8 +1986,7 @@ class ASTValidatorTests(unittest.TestCase):
)
self.stmt(i, "must have Load context")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_with(self):
p = ast.Pass()
self.stmt(ast.With([], [p]), "empty items on With")
@@ -2055,8 +1997,7 @@ class ASTValidatorTests(unittest.TestCase):
i = ast.withitem(ast.Constant(3), ast.Name("x", ast.Load()))
self.stmt(ast.With([i], [p]), "must have Store context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_raise(self):
r = ast.Raise(None, ast.Constant(3))
self.stmt(r, "Raise with cause but no exception")
@@ -2065,8 +2006,7 @@ class ASTValidatorTests(unittest.TestCase):
r = ast.Raise(ast.Constant(4), ast.Name("x", ast.Store()))
self.stmt(r, "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_try(self):
p = ast.Pass()
t = ast.Try([], [], [], [p])
@@ -2087,8 +2027,7 @@ class ASTValidatorTests(unittest.TestCase):
t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
self.stmt(t, "must have Load context")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_try_star(self):
p = ast.Pass()
t = ast.TryStar([], [], [], [p])
@@ -2109,8 +2048,7 @@ class ASTValidatorTests(unittest.TestCase):
t = ast.TryStar([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
self.stmt(t, "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_assert(self):
self.stmt(
ast.Assert(ast.Name("x", ast.Store()), None), "must have Load context"
@@ -2118,36 +2056,30 @@ class ASTValidatorTests(unittest.TestCase):
assrt = ast.Assert(ast.Name("x", ast.Load()), ast.Name("y", ast.Store()))
self.stmt(assrt, "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_import(self):
self.stmt(ast.Import([]), "empty names on Import")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_importfrom(self):
imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
self.stmt(imp, "Negative ImportFrom level")
self.stmt(ast.ImportFrom(None, [], 0), "empty names on ImportFrom")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_global(self):
self.stmt(ast.Global([]), "empty names on Global")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_nonlocal(self):
self.stmt(ast.Nonlocal([]), "empty names on Nonlocal")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_expr(self):
e = ast.Expr(ast.Name("x", ast.Store()))
self.stmt(e, "must have Load context")
# TODO: RUSTPYTHON
@unittest.skip("TODO: RUSTPYTHON; called `Option::unwrap()` on a `None` value")
@unittest.skip('TODO: RUSTPYTHON; called `Option::unwrap()` on a `None` value')
def test_boolop(self):
b = ast.BoolOp(ast.And(), [])
self.expr(b, "less than 2 values")
@@ -2158,14 +2090,12 @@ class ASTValidatorTests(unittest.TestCase):
b = ast.BoolOp(ast.And(), [ast.Constant(4), ast.Name("x", ast.Store())])
self.expr(b, "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_unaryop(self):
u = ast.UnaryOp(ast.Not(), ast.Name("x", ast.Store()))
self.expr(u, "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_lambda(self):
a = ast.arguments([], [], None, [], [], None, [])
self.expr(ast.Lambda(a, ast.Name("x", ast.Store())), "must have Load context")
@@ -2175,24 +2105,21 @@ class ASTValidatorTests(unittest.TestCase):
self._check_arguments(fac, self.expr)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_ifexp(self):
l = ast.Name("x", ast.Load())
s = ast.Name("y", ast.Store())
for args in (s, l, l), (l, s, l), (l, l, s):
self.expr(ast.IfExp(*args), "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_dict(self):
d = ast.Dict([], [ast.Name("x", ast.Load())])
self.expr(d, "same number of keys as values")
d = ast.Dict([ast.Name("x", ast.Load())], [None])
self.expr(d, "None disallowed")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_set(self):
self.expr(ast.Set([None]), "None disallowed")
s = ast.Set([ast.Name("x", ast.Store())])
@@ -2226,23 +2153,19 @@ class ASTValidatorTests(unittest.TestCase):
self._check_comprehension(wrap)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_listcomp(self):
self._simple_comp(ast.ListComp)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_setcomp(self):
self._simple_comp(ast.SetComp)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_generatorexp(self):
self._simple_comp(ast.GeneratorExp)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_dictcomp(self):
g = ast.comprehension(
ast.Name("y", ast.Store()), ast.Name("p", ast.Load()), [], 0
@@ -2259,13 +2182,11 @@ class ASTValidatorTests(unittest.TestCase):
self._check_comprehension(factory)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_yield(self):
self.expr(ast.Yield(ast.Name("x", ast.Store())), "must have Load")
self.expr(ast.YieldFrom(ast.Name("x", ast.Store())), "must have Load")
# TODO: RUSTPYTHON
@unittest.skip("TODO: RUSTPYTHON; thread 'main' panicked")
def test_compare(self):
left = ast.Name("x", ast.Load())
@@ -2278,8 +2199,7 @@ class ASTValidatorTests(unittest.TestCase):
comp = ast.Compare(left, [ast.In()], [ast.Constant("blah")])
self.expr(comp)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_call(self):
func = ast.Name("x", ast.Load())
args = [ast.Name("y", ast.Load())]
@@ -2325,14 +2245,12 @@ class ASTValidatorTests(unittest.TestCase):
],
)
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_attribute(self):
attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load())
self.expr(attr, "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_subscript(self):
sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Constant(3), ast.Load())
self.expr(sub, "must have Load context")
@@ -2348,8 +2266,7 @@ class ASTValidatorTests(unittest.TestCase):
sl = ast.Tuple([s], ast.Load())
self.expr(ast.Subscript(x, sl, ast.Load()), "must have Load context")
# TODO: RUSTPYTHON; ValueError not raised
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError not raised
def test_starred(self):
left = ast.List(
[ast.Starred(ast.Name("x", ast.Load()), ast.Store())], ast.Store()
@@ -2363,13 +2280,11 @@ class ASTValidatorTests(unittest.TestCase):
fac([ast.Name("x", ast.Store())], ast.Load()), "must have Load context"
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_list(self):
self._sequence(ast.List)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_tuple(self):
self._sequence(ast.Tuple)
@@ -2389,8 +2304,7 @@ class ASTValidatorTests(unittest.TestCase):
],
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
@support.requires_resource("cpu")
def test_stdlib_validates(self):
stdlib = os.path.dirname(ast.__file__)
@@ -2486,7 +2400,6 @@ class ASTValidatorTests(unittest.TestCase):
ast.MatchMapping([], [], rest="_"),
]
# TODO: RUSTPYTHON
@unittest.skip("TODO: RUSTPYTHON; thread 'main' panicked")
def test_match_validation_pattern(self):
name_x = ast.Name("x", ast.Load())
@@ -2524,16 +2437,14 @@ class ConstantTests(unittest.TestCase):
self.compile_constant([1, 2, 3])
self.assertEqual(str(cm.exception), "got an invalid type in Constant: list")
# TODO: RUSTPYTHON; b'' is not b''
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; b'' is not b''
def test_singletons(self):
for const in (None, False, True, Ellipsis, b"", frozenset()):
with self.subTest(const=const):
value = self.compile_constant(const)
self.assertIs(value, const)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_values(self):
nested_tuple = (1,)
nested_frozenset = frozenset({1})
@@ -2556,8 +2467,7 @@ class ConstantTests(unittest.TestCase):
result = self.compile_constant(value)
self.assertEqual(result, value)
# TODO: RUSTPYTHON; SyntaxError: cannot assign to literal
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError: cannot assign to literal
def test_assign_to_constant(self):
tree = ast.parse("x = 1")
@@ -3079,8 +2989,7 @@ class NodeTransformerTests(ASTTestMixin, BaseNodeVisitorCases, unittest.TestCase
self.assertASTEqual(result_ast, expected_ast)
# TODO: RUSTPYTHON; <class 'object'> is not <class 'NoneType'>
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; <class 'object'> is not <class 'NoneType'>
def test_node_remove_single(self):
code = "def func(arg) -> SomeType: ..."
expected = "def func(arg): ..."
@@ -3118,8 +3027,7 @@ class NodeTransformerTests(ASTTestMixin, BaseNodeVisitorCases, unittest.TestCase
self.assertASTTransformation(YieldRemover, code, expected)
# TODO: RUSTPYTHON; <class 'object'> is not <class 'NoneType'>
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; <class 'object'> is not <class 'NoneType'>
def test_node_return_list(self):
code = """
class DSL(Base, kw1=True): ...
@@ -3160,8 +3068,7 @@ class NodeTransformerTests(ASTTestMixin, BaseNodeVisitorCases, unittest.TestCase
self.assertASTTransformation(PrintToLog, code, expected)
# TODO: RUSTPYTHON; <class 'object'> is not <class 'NoneType'>
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; <class 'object'> is not <class 'NoneType'>
def test_node_replace(self):
code = """
def func(arg):
@@ -3193,8 +3100,7 @@ class NodeTransformerTests(ASTTestMixin, BaseNodeVisitorCases, unittest.TestCase
class ASTConstructorTests(unittest.TestCase):
"""Test the autogenerated constructors for AST nodes."""
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_FunctionDef(self):
args = ast.arguments()
self.assertEqual(args.args, [])
@@ -3210,8 +3116,7 @@ class ASTConstructorTests(unittest.TestCase):
self.assertEqual(node.name, "foo")
self.assertEqual(node.decorator_list, [])
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_expr_context(self):
name = ast.Name("x")
self.assertEqual(name.id, "x")
@@ -3260,8 +3165,7 @@ class ASTConstructorTests(unittest.TestCase):
obj = FieldsAndTypes(a=1)
self.assertEqual(obj.a, 1)
# TODO: RUSTPYTHON; DeprecationWarning not triggered
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; DeprecationWarning not triggered
def test_custom_attributes(self):
class MyAttrs(ast.AST):
_attributes = ("a", "b")
@@ -3276,8 +3180,7 @@ class ASTConstructorTests(unittest.TestCase):
):
obj = MyAttrs(c=3)
# TODO: RUSTPYTHON; DeprecationWarning not triggered
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; DeprecationWarning not triggered
def test_fields_and_types_no_default(self):
class FieldsAndTypesNoDefault(ast.AST):
_fields = ("a",)
@@ -3293,8 +3196,7 @@ class ASTConstructorTests(unittest.TestCase):
obj = FieldsAndTypesNoDefault(a=1)
self.assertEqual(obj.a, 1)
# TODO: RUSTPYTHON; DeprecationWarning not triggered
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; DeprecationWarning not triggered
def test_incomplete_field_types(self):
class MoreFieldsThanTypes(ast.AST):
_fields = ("a", "b")
@@ -3314,8 +3216,7 @@ class ASTConstructorTests(unittest.TestCase):
self.assertEqual(obj.a, 1)
self.assertEqual(obj.b, 2)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_complete_field_types(self):
class _AllFieldTypes(ast.AST):
_fields = ("a", "b")
@@ -3416,8 +3317,7 @@ class ModuleStateTests(unittest.TestCase):
class ASTMainTests(unittest.TestCase):
# Tests `ast.main()` function.
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_cli_file_input(self):
code = "print(1, 2, 3)"
expected = ast.dump(ast.parse(code), indent=3)
@@ -3435,7 +3335,7 @@ class ASTMainTests(unittest.TestCase):
def compare(left, right):
return ast.dump(left) == ast.dump(right)
class ASTOptimiziationTests(unittest.TestCase):
class ASTOptimizationTests(unittest.TestCase):
binop = {
"+": ast.Add(),
"-": ast.Sub(),
@@ -3492,8 +3392,7 @@ class ASTOptimiziationTests(unittest.TestCase):
def create_binop(self, operand, left=ast.Constant(1), right=ast.Constant(1)):
return ast.BinOp(left=left, op=self.binop[operand], right=right)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_binop(self):
code = "1 %s 1"
operators = self.binop.keys()
@@ -3517,8 +3416,7 @@ class ASTOptimiziationTests(unittest.TestCase):
self.assert_ast(code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_unaryop(self):
code = "%s1"
operators = self.unaryop.keys()
@@ -3538,8 +3436,7 @@ class ASTOptimiziationTests(unittest.TestCase):
):
self.assert_ast(result_code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_not(self):
code = "not (1 %s (1,))"
operators = {
@@ -3572,8 +3469,7 @@ class ASTOptimiziationTests(unittest.TestCase):
):
self.assert_ast(result_code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_format(self):
code = "'%s' % (a,)"
@@ -3594,8 +3490,7 @@ class ASTOptimiziationTests(unittest.TestCase):
self.assert_ast(code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_tuple(self):
code = "(1,)"
@@ -3604,8 +3499,7 @@ class ASTOptimiziationTests(unittest.TestCase):
self.assert_ast(code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_comparator(self):
code = "1 %s %s1%s"
operators = [("in", ast.In()), ("not in", ast.NotIn())]
@@ -3625,8 +3519,7 @@ class ASTOptimiziationTests(unittest.TestCase):
))
self.assert_ast(code % (op, left, right), non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_iter(self):
code = "for _ in %s1%s: pass"
braces = [
@@ -3648,8 +3541,7 @@ class ASTOptimiziationTests(unittest.TestCase):
self.assert_ast(code % (left, right), non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_subscript(self):
code = "(1,)[0]"
@@ -3660,8 +3552,7 @@ class ASTOptimiziationTests(unittest.TestCase):
self.assert_ast(code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_type_param_in_function_def(self):
code = "def foo[%s = 1 + 1](): pass"
@@ -3692,8 +3583,7 @@ class ASTOptimiziationTests(unittest.TestCase):
)
self.assert_ast(result_code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_type_param_in_class_def(self):
code = "class foo[%s = 1 + 1]: pass"
@@ -3722,8 +3612,7 @@ class ASTOptimiziationTests(unittest.TestCase):
)
self.assert_ast(result_code, non_optimized_target, optimized_target)
# TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_folding_type_param_in_type_alias(self):
code = "type foo[%s = 1 + 1] = 1"
+28 -56
View File
@@ -86,14 +86,12 @@ class Test_Csv(unittest.TestCase):
self.assertRaises(ValueError, ctor, arg,
quotechar='\x85', lineterminator='\x85')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_reader_arg_valid(self):
self._test_arg_valid(csv.reader, [])
self.assertRaises(OSError, csv.reader, BadIterable())
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_writer_arg_valid(self):
self._test_arg_valid(csv.writer, StringIO())
class BadWriter:
@@ -214,8 +212,7 @@ class Test_Csv(unittest.TestCase):
self._write_test([bigstring,bigstring], '%s,%s' % \
(bigstring, bigstring))
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_write_quoting(self):
self._write_test(['a',1,'p,q'], 'a,1,"p,q"')
self._write_error_test(csv.Error, ['a',1,'p,q'],
@@ -233,8 +230,7 @@ class Test_Csv(unittest.TestCase):
self._write_test(['a','',None,1], '"a","",,"1"',
quoting = csv.QUOTE_NOTNULL)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_write_escape(self):
self._write_test(['a',1,'p,q'], 'a,1,"p,q"',
escapechar='\\')
@@ -266,8 +262,7 @@ class Test_Csv(unittest.TestCase):
self._write_test(['C\\', '6', '7', 'X"'], 'C\\\\,6,7,"X"""',
escapechar='\\', quoting=csv.QUOTE_MINIMAL)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_write_lineterminator(self):
for lineterminator in '\r\n', '\n', '\r', '!@#', '\0':
with self.subTest(lineterminator=lineterminator):
@@ -281,8 +276,7 @@ class Test_Csv(unittest.TestCase):
f'1,2{lineterminator}'
f'"\r","\n"{lineterminator}')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_write_iterable(self):
self._write_test(iter(['a', 1, 'p,q']), 'a,1,"p,q"')
self._write_test(iter(['a', 1, None]), 'a,1,')
@@ -325,8 +319,7 @@ class Test_Csv(unittest.TestCase):
self.assertEqual(fileobj.read(), 'a\r\n""\r\n')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_write_empty_fields(self):
self._write_test((), '')
self._write_test([''], '""')
@@ -340,8 +333,7 @@ class Test_Csv(unittest.TestCase):
self._write_test(['', ''], ',')
self._write_test([None, None], ',')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_write_empty_fields_space_delimiter(self):
self._write_test([''], '""', delimiter=' ', skipinitialspace=False)
self._write_test([''], '""', delimiter=' ', skipinitialspace=True)
@@ -382,8 +374,7 @@ class Test_Csv(unittest.TestCase):
result = list(reader)
self.assertEqual(result, expect)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_oddinputs(self):
self._read_test([], [])
self._read_test([''], [[]])
@@ -394,8 +385,7 @@ class Test_Csv(unittest.TestCase):
self.assertRaises(csv.Error, self._read_test,
[b'abc'], None)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_eol(self):
self._read_test(['a,b', 'c,d'], [['a','b'], ['c','d']])
self._read_test(['a,b\n', 'c,d\n'], [['a','b'], ['c','d']])
@@ -410,8 +400,7 @@ class Test_Csv(unittest.TestCase):
with self.assertRaisesRegex(csv.Error, errmsg):
next(csv.reader(['a,b\r\nc,d']))
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_eof(self):
self._read_test(['a,"'], [['a', '']])
self._read_test(['"a'], [['a']])
@@ -421,8 +410,7 @@ class Test_Csv(unittest.TestCase):
self.assertRaises(csv.Error, self._read_test,
['^'], [], escapechar='^', strict=True)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_nul(self):
self._read_test(['\0'], [['\0']])
self._read_test(['a,\0b,c'], [['a', '\0b', 'c']])
@@ -435,8 +423,7 @@ class Test_Csv(unittest.TestCase):
self._read_test(['a;b;c'], [['a', 'b', 'c']], delimiter=';')
self._read_test(['a\0b\0c'], [['a', 'b', 'c']], delimiter='\0')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_escape(self):
self._read_test(['a,\\b,c'], [['a', 'b', 'c']], escapechar='\\')
self._read_test(['a,b\\,c'], [['a', 'b,c']], escapechar='\\')
@@ -449,8 +436,7 @@ class Test_Csv(unittest.TestCase):
self._read_test(['a,\\b,c'], [['a', '\\b', 'c']], escapechar=None)
self._read_test(['a,\\b,c'], [['a', '\\b', 'c']])
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_quoting(self):
self._read_test(['1,",3,",5'], [['1', ',3,', '5']])
self._read_test(['1,",3,",5'], [['1', '"', '3', '"', '5']],
@@ -487,8 +473,7 @@ class Test_Csv(unittest.TestCase):
self._read_test(['1\\.5,\\.5,"\\.5"'], [[1.5, 0.5, ".5"]],
quoting=csv.QUOTE_STRINGS, escapechar='\\')
# TODO: RUSTPYTHON; panic
@unittest.skip("TODO: RUSTPYTHON; slice index starts at 1 but ends at 0")
@unittest.skip('TODO: RUSTPYTHON; slice index starts at 1 but ends at 0')
def test_read_skipinitialspace(self):
self._read_test(['no space, space, spaces,\ttab'],
[['no space', 'space', 'spaces', '\ttab']],
@@ -503,8 +488,7 @@ class Test_Csv(unittest.TestCase):
[[None, None, None]],
skipinitialspace=True, quoting=csv.QUOTE_STRINGS)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_space_delimiter(self):
self._read_test(['a b', ' a ', ' ', ''],
[['a', '', '', 'b'], ['', '', 'a', '', ''], ['', '', ''], []],
@@ -544,8 +528,7 @@ class Test_Csv(unittest.TestCase):
self.assertRaises(StopIteration, next, r)
self.assertEqual(r.line_num, 3)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_roundtrip_quoteed_newlines(self):
rows = [
['\na', 'b\nc', 'd\n'],
@@ -564,8 +547,7 @@ class Test_Csv(unittest.TestCase):
for i, row in enumerate(csv.reader(fileobj)):
self.assertEqual(row, rows[i])
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_roundtrip_escaped_unquoted_newlines(self):
rows = [
['\na', 'b\nc', 'd\n'],
@@ -680,8 +662,7 @@ class TestDialectRegistry(unittest.TestCase):
fileobj.seek(0)
self.assertEqual(fileobj.read(), expected)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_dialect_apply(self):
class testA(csv.excel):
delimiter = "\t"
@@ -717,8 +698,7 @@ class TestDialectRegistry(unittest.TestCase):
dialect = csv.get_dialect(name)
self.assertRaises(TypeError, copy.copy, dialect)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_pickle(self):
for name in csv.list_dialects():
dialect = csv.get_dialect(name)
@@ -805,8 +785,7 @@ class TestDialectExcel(TestCsvBase):
'"I see," said the blind man',
'as he picked up his hammer and saw']])
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_quoted_nl(self):
input = '''\
1,2,3,"""I see,""
@@ -847,21 +826,18 @@ class EscapedExcel(csv.excel):
class TestEscapedExcel(TestCsvBase):
dialect = EscapedExcel()
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_escape_fieldsep(self):
self.writerAssertEqual([['abc,def']], 'abc\\,def\r\n')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_escape_fieldsep(self):
self.readerAssertEqual('abc\\,def\r\n', [['abc,def']])
class TestDialectUnix(TestCsvBase):
dialect = 'unix'
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_simple_writer(self):
self.writerAssertEqual([[1, 'abc def', 'abc']], '"1","abc def","abc"\n')
@@ -878,8 +854,7 @@ class TestQuotedEscapedExcel(TestCsvBase):
def test_write_escape_fieldsep(self):
self.writerAssertEqual([['abc,def']], '"abc,def"\r\n')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_escape_fieldsep(self):
self.readerAssertEqual('"abc\\,def"\r\n', [['abc,def']])
@@ -1076,8 +1051,7 @@ class TestDictFields(unittest.TestCase):
"s1": 'abc',
"s2": 'def'})
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_read_with_blanks(self):
reader = csv.DictReader(["1,2,abc,4,5,6\r\n","\r\n",
"1,2,abc,4,5,6\r\n"],
@@ -1129,8 +1103,7 @@ class TestArrayWrites(unittest.TestCase):
fileobj.seek(0)
self.assertEqual(fileobj.read(), expected)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_char_write(self):
import array, string
a = array.array('w', string.ascii_letters)
@@ -1278,8 +1251,7 @@ class TestDialectValidity(unittest.TestCase):
self.assertEqual(str(cm.exception),
'"lineterminator" must be a string')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_invalid_chars(self):
def create_invalid(field_name, value, **kwargs):
class mydialect(csv.Dialect):
+12 -109
View File
@@ -1115,8 +1115,7 @@ class SMTPHandlerTest(BaseTest):
# bpo-14314, bpo-19665, bpo-34092: don't wait forever
TIMEOUT = support.LONG_TIMEOUT
# TODO: RUSTPYTHON
@unittest.skip(reason="RUSTPYTHON hangs")
@unittest.skip("TODO: RUSTPYTHON; hangs")
def test_basic(self):
sockmap = {}
server = TestSMTPServer((socket_helper.HOST, 0), self.process_message, 0.001,
@@ -2154,8 +2153,7 @@ class HTTPHandlerTest(BaseTest):
request.end_headers()
self.handled.set()
# TODO: RUSTPYTHON
@unittest.skip("TODO: RUSTPYTHON; flaky test")
@unittest.skip('TODO: RUSTPYTHON; flaky test')
def test_output(self):
# The log message sent to the HTTPHandler is properly received.
logger = logging.getLogger("http")
@@ -4060,8 +4058,7 @@ class ConfigDictTest(BaseTest):
# log a message (this creates a record put in the queue)
logging.getLogger().info(message_to_log)
# TODO: RUSTPYTHON; ImportError: cannot import name 'SemLock'
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ImportError: cannot import name 'SemLock'
@skip_if_tsan_fork
@support.requires_subprocess()
def test_multiprocessing_queues(self):
@@ -4121,8 +4118,7 @@ class ConfigDictTest(BaseTest):
# Logger should be enabled, since explicitly mentioned
self.assertFalse(logger.disabled)
# TODO: RUSTPYTHON; ImportError: cannot import name 'SemLock'
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ImportError: cannot import name 'SemLock'
def test_111615(self):
# See gh-111615
import_helper.import_module('_multiprocessing') # see gh-113692
@@ -4171,91 +4167,6 @@ class ConfigDictTest(BaseTest):
handler = logging.getHandlerByName('custom')
self.assertEqual(handler.custom_kwargs, custom_kwargs)
# TODO: RUSTPYTHON; ImportError: cannot import name 'SemLock'
@unittest.expectedFailure
# See gh-91555 and gh-90321
@support.requires_subprocess()
def test_deadlock_in_queue(self):
queue = multiprocessing.Queue()
handler = logging.handlers.QueueHandler(queue)
logger = multiprocessing.get_logger()
level = logger.level
try:
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
logger.debug("deadlock")
finally:
logger.setLevel(level)
logger.removeHandler(handler)
def test_recursion_in_custom_handler(self):
class BadHandler(logging.Handler):
def __init__(self):
super().__init__()
def emit(self, record):
logger.debug("recurse")
logger = logging.getLogger("test_recursion_in_custom_handler")
logger.addHandler(BadHandler())
logger.setLevel(logging.DEBUG)
logger.debug("boom")
@threading_helper.requires_working_threading()
def test_thread_supression_noninterference(self):
lock = threading.Lock()
logger = logging.getLogger("test_thread_supression_noninterference")
# Block on the first call, allow others through
#
# NOTE: We need to bypass the base class's lock, otherwise that will
# block multiple calls to the same handler itself.
class BlockOnceHandler(TestHandler):
def __init__(self, barrier):
super().__init__(support.Matcher())
self.barrier = barrier
def createLock(self):
self.lock = None
def handle(self, record):
self.emit(record)
def emit(self, record):
if self.barrier:
barrier = self.barrier
self.barrier = None
barrier.wait()
with lock:
pass
super().emit(record)
logger.info("blow up if not supressed")
barrier = threading.Barrier(2)
handler = BlockOnceHandler(barrier)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
t1 = threading.Thread(target=logger.debug, args=("1",))
with lock:
# Ensure first thread is blocked in the handler, hence supressing logging...
t1.start()
barrier.wait()
# ...but the second thread should still be able to log...
t2 = threading.Thread(target=logger.debug, args=("2",))
t2.start()
t2.join(timeout=3)
self.assertEqual(len(handler.buffer), 1)
self.assertTrue(handler.matches(levelno=logging.DEBUG, message='2'))
# The first thread should still be blocked here
self.assertTrue(t1.is_alive())
# Now the lock has been released the first thread should complete
t1.join()
self.assertEqual(len(handler.buffer), 2)
self.assertTrue(handler.matches(levelno=logging.DEBUG, message='1'))
class ManagerTest(BaseTest):
def test_manager_loggerclass(self):
@@ -4663,8 +4574,7 @@ class FormatterTest(unittest.TestCase, AssertErrorMessage):
f = logging.Formatter('${asctime}--', style='$')
self.assertTrue(f.usesTime())
# TODO: RUSTPYTHON; ValueError: Unexpected error parsing format string
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: Unexpected error parsing format string
def test_format_validate(self):
# Check correct formatting
# Percentage style
@@ -4838,8 +4748,7 @@ class FormatterTest(unittest.TestCase, AssertErrorMessage):
def test_invalid_style(self):
self.assertRaises(ValueError, logging.Formatter, None, None, 'x')
# TODO: RUSTPYTHON; AttributeError: 'struct_time' object has no attribute 'tm_gmtoff'
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'struct_time' object has no attribute 'tm_gmtoff'
def test_time(self):
r = self.get_record()
dt = datetime.datetime(1993, 4, 21, 8, 3, 0, 0, utc)
@@ -4854,8 +4763,7 @@ class FormatterTest(unittest.TestCase, AssertErrorMessage):
f.format(r)
self.assertEqual(r.asctime, '1993-04-21 08:03:00,123')
# TODO: RUSTPYTHON; AttributeError: 'struct_time' object has no attribute 'tm_gmtoff'
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: 'struct_time' object has no attribute 'tm_gmtoff'
def test_default_msec_format_none(self):
class NoMsecFormatter(logging.Formatter):
default_msec_format = None
@@ -5257,8 +5165,7 @@ class ModuleLevelMiscTest(BaseTest):
h.close()
logging.setLoggerClass(logging.Logger)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_logging_at_shutdown(self):
# bpo-20037: Doing text I/O late at interpreter shutdown must not crash
code = textwrap.dedent("""
@@ -5278,8 +5185,7 @@ class ModuleLevelMiscTest(BaseTest):
self.assertIn("exception in __del__", err)
self.assertIn("ValueError: some error", err)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_logging_at_shutdown_open(self):
# bpo-26789: FileHandler keeps a reference to the builtin open()
# function to be able to open or reopen the file during Python
@@ -6480,8 +6386,7 @@ class RotatingFileHandlerTest(BaseFileTest):
rh.close()
class TimedRotatingFileHandlerTest(BaseFileTest):
# TODO: RUSTPYTHON
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
@unittest.skipIf(support.is_wasi, "WASI does not have /dev/null.")
def test_should_not_rollover(self):
# See bpo-45401. Should only ever rollover regular files
@@ -6535,8 +6440,7 @@ class TimedRotatingFileHandlerTest(BaseFileTest):
print(tf.read())
self.assertTrue(found, msg=msg)
# TODO: RUSTPYTHON
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
def test_rollover_at_midnight(self, weekly=False):
os_helper.unlink(self.fn)
now = datetime.datetime.now()
@@ -6580,8 +6484,7 @@ class TimedRotatingFileHandlerTest(BaseFileTest):
for i, line in enumerate(f):
self.assertIn(f'testing1 {i}', line)
# TODO: RUSTPYTHON
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON')
def test_rollover_at_weekday(self):
self.test_rollover_at_midnight(weekly=True)
+32 -32
View File
@@ -187,7 +187,7 @@ class FileTests(unittest.TestCase):
os.close(f)
self.assertTrue(os.access(os_helper.TESTFN, os.W_OK))
@unittest.skipIf(sys.platform == 'win32', "TODO: RUSTPYTHON; , BrokenPipeError: (32, 'The process cannot access the file because it is being used by another process. (os error 32)')")
@unittest.skipIf(sys.platform == 'win32', "TODO: RUSTPYTHON; BrokenPipeError: (32, 'The process cannot access the file because it is being used by another process. (os error 32)')")
@unittest.skipIf(
support.is_emscripten, "Test is unstable under Emscripten."
)
@@ -714,7 +714,7 @@ class StatAttributeTests(unittest.TestCase):
self.assertTrue(isinstance(result.st_file_attributes, int))
self.assertTrue(0 <= result.st_file_attributes <= 0xFFFFFFFF)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.stat return value doesnt have st_file_attributes attribute")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.stat return value doesnt have st_file_attributes attribute')
@unittest.skipUnless(sys.platform == "win32",
"st_file_attributes is Win32 specific")
def test_file_attributes(self):
@@ -736,7 +736,7 @@ class StatAttributeTests(unittest.TestCase):
result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
stat.FILE_ATTRIBUTE_DIRECTORY)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.stat (PermissionError: [Errno 5] Access is denied.)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.stat (PermissionError: [Errno 5] Access is denied.)')
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
def test_access_denied(self):
# Default to FindFirstFile WIN32_FIND_DATA when access is
@@ -759,7 +759,7 @@ class StatAttributeTests(unittest.TestCase):
self.assertNotEqual(result.st_size, 0)
self.assertTrue(os.path.isfile(fname))
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.stat (PermissionError: [Errno 1] Incorrect function.)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.stat (PermissionError: [Errno 1] Incorrect function.)')
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
def test_stat_block_device(self):
# bpo-38030: os.stat fails for block devices
@@ -817,7 +817,7 @@ class UtimeTests(unittest.TestCase):
self.assertEqual(st.st_atime_ns, atime_ns)
self.assertEqual(st.st_mtime_ns, mtime_ns)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (AssertionError: 2.002003 != 1.002003 within 1e-06 delta (1.0000000000000002 difference))")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (AssertionError: 2.002003 != 1.002003 within 1e-06 delta (1.0000000000000002 difference))')
def test_utime(self):
def set_time(filename, ns):
# test the ns keyword parameter
@@ -883,7 +883,7 @@ class UtimeTests(unittest.TestCase):
os.utime(name, dir_fd=dirfd, ns=ns)
self._test_utime(set_time)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (AssertionError: 2.002003 != 1.002003 within 1e-06 delta (1.0000000000000002 difference))")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (AssertionError: 2.002003 != 1.002003 within 1e-06 delta (1.0000000000000002 difference))')
def test_utime_directory(self):
def set_time(filename, ns):
# test calling os.utime() on a directory
@@ -912,14 +912,14 @@ class UtimeTests(unittest.TestCase):
self.assertAlmostEqual(st.st_mtime, current,
delta=delta, msg=msg)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (AssertionError: 3359485824.516508 != 1679742912.516503 within 0.05 delta (1679742912.000005 difference) : st_time=3359485824.516508, current=1679742912.516503, dt=1679742912.000005)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (AssertionError: 3359485824.516508 != 1679742912.516503 within 0.05 delta (1679742912.000005 difference) : st_time=3359485824.516508, current=1679742912.516503, dt=1679742912.000005)')
def test_utime_current(self):
def set_time(filename):
# Set to the current time in the new way
os.utime(self.fname)
self._test_utime_current(set_time)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (AssertionError: 3359485824.5186944 != 1679742912.5186892 within 0.05 delta (1679742912.0000052 difference) : st_time=3359485824.5186944, current=1679742912.5186892, dt=1679742912.0000052)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (AssertionError: 3359485824.5186944 != 1679742912.5186892 within 0.05 delta (1679742912.0000052 difference) : st_time=3359485824.5186944, current=1679742912.5186892, dt=1679742912.0000052)')
def test_utime_current_old(self):
def set_time(filename):
# Set to the current time in the old explicit way.
@@ -958,7 +958,7 @@ class UtimeTests(unittest.TestCase):
os.utime(self.fname, (large, large))
self.assertEqual(os.stat(self.fname).st_mtime, large)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (AssertionError: NotImplementedError not raised)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (AssertionError: NotImplementedError not raised)')
def test_utime_invalid_arguments(self):
# seconds and nanoseconds parameters are mutually exclusive
with self.assertRaises(ValueError):
@@ -1161,7 +1161,7 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol):
self.assertEqual(proc.stdout.rstrip(), repr(None))
# On OS X < 10.6, unsetenv() doesn't return a value (bpo-13415).
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (AssertionError: ValueError not raised by putenv)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (AssertionError: ValueError not raised by putenv)')
@support.requires_mac_ver(10, 6)
def test_putenv_unsetenv_error(self):
# Empty variable name is invalid.
@@ -1796,7 +1796,7 @@ class MakedirTests(unittest.TestCase):
self.assertEqual(os.stat(path).st_mode & 0o777, 0o555)
self.assertEqual(os.stat(parent).st_mode & 0o777, 0o775)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.umask not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.umask not implemented yet for all platforms')
@unittest.skipIf(
support.is_emscripten or support.is_wasi,
"Emscripten's/WASI's umask is a stub."
@@ -1815,7 +1815,7 @@ class MakedirTests(unittest.TestCase):
# Issue #25583: A drive root could raise PermissionError on Windows
os.makedirs(os.path.abspath('/'), exist_ok=True)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.umask not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.umask not implemented yet for all platforms')
@unittest.skipIf(
support.is_emscripten or support.is_wasi,
"Emscripten's/WASI's umask is a stub."
@@ -2205,7 +2205,7 @@ class ExecTests(unittest.TestCase):
self.assertRaises(ValueError, os.execv, 'notepad', ('',))
self.assertRaises(ValueError, os.execv, 'notepad', [''])
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.execve not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.execve not implemented yet for all platforms')
def test_execvpe_with_bad_arglist(self):
self.assertRaises(ValueError, os.execvpe, 'notepad', [], None)
self.assertRaises(ValueError, os.execvpe, 'notepad', [], {})
@@ -2265,7 +2265,7 @@ class ExecTests(unittest.TestCase):
if os.name != "nt":
self._test_internal_execvpe(bytes)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.execve not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.execve not implemented yet for all platforms')
def test_execve_invalid_env(self):
args = [sys.executable, '-c', 'pass']
@@ -2287,7 +2287,7 @@ class ExecTests(unittest.TestCase):
with self.assertRaises(ValueError):
os.execve(args[0], args, newenv)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.execve not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.execve not implemented yet for all platforms')
@unittest.skipUnless(sys.platform == "win32", "Win32-specific test")
def test_execve_with_empty_path(self):
# bpo-32890: Check GetLastError() misuse
@@ -2445,12 +2445,12 @@ class TestInvalidFD(unittest.TestCase):
self.check(os.ftruncate, 0)
self.check_bool(os.truncate, 0)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)')
@unittest.skipUnless(hasattr(os, 'lseek'), 'test needs os.lseek()')
def test_lseek(self):
self.check(os.lseek, 0, 0)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)')
@unittest.skipUnless(hasattr(os, 'read'), 'test needs os.read()')
def test_read(self):
self.check(os.read, 1)
@@ -2464,7 +2464,7 @@ class TestInvalidFD(unittest.TestCase):
def test_tcsetpgrpt(self):
self.check(os.tcsetpgrp, 0)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OSError: [Errno 18] There are no more files.)')
@unittest.skipUnless(hasattr(os, 'write'), 'test needs os.write()')
def test_write(self):
self.check(os.write, b" ")
@@ -2473,7 +2473,7 @@ class TestInvalidFD(unittest.TestCase):
def test_writev(self):
self.check(os.writev, [b'abc'])
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
@support.requires_subprocess()
def test_inheritable(self):
self.check(os.get_inheritable)
@@ -3225,7 +3225,7 @@ class Win32NtTests(unittest.TestCase):
self.assertEqual(0, handle_delta)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.stat (PermissionError: [Errno 5] Access is denied.)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.stat (PermissionError: [Errno 5] Access is denied.)')
@support.requires_subprocess()
def test_stat_unlink_race(self):
# bpo-46785: the implementation of os.stat() falls back to reading
@@ -3435,7 +3435,7 @@ class PidTests(unittest.TestCase):
with self.assertRaises(TypeError):
os.waitstatus_to_exitcode(0.0)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.spawnv not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.spawnv not implemented yet for all platforms')
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
def test_waitpid_windows(self):
# bpo-40138: test os.waitpid() and os.waitstatus_to_exitcode()
@@ -3444,7 +3444,7 @@ class PidTests(unittest.TestCase):
code = f'import _winapi; _winapi.ExitProcess({STATUS_CONTROL_C_EXIT})'
self.check_waitpid(code, exitcode=STATUS_CONTROL_C_EXIT)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (OverflowError: Python int too large to convert to Rust i32)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (OverflowError: Python int too large to convert to Rust i32)')
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
def test_waitstatus_to_exitcode_windows(self):
max_exitcode = 2 ** 32 - 1
@@ -4621,7 +4621,7 @@ class CPUCountTests(unittest.TestCase):
# FD inheritance check is only useful for systems with process support.
@support.requires_subprocess()
class FDInheritanceTests(unittest.TestCase):
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
def test_get_set_inheritable(self):
fd = os.open(__file__, os.O_RDONLY)
self.addCleanup(os.close, fd)
@@ -4666,7 +4666,7 @@ class FDInheritanceTests(unittest.TestCase):
os.set_inheritable(fd, False)
self.assertEqual(os.get_inheritable(fd), False)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
def test_get_set_inheritable_badf(self):
fd = os_helper.make_bad_fd()
@@ -4682,7 +4682,7 @@ class FDInheritanceTests(unittest.TestCase):
os.set_inheritable(fd, False)
self.assertEqual(ctx.exception.errno, errno.EBADF)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.get_inheritable not implemented yet for all platforms')
def test_open(self):
fd = os.open(__file__, os.O_RDONLY)
self.addCleanup(os.close, fd)
@@ -4696,7 +4696,7 @@ class FDInheritanceTests(unittest.TestCase):
self.assertEqual(os.get_inheritable(rfd), False)
self.assertEqual(os.get_inheritable(wfd), False)
@unittest.skipIf(sys.platform == 'win32', "TODO: RUSTPYTHON; os.dup on windows")
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON; os.dup on windows')
def test_dup(self):
fd1 = os.open(__file__, os.O_RDONLY)
self.addCleanup(os.close, fd1)
@@ -4705,13 +4705,13 @@ class FDInheritanceTests(unittest.TestCase):
self.addCleanup(os.close, fd2)
self.assertEqual(os.get_inheritable(fd2), False)
@unittest.skipIf(sys.platform == 'win32', "TODO: RUSTPYTHON; os.dup on windows")
@unittest.skipIf(sys.platform == 'win32', 'TODO: RUSTPYTHON; os.dup on windows')
def test_dup_standard_stream(self):
fd = os.dup(1)
self.addCleanup(os.close, fd)
self.assertGreater(fd, 0)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; os.dup not implemented yet for all platforms")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; os.dup not implemented yet for all platforms')
@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')
def test_dup_nul(self):
# os.dup() was creating inheritable fds for character files.
@@ -5028,7 +5028,7 @@ class TestScandir(unittest.TestCase):
entry_lstat,
os.name == 'nt')
@unittest.skipIf(sys.platform == 'linux', "TODO: RUSTPYTHON; , flaky test")
@unittest.skipIf(sys.platform == 'linux', 'TODO: RUSTPYTHON; flaky test')
def test_attributes(self):
link = os_helper.can_hardlink()
symlink = os_helper.can_symlink()
@@ -5128,7 +5128,7 @@ class TestScandir(unittest.TestCase):
self.assertEqual(fspath,
os.path.join(os.fsencode(self.path),bytes_filename))
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; entry.is_dir() is False")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; entry.is_dir() is False')
def test_removed_dir(self):
path = os.path.join(self.path, 'dir')
@@ -5151,7 +5151,7 @@ class TestScandir(unittest.TestCase):
self.assertRaises(FileNotFoundError, entry.stat)
self.assertRaises(FileNotFoundError, entry.stat, follow_symlinks=False)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; entry.is_file() is False")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; entry.is_file() is False')
def test_removed_file(self):
entry = self.create_file_entry()
os.unlink(entry.path)
@@ -5239,7 +5239,7 @@ class TestScandir(unittest.TestCase):
st = os.stat(entry.name, dir_fd=fd, follow_symlinks=False)
self.assertEqual(entry.stat(follow_symlinks=False), st)
@unittest.expectedFailureIfWindows("TODO: RUSTPYTHON; (AssertionError: FileNotFoundError not raised by scandir)")
@unittest.expectedFailureIfWindows('TODO: RUSTPYTHON; (AssertionError: FileNotFoundError not raised by scandir)')
@unittest.skipIf(support.is_wasi, "WASI maps '' to cwd")
def test_empty_path(self):
self.assertRaises(FileNotFoundError, os.scandir, '')
+25 -42
View File
@@ -112,8 +112,7 @@ class StrTest(string_tests.StringLikeTest,
# raw strings should not have unicode escapes
self.assertNotEqual(r"\u0020", " ")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_ascii(self):
self.assertEqual(ascii('abc'), "'abc'")
self.assertEqual(ascii('ab\\c'), "'ab\\\\c'")
@@ -566,7 +565,7 @@ class StrTest(string_tests.StringLikeTest,
self.checkraises(TypeError, ' ', 'join', [1, 2, 3])
self.checkraises(TypeError, ' ', 'join', ['1', '2', 3])
@unittest.skip("TODO: RUSTPYTHON, oom handling")
@unittest.skip('TODO: RUSTPYTHON; oom handling')
@unittest.skipIf(sys.maxsize > 2**32,
'needs too much memory on a 64-bit platform')
def test_join_overflow(self):
@@ -795,8 +794,7 @@ class StrTest(string_tests.StringLikeTest,
for ch in ['\U0001D7F6', '\U00011066', '\U000104A0']:
self.assertTrue(ch.isdecimal(), '{!a} is decimal.'.format(ch))
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_isdigit(self):
super().test_isdigit()
self.checkequalnofix(True, '\u2460', 'isdigit')
@@ -942,8 +940,7 @@ class StrTest(string_tests.StringLikeTest,
self.assertEqual('\U0008fffe'.upper(), '\U0008fffe')
self.assertEqual('\u2177'.upper(), '\u2167')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_capitalize(self):
string_tests.StringLikeTest.test_capitalize(self)
self.assertEqual('\U0001044F'.capitalize(), '\U00010427')
@@ -961,8 +958,7 @@ class StrTest(string_tests.StringLikeTest,
self.assertEqual('finnish'.capitalize(), 'Finnish')
self.assertEqual('A\u0345\u03a3'.capitalize(), 'A\u0345\u03c2')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_title(self):
super().test_title()
self.assertEqual('\U0001044F'.title(), '\U00010427')
@@ -980,8 +976,7 @@ class StrTest(string_tests.StringLikeTest,
self.assertEqual('A\u03a3 \u1fa1xy'.title(), 'A\u03c2 \u1fa9xy')
self.assertEqual('A\u03a3A'.title(), 'A\u03c3a')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_swapcase(self):
string_tests.StringLikeTest.test_swapcase(self)
self.assertEqual('\U0001044F'.swapcase(), '\U00010427')
@@ -1081,8 +1076,7 @@ class StrTest(string_tests.StringLikeTest,
'\U00100000'.ljust(3, '\U00010000')
'\U00100000'.rjust(3, '\U00010000')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_format(self):
self.assertEqual(''.format(), '')
self.assertEqual('a'.format(), 'a')
@@ -1244,10 +1238,10 @@ class StrTest(string_tests.StringLikeTest,
self.assertEqual('{0:\x00^6}'.format(3), '\x00\x003\x00\x00\x00')
self.assertEqual('{0:<6}'.format(3), '3 ')
self.assertEqual('{0:\x00<6}'.format(3.14), '3.14\x00\x00')
self.assertEqual('{0:\x01<6}'.format(3.14), '3.14\x01\x01')
self.assertEqual('{0:\x00^6}'.format(3.14), '\x003.14\x00')
self.assertEqual('{0:^6}'.format(3.14), ' 3.14 ')
self.assertEqual('{0:\x00<6}'.format(3.25), '3.25\x00\x00')
self.assertEqual('{0:\x01<6}'.format(3.25), '3.25\x01\x01')
self.assertEqual('{0:\x00^6}'.format(3.25), '\x003.25\x00')
self.assertEqual('{0:^6}'.format(3.25), ' 3.25 ')
self.assertEqual('{0:\x00<12}'.format(3+2.0j), '(3+2j)\x00\x00\x00\x00\x00\x00')
self.assertEqual('{0:\x01<12}'.format(3+2.0j), '(3+2j)\x01\x01\x01\x01\x01\x01')
@@ -1466,21 +1460,19 @@ class StrTest(string_tests.StringLikeTest,
self.assertRaises(TypeError, '{a}'.format_map, [])
self.assertRaises(ZeroDivisionError, '{a}'.format_map, BadMapping())
@unittest.skip("TODO: RUSTPYTHON, killed for chewing up RAM")
@unittest.skip('TODO: RUSTPYTHON; killed for chewing up RAM')
def test_format_huge_precision(self):
format_string = ".{}f".format(sys.maxsize + 1)
with self.assertRaises(ValueError):
result = format(2.34, format_string)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_format_huge_width(self):
format_string = "{}f".format(sys.maxsize + 1)
with self.assertRaises(ValueError):
result = format(2.34, format_string)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_format_huge_item_number(self):
format_string = "{{{}:.6f}}".format(sys.maxsize + 1)
with self.assertRaises(ValueError):
@@ -1516,8 +1508,7 @@ class StrTest(string_tests.StringLikeTest,
self.assertEqual('{:{f}}{g}{}'.format(1, 3, g='g', f=2), ' 1g3')
self.assertEqual('{f:{}}{}{g}'.format(2, 4, f=1, g='g'), ' 14g')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_formatting(self):
string_tests.StringLikeTest.test_formatting(self)
# Testing Unicode formatting strings...
@@ -1766,8 +1757,7 @@ class StrTest(string_tests.StringLikeTest,
'character buffers are decoded to unicode'
)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_constructor_keyword_args(self):
"""Pass various keyword argument combinations to the constructor."""
# The object argument can be passed as a keyword.
@@ -1777,8 +1767,7 @@ class StrTest(string_tests.StringLikeTest,
self.assertEqual(str(b'foo', errors='strict'), 'foo') # not "b'foo'"
self.assertEqual(str(object=b'foo', errors='strict'), 'foo')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_constructor_defaults(self):
"""Check the constructor argument defaults."""
# The object argument defaults to '' or b''.
@@ -1790,8 +1779,7 @@ class StrTest(string_tests.StringLikeTest,
# The errors argument defaults to strict.
self.assertRaises(UnicodeDecodeError, str, utf8_cent, encoding='ascii')
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_codecs_utf7(self):
utfTests = [
('A\u2262\u0391.', b'A+ImIDkQ.'), # RFC2152 example
@@ -2301,8 +2289,7 @@ class StrTest(string_tests.StringLikeTest,
self.assertRaises(ValueError, complex, "\ud800")
self.assertRaises(ValueError, complex, "\udf00")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_codecs(self):
# Encoding
self.assertEqual('hello'.encode('ascii'), b'hello')
@@ -2432,8 +2419,7 @@ class StrTest(string_tests.StringLikeTest,
else:
self.fail("Should have raised UnicodeDecodeError")
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_conversion(self):
# Make sure __str__() works properly
class StrWithStr(str):
@@ -2482,7 +2468,7 @@ class StrTest(string_tests.StringLikeTest,
# This test only affects 32-bit platforms because expandtabs can only take
# an int as the max value, not a 64-bit C long. If expandtabs is changed
# to take a 64-bit long, this test should apply to all platforms.
@unittest.skip("TODO: RUSTPYTHON, oom handling")
@unittest.skip('TODO: RUSTPYTHON; oom handling')
@unittest.skipIf(sys.maxsize > (1 << 32) or struct.calcsize('P') != 4,
'only applies to 32-bit platforms')
def test_expandtabs_overflows_gracefully(self):
@@ -2493,7 +2479,7 @@ class StrTest(string_tests.StringLikeTest,
s = 'abc'
self.assertIs(s.expandtabs(), s)
@unittest.skip("TODO: RUSTPYTHON, aborted: memory allocation of 9223372036854775759 bytes failed")
@unittest.skip('TODO: RUSTPYTHON; aborted: memory allocation of 9223372036854775759 bytes failed')
def test_raiseMemError(self):
asciifields = "nnb"
compactfields = asciifields + "nP"
@@ -2633,14 +2619,12 @@ class StrTest(string_tests.StringLikeTest,
self.assertTrue(astral >= bmp2)
self.assertFalse(astral >= astral2)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_free_after_iterating(self):
support.check_free_after_iterating(self, iter, str)
support.check_free_after_iterating(self, reversed, str)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_check_encoding_errors(self):
# bpo-37388: str(bytes) and str.decode() must check encoding and errors
# arguments in dev mode
@@ -2701,8 +2685,7 @@ class StrTest(string_tests.StringLikeTest,
proc = assert_python_failure('-X', 'dev', '-c', code)
self.assertEqual(proc.rc, 10, proc)
# TODO: RUSTPYTHON
@unittest.expectedFailure
@unittest.expectedFailure # TODO: RUSTPYTHON
def test_str_invalid_call(self):
# too many args
with self.assertRaisesRegex(TypeError, r"str expected at most 3 arguments, got 4"):
+130 -260
View File
File diff suppressed because it is too large. Load diff
+78 -59
View File
@@ -32,6 +32,7 @@ import json
import pathlib
import re
import sys
import textwrap
import typing
if typing.TYPE_CHECKING:
@@ -39,10 +40,9 @@ if typing.TYPE_CHECKING:
type Patches = dict[str, dict[str, list["PatchSpec"]]]
COL_OFFSET = 4
INDENT1 = " " * COL_OFFSET
INDENT2 = INDENT1 * 2
DEFAULT_INDENT = " " * 4
COMMENT = "TODO: RUSTPYTHON"
UT = "unittest"
@enum.unique
@@ -54,6 +54,9 @@ class UtMethod(enum.StrEnum):
def _generate_next_value_(name, start, count, last_values) -> str:
return name[0].lower() + name[1:]
def has_args(self) -> bool:
return self != self.ExpectedFailure
def has_cond(self) -> bool:
return self.endswith(("If", "Unless"))
@@ -81,17 +84,32 @@ class PatchSpec(typing.NamedTuple):
cond: str | None = None
reason: str = ""
def fmt(self) -> str:
prefix = f"@unittest.{self.ut_method}"
match self.ut_method:
case UtMethod.ExpectedFailure:
line = f"{prefix} # {COMMENT}; {self.reason}"
case UtMethod.ExpectedFailureIfWindows | UtMethod.Skip:
line = f'{prefix}("{COMMENT}; {self.reason}")'
case UtMethod.SkipIf | UtMethod.SkipUnless | UtMethod.ExpectedFailureIf:
line = f'{prefix}({self.cond}, "{COMMENT}; {self.reason}")'
@property
def _reason(self) -> str:
return f"{COMMENT}; {self.reason}".strip(" ;")
return line.strip().rstrip(";").strip()
@property
def _attr_node(self) -> ast.Attribute:
return ast.Attribute(value=ast.Name(id=UT), attr=self.ut_method)
def as_ast_node(self) -> ast.Attribute | ast.Call:
if not self.ut_method.has_args():
return self._attr_node
args = []
if self.cond:
args.append(ast.parse(self.cond).body[0].value)
args.append(ast.Constant(value=self._reason))
return ast.Call(func=self._attr_node, args=args, keywords=[])
def as_decorator(self) -> str:
unparsed = ast.unparse(self.as_ast_node())
if not self.ut_method.has_args():
unparsed = f"{unparsed} # {self._reason}"
return f"@{unparsed}"
class PatchEntry(typing.NamedTuple):
@@ -128,7 +146,7 @@ class PatchEntry(typing.NamedTuple):
if (
isinstance(attr_node, ast.Name)
or getattr(attr_node.value, "id", None) != "unittest"
or getattr(attr_node.value, "id", None) != UT
):
continue
@@ -138,41 +156,39 @@ class PatchEntry(typing.NamedTuple):
except ValueError:
continue
match ut_method:
case UtMethod.ExpectedFailure:
# Search first on decorator line, then in the line before
for line in lines[
dec_node.lineno - 1 : dec_node.lineno - 3 : -1
]:
if COMMENT not in line:
continue
reason = "".join(re.findall(rf"{COMMENT}.?(.*)", line))
# If our ut_method has args then,
# we need to search for a constant that contains our `COMMENT`.
# Otherwise we need to search it in the raw source code :/
if ut_method.has_args():
reason = next(
(
node.value
for node in ast.walk(dec_node)
if isinstance(node, ast.Constant)
and isinstance(node.value, str)
and COMMENT in node.value
),
None,
)
# If we didn't find a constant containing <COMMENT>,
# then we didn't put this decorator
if not reason:
continue
if ut_method.has_cond():
cond = ast.unparse(dec_node.args[0])
else:
# Search first on decorator line, then in the line before
for line in lines[dec_node.lineno - 1 : dec_node.lineno - 3 : -1]:
if found := re.search(rf"{COMMENT}.?(.*)", line):
reason = found.group()
break
else:
continue
case _:
reason = next(
(
node.value
for node in ast.walk(dec_node)
if isinstance(node, ast.Constant)
and isinstance(node.value, str)
and COMMENT in node.value
),
None,
)
else:
# Didn't find our `COMMENT` :)
continue
# If we didn't find a constant containing <COMMENT>,
# then we didn't put this decorator
if not reason:
continue
if ut_method.has_cond():
cond = ast.unparse(dec_node.args[0])
reason = (
reason.replace(COMMENT, "").strip().lstrip(";").lstrip(":").strip()
)
reason = reason.removeprefix(COMMENT).strip(";:, ")
spec = PatchSpec(ut_method, cond, reason)
yield cls(parent_class, fn_node.name, spec)
@@ -210,7 +226,7 @@ def build_patch_dict(it: "Iterator[PatchEntry]") -> Patches:
def iter_patch_lines(tree: ast.Module, patches: Patches) -> "Iterator[tuple[int, str]]":
cache = {} # Used in phase 2
cache = {} # Used in phase 2. Stores the end line location of a class name.
# Phase 1: Iterate and mark existing tests
for cls_node, fn_node in iter_tests(tree):
@@ -224,7 +240,8 @@ def iter_patch_lines(tree: ast.Module, patches: Patches) -> "Iterator[tuple[int,
default=fn_node.lineno,
)
indent = " " * fn_node.col_offset
yield (lineno - 1, "\n".join(f"{indent}{spec.fmt()}" for spec in specs))
patch_lines = "\n".join(spec.as_decorator() for spec in specs)
yield (lineno - 1, textwrap.indent(patch_lines, indent))
# Phase 2: Iterate and mark inhereted tests
for cls_name, tests in patches.items():
@@ -232,16 +249,15 @@ def iter_patch_lines(tree: ast.Module, patches: Patches) -> "Iterator[tuple[int,
if not lineno:
print(f"WARNING: {cls_name} does not exist in remote file", file=sys.stderr)
continue
for test_name, specs in tests.items():
patch_lines = "\n".join(f"{INDENT1}{spec.fmt()}" for spec in specs)
yield (
lineno,
f"""
{patch_lines}
{INDENT1}def {test_name}(self):
{INDENT2}return super().{test_name}()
""".rstrip(),
)
decorators = "\n".join(spec.as_decorator() for spec in specs)
patch_lines = f"""
{decorators}
def {test_name}(self):
{DEFAULT_INDENT}return super().{test_name}()
""".rstrip()
yield (lineno, textwrap.indent(patch_lines, DEFAULT_INDENT))
def apply_patches(contents: str, patches: Patches) -> str:
@@ -309,7 +325,10 @@ if __name__ == "__main__":
if args.patches:
patches = {
cls_name: {
test_name: [PatchSpec(**spec) for spec in specs]
test_name: [
PatchSpec(**spec)._replace(ut_method=UtMethod(spec["ut_method"]))
for spec in specs
]
for test_name, specs in tests.items()
}
for cls_name, tests in json.loads(args.patches.read_text()).items()