Deal with __getstate__ methods#633
Conversation
…ait on the class)
| # ------------------------------------------------------------------------ | ||
| def __getstate__(self): | ||
| state = super(AbstractMapper, self).__getstate__() | ||
| for key in ["_cache_valid"]: |
There was a problem hiding this comment.
_cache_valid is not a trait on this class or any of its base classes
There was a problem hiding this comment.
sigh. but it is a trait on the subclasses e.g. Base1DMapper so those need to be updated
There was a problem hiding this comment.
Ah you are right. TBH I believe that all related traits should be transient even if they weren't perviously involved in a __getstate__method. For example other classes have _screen_cache_valid or _selection_cache_valid traits. I think I will update all of these (to be specific I am going to update any privately named cache trait) to be transient as I can't see why they shouldn't all be so
It also doesn't make sense that for some objects the _cache_valid and similar traits would be transient traits but on others not
|
|
||
| # The pointer to use when drawing a zoom box. | ||
| pointer = "magnifier" | ||
| pointer = Str("magnifier", transient=True) |
There was a problem hiding this comment.
This may be bad if pointer is meant to be a class attribute, similar to stack_index in plot_container.py.
I need to climb up the class hierarchy to see if it was previously defined as a trait. I remember Kit mentioning this being a point of confusion. I am not sure what the ideal way to avoid this confusion would be (aside from maybe a comment above saying if this is a class attribute or just setting a trait to a value. I guess if setting a trait to some value, you could do as I have done here? and explicitly do something like Str(___)
There was a problem hiding this comment.
As a quick sanity check, on master I defined a class attribute thing = "A" on SimpleZoom. I then ran:
from chaco.tools.simple_zoom import SimpleZoom
SimpleZoom.thing # I see 'A' printed
SimpleZoom.pointer # I get an error "type object 'SimpleZoom' has no attribute 'pointer'"
So, I believe the change made here is the right one
| "_max_index", | ||
| ]: | ||
| self.assertIn(key, state) | ||
| self.assertNotIn(key, state) |
There was a problem hiding this comment.
If not persisting they should not be in state, but if we are they should be. I believe these tests are doing what they are supposed to now
| if key in state: | ||
| del state[key] | ||
| if "stack_index" in state: | ||
| del state["stack_index"] |
There was a problem hiding this comment.
stack_index is a class attribute not a trait, so I believe this is still needed
rahulporuri
left a comment
There was a problem hiding this comment.
LGTM with a couple of comments
| # ------------------------------------------------------------------------ | ||
| def __getstate__(self): | ||
| state = super(AbstractMapper, self).__getstate__() | ||
| for key in ["_cache_valid"]: |
There was a problem hiding this comment.
sigh. but it is a trait on the subclasses e.g. Base1DMapper so those need to be updated
|
|
||
| def __getstate__(self): | ||
| state = super(LinePlot, self).__getstate__() | ||
| for key in ["traits_view"]: |
There was a problem hiding this comment.
Is traits_view a transient trait? I dont see anything in the code or in the documentation saying that it is.
There was a problem hiding this comment.
I was going off wha Corran said in this issue description: "This is removing the traits_view trait from the state - under normal Traits, this will never be in the state because of special handling of Views, so this whole method can be removed."
This should certainly be documented though
| "reset_zoom_key", | ||
| "prev_zoom_key", | ||
| "next_zoom_key", |
There was a problem hiding this comment.
im not sure where these traits were being magically defined
There was a problem hiding this comment.
me either, this is the only place I was seeing them in the codebase. Perhaps they once existed but had been removed
|
Looks like the CI failure on windows/pyqt from the test introduced by #636 is reproducible on every PR except the original (no idea how it didn't fail on 636). I also find the error quite confusing, as looking in enable, the |
|
|
||
| # Is the cached color data valid? | ||
| _colors_cache_valid = Bool(False) | ||
| _colors_cache_valid = Bool(False, transient=True) |
There was a problem hiding this comment.
If the cache valid flags arent transient, then the caches themselves should also be transient - _levels and _colors.
I would think HasTraits would ignore traits that are private i.e. that start an _. If that isn't the case, there are a lot more private traits that we will want to mark as transient.
There was a problem hiding this comment.
As you suggested, I printed state inside the ArrayDataSource.__getstate__ method on master and ran the test suite. I do see _ prefixed traits, eg _data, '_min_index', etc. So it looks like these need to be addressed
There was a problem hiding this comment.
If that isn't the case, there are a lot more private traits that we will want to mark as transient.
Does this mean all private traits be transient?
There was a problem hiding this comment.
As you suggested, I printed state inside the ArrayDataSource.getstate method on master and ran the test suite. I do see _ prefixed traits, eg _data, '_min_index', etc. So it looks like these need to be addressed
Sigh. I was afraid of that.
Does this mean all private traits be transient?
Let's not do that. Definitely not in this PR.
There was a problem hiding this comment.
So, I imagine the code will recreate the cache if a *cache* is False, which it is by default because we're marking it as a transient. So, I think we can ignore all of the traits that are recalculated based on the *cache* flag. - i.e. nothing actionable in this PR.
| # Cached list of line widths | ||
| _widths = List |
There was a problem hiding this comment.
looks like this is technically a cache but like I said earlier, this will be ignored/recomputed because the _widths_cache_valid trait is False - no action required, just pointing it out.
| # Is the tool always "on"? If True, left-clicking always initiates | ||
| # a zoom operation; if False, the user must press a key to enter zoom mode. |
There was a problem hiding this comment.
looks like you lost the #: because of the merge conflicts.
closes #583, #248
This PR rermoves uses of the
__getstate__method when it is not needed, and cleans up its use where it is.The
__setstate__methods can be dealt with in a follow up PR