#5222 closed enhancement (not a bug)
core/state.py: Allow NamedTuples in bundle data
| Reported by: | Zach Pearson | Owned by: | Zach Pearson |
|---|---|---|---|
| Priority: | low | Milestone: | Ideas |
| Component: | Sessions | Version: | |
| Keywords: | Cc: | Greg Couch | |
| Blocked By: | Blocking: | ||
| Notify when closed: | Platform: | all | |
| Project: | ChimeraX |
Description
Would be good to have some way to register NamedTuples with _container_primitives from src/core/state.py. NamedTuples are instances of tuple.
Change History (6)
comment:1 by , 4 years ago
| Cc: | added |
|---|
comment:2 by , 4 years ago
comment:3 by , 4 years ago
I see, OK -- thanks!
We might be able to do a clever trick to simplify the Bundle API a litte here by using Python's inspect library.
To get a list of all the classes a module exposes publicly (i.e. that don't start with underscores) we can have a line:
[def_tuple for def_tuple in inspect.getmembers(sys.modules[__name__]) if inspect.isclass(def_tuple[1])]
With that in mind, in get_class:
def get_class(class_name): classes = {} for cls in [def_tuple for def_tuple in inspect.getmembers(sys.modules[__name__]) if inspect.isclass(def_tuple[1])]: classes[cls[0]] = cls[1] return classes.get(class_name, None)
If we made this the default behavior I wonder how many bundles would have to bother implementing get_class.
comment:4 by , 4 years ago
It would convenient, but no. The classes exported by a bundle via get_class have to be supported forever or else sessions can not restore. That needs to be an explicit API decision by the bundle writer, not automatically inferred.
And in the case of named tuples, I'd recommend not putting them in get_class. The more the session data can be make of just primitive data, the better. If there are no objects in the saved state data, then the FinalizedState hack can be used to speed up the saving and restoring of data because the data does not need to be scanned, and copied, to handle objects.
comment:5 by , 4 years ago
| Resolution: | → not a bug |
|---|---|
| Status: | assigned → closed |
OK, that makes sense. The only other suggestion I'd make would be to then use a class attribute that lists the supported classes and check class requests against it, but I don't think that's enough of an improvement over the status quo to put work into doing it.
My current workaround is to unpack the data into a regular tuple and repack it into the NamedTuple when the session gets restored -- but now that I know about the FinalizedState speed-up you mentioned that'll be a more deliberate decision in the future; I thought of it as more of a hack previously.
comment:6 by , 4 years ago
(in reverse order)
FinalizedState is a hack. I wish it weren't needed, but it makes saving and restoring atomic data reasonably quick as opposed to intolerably slow.
Your workaround is the right thing to do. It's same thing that needs to be done when reading/writing JSON from richer data structures.
I'm not sure how much we can standardize how get_class works. For example, not all classes saved in sessions derive from chimerax.core.state.State. See Session.register_snapshot_methods and bundles/graphics/src/gsession.py. And a bundle writer can use a class attribute if they wish.
You should not need to do this if the named tuple class is in the bundle's bundle_api's get_class method.