Make Timezone instances built via from_file() picklable - #1000
Open
afonsojanu wants to merge 1 commit into
Open
Conversation
get_local_timezone()'s last-resort fallback reads the raw zoneinfo file at /etc/localtime (or the value of TZ, when it points at a file) directly, since the system's timezone name couldn't be derived any other way. That goes through Timezone.from_file(), and the underlying zoneinfo.ZoneInfo.from_file() refuses to pickle any instance built that way, key or no key, since it has no record of which file it came from to reconstruct on unpickling. Attempting to pickle a DateTime carrying that tzinfo raises PicklingError: Cannot pickle a ZoneInfo file from a file stream. Timezone.from_file() now keeps the raw TZif bytes it read around on the instance, and __reduce__ uses them to rebuild an equivalent instance on unpickling instead of delegating to the version inherited from zoneinfo.ZoneInfo, which unconditionally rejects this. Instances built via the regular Timezone(key) constructor still pickle exactly as before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #899.
get_local_timezone()'s last-resort fallback reads the raw zoneinfo file at/etc/localtime(or the file theTZenvironment variable points at) directly, since the system's timezone name couldn't be derived any other way. That goes throughTimezone.from_file(), and the underlyingzoneinfo.ZoneInfo.from_file()refuses to pickle any instance built that way, key or no key, since it has no record of which file it came from to reconstruct on unpickling.This reproduces whenever the local timezone name can't be identified (as reported in the issue), so the local tzinfo ends up being one of these keyless, file-based instances.
Timezone.from_file()now keeps the raw TZif bytes it read around on the instance, and__reduce__uses them to rebuild an equivalent instance on unpickling instead of delegating to the version inherited fromzoneinfo.ZoneInfo, which unconditionally rejects this. Instances built via the regularTimezone(key)constructor still pickle exactly as before, by key.Added two tests covering both cases (keyless
from_file(), andfrom_file()with a key), using the raw TZif bytes from thetzdatapackage (already a dependency) so the test works the same on every platform, including Windows, which has no/usr/share/zoneinfoat all.