Skip to content

Match CPython wording for compile() optimize and flags validation#7765

Merged
youknowone merged 1 commit into
RustPython:mainfrom
changjoon-park:fix-compile-optimize-validation
May 4, 2026
Merged

Match CPython wording for compile() optimize and flags validation#7765
youknowone merged 1 commit into
RustPython:mainfrom
changjoon-park:fix-compile-optimize-validation

Conversation

@changjoon-park
Copy link
Copy Markdown
Contributor

@changjoon-park changjoon-park commented May 2, 2026

Summary

Two CPython parity gaps in compile() argument validation, both in crates/vm/src/stdlib/builtins.rs.

1. optimize validation gap (real bug)

CPython accepts optimize ∈ {-1, 0, 1, 2} only; anything else raises ValueError("compile(): invalid optimize value") (Python/bltinmodule.c::builtin_compile_impl).

The previous logic only validated through i32::try_into::<u8>(), which silently accepts every value in [0, 255]. So optimize=3, optimize=99, etc. were silently truncated to a u8 instead of being rejected.

>>> compile('x = 1', '<x>', 'exec', optimize=3)
# CPython 3.14.4: ValueError: compile(): invalid optimize value
# RustPython main: <code object ...>  ❌

2. flags error wording (wording-only)

CPython uses British "unrecognised" with a colon separator: compile(): unrecognised flags. The previous wording was American "unrecognized" without the colon.

Fix

Replace the cast-based optimize validation with a range pattern, and align the flags wording with CPython's.

let optimize: u8 = match optimize {
    -1 => vm.state.config.settings.optimize,
    0..=2 => optimize as u8,
    _ => return Err(vm.new_value_error("compile(): invalid optimize value")),
};

The optimize=1 << 1000 boundary still raises OverflowError via the ArgPrimitiveIndex<i32> conversion layer before this check (preserves Lib/test/test_compile.py:668).

Verification (CPython 3.14.4)

Probe Cases Match
optimize boundary (-1, 0..2, 3, 4, 99, 255, 256, 1000, -2, -99) 12 12/12
flags invalid bits (99999, 0x10000) 2 2/2
flags valid bits (0x20000, 0x40000) 2 2/2

cargo run --release -- -m test test_compile test_builtin test_compileall test_codeop test_ast — 703 tests pass, 0 regressions. All 189 extra_tests/snippets/*.py pass under the CI feature set. A new builtin_compile.py adds regression coverage for both wordings.

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced the compile() function's parameter validation with clearer error messages for invalid optimize values and unrecognized compile flags.
  • Tests

    • Added comprehensive test coverage for the compile() function, validating accepted parameter values and ensuring proper error handling across different scenarios.

CPython's `builtin_compile_impl` (Python/bltinmodule.c) accepts only
optimize ∈ {-1, 0, 1, 2}; anything else raises
`ValueError("compile(): invalid optimize value")`. The previous logic
only validated via `i32::try_into::<u8>()`, which silently accepts every
value in [0, 255], so `compile(..., optimize=3)`, `optimize=99`, etc.
were silently truncated to a u8. The error wording also had the wrong
word order.

Replace the cast-based check with a `match` against the spec range.

Adjacent: the unrecognised-flags message used American spelling
("unrecognized") and missed the colon separator. CPython uses British
"unrecognised" with a colon — match it.

Verified byte-identical with CPython 3.14.4 across 12 boundary values
for optimize and 4 cases for flags. Preserves the existing OverflowError
path for `optimize=1 << 1000` (raised at the ArgPrimitiveIndex<i32>
conversion layer, before this check).
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 2, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: ffe7acb5-b352-4587-83cc-c01ada11d3dd

📥 Commits

Reviewing files that changed from the base of the PR and between 926d69b and 40f208b.

📒 Files selected for processing (2)
  • crates/vm/src/stdlib/builtins.rs
  • extra_tests/snippets/builtin_compile.py

📝 Walkthrough

Walkthrough

This PR refines the compile() builtin's optimize parameter validation in RustPython's VM. The implementation changes from an if/else cast to a match-based mapping that explicitly handles -1 (VM config level), 0..=2 (valid values), and rejects others with a precise error message. Error text for invalid flags is also corrected to use British spelling. Comprehensive tests verify the new validation behavior.

Changes

Compile Builtin Validation

Layer / File(s) Summary
Core Validation Logic
crates/vm/src/stdlib/builtins.rs
optimize argument handling refactored from if/else with try_into() to match-based mapping: -1 selects VM config level, 0..=2 converts to u8, others raise "compile(): invalid optimize value". Error message for invalid flags corrected from "compile() unrecognized flags" to "compile(): unrecognised flags".
Test Coverage
extra_tests/snippets/builtin_compile.py
New test file validates compile() modes ("exec", "eval", "single") and confirms optimize accepts only -1, 0, 1, 2, with exact error message checking for invalid values and flags. Includes helpers _check_optimize_error() and _check_flags_error(), plus OverflowError test for extremely large optimize values.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • youknowone
  • ShaharNaveh

Poem

🐰 A rabbit hops through compile's gates,
Where -1 finds its proper state,
And 0 through 2 now safely bind,
While errors spell their way, so refined!
With tests that hop from branch to branch, 🌿
This validation takes its lunch!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main change: matching CPython wording for compile() validation errors, which aligns with both the functional optimize range fix and the flags error message update.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@ShaharNaveh ShaharNaveh left a comment

Choose a reason for hiding this comment

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

Looks great!
tysm:)

@youknowone youknowone merged commit c3c9292 into RustPython:main May 4, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants