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
Improved (in)equality testing with non-boolean results #5533
Conversation
Thanks for following up! Initial tests for size difference gives:
That's very reasonable. |
…nto equal_non_bool_v2
@dpgeorge Something strange is happening with the test coverage. The new tests that I just added do cover the one line in |
Yeah, that happens sometimes. It seems that gcov is not always accurate with the lines it hits. I'll double check it though. |
I see that the check and warning for comparison between str and bytes is now gone. There is a test for this in IMO the check and warning should be retained. I don't think there's an elegant way to add it, I think there needs to be explicit tests in |
I've reinstated the warning for comparisons of strings and bytes. |
// fast path for strings | ||
if (mp_obj_is_str(o1)) { | ||
if (is_str_1 && is_str_2) { |
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.
Is this correct? I think it should be ||
not &&
... anyway, I can take it from here, I think I can make this a bit simpler.
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.
There's definitely something wrong either here or the line below. Let me investigate and fix before you merge.
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.
I've already fixed it and have done a few other clean ups.... I can push it as a new PR for further review.
See #5593 for a slightly reworked version of this PR. |
Improved shortcut cases for strings. Cleaned up indentation.
I only just saw your last comment after I pushed a fix with some other improvements. I'm happy to go with your version if you prefer. |
No worries. I'll see if your version of the string handling is smaller and work it in. |
int pass_number = 0; | ||
|
||
bool o2_shortcut = !(mp_obj_is_obj(o2) && | ||
(((mp_obj_base_t*)MP_OBJ_TO_PTR(o2))->type->flags & MP_TYPE_FLAG_NO_EQUALITY_SHORTCUTS)); |
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.
This doesn't work for object representations C&D where floats are not objects (they are inline values stored in the mp_obj_t
itself), so it fails the nan==nan
test (see nanbox failure on Travis).
Sounds good. Thanks very much @dpgeorge for the hard work of creating MicroPython in the first place! |
…r-4981 Reversal of PR micropython#4981
This is a version of #5479 which makes use of a new flag in the
flags
word ofmp_obj_type_t
to indicate if various shortcuts can not be used when performing equality and inequality tests, as per the comment in the discussion of that PR.The semantics of the new
TYPE_FLAG_NO_EQUALITY_SHORTCUTS
are that when this is clear (or uninitialised, in a static structure) the code can assume that this class (a) only ever returns a boolean result, (b) is reflexive, (c) only implements the__eq__
operator and not the__ne__
operator and (d) can not be equal to an instance of any different class that also has this flag clear. If the flag is set then at least one of these assumptions does not hold.Currently four built-in classes have the flag set:
float
andcomplex
are non-reflexive (sincenan != nan
) whilebytearray
andfrozenszet
instances can equal other builtin class instances (bytes
andset
respectively).The flag is set for any new class defined by the user. In the future, code could be added to analyse user-defined classes to see if either of the
__eq__
or__ne__
special methods are defined and clear the flag if both are absent in the class and all its superclasses.Adding the flag (and setting it for a few built-in classes) looks like it reduced the amount of code and it should now take the fast paths for most common cases, while further improving the compatibility with CPython behaviour.
The PR also expands the test cases to cover some cases that previously did not function as CPython did.