Browse Source

fix context manager to close, and properly handle closing...

Minor fix is allowing to use pathlib w/ Archive as well..

This also adds a basic test to make sure these features aren't
broken in the future..
master
John-Mark Gurney 2 years ago
parent
commit
f8ce7b22ee
3 changed files with 57 additions and 6 deletions
  1. BIN
      fixtures/testfile.tar.gz
  2. +8
    -6
      libarchive/__init__.py
  3. +49
    -0
      libarchive/tests.py

BIN
fixtures/testfile.tar.gz View File


+ 8
- 6
libarchive/__init__.py View File

@@ -200,7 +200,7 @@ class EntryReadStream(object):
return self

def __exit__(self, *args):
return
self.close()

def __iter__(self):
if self.closed:
@@ -438,6 +438,10 @@ class Archive(object):
self.encoding = encoding
self.blocksize = blocksize
self.password = password
try:
f = str(f)
except:
pass
if isinstance(f, str):
self.filename = f
f = open(f, mode)
@@ -493,7 +497,7 @@ class Archive(object):
return self

def __exit__(self, type, value, traceback):
self.denit()
self.close()

def __del__(self):
self.close()
@@ -543,9 +547,7 @@ class Archive(object):
if _defer:
# This call came from our open stream.
self._stream = None
if not self._defer_close:
# We are not yet ready to close.
return
return
if self._stream is not None:
# We have a stream open! don't close, but remember we were asked to.
self._defer_close = True
@@ -563,7 +565,7 @@ class Archive(object):
if hasattr(self.f, "fileno"):
os.fsync(self.f.fileno())
# and then close it, if we opened it...
if getattr(self, '_close', None):
if getattr(self.f, 'close', None):
self.f.close()

@property


+ 49
- 0
libarchive/tests.py View File

@@ -0,0 +1,49 @@
import hashlib
import libarchive
import pathlib
import unittest

_defaulthash = 'sha512'

def _readfp(fp):
while True:
r = fp.read(64*1024)
# libarchive returns None on EOF
if r == b'' or r is None:
return

yield r

def _hashfp(fp):
hash = getattr(hashlib, _defaulthash)()
for r in _readfp(fp):
hash.update(r)

return '%s:%s' % (_defaulthash, hash.hexdigest())


class TestArchive(unittest.TestCase):
def setUp(self):
self.fixtures = pathlib.Path(__file__).parent.parent / 'fixtures'

def test_closed(self):
fname = self.fixtures / 'testfile.tar.gz'

with libarchive.Archive(fname) as arch:
origfp = arch.f

hashes = []

for i in arch:
if not i.isfile():
continue

with arch.readstream(i.size) as fp:
hashes.append(_hashfp(fp))

self.assertTrue(fp.closed)
self.assertIsNone(arch._stream)

self.assertEqual(hashes, [ 'sha512:90f8342520f0ac57fb5a779f5d331c2fa87aa40f8799940257f9ba619940951e67143a8d746535ed0284924b2b7bc1478f095198800ba96d01847d7b56ca465c', 'sha512:7d5768d47b6bc27dc4fa7e9732cfa2de506ca262a2749cb108923e5dddffde842bbfee6cb8d692fb43aca0f12946c521cce2633887914ca1f96898478d10ad3f' ])

self.assertTrue(arch.f.closed)

Loading…
Cancel
Save