-
Notifications
You must be signed in to change notification settings - Fork 1.4k
typing.TypeVar #5834
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
typing.TypeVar #5834
Conversation
WalkthroughThe changes introduce enhanced support for Python's typing module in a Rust-based Python VM. This includes a comprehensive refactor of the internal Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant VM
participant TypingModule
participant PythonTyping
User->>VM: Create TypeVar(name, constraints, bound, default)
VM->>TypingModule: TypeVar.__new__(...)
TypingModule->>TypingModule: Parse & validate arguments
TypingModule->>PythonTyping: Call _type_check for constraints/bound
PythonTyping-->>TypingModule: Return checked types
TypingModule->>VM: Return TypeVar instance with default (or NoDefault)
sequenceDiagram
participant VM
participant TypingModule
VM->>TypingModule: Access NoDefault singleton
TypingModule->>VM: Return NoDefault instance from context
Poem
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.github/copilot-instructions.md (1)
87-91: Quote the env-var to avoid word-splitting in bashShell will word-split
${TEST_MODULE}if it ever contains spaces or shell-metacharacters. Safer example:-cargo run --release -- -m test ${TEST_MODULE} +cargo run --release -- -m test "${TEST_MODULE}"Pure documentation change – feel free to ignore if you don’t expect funky module names.
Lib/test/test_typing.py (1)
9709-9710: Add a descriptive reason to the TODO marker.Per the repo’s guideline, comments accompanying
unittest.expectedFailureshould specify the RustPython limitation that triggers the failure. A brief reason makes triage easier and avoids the inevitable “why is this still xfail?” question in a few months.- # TODO: RUSTPYTHON + # TODO: RUSTPYTHON: NoDefault is not yet picklable
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
.github/copilot-instructions.md(1 hunks)Lib/test/test_typing.py(1 hunks)vm/src/builtins/type.rs(1 hunks)vm/src/stdlib/typing.rs(5 hunks)vm/src/types/zoo.rs(2 hunks)vm/src/vm/context.rs(3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
`**/*.rs`: Follow the default rustfmt code style; use 'cargo fmt' to format Rust code. Always run clippy to lint Rust code ('cargo clippy') before completing tasks, and fix any war...
**/*.rs: Follow the default rustfmt code style; use 'cargo fmt' to format Rust code.
Always run clippy to lint Rust code ('cargo clippy') before completing tasks, and fix any warnings or lints introduced by your changes.
vm/src/builtins/type.rsvm/src/types/zoo.rsvm/src/vm/context.rsvm/src/stdlib/typing.rs
`Lib/**/*`: Files in the Lib/ directory (copied from CPython) should be edited very conservatively; modifications should be minimal and only to work around RustPython limitations.
Lib/**/*: Files in the Lib/ directory (copied from CPython) should be edited very conservatively; modifications should be minimal and only to work around RustPython limitations.
Lib/test/test_typing.py
`Lib/test/**/*`: Tests in Lib/test often use markers such as '# TODO: RUSTPYTHON', 'unittest.skip("TODO: RustPython ")', or 'unittest.expectedFailure' with a '# TODO: RUSTP...
Lib/test/**/*: Tests in Lib/test often use markers such as '# TODO: RUSTPYTHON', 'unittest.skip("TODO: RustPython ")', or 'unittest.expectedFailure' with a '# TODO: RUSTPYTHON ' comment when modifications are made.
Lib/test/test_typing.py
`**/*.py`: Follow PEP 8 style for custom Python code. Use ruff for linting Python code.
**/*.py: Follow PEP 8 style for custom Python code.
Use ruff for linting Python code.
Lib/test/test_typing.py
⏰ Context from checks skipped due to timeout of 90000ms (6)
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Check Rust code with rustfmt and clippy
- GitHub Check: Run tests under miri
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Ensure compilation on various targets
🔇 Additional comments (15)
vm/src/builtins/type.rs (1)
1498-1503: Good call – aligns with CPython’stp_nameSwitching from
name()toslot_name()yields the fully-qualified type name (incl. module path) and matches the wording produced by CPython’sPyType.tp_name. No functional risk spotted.vm/src/types/zoo.rs (2)
89-93: Field addition looks correct
typing_no_default_typeis added in the struct and initialised below. Type is&'static Py<PyType>so#[derive(Clone)]still works and no extra trait bounds are needed.
181-185: Initialisation path is consistent
crate::stdlib::typing::NoDefault::init_builtin_type()returns the expected&'static Py<PyType>and mirrors how other singleton types are registered, so the new field is initialised coherently.vm/src/vm/context.rs (3)
44-45: New singleton stored inContextThe extra field is correctly typed (
PyRef<…>) and keeps ordering with struct initialisation later in the file.
283-287: Singleton instance creation mirrors existing pattern
create_object(NoDefault, NoDefault::static_type())follows the same zero-sized-struct pattern used forNone,Ellipsis, etc. No issues.
323-333: Struct construction remains in declaration order
typing_no_defaultis inserted betweennoneandempty_tuple, matching the revised struct layout – prevents a potential field-init-shorthand compiler error.vm/src/stdlib/typing.rs (9)
1-11: LGTM! Clean module structure with proper singleton access.The module now properly extends the
_typingmodule with theNoDefaultsingleton from the VM context, which is the correct pattern for singleton types in the VM.
22-39: Well-designed helper functions for typing module interaction.Both functions properly handle VM interactions:
_call_typing_func_objectcorrectly imports and calls typing module functionstype_checkappropriately avoids bootstrapping issues by special-casing None
47-62: TypeVar struct properly extended for default value support.The addition of
default_valueandevaluate_defaultfields, along withHAS_DICTflag and appropriate traits, correctly implements the infrastructure needed for TypeVar defaults.
64-132: Comprehensive property implementations with proper lazy evaluation.All property getters are well-implemented:
mro_entriescorrectly prevents TypeVar subclassing- Properties use consistent locking patterns for thread safety
defaultproperty properly returns the NoDefault singleton when appropriate
134-162: TypeVar methods correctly implement Python typing semantics.The methods properly handle:
typing_substdelegates to the Python typing module as expectedreducesupports pickling by returning the namehas_defaultcorrectly checks both lazy evaluation and NoDefault singleton
164-178: String representation correctly follows Python typing conventions.The variance indicators (+, -, ~) properly represent covariant, contravariant, and invariant type variables respectively.
221-266: Robust validation logic for TypeVar constraints.The implementation correctly validates:
- Bivariant types are rejected
- Variance and infer_variance are mutually exclusive
- Single constraints are disallowed
- Constraints and bounds cannot be used together
- Bounds are properly type-checked
409-439: NoDefault singleton correctly implements Python typing.NoDefault semantics.The implementation properly:
- Enforces singleton pattern through VM context
- Prevents attribute assignment with
no_attrflag- Validates that no arguments are accepted
- Provides appropriate string representations
298-316: make_typevar correctly initializes new default fields.The function properly initializes the new
default_valueandevaluate_defaultfields to None, maintaining consistency with the TypeVar implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
vm/src/stdlib/typing.rs (1)
181-226: Complex constructor with thorough validation - verify past duplicate removal issue.The constructor implementation is comprehensive with proper argument parsing and validation. However, there was a past review comment about duplicate key removal on line 188 that needs verification.
Looking at the current code, I don't see the duplicate
kwargs.swap_remove("name")call mentioned in the past review. The code appears to correctly handle the name parameter extraction. Let me verify this hasn't regressed:#!/bin/bash # Search for any duplicate swap_remove calls on the same key rg -A 3 -B 3 'swap_remove.*"name"' --type rust
🧹 Nitpick comments (1)
vm/src/stdlib/typing.rs (1)
150-160: Consider simplifying the has_default method logic.The
has_defaultmethod has nested conditions that could be streamlined for better readability:fn has_default(&self, vm: &VirtualMachine) -> bool { - if !vm.is_none(&self.evaluate_default) { - return true; - } - let default_value = self.default_value.lock(); - if vm.is_none(&default_value) { - return false; - } - // Check if default_value is NoDefault - !default_value.is(&vm.ctx.typing_no_default) + // Check evaluate_default first + if !vm.is_none(&self.evaluate_default) { + return true; + } + + // Check if default_value is set and not NoDefault + let default_value = self.default_value.lock(); + !vm.is_none(&default_value) && !default_value.is(&vm.ctx.typing_no_default) }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
Lib/test/test_typing.py(1 hunks)vm/src/builtins/type.rs(1 hunks)vm/src/stdlib/typing.rs(5 hunks)vm/src/types/zoo.rs(2 hunks)vm/src/vm/context.rs(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- vm/src/builtins/type.rs
- vm/src/types/zoo.rs
- vm/src/vm/context.rs
- Lib/test/test_typing.py
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.rs`: Follow the default rustfmt code style; use 'cargo fmt' to format Rust code. Always run clippy to lint Rust code ('cargo clippy') before completing tasks, and fix any war...
**/*.rs: Follow the default rustfmt code style; use 'cargo fmt' to format Rust code.
Always run clippy to lint Rust code ('cargo clippy') before completing tasks, and fix any warnings or lints introduced by your changes.
vm/src/stdlib/typing.rs
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Check Rust code with rustfmt and clippy
- GitHub Check: Run tests under miri
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Check the WASM package and demo
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
🔇 Additional comments (8)
vm/src/stdlib/typing.rs (8)
1-11: LGTM: Clean module organization.The new module structure properly separates the internal
_typingmodule from the public interface and correctly integrates theNoDefaultsingleton from the VM context.
22-39: Well-designed helper functions for typing integration.The
_call_typing_func_objectfunction provides a clean abstraction for calling Python typing module functions, andtype_checkappropriately handles the bootstrapping issue by avoiding direct imports during initialization.
242-256: Robust constraint validation logic.The constraint handling properly validates single constraints (which aren't allowed) and prevents mixing constraints with bounds. The tuple creation and assignment logic is correct.
259-269: Proper type checking for bounds.The bound validation correctly calls
type_checkto ensure type safety, which is essential for TypeVar constraints. Good error handling for None values.
291-299: Smart module name detection from frame globals.Setting
__module__from the current frame's globals is a clever way to maintain proper module attribution. The None check prevents setting invalid module names.
317-322: Update make_typevar for consistency.Good that the
make_typevarhelper function has been updated to initialize the newdefault_valueandevaluate_defaultfields, maintaining consistency with the enhanced TypeVar structure.
416-446: Excellent singleton implementation for NoDefaultType.The NoDefaultType implementation properly enforces the singleton pattern by:
- Rejecting any constructor arguments
- Returning the singleton instance from VM context
- Providing appropriate string representation
- Implementing proper reduction for pickling
This is a textbook example of singleton implementation in Rust.
56-61: Verify thread safety with multiple mutexes.The TypeVar struct now has three mutex-protected fields (
bound,constraints,default_value). While each individual mutex is thread-safe, consider whether operations that need to access multiple fields simultaneously could lead to inconsistent states.#!/bin/bash # Check for patterns where multiple mutex fields might be accessed together rg -A 10 -B 2 "\.lock\(\)" --type rust | rg -A 5 -B 5 "constraints|bound|default_value"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
vm/src/stdlib/typing.rs (1)
307-325: Consider using NoDefault singleton for consistency.The
make_typevarhelper function initializesdefault_valuewithvm.ctx.none(), while the main constructor uses theNoDefaultsingleton when no default is provided. This inconsistency could lead to different behavior inhas_default()method calls.Consider updating for consistency:
- default_value: parking_lot::Mutex::new(vm.ctx.none()), + default_value: parking_lot::Mutex::new(vm.ctx.typing_no_default.clone().into()),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
Lib/test/test_genericalias.py(0 hunks)Lib/test/test_types.py(0 hunks)Lib/test/test_typing.py(1 hunks)vm/src/stdlib/typing.rs(5 hunks)vm/src/types/zoo.rs(2 hunks)vm/src/vm/context.rs(3 hunks)
💤 Files with no reviewable changes (2)
- Lib/test/test_genericalias.py
- Lib/test/test_types.py
🚧 Files skipped from review as they are similar to previous changes (3)
- vm/src/types/zoo.rs
- vm/src/vm/context.rs
- Lib/test/test_typing.py
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.rs`: Follow the default rustfmt code style; use 'cargo fmt' to format Rust code. Always run clippy to lint Rust code ('cargo clippy') before completing tasks, and fix any war...
**/*.rs: Follow the default rustfmt code style; use 'cargo fmt' to format Rust code.
Always run clippy to lint Rust code ('cargo clippy') before completing tasks, and fix any warnings or lints introduced by your changes.
vm/src/stdlib/typing.rs
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Check Rust code with rustfmt and clippy
- GitHub Check: Check the WASM package and demo
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run tests under miri
🔇 Additional comments (7)
vm/src/stdlib/typing.rs (7)
1-11: LGTM! Clean module setup with proper NoDefault integration.The module structure is well-organized and correctly integrates the
NoDefaultsingleton from the VM context into the typing module.
22-39: LGTM! Well-implemented helper functions.The helper functions are cleanly implemented with proper error handling and good performance optimizations (like the None check in
type_check).
46-118: LGTM! Excellent enhancement of TypeVar with proper thread safety.The addition of default value support and variance properties is well-implemented. The use of
parking_lot::Mutexprovides appropriate thread safety, and the lazy evaluation pattern for constraints and bounds is efficient.
119-159: LGTM! Correct implementation of default value handling.The default property correctly distinguishes between
Noneand theNoDefaultsingleton, and thehas_defaultmethod properly implements the logic for determining if a default value exists. The lazy evaluation pattern is consistent with other properties.
176-305: LGTM! Comprehensive and well-validated TypeVar constructor.The constructor implementation is excellent with:
- Proper argument parsing for both positional and keyword arguments
- Thorough validation of variance combinations and constraint/bound conflicts
- Clear and descriptive error messages
- Correct initialization of default values using the NoDefault singleton
- The duplicate key removal issue from the past review has been properly addressed
418-448: LGTM! Excellent singleton implementation of NoDefault.The
NoDefaulttype is properly implemented as a singleton with:
- Correct singleton enforcement in the constructor by returning the context instance
- Proper argument validation (rejecting any arguments)
- Clean string representation and reduce method
- Thread-safe singleton pattern through the VM context
449-532: LGTM! Supporting typing constructs are appropriately implemented.The remaining typing constructs (
TypeVarTuple,ParamSpec,TypeAliasType,Generic) are well-structured and follow consistent patterns. TheGenericclass correctly implements__class_getitem__for generic alias creation.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation