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

Fix comparison #104

Closed
wants to merge 3 commits into from
Closed

Fix comparison #104

wants to merge 3 commits into from

Conversation

scls19fr
Copy link
Member

Closes #102
Closes #103

Closes #102
Closes #103
semver.py Outdated
def _ensure_is_comparable(other):
comparable_types = (VersionInfo, dict, tuple)
if not isinstance(other, comparable_types):
raise NotImplementedError("other type %r must be in %r"
Copy link
Contributor

Choose a reason for hiding this comment

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

https://docs.python.org/3/library/constants.html#NotImplemented

You need to return NotImplemented here. Python itself will raise proper TypeError if objects aren't comparable.

Copy link
Member Author

Choose a reason for hiding this comment

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

semver.py Outdated
@@ -261,6 +257,13 @@ def _compare_by_keys(d1, d2):
return rccmp


def _ensure_is_comparable(other):
comparable_types = (VersionInfo, dict, tuple)
Copy link
Contributor

Choose a reason for hiding this comment

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

@ppkt made a good point about using interfaces in place of dict/tuple. This will allow us to compare with dict-like / tuple-like objects for free (well, not really, but nothing to care about).

The only thing is str - it's Iterable, but unlikely *str will give us what we really expected from it.

return NotImplemented
if not _is_comparable(other):
if PY2:
raise TypeError
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, but why? NotImplemented existed for Python 2.x as well and there rules are the same for it.

Copy link
Member Author

Choose a reason for hiding this comment

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

See previous build https://travis-ci.org/k-bx/python-semver/builds/404887965?utm_source=github_status&utm_medium=notification for Python 2.7 (see job)

even if NotImplemented existed for Python 2.x returning it doesn't raise TypeError (contrary to Python 3.x) and comparison wasn't returning a correct result.

Copy link
Member

Choose a reason for hiding this comment

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

No, NotImplemented in Py2.7 works in the same way: https://docs.python.org/2.7/library/constants.html#NotImplemented

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, Python 2.x swallows them and returns always True or False...or False in our case.

Copy link
Contributor

@kxepal kxepal Jul 17, 2018

Choose a reason for hiding this comment

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

I think, it would be better to move that check and behaviour difference into tests.

While it's good idea to keep same behaviour in both Pythons, Python 2.x world tells that every comparison ends with boolean result, so we would looks here like a rule breaker.

Raising TypeError for Python 2.x also breaks NotImplemented behavior when if a.__eq__(b) fails, Python tries to do b.__eq__(a) - by raising exception we drops the second and our behaviour in both Pythons still remains inconsistent.

@Flamefire Flamefire mentioned this pull request May 29, 2019
@scls19fr scls19fr closed this Jun 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants