Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Jan 31, 2026

descriptor.rs:

  • Add objclass, name (pymember) and reduce (pymethod)
  • Add type check (descr_check) in descr_get; simplify None branch
  • Remove incorrect BASETYPE flag
  • Add MemberKind::Object (_Py_T_OBJECT = 6)
  • Prevent Bool slot deletion (TypeError)
  • Raise AttributeError on ObjectEx deletion when already None

pyclass.rs (derive-impl):

  • Remove duplicate MemberKind enum; use MemberKindStr (Option)
  • Simplify MemberNursery map key from (String, MemberKind) to String
  • Support #[pymember(type="object")] for _Py_T_OBJECT semantics

Summary by CodeRabbit

  • New Features

    • Added support for Object member kind in the descriptor system
    • New descriptor introspection methods: objclass and name
    • Enabled pickling support for descriptors via reduce method
  • Improvements

    • Enhanced validation and error handling for descriptor member access
    • Improved type checking when accessing descriptor members on instances

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 31, 2026

📝 Walkthrough

Walkthrough

Refactored MemberNursery to use string-based optional member types with a new entry structure, replacing composite-key lookups. Enhanced PyMemberDescriptor with a new Object kind variant, added public descriptor methods (__objclass__, __name__, __reduce__), and expanded slot access behavior to support the new kind with validation and deletion semantics.

Changes

Cohort / File(s) Summary
Member type system refactoring
crates/derive-impl/src/pyclass.rs
Replaced strict MemberKind enum with string-based optional MemberKindStr. Restructured MemberNursery to map name → MemberNurseryEntry (holding kind, getter, setter) instead of composite keys. Updated add_item, validation logic, and ToTokens generation to work with new entry structure and derive MemberKind from stored strings.
Descriptor enhancements
crates/vm/src/builtins/descriptor.rs
Added MemberKind::Object variant. Removed BASETYPE from PyMemberDescriptor class flags. Introduced public methods: __objclass__, __name__, __reduce__. Modified GetDescriptor to validate subclass before instance access. Enhanced slot handling: get_slot_from_object returns None for absent Object kind; set_slot_at_object supports assignment and deletion for both Object and ObjectEx kinds.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 The nursery now speaks in strings so clear,
Where members nest in entries without fear,
And descriptors dance with objects new,
Slot by slot, a refactoring true!
With qualnames cached and classes aligned,
The rabbits hop—cleaner code we find! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% 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 title "Fix member_descriptor to match CPython behavior" directly describes the main objective of the changeset: aligning the member_descriptor implementation with CPython behavior through additions of descriptor attributes, type checks, and MemberKind::Object support.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

descriptor.rs:
- Add __objclass__, __name__ (pymember) and __reduce__ (pymethod)
- Add type check (descr_check) in descr_get; simplify None branch
- Remove incorrect BASETYPE flag
- Add MemberKind::Object (_Py_T_OBJECT = 6)
- Prevent Bool slot deletion (TypeError)
- Raise AttributeError on ObjectEx deletion when already None

pyclass.rs (derive-impl):
- Remove duplicate MemberKind enum; use MemberKindStr (Option<String>)
- Simplify MemberNursery map key from (String, MemberKind) to String
- Support #[pymember(type="object")] for _Py_T_OBJECT semantics

test_inspect.py:
- Remove expectedFailure from test_getdoc (now passing)
@github-actions
Copy link
Contributor

📦 Library Dependencies

The following Lib/ modules were modified. Here are their dependencies:

[x] lib: cpython/Lib/inspect.py
[ ] test: cpython/Lib/test/test_inspect (TODO: 55)

dependencies:

  • inspect

