-
Notifications
You must be signed in to change notification settings - Fork 804
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
RFC: automatically implement equality and ordering using Eq and Ord #3195
Conversation
If we like this, I think we can do the same thing with |
I think we could land this first if it is easier to implement, but we should make sure that we do not block manually implementing Reading a comment from there and
I would actually prefer if this worked like
As a I am not sure though that the concerns w.r.t. |
As my role as local resident autoref specialization sceptic also seems to be a given, I'd also like to add that doing this opt-in would probably make that unnecessary as well? I would see that as a benefit because while autoref specialization is an ingenious trick, it is also a somewhat indirect/implicit method of realizing specialization that does make the code harder to maintain IMHO. |
I think I see both sides of the coin. I agree that opt-in feels more Rusty and avoids the compile overhead and maintenance complexity of the specialization. On the other hand, I think there's quite a strong argument that the user has already opted in by deriving or implementing these traits for a I think for me it may hinge what the solution for inheritance looks like. If we can only safely implement these methods in absence of insurance then the rules get very complicated for automatic implementation. If the inheritance cases can be cleanly handled by our automatic implementation then I think the bet that doing this automatically helps the user avoid the bug of forgetting to opt in is a strong motivator to me.
Great question. I suppose ordering-based containers in Rust have the same problem with interior mutability? So perhaps automatic |
Some(CompareOp::Eq) => Ok(PyBool::new(py, slf.eq(&other)).into_ptr()), | ||
Some(CompareOp::Ne) => Ok(PyBool::new(py, slf.ne(&other)).into_ptr()), | ||
Some(_) => Ok(py.NotImplemented().into_ptr()), | ||
None => unreachable!("invalid compareop"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just CompareOp::from_raw(op).expect("invalid compareop")
?
To me it mostly boils down to whether generated Rust and Python types should behave same (to the reasonable extent) or not. This is a philosophical question and I have no opinion nor strong preference about how it should be, so I won't assume it as a fact. If Rust and Python types should act identically, I think not only this PR should be merged, but also OTOH if they may behave differently, I don't think this PR is a good idea. It is still good to have a shortcut for deriving a Python
|
This is an interesting question. Overall I have had the philosophy that I am mostly in favour of not making On reflection about whether this automatic implementation should be merged - I think PyO3 may not be ready for this yet, though I would like us to still keep open about it in the future. I think merging the opt-in forms I think the clear next step is to complete #2089, as that's a clearly desirable addition and we'll then understand what implementation constraints we'd be working with for all of the possibilities discussed here. I'll try to get to that sometime in the near-ish future. |
I had a sudden insight today that we can automatically generate implementations of equality and ordering based on the presence of
Eq
andOrd
implementations for#[pyclass]
. (Note thatOrd: Eq
.) The implementation selects for these traits using autoderef specialization.I think this could be very convenient, but it has the potential to be breaking because existing types will suddenly have new behaviour in Python. If we went with this automatic implementation, we could land it in 0.20 with appropriate documentation.
I think at the very least we should have
#[pyclass(eq = false)]
and#[pyclass(order = false)]
opt-outs (names matching the same functionality in Python@dataclass
, although note the defaults here are notTrue
andFalse
respectively but instead based on whetherT
implementsEq
orOrd
).Design discussions:
false
, and requireeq = true
(andorder = true
) to opt-in to adding these implementations. This would be non-breaking but I think is not as nice for future usage.#[pyclass(extends = ...)]
and also ifT
is subclassed.__eq__
for pyclass #2089. Maybe it's better to land that first?