chore: rely on the default inclusions for ruff

This commit is contained in:
Rex Ledesma
2025-05-08 00:37:54 -04:00
committed by Jeong, YunWon
parent d11d5c65e6
commit b696e56c5f
7 changed files with 126 additions and 67 deletions

View File

@@ -1,4 +1,4 @@
""" This script can be used to test the equivalence in parsing between
"""This script can be used to test the equivalence in parsing between
rustpython and cpython.
Usage example:
@@ -8,76 +8,80 @@ $ cargo run crawl_sourcecode.py crawl_sourcecode.py > rustpython.txt
$ diff cpython.txt rustpython.txt
"""
import ast
import sys
import symtable
import dis
filename = sys.argv[1]
print('Crawling file:', filename)
print("Crawling file:", filename)
with open(filename, 'r') as f:
with open(filename, "r") as f:
source = f.read()
t = ast.parse(source)
print(t)
shift = 3
def print_node(node, indent=0):
indents = ' ' * indent
indents = " " * indent
if isinstance(node, ast.AST):
lineno = 'row={}'.format(node.lineno) if hasattr(node, 'lineno') else ''
lineno = "row={}".format(node.lineno) if hasattr(node, "lineno") else ""
print(indents, "NODE", node.__class__.__name__, lineno)
for field in node._fields:
print(indents,'-', field)
print(indents, "-", field)
f = getattr(node, field)
if isinstance(f, list):
for f2 in f:
print_node(f2, indent=indent+shift)
print_node(f2, indent=indent + shift)
else:
print_node(f, indent=indent+shift)
print_node(f, indent=indent + shift)
else:
print(indents, 'OBJ', node)
print(indents, "OBJ", node)
print_node(t)
# print(ast.dump(t))
flag_names = [
'is_referenced',
'is_assigned',
'is_global',
'is_local',
'is_parameter',
'is_free',
"is_referenced",
"is_assigned",
"is_global",
"is_local",
"is_parameter",
"is_free",
]
def print_table(table, indent=0):
indents = ' ' * indent
print(indents, 'table:', table.get_name())
print(indents, ' ', 'name:', table.get_name())
print(indents, ' ', 'type:', table.get_type())
print(indents, ' ', 'line:', table.get_lineno())
print(indents, ' ', 'identifiers:', table.get_identifiers())
print(indents, ' ', 'Syms:')
indents = " " * indent
print(indents, "table:", table.get_name())
print(indents, " ", "name:", table.get_name())
print(indents, " ", "type:", table.get_type())
print(indents, " ", "line:", table.get_lineno())
print(indents, " ", "identifiers:", table.get_identifiers())
print(indents, " ", "Syms:")
for sym in table.get_symbols():
flags = []
for flag_name in flag_names:
func = getattr(sym, flag_name)
if func():
flags.append(flag_name)
print(indents, ' sym:', sym.get_name(), 'flags:', ' '.join(flags))
print(indents, " sym:", sym.get_name(), "flags:", " ".join(flags))
if table.has_children():
print(indents, ' ', 'Child tables:')
print(indents, " ", "Child tables:")
for child in table.get_children():
print_table(child, indent=indent+shift)
print_table(child, indent=indent + shift)
table = symtable.symtable(source, 'a', 'exec')
table = symtable.symtable(source, "a", "exec")
print_table(table)
print()
print('======== dis.dis ========')
print("======== dis.dis ========")
print()
co = compile(source, filename, 'exec')
co = compile(source, filename, "exec")
dis.dis(co)

View File

@@ -1,13 +1,12 @@
def foo(x):
def bar(z):
return z + x
return bar
f = foo(9)
g = foo(10)
print(f(2))
print(g(2))

View File

@@ -1,11 +1,4 @@
include = [
"examples/**/*.py",
"extra_tests/**/*.py",
"wasm/**/*.py",
]
exclude = [
".*",
"Lib",
"vm/Lib",
"benches",

View File

@@ -3,18 +3,21 @@ import subprocess
TARGET = "extra_tests/snippets"
def run_llvm_cov(file_path: str):
""" Run cargo llvm-cov on a file. """
"""Run cargo llvm-cov on a file."""
if file_path.endswith(".py"):
command = ["cargo", "llvm-cov", "--no-report", "run", "--", file_path]
subprocess.call(command)
def iterate_files(folder: str):
""" Iterate over all files in a folder. """
"""Iterate over all files in a folder."""
for root, _, files in os.walk(folder):
for file in files:
file_path = os.path.join(root, file)
run_llvm_cov(file_path)
if __name__ == "__main__":
iterate_files(TARGET)
iterate_files(TARGET)

View File

@@ -10,21 +10,26 @@ How to use:
4. Ensure that there are no unexpected successes in the test.
5. Actually fix the test.
"""
import argparse
import ast
import itertools
import platform
from pathlib import Path
def parse_args():
parser = argparse.ArgumentParser(description="Fix test.")
parser.add_argument("--path", type=Path, help="Path to test file")
parser.add_argument("--force", action="store_true", help="Force modification")
parser.add_argument("--platform", action="store_true", help="Platform specific failure")
parser.add_argument(
"--platform", action="store_true", help="Platform specific failure"
)
args = parser.parse_args()
return args
class Test:
name: str = ""
path: str = ""
@@ -33,6 +38,7 @@ class Test:
def __str__(self):
return f"Test(name={self.name}, path={self.path}, result={self.result})"
class TestResult:
tests_result: str = ""
tests = []
@@ -52,7 +58,11 @@ def parse_results(result):
in_test_results = True
elif line.startswith("-----------"):
in_test_results = False
if in_test_results and not line.startswith("tests") and not line.startswith("["):
if (
in_test_results
and not line.startswith("tests")
and not line.startswith("[")
):
line = line.split(" ")
if line != [] and len(line) > 3:
test = Test()
@@ -67,9 +77,11 @@ def parse_results(result):
test_results.tests_result = res
return test_results
def path_to_test(path) -> list[str]:
return path.split(".")[2:]
def modify_test(file: str, test: list[str], for_platform: bool = False) -> str:
a = ast.parse(file)
lines = file.splitlines()
@@ -84,6 +96,7 @@ def modify_test(file: str, test: list[str], for_platform: bool = False) -> str:
break
return "\n".join(lines)
def modify_test_v2(file: str, test: list[str], for_platform: bool = False) -> str:
a = ast.parse(file)
lines = file.splitlines()
@@ -101,8 +114,13 @@ def modify_test_v2(file: str, test: list[str], for_platform: bool = False) -> st
if fn.name == test[-1]:
assert not for_platform
indent = " " * fn.col_offset
lines.insert(fn.lineno - 1, indent + fixture)
lines.insert(fn.lineno - 1, indent + "# TODO: RUSTPYTHON")
lines.insert(
fn.lineno - 1, indent + fixture
)
lines.insert(
fn.lineno - 1,
indent + "# TODO: RUSTPYTHON",
)
break
case ast.FunctionDef():
if n.name == test[0] and len(test) == 1:
@@ -115,11 +133,17 @@ def modify_test_v2(file: str, test: list[str], for_platform: bool = False) -> st
exit()
return "\n".join(lines)
def run_test(test_name):
print(f"Running test: {test_name}")
rustpython_location = "./target/release/rustpython"
import subprocess
result = subprocess.run([rustpython_location, "-m", "test", "-v", test_name], capture_output=True, text=True)
result = subprocess.run(
[rustpython_location, "-m", "test", "-v", test_name],
capture_output=True,
text=True,
)
return parse_results(result)

