Skip to content
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

add bound method variants for PyTypeInfo #3782

Merged
merged 1 commit into from
Feb 9, 2024

Conversation

davidhewitt
Copy link
Member

Part of #3684

This PR updates the PyTypeInfo and PyTypeCheck traits for the Bound API:

  • PyTypeCheck is new in 0.21 so I immediately made it take &Bound<'_, PyAny> without any backwards compatibility
  • PyTypeInfo has had new _bound method variants added for those which took or returned gil-refs. I added the usual deprecation warnings and migrated internal code to these new methods. (That makes up a fair chunk of this diff.)

@davidhewitt davidhewitt added the CI-skip-changelog Skip checking changelog entry label Jan 30, 2024
fn type_object(py: Python<'_>) -> &PyType {
unsafe { py.from_borrowed_ptr(Self::type_object_raw(py) as _) }
}

/// Returns the safe abstraction over the type object.
#[inline]
fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType> {
Copy link
Member Author

Choose a reason for hiding this comment

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

I considered whether to make type_object_bound, is_type_of_bound and is_exact_type_of_bound have defaults implemented in terms of their original methods (or vice versa).

Given that we don't expect users to be implementing PyTypeInfo, I decided it was probably simpler to just give them all defaults which match their final expected forms.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that the new methods should be implemented in their final form. Whats the reason not reimplementing the old API in terms of the new one?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a very good point, I will go ahead and do that 👍

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, there is one reason: type_object_bound now returns an owned Bound instead of a borrowed gil-ref, which I think is correct for the safety reasoning I express in the note below.

But is_type_of and is_exact_type_of can be implemented in terms of their new replacements 👍

Copy link

codspeed-hq bot commented Jan 30, 2024

CodSpeed Performance Report

Merging #3782 will degrade performances by 22.87%

Comparing davidhewitt:type-check-bound (367eeae) with main (9bb0011)

🎉 Hooray! codspeed-rust just leveled up to 2.3.3!

A heads-up, this is a breaking change and it might affect your current performance baseline a bit. But here's the exciting part - it's packed with new, cool features and promises improved result stability 🥳!
Curious about what's new? Visit our releases page to delve into all the awesome details about this new version.

Summary

⚡ 2 improvements
❌ 3 regressions
✅ 74 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark main davidhewitt:type-check-bound Change
not_a_list_via_downcast 272.2 ns 216.7 ns +25.64%
sequence_from_tuple 232.8 ns 260.6 ns -10.66%
list_via_extract 281.1 ns 364.4 ns -22.87%
sequence_from_list 300 ns 272.2 ns +10.2%
list_via_downcast 157.2 ns 185 ns -15.02%

fn type_object(py: Python<'_>) -> &PyType {
unsafe { py.from_borrowed_ptr(Self::type_object_raw(py) as _) }
}

/// Returns the safe abstraction over the type object.
#[inline]
fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that the new methods should be implemented in their final form. Whats the reason not reimplementing the old API in terms of the new one?

fn is_type_of(object: &PyAny) -> bool {
unsafe { ffi::PyObject_TypeCheck(object.as_ptr(), Self::type_object_raw(object.py())) != 0 }
}

/// Checks if `object` is an instance of this type or a subclass of this type.
#[inline]
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

is_bound_type_of might read a little nicer (maybe, not sure 🙃, maybe someone else has an opinion too ). Similarly for the others

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, I'm a bit stuck on that too. I don't really like either option, so my thinking was to stick with _bound as a suffix because that matches the majority of the other APIs...

Copy link
Contributor

Choose a reason for hiding this comment

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

I tend to agree, they both read a bit odd, so its probably better to stick with the system we've introduced

src/types/ellipsis.rs Outdated Show resolved Hide resolved
src/types/none.rs Outdated Show resolved Hide resolved
src/types/notimplemented.rs Outdated Show resolved Hide resolved
src/types/mod.rs Outdated Show resolved Hide resolved
@davidhewitt
Copy link
Member Author

Thanks for the review! I've given this a rebase and actioned all the feedback at the same time.

fn is_type_of(object: &PyAny) -> bool {
unsafe { ffi::PyObject_TypeCheck(object.as_ptr(), Self::type_object_raw(object.py())) != 0 }
}

/// Checks if `object` is an instance of this type or a subclass of this type.
#[inline]
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

I tend to agree, they both read a bit odd, so its probably better to stick with the system we've introduced

@davidhewitt davidhewitt added this pull request to the merge queue Feb 9, 2024
Merged via the queue into PyO3:main with commit b7fb9e6 Feb 9, 2024
36 of 38 checks passed
@davidhewitt davidhewitt deleted the type-check-bound branch February 9, 2024 21:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI-skip-changelog Skip checking changelog entry
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants