◐ Shell
reader mode source ↗
Skip to content

_abc, _typing and update typing,test_types from 3.14.2#6797

Merged
youknowone merged 9 commits into
RustPython:mainfrom
youknowone:abc
Jan 20, 2026
Merged

_abc, _typing and update typing,test_types from 3.14.2#6797
youknowone merged 9 commits into
RustPython:mainfrom
youknowone:abc

Conversation

@youknowone

@youknowone youknowone commented Jan 19, 2026

Copy link
Copy Markdown
Member

The last commit is generated by #6796
python3 scripts/update_lib quick typing

Summary by CodeRabbit

  • New Features
    • PyMappingProxy objects are now hashable.
    • Added Abstract Base Classes (_abc) support with caching and subclass registry management.
    • Namespace gains replace and enhanced initialization from mappings.
    • Union type gains rich attributes (name/qualname/origin/parameters/args), stricter construction, and improved hashing/equality semantics.
  • Improvements
    • Improved error message formatting for unhashable types.
    • Union/type-alias union operations now have more consistent operator behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 19, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

This PR standardizes binary operator hooks to return PyResult, reworks PyUnion to track hashable vs unhashable components with dedup/flatten logic, adds a new stdlib _abc module implementing ABC mechanics and caching, and makes related module/export and small API adjustments.

Changes

Cohort / File(s) Summary
Binary operator return types
crates/vm/src/builtins/genericalias.rs, crates/vm/src/builtins/type.rs, crates/vm/src/stdlib/typing.rs
Change __or__/__ror__ and number-slot or wiring to return PyResult directly; remove ToPyResult wrapping in caller sites.
PyUnion / typing surface
crates/vm/src/builtins/union.rs, crates/vm/src/builtins/mod.rs, crates/vm/src/stdlib/typevar.rs, crates/vm/src/stdlib/typing.rs
Major PyUnion refactor: add hashable_args/unhashable_args, dedup/flatten args, new constructors/helpers (make_union, dedup_and_flatten_args, string_to_forwardref), new getters, __mro_entries__, move union type into typing surface and export make_union/Union.
ABC implementation
crates/vm/src/stdlib/_abc.rs, crates/vm/src/stdlib/mod.rs
Add new _abc module providing ABC data, registry/cache/negative_cache with invalidation counter, subclass/instance check functions, registration and reset APIs; register module in stdlib init map.
MappingProxy hashing
crates/vm/src/builtins/mappingproxy.rs
Add Hashable impl delegating to underlying mapped object's hash.
Namespace changes
crates/vm/src/builtins/namespace.rs
Add __replace__ and allow optional mapping positional arg for initialization (keys must be strings).
Misc small changes
crates/vm/src/types/slot.rs, .cspell.dict/python-more.txt
Tweak unhashable type error formatting ('name') and add frozensets to spell dictionary.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant make_union as make_union()
    participant dedup as dedup_and_flatten_args()
    participant PyUnion as PyUnion

    Caller->>make_union: call with args (PyTuple)
    make_union->>dedup: dedup_and_flatten_args(args)
    dedup->>dedup: flatten strings -> ForwardRef, separate hashable/unhashable, dedupe
    dedup-->>make_union: UnionComponents {args, hashable_args?, unhashable_args?}
    alt single arg
        make_union-->>Caller: return underlying arg (unwrapped)
    else multiple args
        make_union->>PyUnion: from_components(UnionComponents)
        PyUnion-->>make_union: PyUnion instance (PyResult)
        make_union-->>Caller: PyUnion (PyResult)
    end
Loading
sequenceDiagram
    participant Code
    participant ABCMethods as _abc methods
    participant Cache as Registry/Cache
    participant Counter as InvalidationCounter

    Code->>ABCMethods: _abc_subclasscheck(cls, subclass)
    ABCMethods->>Cache: check positive cache
    alt cached hit
        Cache-->>ABCMethods: result
    else cache miss
        ABCMethods->>Cache: check negative_cache version
        alt negative cache stale
            ABCMethods->>Counter: increment token
            ABCMethods->>Cache: clear negative cache
        end
        ABCMethods->>ABCMethods: run subclass hooks / direct checks / recursive registry traversal
        ABCMethods->>Cache: update positive or negative cache
    end
    ABCMethods-->>Code: boolean result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • arihant2math

Poem

🐇 I hopped through unions, hashed and not,

I flattened strings and trimmed a lot,
ABCs now count and cache the way,
Operators return results today,
A tiny rabbit cheers the new array!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 59.02% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title references specific changes (_abc, _typing updates from 3.14.2) that align with the actual changeset, which includes new _abc module implementation, Union type updates, typing modifications, and supporting changes to type operators.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

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

