Jason R. Coombs <jar...@jaraco.com> added the comment:

I'm a little surprised from Nick's original post that the behavior is 
triggered. After all, the code [already has a protection for a 
previously-closed 
zipfile](https://github.com/python/cpython/blob/0dd98c2d00a75efbec19c2ed942923981bc06683/Lib/zipfile.py#L1812-L1813)
 and that value is [unconditionally set during 
close](https://github.com/python/cpython/blob/0dd98c2d00a75efbec19c2ed942923981bc06683/Lib/zipfile.py#L1828).
 So how is it that Zipfile.__del__ is being called?

Jeffrey suggests that

> a copy of the zip_file object is getting created, probably by the Path 
> constructor

And indeed, I can confirm the ZipFile [state is copied into a new object 
here](https://github.com/python/cpython/blob/0dd98c2d00a75efbec19c2ed942923981bc06683/Lib/zipfile.py#L2202).
 The FastLookup and CompleteDirs functionality is for performance optimizations.

> I created a simpler test case that exercises the buggy code.

Although the simpler test does trigger the error, I'd argue that the error is 
_expected_ in this case and that the zip file will be invalid because 
`self._write_end_record` will never get called.

I expected this example to more accurately capture the failure:

```
import io
import zipfile
buf = io.BytesIO()
zf = zipfile.ZipFile(buf, mode='w')
zp = zipfile.Path(zf)
with zp.joinpath('zile-a').open('w') as fp:
    fp.write(b'contents of file-a')
zf.close()
zp.root.close()
```

But it does not. I'll need to do more investigation.

One option here is for `Path` to document that any zipfile passed to it is no 
longer valid and enforce that fact by disabling the original object passed to 
it.

Another approach could be to try to use an adapter pattern to adapt the 
original ZipFile rather than clone it into a subclass.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41350>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to