Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ rm -r target/debug/build/rustpython-* && find . | grep -E "\.pyc$" | xargs rm -r

```bash
# Run Rust unit tests
cargo test --workspace --exclude rustpython_wasm
cargo test --workspace --exclude rustpython_wasm --exclude rustpython-venvlauncher

# Run Python snippets tests (debug mode recommended for faster compilation)
cargo run -- extra_tests/snippets/builtin_bytes.py
Expand Down
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ $ pytest -v
Rust unit tests can be run with `cargo`:

```shell
$ cargo test --workspace --exclude rustpython_wasm
$ cargo test --workspace --exclude rustpython_wasm --exclude rustpython-venvlauncher
```
Comment on lines 67 to 69
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove the shell prompt to satisfy markdownlint MD014.

The $ prompt in a fenced block without output triggers MD014. Consider removing it.

Suggested edit
-$ cargo test --workspace --exclude rustpython_wasm --exclude rustpython-venvlauncher
+cargo test --workspace --exclude rustpython_wasm --exclude rustpython-venvlauncher
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 68-68: Dollar signs used before commands without showing output

(MD014, commands-show-output)

🤖 Prompt for AI Agents
In `@DEVELOPMENT.md` around lines 67 - 69, The fenced code block contains a shell
prompt character ("$ ") before the command string "cargo test --workspace
--exclude rustpython_wasm --exclude rustpython-venvlauncher" which triggers
markdownlint MD014; edit the fenced block to remove the leading "$ " so it
contains just the plain command line (i.e., "cargo test --workspace --exclude
rustpython_wasm --exclude rustpython-venvlauncher") to satisfy the lint rule.


Python unit tests can be run by compiling RustPython and running the test module:
Expand Down
63 changes: 28 additions & 35 deletions Lib/test/test_ast/test_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def test_AST_objects(self):
# "ast.AST constructor takes 0 positional arguments"
ast.AST(2)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: "type object 'ast.AST' has no attribute '_fields'" does not match "'AST' object has no attribute '_fields'"
def test_AST_fields_NULL_check(self):
# See: https://github.com/python/cpython/issues/126105
old_value = ast.AST._fields
Expand All @@ -115,7 +115,7 @@ def cleanup():
with self.assertRaisesRegex(AttributeError, msg):
ast.AST()

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: <test.test_ast.test_ast.AST_Tests.test_AST_garbage_collection.<locals>.X object at 0x7e85c3a80> is not None
def test_AST_garbage_collection(self):
class X:
pass
Expand All @@ -140,7 +140,7 @@ def test_snippets(self):
with self.subTest(action="compiling", input=i, kind=kind):
compile(ast_tree, "?", kind)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: expected some sort of expr, but got <_ast.TemplateStr object at 0x7e85c34e0>
def test_ast_validation(self):
# compile() is the only function that calls PyAST_Validate
snippets_to_validate = exec_tests + single_tests + eval_tests
Expand Down Expand Up @@ -439,7 +439,7 @@ def _construct_ast_class(self, cls):
kwargs[name] = self._construct_ast_class(typ)
return cls(**kwargs)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: type object 'arguments' has no attribute '__annotations__'
def test_arguments(self):
x = ast.arguments()
self.assertEqual(x._fields, ('posonlyargs', 'args', 'vararg', 'kwonlyargs',
Expand Down Expand Up @@ -590,15 +590,15 @@ def test_no_fields(self):
x = ast.Sub()
self.assertEqual(x._fields, ())

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: 'but got expr()' not found in 'expected some sort of expr, but got <_ast.expr object at 0x7e911a9a0>'
def test_invalid_sum(self):
pos = dict(lineno=2, col_offset=3)
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
with self.assertRaises(TypeError) as cm:
compile(m, "<test>", "exec")
self.assertIn("but got expr()", str(cm.exception))

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: expected str for name
def test_invalid_identifier(self):
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
ast.fix_missing_locations(m)
Expand All @@ -615,7 +615,7 @@ def test_invalid_constant(self):
):
compile(e, "<test>", "eval")

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: expected some sort of expr, but got None
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()")
Expand Down Expand Up @@ -670,7 +670,7 @@ def test_issue39579_dotted_name_end_col_offset(self):
attr_b = tree.body[0].decorator_list[0].value
self.assertEqual(attr_b.end_col_offset, 4)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: None != 'withitem(expr context_expr, expr? optional_vars)'
def test_ast_asdl_signature(self):
self.assertEqual(ast.withitem.__doc__, "withitem(expr context_expr, expr? optional_vars)")
self.assertEqual(ast.GtE.__doc__, "GtE")
Expand Down Expand Up @@ -776,7 +776,6 @@ def test_compare_fieldless(self):
del a2.id
self.assertTrue(ast.compare(a1, a2))

@unittest.expectedFailure # TODO: RUSTPYTHON; AttributeError: type object '_ast.Module' has no attribute '_field_types'
def test_compare_modes(self):
for mode, sources in (
("exec", exec_tests),
Expand Down Expand Up @@ -1100,10 +1099,6 @@ def test_tstring(self):
self.assertIsInstance(tree.body[0].value.values[0], ast.Constant)
self.assertIsInstance(tree.body[0].value.values[1], ast.Interpolation)

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_classattrs_deprecated(self):
return super().test_classattrs_deprecated()

@unittest.expectedFailure # TODO: RUSTPYTHON; ValueError: compile() unrecognized flags
def test_optimization_levels_const_folding(self):
return super().test_optimization_levels_const_folding()
Expand Down Expand Up @@ -1472,7 +1467,6 @@ def test_replace_reject_unknown_instance_fields(self):
class ASTHelpers_Test(unittest.TestCase):
maxDiff = None

@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)
Expand All @@ -1486,7 +1480,7 @@ def test_parse_in_error(self):
ast.literal_eval(r"'\U'")
self.assertIsNotNone(e.exception.__context__)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; + Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')]))])
def test_dump(self):
node = ast.parse('spam(eggs, "and cheese")')
self.assertEqual(ast.dump(node),
Expand All @@ -1507,7 +1501,7 @@ def test_dump(self):
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)])"
)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; - type_ignores=[])
def test_dump_indent(self):
node = ast.parse('spam(eggs, "and cheese")')
self.assertEqual(ast.dump(node, indent=3), """\
Expand Down Expand Up @@ -1563,7 +1557,7 @@ def test_dump_indent(self):
end_lineno=1,
end_col_offset=24)])""")

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; + Raise()
def test_dump_incomplete(self):
node = ast.Raise(lineno=3, col_offset=4)
self.assertEqual(ast.dump(node),
Expand Down Expand Up @@ -1731,7 +1725,7 @@ def check_text(code, empty, full, **kwargs):
full="Module(body=[Import(names=[alias(name='_ast', asname='ast')]), ImportFrom(module='module', names=[alias(name='sub')], level=0)], type_ignores=[])",
)

@unittest.expectedFailure # TODO: RUSTPYTHON
@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)
Expand All @@ -1749,7 +1743,7 @@ def test_copy_location(self):
self.assertEqual(new.lineno, 1)
self.assertEqual(new.col_offset, 1)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; + Module(body=[Expr(value=Call(func=Name(id='write', ctx=Load(), lineno=1, col_offset=0, end_lineno=1, end_col_offset=5), args=[Constant(value='spam', lineno=1, col_offset=6, end_lineno=1, end_col_offset=12)], lineno=1, col_offset=0, end_lineno=1, end_col_offset=13), lineno=1, col_offset=0, end_lineno=1, end_col_offset=13), Expr(value=Call(func=Name(id='spam', ctx=Load(), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)])
def test_fix_missing_locations(self):
src = ast.parse('write("spam")')
src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()),
Expand All @@ -1769,7 +1763,7 @@ def test_fix_missing_locations(self):
"end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)])"
)

@unittest.expectedFailure # TODO: RUSTPYTHON
@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)
Expand Down Expand Up @@ -1813,7 +1807,7 @@ def test_iter_fields(self):
self.assertEqual(d.pop('func').id, 'foo')
self.assertEqual(d, {'keywords': [], 'args': []})

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; + keyword(arg='eggs', value=Constant(value='leek'))
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)
Expand Down Expand Up @@ -1966,7 +1960,7 @@ def test_literal_eval_malformed_dict_nodes(self):
malformed = ast.Dict(keys=[ast.Constant(1)], values=[ast.Constant(2), ast.Constant(3)])
self.assertRaises(ValueError, ast.literal_eval, malformed)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError: expected an expression
def test_literal_eval_trailing_ws(self):
self.assertEqual(ast.literal_eval(" -1"), -1)
self.assertEqual(ast.literal_eval("\t\t-1"), -1)
Expand All @@ -1985,15 +1979,15 @@ def test_literal_eval_malformed_lineno(self):
with self.assertRaisesRegex(ValueError, msg):
ast.literal_eval(node)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: "unexpected indent" does not match "expected an expression (<unknown>, line 2)"
def test_literal_eval_syntax_errors(self):
with self.assertRaisesRegex(SyntaxError, "unexpected indent"):
ast.literal_eval(r'''
\
(\
\ ''')

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: required field "lineno" missing from alias
def test_bad_integer(self):
# issue13436: Bad error message with invalid numeric values
body = [ast.ImportFrom(module='time',
Expand Down Expand Up @@ -2222,7 +2216,7 @@ def test_if(self):
[ast.Expr(ast.Name("x", ast.Store()))])
self.stmt(i, "must have Load context")

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError: empty items on With
def test_with(self):
p = ast.Pass()
self.stmt(ast.With([], [p]), "empty items on With")
Expand Down Expand Up @@ -2263,7 +2257,7 @@ def test_try(self):
t = ast.Try([p], e, [p], [ast.Expr(ast.Name("x", ast.Store()))])
self.stmt(t, "must have Load context")

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: ValueError not raised
def test_try_star(self):
p = ast.Pass()
t = ast.TryStar([], [], [], [p])
Expand Down Expand Up @@ -2296,7 +2290,7 @@ def test_assert(self):
def test_import(self):
self.stmt(ast.Import([]), "empty names on Import")

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; OverflowError: Python int too large to convert to Rust u32
def test_importfrom(self):
imp = ast.ImportFrom(None, [ast.alias("x", None)], -42)
self.stmt(imp, "Negative ImportFrom level")
Expand Down Expand Up @@ -2354,7 +2348,7 @@ def test_dict(self):
d = ast.Dict([ast.Name("x", ast.Load())], [None])
self.expr(d, "None disallowed")

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: expected some sort of expr, but got None
def test_set(self):
self.expr(ast.Set([None]), "None disallowed")
s = ast.Set([ast.Name("x", ast.Store())])
Expand Down Expand Up @@ -2412,7 +2406,7 @@ def factory(comps):
return ast.DictComp(k, v, comps)
self._check_comprehension(factory)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; SyntaxError: 'yield' outside function
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")
Expand Down Expand Up @@ -2478,11 +2472,11 @@ def _sequence(self, fac):
self.expr(fac([ast.Name("x", ast.Store())], ast.Load()),
"must have Load context")

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: expected some sort of expr, but got None
def test_list(self):
self._sequence(ast.List)

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; TypeError: expected some sort of expr, but got None
def test_tuple(self):
self._sequence(ast.Tuple)

Expand Down Expand Up @@ -3264,7 +3258,7 @@ def visit_Call(self, node: ast.Call):
class ASTConstructorTests(unittest.TestCase):
"""Test the autogenerated constructors for AST nodes."""

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: DeprecationWarning not triggered
def test_FunctionDef(self):
args = ast.arguments()
self.assertEqual(args.args, [])
Expand All @@ -3278,7 +3272,7 @@ def test_FunctionDef(self):
self.assertEqual(node.name, 'foo')
self.assertEqual(node.decorator_list, [])

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: None is not an instance of <class '_ast.Load'>
def test_expr_context(self):
name = ast.Name("x")
self.assertEqual(name.id, "x")
Expand Down Expand Up @@ -3382,7 +3376,7 @@ class BadFields(ast.AST):
with self.assertWarnsRegex(DeprecationWarning, r"Field b'\\xff\\xff.*' .*"):
obj = BadFields()

@unittest.expectedFailure # TODO: RUSTPYTHON
@unittest.expectedFailure # TODO: RUSTPYTHON; AssertionError: None != []
def test_complete_field_types(self):
class _AllFieldTypes(ast.AST):
_fields = ('a', 'b')
Expand Down Expand Up @@ -3508,7 +3502,6 @@ def check_output(self, source, expect, *flags):
expect = self.text_normalize(expect)
self.assertEqual(res, expect)

@unittest.expectedFailure # TODO: RUSTPYTHON
@support.requires_resource('cpu')
def test_invocation(self):
# test various combinations of parameters
Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_exception_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ def test_exception_group_types(self):
self.assertTrue(issubclass(ExceptionGroup, BaseExceptionGroup))
self.assertTrue(issubclass(BaseExceptionGroup, BaseException))

# TODO: RUSTPYTHON
@unittest.expectedFailure
def test_exception_is_not_generic_type(self):
with self.assertRaisesRegex(TypeError, 'Exception'):
Exception[OSError]
Expand Down
2 changes: 0 additions & 2 deletions Lib/test/test_genericalias.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ def test_subscriptable(self):
self.assertEqual(alias.__args__, (int,))
self.assertEqual(alias.__parameters__, ())

@unittest.expectedFailure # TODO: RUSTPYTHON; wrong error message
def test_unsubscriptable(self):
for t in int, str, float, Sized, Hashable:
tname = t.__name__
Expand Down Expand Up @@ -365,7 +364,6 @@ def test_type_generic(self):
self.assertEqual(t(test), Test)
self.assertEqual(t(0), int)

@unittest.expectedFailure # TODO: RUSTPYTHON; wrong error message
def test_type_subclass_generic(self):
class MyType(type):
pass
Expand Down
1 change: 0 additions & 1 deletion Lib/test/test_genericclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ def __class_getitem__(cls, one, two):
with self.assertRaises(TypeError):
C_too_many[int]

@unittest.expectedFailure # TODO: RUSTPYTHON
def test_class_getitem_errors_2(self):
class C:
def __class_getitem__(cls, item):
Expand Down
Loading
Loading