@youknowone youknowone changed the title _abc Jan 19, 2026
@github-actions

github-actions Bot commented Jan 19, 2026

Copy link
Copy Markdown
Contributor

Code has been automatically formatted

The code in this PR has been formatted using:

  • cargo fmt --all
    Please pull the latest changes before pushing again:
git pull origin abc

@youknowone youknowone force-pushed the abc branch 3 times, most recently from 6df2b89 to e8077f2 Compare January 19, 2026 15:39
@youknowone youknowone changed the title _abc, _typing and update typing from 3.14.2 Jan 19, 2026
@youknowone youknowone marked this pull request as ready for review January 19, 2026 15:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hide comment

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/vm/src/builtins/union.rs`:
- Around line 248-332: The dedup_and_flatten_args function currently treats any
error from arg.hash(vm) as "unhashable", masking real exceptions; change the
Err(_) arm to capture the exception (Err(e)) and propagate it unless it's a
TypeError, in which case proceed with unhashable handling. Concretely, in
dedup_and_flatten_args replace the match on arg.hash(vm) so that if Err(e) you
check the exception type (compare against vm.ctx.exceptions.type_error or use
vm.is_instance) and return Err(e) for non-TypeError, otherwise handle as now by
doing equality comparisons and adding to unhashable_list.
🧹 Nitpick comments (2)
crates/vm/src/stdlib/_abc.rs (1)

341-350: Avoid calling into the VM while holding AbcData locks.

Drop the lock guard before invoking set.clear() to reduce reentrancy/deadlock risk; apply the same pattern in _reset_registry and _reset_caches.

♻️ Suggested refactor pattern (apply similarly in reset helpers)
-        let negative_cache = impl_data.negative_cache.read();
-        if let Some(ref set) = *negative_cache {
-            vm.call_method(set.as_ref(), "clear", ())?;
-        }
-        drop(negative_cache);
+        let negative_cache = impl_data.negative_cache.read();
+        let set = negative_cache.as_ref().cloned();
+        drop(negative_cache);
+        if let Some(set) = set {
+            vm.call_method(set.as_ref(), "clear", ())?;
+        }
         impl_data.set_cache_version(invalidation_counter);

Also applies to: 453-477

crates/vm/src/builtins/union.rs (1)

389-441: Optional: fast equality path when all args are hashable.

If both unions have unhashable_args == None, consider comparing hashable_args (frozensets) directly to avoid the O(n²) nested loops.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hide comment

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/vm/src/builtins/namespace.rs`:
- Around line 46-69: The __replace__ implementation currently calls cls.call((),
vm) then mutates the new instance's __dict__; instead, build a mapping from the
current namespace (src_dict) and call the constructor with that mapping as the
single positional argument and the replacement kwargs (args.kwargs) as **kwargs
so subclasses' __init__ runs normally. Concretely, stop creating result then
copying src_dict and calling set_attr; instead prepare a positional tuple
containing the namespace mapping and pass args.kwargs into cls.call(...) so
cls.call receives (mapping,) and the kwargs, preserving existing checks for
positional args and using the same vm/context objects (referencing __replace__,
cls.call, zelf, src_dict, and args.kwargs).
♻️ Duplicate comments (1)
crates/vm/src/builtins/union.rs (1)

290-307: Hash error handling catches all exceptions.

The Err(_) pattern treats any hash exception as "unhashable," including non-TypeError exceptions like ValueError. While this could mask real errors from faulty __hash__ implementations, I note that a similar concern was raised previously and the maintainer indicated the current behavior is intentional.

🧹 Nitpick comments (1)
crates/vm/src/builtins/union.rs (1)

458-492: Minor: Potentially misleading error message when previously-unhashable args become hashable.

Lines 470-474 raise "union contains N unhashable element(s)" even when all previously-unhashable args have since become hashable (passed arg.hash(vm)? at line 466). This maintains consistent hashing semantics (objects that were unhashable at creation time remain treated as such), but the error message could be confusing since the elements are no longer actually unhashable.

Consider updating the message to something like: "union was created with unhashable element(s)" to clarify the semantic.

Suggested message improvement
-            return Err(vm.new_type_error(format!(
-                "union contains {} unhashable element{}",
-                n,
-                if n > 1 { "s" } else { "" }
-            )));
+            return Err(vm.new_type_error(format!(
+                "union was created with {} unhashable element{}",
+                n,
+                if n > 1 { "s" } else { "" }
+            )));

Hide details View details @youknowone youknowone merged commit 6f41a94 into RustPython:main Jan 20, 2026
12 of 13 checks passed
@youknowone youknowone deleted the abc branch January 20, 2026 01:59
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.

1 participant