-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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.expectedFailure
should 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.rs
vm/src/types/zoo.rs
vm/src/vm/context.rs
vm/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_name
Switching 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_type
is 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 inContext
The 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_default
is inserted betweennone
andempty_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
_typing
module with theNoDefault
singleton 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_object
correctly imports and calls typing module functionstype_check
appropriately avoids bootstrapping issues by special-casing None
47-62
: TypeVar struct properly extended for default value support.The addition of
default_value
andevaluate_default
fields, along withHAS_DICT
flag 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_entries
correctly prevents TypeVar subclassing- Properties use consistent locking patterns for thread safety
default
property properly returns the NoDefault singleton when appropriate
134-162
: TypeVar methods correctly implement Python typing semantics.The methods properly handle:
typing_subst
delegates to the Python typing module as expectedreduce
supports pickling by returning the namehas_default
correctly 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_attr
flag- 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_value
andevaluate_default
fields 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_default
method 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
_typing
module from the public interface and correctly integrates theNoDefault
singleton from the VM context.
22-39
: Well-designed helper functions for typing integration.The
_call_typing_func_object
function provides a clean abstraction for calling Python typing module functions, andtype_check
appropriately 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_check
to 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_typevar
helper function has been updated to initialize the newdefault_value
andevaluate_default
fields, 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_typevar
helper function initializesdefault_value
withvm.ctx.none()
, while the main constructor uses theNoDefault
singleton 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
NoDefault
singleton 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::Mutex
provides 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
None
and theNoDefault
singleton, and thehas_default
method 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
NoDefault
type 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. TheGeneric
class correctly implements__class_getitem__
for generic alias creation.
Summary by CodeRabbit
New Features
Bug Fixes
Documentation