-
-
Notifications
You must be signed in to change notification settings - Fork 590
Fixes unique and equal checks #820
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
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -158,10 +158,46 @@ def ensure_list(thing): | |
return thing | ||
|
||
|
||
def dict_equal(one, two): | ||
""" | ||
Check if two dicts are the same using `equal` | ||
""" | ||
if len(one.keys()) != len(two.keys()): | ||
return False | ||
|
||
for key in one: | ||
if key not in two: | ||
return False | ||
if not equal(one[key], two[key]): | ||
return False | ||
|
||
return True | ||
|
||
|
||
def list_equal(one, two): | ||
""" | ||
Check if two lists are the same using `equal` | ||
""" | ||
if len(one) != len(two): | ||
return False | ||
|
||
for i in range(0, len(one)): | ||
if not equal(one[i], two[i]): | ||
return False | ||
|
||
return True | ||
|
||
|
||
def equal(one, two): | ||
""" | ||
Check if two things are equal, but evade booleans and ints being equal. | ||
""" | ||
if isinstance(one, list) and isinstance(two, list): | ||
return list_equal(one, two) | ||
|
||
if isinstance(one, dict) and isinstance(two, dict): | ||
return dict_equal(one, two) | ||
|
||
return unbool(one) == unbool(two) | ||
|
||
|
||
|
@@ -181,25 +217,27 @@ def uniq(container): | |
""" | ||
Check if all of a container's elements are unique. | ||
|
||
Successively tries first to rely that the elements are hashable, then | ||
falls back on them being sortable, and finally falls back on brute | ||
force. | ||
Successively tries first to rely that the elements are being sortable | ||
and finally falls back on brute force. | ||
""" | ||
|
||
try: | ||
return len(set(unbool(i) for i in container)) == len(container) | ||
except TypeError: | ||
try: | ||
sort = sorted(unbool(i) for i in container) | ||
sliced = itertools.islice(sort, 1, None) | ||
for i, j in zip(sort, sliced): | ||
if i == j: | ||
sort = sorted(unbool(i) for i in container) | ||
sliced = itertools.islice(sort, 1, None) | ||
|
||
for i, j in zip(sort, sliced): | ||
return not list_equal(list(i), list(j)) | ||
|
||
except (NotImplementedError, TypeError): | ||
seen = [] | ||
for e in container: | ||
e = unbool(e) | ||
|
||
for i in seen: | ||
if isinstance(i, dict) and isinstance(e, dict): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This line too I'm suspicious of if it still contains Let me know if that makes sense. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This has been removed and it makes use of the |
||
if dict_equal(i, e): | ||
return False | ||
elif i == e: | ||
return False | ||
except (NotImplementedError, TypeError): | ||
seen = [] | ||
for e in container: | ||
e = unbool(e) | ||
if e in seen: | ||
return False | ||
seen.append(e) | ||
|
||
seen.append(e) | ||
return True |
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 think this will now likely fail for triply-nested non-list containers.
It also will now do a lot of copying (every object will always be copied).
It's a bit better if we instead just use
isinstance(collections.Sequence
orcollections.Mapping
I suspect.But yeah please check the additional nesting, I suspect we need even better tests that uncover that. Really the nice thing would be a hypothesis test that generates arbitrarily nested containers which it puts
0
s andFalse
s inside and ensures they're always considered unique. If you know how to do that that'd be great, otherwise yeah I suspect at least another manual test is needed.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.
You are absolutely right, a tripple nesting caused new failures, this was related to the
equal
function where the behavior was not extended. I refactored the tests and added some more cases as I'm not really sure how to create a data generator here and I'm afraid this makes debugging harder.