Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork938
Description
AGit
instance produced by pickle deserialization always has aversion_info
ofNone
. This prevents version information from being accessed throughversion_info
. It also causes theversion_info
property not to satisfy its type annotation as a tuple ofint
s (independently of#1830). This is the case whether or notversion_info
has been accessed on the original instance before it was pickled:
>>>importpickle,git>>>g=git.Git()>>>g.version_info(2,34,1)>>>g2=pickle.loads(pickle.dumps(g))>>>g2.version_info>>>
>>>importpickle,git>>>g=git.Git()>>>g2=pickle.loads(pickle.dumps(g))>>>g2.version_info>>>
This is due to an inconsistency in how the state of not yet having computedversion_info
is represented in the backing attribute_version_info
:
Git
usesLazyMixin
caching for_version_info
, which treats the attribute as uncomputed when absent and computed when present.Git
defines__getstate__
and__setstate__
for pickling and unpickling to represent state pickling does not preserve by setting attributes toNone
.
The_version_info
attribute is set toNone
on aGit
object created by unpickling, so when accessing theversion_info
property delegates to the_version_info
attribute, its value ofNone
is returned and theif attr == "_version_info"
logic in the_set_cache_
method (inherited fromLazyMixin
and overridden) is never run.
The intention is that an unpickledGit
object haveversion_info
in the uncomputed state. This works for the other two excluded attributes, which use the sameNone
convention as in the__getstate__
and__setstate__
implementations, and which do not use anyLazyMixin
functionality for their caching:
Line 315 inafa5754
_excluded_= ("cat_file_all","cat_file_header","_version_info") |
Lines 319 to 323 inafa5754
def__getstate__(self)->Dict[str,Any]: | |
returnslots_to_dict(self,exclude=self._excluded_) | |
def__setstate__(self,d:Dict[str,Any])->None: | |
dict_to_slots_and__excluded_are_none(self,d,excluded=self._excluded_) |
Unlike_version_info
, which is managed by_set_cache_
, thecat_file_all
andcat_file_header
attributes are initialized toNone
inGit.__init__
:
Lines 786 to 788 inafa5754
# Cached command slots | |
self.cat_file_header:Union[None,TBD]=None | |
self.cat_file_all:Union[None,TBD]=None |
This is natural to fix at the same time as#1829, because a fix for that should change the way caching works.LazyMixin
caching supports attributes that are computed once and never become stale, soversion_info
/_version_info
should implement caching in a different way to fix#1829, and that can fix this too if consistent with__getstate__
/__setstate__
.