View File

@@ -10,6 +10,7 @@ del m
assert re._constants.MAGIC == sre_engine_magic
class CompiledPattern:
@classmethod
def compile(cls, pattern, flags=0):
@@ -21,40 +22,50 @@ class CompiledPattern:
self.flags = re.RegexFlag(flags | p.state.flags)
return self
for k, v in re.RegexFlag.__members__.items():
setattr(CompiledPattern, k, v)
class EscapeRustStr:
hardcoded = {
ord('\r'): '\\r',
ord('\t'): '\\t',
ord('\r'): '\\r',
ord('\n'): '\\n',
ord('\\'): '\\\\',
ord('\''): '\\\'',
ord('\"'): '\\\"',
ord("\r"): "\\r",
ord("\t"): "\\t",
ord("\r"): "\\r",
ord("\n"): "\\n",
ord("\\"): "\\\\",
ord("'"): "\\'",
ord('"'): '\\"',
}
@classmethod
def __class_getitem__(cls, ch):
if (rpl := cls.hardcoded.get(ch)) is not None:
return rpl
if ch in range(0x20, 0x7f):
if ch in range(0x20, 0x7F):
return ch
return f"\\u{{{ch:x}}}"
def rust_str(s):
return '"' + s.translate(EscapeRustStr) + '"'
# matches `// pattern {varname} = re.compile(...)`
pattern_pattern = re.compile(r"^((\s*)\/\/\s*pattern\s+(\w+)\s+=\s+(.+?))$(?:.+?END GENERATED)?", re.M | re.S)
pattern_pattern = re.compile(
r"^((\s*)\/\/\s*pattern\s+(\w+)\s+=\s+(.+?))$(?:.+?END GENERATED)?", re.M | re.S
)
def replace_compiled(m):
line, indent, varname, pattern = m.groups()
pattern = eval(pattern, {"re": CompiledPattern})
pattern = f"Pattern {{ pattern: {rust_str(pattern.pattern)}, code: &{json.dumps(pattern.code)} }}"
return f'''{line}
return f"""{line}
{indent}// START GENERATED by generate_tests.py
{indent}#[rustfmt::skip] let {varname} = {pattern};
{indent}// END GENERATED'''
{indent}// END GENERATED"""
with os.scandir("tests") as t, os.scandir("benches") as b:
for f in chain(t, b):

