-
Notifications
You must be signed in to change notification settings - Fork 763
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
Implement PartialEq
for more Bound<'py, T>
types
#4250
Comments
In #4245 we decided that (at least for strings) it was appropriate to proceed in the face of subclasses and document this case. It might be for the other types that we have to make a decision whether the subclass risk is too high, but I think probably it's fine. Also, labelling this as "good first issue" as each type can be implemented as a fairly small and straightforward PR. |
@davidhewitt I'm starting to look at this |
Super, thanks! |
@davidhewitt I had an idea related to this... What if we added a public pub trait PyPartialEq<'py, Other: ?Sized = Bound<'py, Self>>: Sized {
// users can impl this since `Bound` is more familiar
fn bound_eq(slf: &Bound<'py, Self>, other: &Other) -> bool;
// they could also override this if there's a better way
#[inline]
fn borrowed_eq(slf: &Borrowed<'_, 'py, Self>, other: &Other) -> bool {
Self::bound_eq(slf, other)
}
} and then we provide blanket impls such as: impl<'py, T, Other> PartialEq<Other> for Bound<'py, T>
where
T: PyPartialEq<'py, Other>
{
#[inline]
fn eq(&self, other: &Other) -> bool {
T::bound_eq(self, other)
}
}
impl<'a, 'py, T, Other> PartialEq<Other> for Borrowed<'a, 'py, T>
where
T: PyPartialEq<'py, Other>
{
#[inline]
fn eq(&self, other: &Other) -> bool {
T::borrowed_eq(self, other)
}
} This can be used internally to define the impls from #4245 and this issue, while also letting users implement For example the following would give us the impl<'py> PyPartialEq<'py, str> for PyString {
#[inline]
fn bound_eq(slf: &Bound<'py, Self>, other: &str) -> bool {
Self::borrowed_eq(&slf.as_borrowed(), other)
}
#[inline]
fn borrowed_eq(slf: &Borrowed<'_, 'py, Self>, other: &str) -> bool {
slf.to_cow().map_or(false, |s| s == *other)
}
} And the following would give a user impl<'py> PyPartialEq<'py> for MyClass {
fn bound_eq(slf: &Bound<'py, Self>, other: &Bound<'py, Self>) -> bool {
slf.borrow().value == other.borrow().value
}
} Another place this could be useful is to get an implementation of Some details about this would need to be ironed out, but I think the general concept would be pretty useful. |
I'm reluctant to add more traits as we have a lot already. I don't think this trait is good or useful enough for that. (also, there are a lot of traits in I wonder if we can we just have a blanket impl? Something like: impl<T: PartialEq> PartialEq for Bound<T> {
#[inline]
fn eq(&self, other: &Self) -> bool {
PartialEq::eq(self.get(), other)
}
} Regardless, I'd prefer we do this just for bytes and str and see how it works out in practice. We can consider more if there's a compelling use case or demand for them. |
IMO it shouldn't be an issue to add self-contained utility traits like this this that would give users more options without complicating existing mechanisms, but that's just me.
I think there's a small handful of obvious candidates (PartialEq, Add, Sub, Mul, Div), it certainly doesn't need to be exhaustive and wouldn't even need to include all 5 at first. But if a contributor has a use for
That impl would need a
Fair enough, I wasn't trying to imply that this needs to happen now. I just thought it was an interesting concept to propose while on the topic of expanding the collection of |
I'm somewhat wary of Rust traits for Python ops for a couple of reasons:
Given these two risks, it seems to me like the most reasonable best practice we can offer is the existing conveniences like |
Done in #4259 |
Hi there, can I get a review for my PR here ? Thanks |
After #4245 we have equality between Python
str
and Ruststr
, which I think is a nice user-facing feature.There's a possibility to go further here and implement this for more types:
PartialEq<[u8]>
forBound<'py, PyBytes>
seems to fit the same category of behaviourPartialEq<i32>
forBound<'py, PyLong>
, maybe? (And other int types)PartialEq<bool>
forBound<'py, PyBool>
?I think there's a reasonable case to be made that all of these can be implemented without risk of exception.
The main concern I have with these implementations is what to do with Python subclasses - as per #4245 (comment)
The text was updated successfully, but these errors were encountered: