Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Dec 28, 2025

Summary by CodeRabbit

  • Chores
    • Improved type object layout calculations and initialization logic for more accurate size computation and enhanced dictionary support handling during type creation.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 28, 2025

📝 Walkthrough

Walkthrough

These changes refine the Python type system's memory layout calculations and dict-handling logic. A new constant SIZEOF_PYOBJECT_HEAD is introduced to represent the base object header size, which is then used to correctly compute __basicsize__ for types. The type creation logic propagates itemsize from base types and adds conditional may_add_dict gating for dict-related flags. A new shape_differs helper function improves layout comparison between types.

Changes

Cohort / File(s) Summary
Type layout and size calculation
crates/vm/src/builtins/type.rs
__basicsize__ signature changed from const fn to regular fn; now returns SIZEOF_PYOBJECT_HEAD + self.slots.basicsize instead of just self.slots.basicsize. Added shape_differs() helper to compare layout differences between types. Updated solid_base() to use shape_differs() instead of inline size comparison. Added itemsize: base.slots.itemsize to heap type slot initialization.
Object header size constant
crates/vm/src/object/core.rs, crates/vm/src/object/mod.rs
Added crate-private constant SIZEOF_PYOBJECT_HEAD in core.rs computing size_of::<PyInner<()>>(). Re-exported via pub(crate) use in mod.rs.
Dict addition gating
crates/vm/src/builtins/type.rs
Introduced may_add_dict variable to gate HAS_DICT/MANAGED_DICT flag addition; condition now requires heaptype_slots.is_none() && may_add_dict in addition to existing add_dict path.
Documentation
crates/derive-impl/src/pyclass.rs
Minor inline comment added to generate_class_def describing alternative behavior when repr(transparent) with a base is not present.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • arihant2math

Poem

🐰 A rabbit hops through types with care,
Measuring headers here and there,
Layout diffs in shapes take flight,
Dict gates close, then open right—
Size by size, the code grows bright! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'impl basicsize' is vague and generic, using non-descriptive terminology that doesn't clearly convey what was implemented or changed regarding basicsize. Use a more descriptive title such as 'Add SIZEOF_PYOBJECT_HEAD constant and update PyType.basicsize calculation' to clearly explain the main changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee74713 and 63c3ba3.

⛔ Files ignored due to path filters (1)
  • Lib/test/test_types.py is excluded by !Lib/**
📒 Files selected for processing (4)
  • crates/derive-impl/src/pyclass.rs
  • crates/vm/src/builtins/type.rs
  • crates/vm/src/object/core.rs
  • crates/vm/src/object/mod.rs
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style by running cargo fmt to format Rust code
Always run clippy to lint code (cargo clippy) before completing tasks and fix any warnings or lints introduced by 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

Files:

  • crates/vm/src/object/mod.rs
  • crates/derive-impl/src/pyclass.rs
  • crates/vm/src/object/core.rs
  • crates/vm/src/builtins/type.rs
🔇 Additional comments (8)
crates/derive-impl/src/pyclass.rs (1)

456-463: LGTM! Documentation clarifies basicsize computation.

The updated comment accurately reflects that when repr(transparent) with a base is not present, basicsize stores only the payload size, and the SIZEOF_PYOBJECT_HEAD is added separately in the __basicsize__ getter. This aligns with the implementation changes in crates/vm/src/builtins/type.rs.

crates/vm/src/object/mod.rs (1)

10-10: LGTM! Appropriate crate-internal re-export.

The pub(crate) visibility correctly limits access to within the VM crate while making SIZEOF_PYOBJECT_HEAD available for internal basicsize calculations.

crates/vm/src/object/core.rs (1)

117-117: LGTM! Clean calculation of object header size.

Using std::mem::size_of::<PyInner<()>>() is an elegant way to compute the PyObject header size by measuring the struct with a zero-sized type payload. The pub(crate) visibility is appropriate for internal use in basicsize calculations.

crates/vm/src/builtins/type.rs (5)

1341-1352: LGTM! Correct gating logic for dict addition.

The may_add_dict guard properly prevents adding a dict when the primary base class already has one (checking !base.slots.flags.has_feature(PyTypeFlags::HAS_DICT)). The updated condition on line 1350 correctly combines:

  1. No __slots__ defined AND base doesn't have dict (automatic dict), OR
  2. __dict__ explicitly in __slots__

This matches CPython's behavior of checking tp_dictoffset == 0 on the base.


1354-1360: LGTM! Proper itemsize inheritance from base type.

Line 1358 correctly propagates itemsize from the base type during heap type creation. This is essential for correctly handling subclasses of variable-length types (e.g., tuple, list, bytes) where itemsize determines the per-element size.


2019-2022: LGTM! Clean helper for layout comparison.

The shape_differs function encapsulates layout comparison logic, checking both __basicsize__() (instance size) and itemsize (per-element size for variable-length types). This improves code readability and maintainability.


2024-2032: LGTM! Refactored to use shape_differs helper.

Line 2031 now uses the shape_differs helper for clearer intent. The logic remains equivalent: if the derived type has a different layout than its base, it becomes the solid base; otherwise, continue up the chain.


785-787: Remove unnecessary concern about const removal—the change is correct and has no breaking callers.

The removal of const from __basicsize__ is correct. The only usage in the codebase (line 2021 in shape_differs) is a normal runtime call. The #[pygetset] decorator indicates this is a Python property getter, which cannot be const. No existing code depends on this being a const fn.


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 marked this pull request as ready for review December 28, 2025 05:06
@youknowone youknowone merged commit f8199d7 into RustPython:main Dec 28, 2025
13 checks passed
@youknowone youknowone deleted the basicsize branch December 28, 2025 05:25
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