GitHub Copilot Instructions for RustPython
This document provides guidelines for working with GitHub Copilot when contributing to the RustPython project.
RustPython is a Python 3 interpreter written in Rust, implementing Python 3.13.0+ compatibility. The project aims to provide:
- A complete Python-3 environment entirely in Rust (not CPython bindings)
- A clean implementation without compatibility hacks
- Cross-platform support, including WebAssembly compilation
- The ability to embed Python scripting in Rust applications
- src/ - Top-level code for the RustPython binary
- vm/ - The Python virtual machine implementation
- builtins/ - Python built-in types and functions
- stdlib/ - Essential standard library modules implemented in Rust, required to run the Python core
- compiler/ - Python compiler components
- parser/ - Parser for converting Python source to AST
- core/ - Bytecode representation in Rust structures
- codegen/ - AST to bytecode compiler
- Lib/ - CPython's standard library in Python (copied from CPython). IMPORTANT: Do not edit this directory directly; The only allowed operation is copying files from CPython.
- derive/ - Rust macros for RustPython
- common/ - Common utilities
- extra_tests/ - Integration tests and snippets
- stdlib/ - Non-essential Python standard library modules implemented in Rust (useful but not required for core functionality)
- wasm/ - WebAssembly support
- jit/ - Experimental JIT compiler implementation
- pylib/ - Python standard library packaging (do not modify this directory directly - its contents are generated automatically)
Important Development Notes
When testing Python code, always use RustPython instead of the standard python command:
# Use this instead of python script.py
cargo run -- script.py
# For interactive REPL
cargo run
# With specific features
cargo run --features ssl
# Release mode (recommended for better performance)
cargo run --release -- script.py
When you need to compare behavior with CPython or run test suites:
# Use python command to explicitly run CPython
python my_test_script.py
# Run RustPython
cargo run -- my_test_script.py
Working with the Lib Directory
The Lib/ directory contains Python standard library files copied from the CPython repository. Important notes:
- These files should be edited very conservatively
- Modifications should be minimal and only to work around RustPython limitations
- Tests in Lib/test often use one of the following markers:
- Add a # TODO: RUSTPYTHON comment when modifications are made
- unittest.skip("TODO: RustPython <reason>")
- unittest.expectedFailure with # TODO: RUSTPYTHON <reason> comment
# Run Rust unit tests
cargo test --workspace --exclude rustpython_wasm
# Run Python snippets tests
cd extra_tests
pytest -v
# Run the Python test module
cargo run --release -- -m test ${TEST_MODULE}
cargo run --release -- -m test test_unicode # to test test_unicode.py
# Run the Python test module with specific function
cargo run --release -- -m test test_unicode -k test_unicode_escape
Determining What to Implement
Run ./whats_left.py to get a list of unimplemented methods, which is helpful when looking for contribution opportunities.
- Follow the default rustfmt code style (cargo fmt to format)
- IMPORTANT: Always run clippy to lint code (cargo clippy) before completing tasks. Fix any warnings or lints that are introduced by your changes
- Follow Rust best practices for error handling and memory management
- Use the macro system (pyclass, pymodule, pyfunction, etc.) when implementing Python functionality in Rust
- IMPORTANT: In most cases, Python code should not be edited. Bug fixes should be made through Rust code modifications only
- Follow PEP 8 style for custom Python code
- Use ruff for linting Python code
- Minimize modifications to CPython standard library files
Integration Between Rust and Python
The project provides several mechanisms for integration:
- pymodule macro for creating Python modules in Rust
- pyclass macro for implementing Python classes in Rust
- pyfunction macro for exposing Rust functions to Python
- PyObjectRef and other types for working with Python objects in Rust
Implementing a Python Module in Rust
#[pymodule]
mod mymodule {
use rustpython_vm::prelude::*;
#[pyfunction]
fn my_function(value: i32) -> i32 {
value * 2
}
#[pyattr]
#[pyclass(name = "MyClass")]
#[derive(Debug, PyPayload)]
struct MyClass {
value: usize,
}
#[pyclass]
impl MyClass {
#[pymethod]
fn get_value(&self) -> usize {
self.value
}
}
}
Adding a Python Module to the Interpreter
vm.add_native_module(
"my_module_name".to_owned(),
Box::new(my_module::make_module),
);
Building for Different Targets
# Build for WASM
cargo build --target wasm32-wasip1 --no-default-features --features freeze-stdlib,stdlib --release
# Enable JIT support
cargo run --features jit
# Enable SSL support
cargo run --features ssl
Test Code Modification Rules
CRITICAL: Test code modification restrictions
- NEVER comment out or delete any test code lines except for removing @unittest.expectedFailure decorators and upper TODO comments
- NEVER modify test assertions, test logic, or test data
- When a test cannot pass due to missing language features, keep it as expectedFailure and document the reason
- The only acceptable modifications to test files are:
- Removing @unittest.expectedFailure decorators and the upper TODO comments when tests actually pass
- Adding @unittest.expectedFailure decorators when tests cannot be fixed
Examples of FORBIDDEN modifications:
- Commenting out test lines
- Changing test assertions
- Modifying test data or expected results
- Removing test logic
Correct approach when tests fail due to unsupported syntax:
- Keep the test as @unittest.expectedFailure
- Document that it requires PEP 695 support
- Focus on tests that can be fixed through Rust code changes only