Skip to content

Conversation

@danielballan
Copy link
Contributor

Cleaning up after my own mistakes...

This example reproduces the bug. It only affects the IPython "rich display" repr, so it is only noticeable in the notebook. IPython currently converts the TypeError into a warning, but it would be better if it worked!

class A:
    pass

a = A()
b = A()

cycler(a, [1,2]) + cycler(b, [3, 4])

@mdboom
Copy link
Member

mdboom commented Oct 21, 2015

What's the case in which the keys aren't sortable?

@WeatherGod
Copy link
Member

Looking at the codebase, I think this is the only place where we assume sortable keys. Indeed, I think this is a contrived usecase, but there is no other place in the code or documentation that says they have to be sortable.

The only issue is consistency of the output. The keys are stored in a set() object, so order isn't guaranteed at any point, so the output could keep changing, hence the sorting to keep it consistent.

@mdboom
Copy link
Member

mdboom commented Oct 21, 2015

My question just is: what keys wouldn't be sortable? Are they not always strings?

@danielballan
Copy link
Contributor Author

Good question. At BNL we use cycler to compose joint trajectories for motors. For example, I can scan two motors through a mesh like so:

cycler(motor1, [1, 2, 3]) * cycler(motor2, [4, 5, 6])

Clearly there is no sense of "orderability" to the motors, but this is still a useful application of cycler. I could have used a string representation of motor1 and motor2. Is there a reason that cycler shouldn't let me use the objects themselves?

@WeatherGod
Copy link
Member

no such restriction exists. They can be integers or anything else. They just must be hash-able. In fact, I even wrote a unit test with integers as keys to make sure that we didn't do keyword expansions in the codebase, IIRC.

cycler.py Outdated
Copy link
Member

Choose a reason for hiding this comment

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

What about:

sorted_keys = sorted(str(x) for x in self.keys)

that way they are sorted by their repr even if not sortable themselves...?

Copy link
Member

Choose a reason for hiding this comment

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

can't do that because the string representation aren't keys themselves. You would have to pass the string reprs as a key to sorted.

Copy link
Member

Choose a reason for hiding this comment

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

This approach would also help in situations where cyclers have mixed types for keys because in py3k, they would not be orderable as-is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is better. Are we all on board with @WeatherGod's refinement of the idea?

sorted(self.keys, key=repr)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah -- works for me.

Copy link
Member

Choose a reason for hiding this comment

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

my only concern is that are we guaranteed order between successive iterations through an unchanged set() object? So, if one makes a list of reprs from a set object, and then does zip(set_object, list_object), will the items pair up correctly every time?

I might be a little overly paranoid about things like that, though...

Copy link
Member

Choose a reason for hiding this comment

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

The iteration order should be fixed for a given set in a given processes. IIRC the iteration order is based on the internal hash of the key.

ss = set("this is a crazy test")
lss = list(ss)
assert all(map(lambda x: x[0] == x[1], zip(lss, ss)))

seems to work.

I am 20/80 on the repr fallback, The intent of this is to make the ordering stable run-to-run, but if you fall back to repr which may include a memory address which will be random anyway and the repr call is just over head.

On the other hand, this code path only happen when you display the cycler in a IPython notebook so the overhead does not matter and it does do the right thing if your reprs are good.

@WeatherGod
Copy link
Member

I think sorting by the string reprs of the keys is a good fall-back because it helps with ensuring consistent order of the output.

@tacaswell tacaswell added this to the v1.0 milestone Nov 16, 2015
tacaswell added a commit that referenced this pull request Feb 14, 2016
FIX: Do not fail _repr_html_ if keys are unorderable.
@tacaswell tacaswell merged commit 25e3ceb into matplotlib:master Feb 14, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants