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

Use PyMethodsImpl instead of *ProtocolImpl::methods #917

Merged
merged 1 commit into from
May 11, 2020

Conversation

kngwyu
Copy link
Member

@kngwyu kngwyu commented May 9, 2020

To reduce specialization.
We have two kinds of protocol methods.

  1. Slot methods. We have to set these methods to the type object. E.g., we have to set mp_length to enable len(obj).
  2. Normal methods, called PyMethods in our proc-macro implementation.

For the later one, we don't need to use specialization. We can use the same trick as #[pymethods].

#897 should be merged before this PR.
I'll add CHANGELOG later to make rebasing easier.

@@ -17,76 +17,7 @@ struct MyClass {
The above example generates implementations for [`PyTypeInfo`], [`PyTypeObject`],
and [`PyClass`] for `MyClass`.

Specifically, the following implementation is generated:
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 moved this code block to the last of the page.
It's too long for a user who doesn't have a strong interest in the implementation detail.

Copy link
Member

Choose a reason for hiding this comment

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

Good idea!

@kngwyu kngwyu added the blocked label May 9, 2020
Copy link
Member

@davidhewitt davidhewitt left a comment

Choose a reason for hiding this comment

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

Looking great, good to see ~400 lines reduction total!

One step closer to stable Rust 🎉

Comment on lines 211 to 214
/// To allow multiple #[pymethods] block, we define inventory types.
fn impl_methods_inventory(cls: &syn::Ident) -> TokenStream {
// Try to build a unique type for better error messages
let name = format!("Pyo3MethodsInventoryFor{}", cls);
Copy link
Member

Choose a reason for hiding this comment

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

Looking at the comment "The orphan rule disallows using a generic inventory struct..."

It might be possible now to achieve this, as Rust 1.41.0 relaxed orphan rules slightly: https://blog.rust-lang.org/2020/01/30/Rust-1.41.0.html#relaxed-restrictions-when-implementing-traits

So maybe we can have Pyo3MethodsInventory<MyClass>

Copy link
Member Author

Choose a reason for hiding this comment

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

What the above change made possible is impl<T> ForeignTrait<LocalType> for ForeignType<T>.
impl inventory::Collect for PyO3MethodsInventory<MyClass> is still impossible.

Copy link
Member

Choose a reason for hiding this comment

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

Ah yep you're correct 👍

@@ -57,53 +57,52 @@ fn impl_proto_impl(
ty: &syn::Type,
impls: &mut Vec<syn::ImplItem>,
proto: &defs::Proto,
) -> TokenStream {
let mut tokens = TokenStream::new();
) -> syn::Result<TokenStream> {
Copy link
Member

Choose a reason for hiding this comment

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

👍

ml_doc: ""
})
}
// TODO(kngwyu): doc
Copy link
Member

Choose a reason for hiding this comment

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

:)

}

/// Implementation detail. Only to be used through the proc macros.
/// Similar to `PyProtoMethodsImpl`, but for `#[pyproto]`.
Copy link
Member

Choose a reason for hiding this comment

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

"Similar to" looks wrong as it's listing the same type?

Copy link
Member Author

Choose a reason for hiding this comment

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

👍

src/pyclass.rs Outdated
@@ -73,7 +75,7 @@ pub unsafe fn tp_free_fallback(obj: *mut ffi::PyObject) {
/// The `#[pyclass]` attribute automatically implements this trait for your Rust struct,
/// so you don't have to use this trait directly.
pub trait PyClass:
PyTypeInfo<Layout = PyCell<Self>> + Sized + PyClassAlloc + PyMethodsImpl
PyTypeInfo<Layout = PyCell<Self>> + Sized + PyClassAlloc + PyMethodsImpl + PyProtoMethodsImpl
Copy link
Member

Choose a reason for hiding this comment

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

I'm trying to understand - why is it necessary to make a new PyProtoMethodsImpl rather than using PyMethodsImpl for all of these?

Copy link
Member Author

Choose a reason for hiding this comment

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

Technically we can reuse PyMethodsImpl but I felt it easier to understand to have two inventory types corresponding to #[pymethods] and #[pyproto].
Not so string reason, though.

Copy link
Member

Choose a reason for hiding this comment

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

As this isn't a user-facing API, I guess the only people who need to understand it are us. I probably have a preference for just one inventory type so that there's less code overall to understand, but happy if you prefer to keep it as two.

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 removed PyProtoMethodsImpl.

@kngwyu kngwyu changed the title Introduce PyProtoMethodsImpl and remove *ProtocolImpl::methods Use PyMethodsImpl instead of *ProtocolImpl::methods May 11, 2020
@kngwyu kngwyu removed the blocked label May 11, 2020
@kngwyu kngwyu merged commit 3e61a58 into PyO3:master May 11, 2020
@kngwyu kngwyu deleted the pymethods-nodefault branch May 11, 2020 11:36
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.

2 participants