View File

@@ -39,7 +39,10 @@ implementation = platform.python_implementation()
if implementation != "CPython":
sys.exit(f"whats_left.py must be run under CPython, got {implementation} instead")
if sys.version_info[:2] < (3, 13):
sys.exit(f"whats_left.py must be run under CPython 3.13 or newer, got {implementation} {sys.version} instead")
sys.exit(
f"whats_left.py must be run under CPython 3.13 or newer, got {implementation} {sys.version} instead"
)
def parse_args():
parser = argparse.ArgumentParser(description="Process some integers.")
@@ -73,8 +76,16 @@ args = parse_args()
# CPython specific modules (mostly consisting of templates/tests)
CPYTHON_SPECIFIC_MODS = {
'xxmodule', 'xxsubtype', 'xxlimited', '_xxtestfuzz',
'_testbuffer', '_testcapi', '_testimportmultiple', '_testinternalcapi', '_testmultiphase', '_testlimitedcapi'
"xxmodule",
"xxsubtype",
"xxlimited",
"_xxtestfuzz",
"_testbuffer",
"_testcapi",
"_testimportmultiple",
"_testinternalcapi",
"_testmultiphase",
"_testlimitedcapi",
}
IGNORED_MODULES = {"this", "antigravity"} | CPYTHON_SPECIFIC_MODS
@@ -291,7 +302,7 @@ output = """\
output += gen_methods()
output += f"""
cpymods = {gen_modules()!r}
libdir = {os.path.abspath("Lib/").encode('utf8')!r}
libdir = {os.path.abspath("Lib/").encode("utf8")!r}
"""
@@ -310,6 +321,8 @@ for fn in REUSED:
expected_methods = {}
cpymods = {}
libdir = ""
# This function holds the source code that will be run under RustPython
def compare():
import inspect
@@ -376,7 +389,9 @@ def compare():
if rustpymod is None:
result["not_implemented"][modname] = None
elif isinstance(rustpymod, Exception):
result["failed_to_import"][modname] = rustpymod.__class__.__name__ + str(rustpymod)
result["failed_to_import"][modname] = rustpymod.__class__.__name__ + str(
rustpymod
)
else:
implemented_items = sorted(set(cpymod) & set(rustpymod))
mod_missing_items = set(cpymod) - set(rustpymod)
@@ -418,13 +433,23 @@ def remove_one_indent(s):
compare_src = inspect.getsourcelines(compare)[0][1:]
output += "".join(remove_one_indent(line) for line in compare_src)
with open(GENERATED_FILE, "w", encoding='utf-8') as f:
with open(GENERATED_FILE, "w", encoding="utf-8") as f:
f.write(output + "\n")
subprocess.run(["cargo", "build", "--release", f"--features={args.features}"], check=True)
subprocess.run(
["cargo", "build", "--release", f"--features={args.features}"], check=True
)
result = subprocess.run(
["cargo", "run", "--release", f"--features={args.features}", "-q", "--", GENERATED_FILE],
[
"cargo",
"run",
"--release",
f"--features={args.features}",
"-q",
"--",
GENERATED_FILE,
],
env={**os.environ.copy(), "RUSTPYTHONPATH": "Lib"},
text=True,
capture_output=True,
@@ -475,7 +500,7 @@ if args.signature:
if args.doc:
print("\n# mismatching `__doc__`s (warnings)")
for modname, mismatched in result["mismatched_doc_items"].items():
for (item, rustpy_doc, cpython_doc) in mismatched:
for item, rustpy_doc, cpython_doc in mismatched:
print(f"{item} {repr(rustpy_doc)} != {repr(cpython_doc)}")