dependent tests: (43 tests)

  • inspect: test_abc test_argparse test_asyncgen test_builtin test_code test_collections test_decimal test_enum test_functools test_generators test_grammar test_inspect test_ntpath test_operator test_patma test_posixpath test_signal test_traceback test_types test_typing test_unittest test_yield_from test_zipimport
    • asyncio: test_asyncio test_contextlib_async test_logging test_os test_sys_settrace test_unittest
    • bdb: test_bdb
    • dataclasses: test__colorize test_genericalias test_pprint test_regrtest test_zoneinfo
      • pprint: test_htmlparser test_ssl test_sys_setprofile
    • importlib.metadata: test_importlib
    • pydoc:
      • xmlrpc.server: test_docxmlrpc test_xmlrpc
    • rlcompleter: test_rlcompleter
    • trace: test_trace

Legend:

  • [+] path exists in CPython
  • [x] up-to-date, [ ] outdated

@youknowone youknowone marked this pull request as ready for review January 31, 2026 23:45
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

🤖 Fix all issues with AI agents
In `@crates/derive-impl/src/pyclass.rs`:
- Around line 1431-1438: The current add_item logic inserts or reuses a
MemberNurseryEntry but silently ignores a differing member_kind when a getter
and setter declare different types; update add_item to validate that if an
existing MemberNurseryEntry (from self.map.entry(name)) has a different kind
than the incoming member_kind you detect the mismatch and emit a clear
error/diagnostic (or return Err) rather than silently overwriting/ignoring it.
Locate the creation/lookup code around MemberNurseryEntry and the map.entry(...)
call in add_item, compare entry.kind with the new member_kind, and produce a
compile-time friendly failure that references the member name and both kinds so
the user can fix the #[pymember(type="...")] mismatch.

Comment on lines +1431 to +1438
let entry = self
.map
.entry(name.clone())
.or_insert_with(|| MemberNurseryEntry {
kind: member_kind,
getter: None,
setter: None,
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Potential silent inconsistency when getter and setter specify different type values.

If a getter specifies #[pymember(type="bool")] and the setter specifies #[pymember(setter, type="object")], the first one processed wins and the second's member_kind is silently ignored. Consider adding validation in add_item to detect and report mismatched kinds:

🛡️ Suggested validation
         let entry = self
             .map
             .entry(name.clone())
             .or_insert_with(|| MemberNurseryEntry {
                 kind: member_kind,
                 getter: None,
                 setter: None,
             });
+        // Validate that getter and setter have consistent member_kind
+        if entry.kind != member_kind && member_kind.is_some() && entry.kind.is_some() {
+            bail_span!(item_ident, "Member '{}' has inconsistent type specifications", name);
+        }
+        // If entry was created with None kind, allow later specification
+        if entry.kind.is_none() && member_kind.is_some() {
+            entry.kind = member_kind;
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let entry = self
.map
.entry(name.clone())
.or_insert_with(|| MemberNurseryEntry {
kind: member_kind,
getter: None,
setter: None,
});
let entry = self
.map
.entry(name.clone())
.or_insert_with(|| MemberNurseryEntry {
kind: member_kind,
getter: None,
setter: None,
});
// Validate that getter and setter have consistent member_kind
if entry.kind != member_kind && member_kind.is_some() && entry.kind.is_some() {
bail_span!(item_ident, "Member '{}' has inconsistent type specifications", name);
}
// If entry was created with None kind, allow later specification
if entry.kind.is_none() && member_kind.is_some() {
entry.kind = member_kind;
}
🤖 Prompt for AI Agents
In `@crates/derive-impl/src/pyclass.rs` around lines 1431 - 1438, The current
add_item logic inserts or reuses a MemberNurseryEntry but silently ignores a
differing member_kind when a getter and setter declare different types; update
add_item to validate that if an existing MemberNurseryEntry (from
self.map.entry(name)) has a different kind than the incoming member_kind you
detect the mismatch and emit a clear error/diagnostic (or return Err) rather
than silently overwriting/ignoring it. Locate the creation/lookup code around
MemberNurseryEntry and the map.entry(...) call in add_item, compare entry.kind
with the new member_kind, and produce a compile-time friendly failure that
references the member name and both kinds so the user can fix the
#[pymember(type="...")] mismatch.

@youknowone youknowone merged commit 111ced0 into RustPython:main Feb 1, 2026
14 checks passed
@youknowone youknowone deleted the pymember branch February 1, 2026 00:41
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