Skip to content

Commit

Permalink
Merge pull request #82 from parkerhancock/attempt_1
Browse files Browse the repository at this point in the history
create lazy loading lookup class to support pickling
  • Loading branch information
jaraco authored Oct 8, 2022
2 parents c3b5c4e + c017444 commit 952b20e
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
v3.9.0
======

* #81: ``Path`` objects are now pickleable if they've been
constructed from pickleable objects. Any restored objects
will re-construct the zip file with the original arguments.

v3.8.1
======

Expand Down
32 changes: 25 additions & 7 deletions test_zipp.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import tempfile
import shutil
import string
import pickle
import itertools

import jaraco.itertools
import func_timeout
Expand Down Expand Up @@ -74,13 +76,12 @@ def temp_dir():
shutil.rmtree(tmpdir)


pass_alpharep = parameterize(
['alpharep'],
[
Invoked.wrap(build_alpharep_fixture),
Invoked.wrap(compose(add_dirs, build_alpharep_fixture)),
],
)
alpharep_generators = [
Invoked.wrap(build_alpharep_fixture),
Invoked.wrap(compose(add_dirs, build_alpharep_fixture)),
]

pass_alpharep = parameterize(['alpharep'], alpharep_generators)


class TestPath(unittest.TestCase):
Expand Down Expand Up @@ -407,3 +408,20 @@ def test_inheritance(self, alpharep):
cls = type('PathChild', (zipp.Path,), {})
file = cls(alpharep).joinpath('some dir').parent
assert isinstance(file, cls)

@parameterize(
['alpharep', 'path_type', 'subpath'],
itertools.product(
alpharep_generators,
[str, pathlib.Path],
['', 'b/'],
),
)
def test_pickle(self, alpharep, path_type, subpath):
print(alpharep, path_type, subpath)
zipfile_ondisk = path_type(self.zipfile_ondisk(alpharep))

saved_1 = pickle.dumps(zipp.Path(zipfile_ondisk, at=subpath))
restored_1 = pickle.loads(saved_1)
first, *rest = restored_1.iterdir()
assert first.read_text().startswith('content of ')
20 changes: 19 additions & 1 deletion zipp.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,25 @@ def _difference(minuend, subtrahend):
return itertools.filterfalse(set(subtrahend).__contains__, minuend)


class CompleteDirs(zipfile.ZipFile):
class InitializedState:
"""
Mix-in to save the initialization state for pickling.
"""

def __init__(self, *args, **kwargs):
self.__args = args
self.__kwargs = kwargs
super().__init__(*args, **kwargs)

def __getstate__(self):
return self.__args, self.__kwargs

def __setstate__(self, state):
args, kwargs = state
super().__init__(*args, **kwargs)


class CompleteDirs(InitializedState, zipfile.ZipFile):
"""
A ZipFile subclass that ensures that implied directories
are always included in the namelist.
Expand Down

0 comments on commit 952b20e

Please sign in to comment.