From cdb7e6750acc5f110c3b41b6c60472d15a9c22ef Mon Sep 17 00:00:00 2001 From: Jessica Hair Date: Wed, 4 Dec 2019 15:15:44 -0500 Subject: [PATCH 01/16] Update to python 3 --- docs/conf.py | 12 ++++++------ libarchive/__init__.py | 22 +++++++++++----------- libarchive/tar.py | 4 ++-- libarchive/zip.py | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index fc804b3..3c30818 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -40,8 +40,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'python-libarchive' -copyright = u'2012, Ben Timby' +project = 'python-libarchive' +copyright = '2012, Ben Timby' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -178,8 +178,8 @@ htmlhelp_basename = 'python-libarchivedoc' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'python-libarchive.tex', u'python-libarchive Documentation', - u'Ben Timby', 'manual'), + ('index', 'python-libarchive.tex', 'python-libarchive Documentation', + 'Ben Timby', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -211,6 +211,6 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'python-libarchive', u'python-libarchive Documentation', - [u'Ben Timby'], 1) + ('index', 'python-libarchive', 'python-libarchive Documentation', + ['Ben Timby'], 1) ] diff --git a/libarchive/__init__.py b/libarchive/__init__.py index 7e4041b..205d7ae 100644 --- a/libarchive/__init__.py +++ b/libarchive/__init__.py @@ -31,9 +31,9 @@ import warnings from libarchive import _libarchive try: - from cStringIO import StringIO + from io import StringIO except ImportError: - from StringIO import StringIO + from io import StringIO # Suggested block size for libarchive. Libarchive may adjust it. BLOCK_SIZE = 10240 @@ -134,7 +134,7 @@ def is_archive_name(filename, formats=None): This function will return the name of the most likely archive format, None if the file is unlikely to be an archive.''' if formats is None: - formats = FORMAT_EXTENSIONS.values() + formats = list(FORMAT_EXTENSIONS.values()) format, filter = guess_format(filename) if format in formats: return format @@ -153,7 +153,7 @@ def is_archive(f, formats=(None, ), filters=(None, )): This function will return True if the file can be opened as an archive using the given format(s)/filter(s).''' - if isinstance(f, basestring): + if isinstance(f, str): f = file(f, 'r') a = _libarchive.archive_read_new() for format in formats: @@ -165,7 +165,7 @@ def is_archive(f, formats=(None, ), filters=(None, )): filter = get_func(filter, FILTERS, 0) if filter is None: return False - filter(a) + list(filter(a)) try: try: call_and_check(_libarchive.archive_read_open_fd, a, a, f.fileno(), BLOCK_SIZE) @@ -330,7 +330,7 @@ class Entry(object): if entry is None: entry = cls(encoding=encoding) if entry.pathname is None: - if isinstance(f, basestring): + if isinstance(f, str): st = os.stat(f) entry.pathname = f entry.size = st.st_size @@ -390,7 +390,7 @@ class Archive(object): self._stream = None self.encoding = encoding self.blocksize = blocksize - if isinstance(f, basestring): + if isinstance(f, str): self.filename = f f = file(f, mode) # Only close it if we opened it... @@ -520,7 +520,7 @@ class Archive(object): def readpath(self, f): '''Write current archive entry contents to file. f can be a file-like object or a path.''' - if isinstance(f, basestring): + if isinstance(f, str): basedir = os.path.basename(f) if not os.path.exists(basedir): os.makedirs(basedir) @@ -534,7 +534,7 @@ class Archive(object): def write(self, member, data=None): '''Writes a string buffer to the archive as the given entry.''' - if isinstance(member, basestring): + if isinstance(member, str): member = self.entry_class(pathname=member, encoding=self.encoding) if data: member.size = len(data) @@ -548,7 +548,7 @@ class Archive(object): '''Writes a file to the archive. f can be a file-like object or a path. Uses write() to do the actual writing.''' member = self.entry_class.from_file(f, encoding=self.encoding) - if isinstance(f, basestring): + if isinstance(f, str): if os.path.isfile(f): f = file(f, 'r') if pathname: @@ -587,7 +587,7 @@ class SeekableArchive(Archive): self._stream = None # Convert file to open file. We need this to reopen the archive. mode = kwargs.setdefault('mode', 'r') - if isinstance(f, basestring): + if isinstance(f, str): f = file(f, mode) super(SeekableArchive, self).__init__(f, **kwargs) self.entries = [] diff --git a/libarchive/tar.py b/libarchive/tar.py index dadd84e..773234f 100644 --- a/libarchive/tar.py +++ b/libarchive/tar.py @@ -76,14 +76,14 @@ class TarFile(SeekableArchive): def getnames(self): return list(self.iterpaths) - def next(self): + def __next__(self): raise NotImplementedError pass # TODO: how to do this? def extract(self, member, path=None): if path is None: path = os.getcwd() - if isinstance(member, basestring): + if isinstance(member, str): f = os.path.join(path, member) else: f = os.path.join(path, member.pathname) diff --git a/libarchive/zip.py b/libarchive/zip.py index 2fc32c0..053d712 100644 --- a/libarchive/zip.py +++ b/libarchive/zip.py @@ -23,7 +23,7 @@ class ZipEntry(Entry): return self.size def set_file_size(self, value): - assert isinstance(value, (int, long)), 'Please provide size as int or long.' + assert isinstance(value, int), 'Please provide size as int or long.' self.size = value file_size = property(get_file_size, set_file_size) From 950ef2c4b0561965c10e654b492a78337f0dee99 Mon Sep 17 00:00:00 2001 From: Jessica Hair Date: Wed, 4 Dec 2019 15:20:31 -0500 Subject: [PATCH 02/16] use open instead of file --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index aa04d82..0e54f82 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ versrel = version + '-' + release readme = 'README.rst' download_url = "http://" + name + ".googlecode.com/files/" + name + "-" + \ versrel + ".tar.gz" -long_description = file(readme).read() +long_description = open(readme).read() class build_ext_extra(build_ext, object): """ From 52b97691e0b6772d6de096f975d225d2313df1d7 Mon Sep 17 00:00:00 2001 From: Jessica Hair Date: Thu, 5 Dec 2019 14:37:06 -0500 Subject: [PATCH 03/16] Remove PyString and use PyUnicode --- libarchive/_libarchive.i | 2 +- libarchive/_libarchive_wrap.c | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/libarchive/_libarchive.i b/libarchive/_libarchive.i index d3d49b1..13b2474 100644 --- a/libarchive/_libarchive.i +++ b/libarchive/_libarchive.i @@ -360,7 +360,7 @@ extern const char *archive_error_string(struct archive *); %inline %{ PyObject *archive_read_data_into_str(struct archive *archive, int len) { PyObject *str = NULL; - if (!(str = PyString_FromStringAndSize(NULL, len))) { + if (!(str = PyUnicode_FromStringAndSize(NULL, len))) { PyErr_SetString(PyExc_MemoryError, "could not allocate string."); return NULL; } diff --git a/libarchive/_libarchive_wrap.c b/libarchive/_libarchive_wrap.c index c8c18bd..d7aba11 100644 --- a/libarchive/_libarchive_wrap.c +++ b/libarchive/_libarchive_wrap.c @@ -3274,11 +3274,7 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size) return pchar_descriptor ? SWIG_InternalNewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); } else { -#if PY_VERSION_HEX >= 0x03000000 - return PyUnicode_FromStringAndSize(carray, (int)(size)); -#else - return PyString_FromStringAndSize(carray, (int)(size)); -#endif +return PyUnicode_FromStringAndSize(carray, (int)(size)); } } else { return SWIG_Py_Void(); @@ -3342,7 +3338,7 @@ SWIG_AsVal_unsigned_SS_short (PyObject * obj, unsigned short *val) PyObject *archive_read_data_into_str(struct archive *archive, int len) { PyObject *str = NULL; - if (!(str = PyString_FromStringAndSize(NULL, len))) { + if (!(str = PyUnicode_FromStringAndSize(NULL, len))) { PyErr_SetString(PyExc_MemoryError, "could not allocate string."); return NULL; } From 2205c003d7c86946c3829a65658b1c57b4e37302 Mon Sep 17 00:00:00 2001 From: Jessica Hair Date: Thu, 5 Dec 2019 15:04:51 -0500 Subject: [PATCH 04/16] Use unicode instead of string in variable names --- libarchive/_libarchive_wrap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libarchive/_libarchive_wrap.c b/libarchive/_libarchive_wrap.c index d7aba11..644f7cb 100644 --- a/libarchive/_libarchive_wrap.c +++ b/libarchive/_libarchive_wrap.c @@ -739,7 +739,7 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { #define PyString_Size(str) PyBytes_Size(str) #define PyString_InternFromString(key) PyUnicode_InternFromString(key) #define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE -#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x) +#define PyString_AS_STRING(x) PyUnicode_AS_UNICODE(x) #define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) #endif From bfe92166e5475761d3484aab4817e77c21b99917 Mon Sep 17 00:00:00 2001 From: Jessica Hair Date: Fri, 13 Dec 2019 11:43:52 -0500 Subject: [PATCH 05/16] Use open instead of file --- libarchive/__init__.py | 10 +++++----- tests.py | 28 ++++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libarchive/__init__.py b/libarchive/__init__.py index 205d7ae..5bb0e1d 100644 --- a/libarchive/__init__.py +++ b/libarchive/__init__.py @@ -154,7 +154,7 @@ def is_archive(f, formats=(None, ), filters=(None, )): This function will return True if the file can be opened as an archive using the given format(s)/filter(s).''' if isinstance(f, str): - f = file(f, 'r') + f = open(f, 'r') a = _libarchive.archive_read_new() for format in formats: format = get_func(format, FORMATS, 0) @@ -392,7 +392,7 @@ class Archive(object): self.blocksize = blocksize if isinstance(f, str): self.filename = f - f = file(f, mode) + f = open(f, mode) # Only close it if we opened it... self._defer_close = True elif hasattr(f, 'fileno'): @@ -524,7 +524,7 @@ class Archive(object): basedir = os.path.basename(f) if not os.path.exists(basedir): os.makedirs(basedir) - f = file(f, 'w') + f = open(f, 'w') return _libarchive.archive_read_data_into_fd(self._a, f.fileno()) def readstream(self, size): @@ -550,7 +550,7 @@ class Archive(object): member = self.entry_class.from_file(f, encoding=self.encoding) if isinstance(f, str): if os.path.isfile(f): - f = file(f, 'r') + f = open(f, 'r') if pathname: member.pathname = pathname if folder and not member.isdir(): @@ -588,7 +588,7 @@ class SeekableArchive(Archive): # Convert file to open file. We need this to reopen the archive. mode = kwargs.setdefault('mode', 'r') if isinstance(f, str): - f = file(f, mode) + f = open(f, mode) super(SeekableArchive, self).__init__(f, **kwargs) self.entries = [] self.eof = False diff --git a/tests.py b/tests.py index 5439942..cb41d61 100644 --- a/tests.py +++ b/tests.py @@ -47,7 +47,7 @@ FILENAMES = [ def make_temp_files(): if not os.path.exists(ZIPPATH): for name in FILENAMES: - file(os.path.join(TMPDIR, name), 'w').write(''.join(random.sample(string.printable, 10))) + open(os.path.join(TMPDIR, name), 'w').write(''.join(random.sample(string.printable, 10))) def make_temp_archive(): @@ -99,7 +99,7 @@ class TestZipRead(unittest.TestCase): self.assertEqual(is_zipfile(ZIPPATH), True) def test_iterate(self): - f = file(ZIPPATH, mode='r') + f = open(ZIPPATH, mode='r') z = ZipFile(f, 'r') count = 0 for e in z: @@ -108,7 +108,7 @@ class TestZipRead(unittest.TestCase): def test_deferred_close_by_archive(self): """ Test archive deferred close without a stream. """ - f = file(ZIPPATH, mode='r') + f = open(ZIPPATH, mode='r') z = ZipFile(f, 'r') self.assertIsNotNone(z._a) self.assertIsNone(z._stream) @@ -117,7 +117,7 @@ class TestZipRead(unittest.TestCase): def test_deferred_close_by_stream(self): """ Ensure archive closes self if stream is closed first. """ - f = file(ZIPPATH, mode='r') + f = open(ZIPPATH, mode='r') z = ZipFile(f, 'r') stream = z.readstream(FILENAMES[0]) stream.close() @@ -131,7 +131,7 @@ class TestZipRead(unittest.TestCase): def test_close_stream_first(self): """ Ensure that archive stays open after being closed if a stream is open. Further, ensure closing the stream closes the archive. """ - f = file(ZIPPATH, mode='r') + f = open(ZIPPATH, mode='r') z = ZipFile(f, 'r') stream = z.readstream(FILENAMES[0]) z.close() @@ -146,7 +146,7 @@ class TestZipRead(unittest.TestCase): self.assertIsNone(z._stream) def test_filenames(self): - f = file(ZIPPATH, mode='r') + f = open(ZIPPATH, mode='r') z = ZipFile(f, 'r') names = [] for e in z: @@ -165,7 +165,7 @@ class TestZipWrite(unittest.TestCase): make_temp_files() def test_writepath(self): - f = file(ZIPPATH, mode='w') + f = open(ZIPPATH, mode='w') z = ZipFile(f, 'w') for fname in FILENAMES: z.writepath(file(os.path.join(TMPDIR, fname), 'r')) @@ -174,14 +174,14 @@ class TestZipWrite(unittest.TestCase): def test_writepath_directory(self): """ Test writing a directory. """ - f = file(ZIPPATH, mode='w') + f = open(ZIPPATH, mode='w') z = ZipFile(f, 'w') z.writepath(None, pathname='/testdir', folder=True) z.writepath(None, pathname='/testdir/testinside', folder=True) z.close() f.close() - f = file(ZIPPATH, mode='r') + f = open(ZIPPATH, mode='r') z = ZipFile(f, 'r') entries = z.infolist() @@ -192,11 +192,11 @@ class TestZipWrite(unittest.TestCase): f.close() def test_writestream(self): - f = file(ZIPPATH, mode='w') + f = open(ZIPPATH, mode='w') z = ZipFile(f, 'w') for fname in FILENAMES: full_path = os.path.join(TMPDIR, fname) - i = file(full_path) + i = open(full_path) o = z.writestream(fname) while True: data = i.read(1) @@ -208,11 +208,11 @@ class TestZipWrite(unittest.TestCase): z.close() def test_writestream_unbuffered(self): - f = file(ZIPPATH, mode='w') + f = open(ZIPPATH, mode='w') z = ZipFile(f, 'w') for fname in FILENAMES: full_path = os.path.join(TMPDIR, fname) - i = file(full_path) + i = open(full_path) o = z.writestream(fname, os.path.getsize(full_path)) while True: data = i.read(1) @@ -225,7 +225,7 @@ class TestZipWrite(unittest.TestCase): def test_deferred_close_by_archive(self): """ Test archive deferred close without a stream. """ - f = file(ZIPPATH, mode='w') + f = open(ZIPPATH, mode='w') z = ZipFile(f, 'w') o = z.writestream(FILENAMES[0]) z.close() From 311a559c9c27999bff8e138cdac03ec500db439c Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Fri, 13 Dec 2019 14:00:13 -0500 Subject: [PATCH 06/16] Fix compilation procedure --- libarchive/Makefile | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libarchive/Makefile b/libarchive/Makefile index ddc33eb..7e9b6bb 100644 --- a/libarchive/Makefile +++ b/libarchive/Makefile @@ -1,12 +1,8 @@ CFLAGS = -g INCLUDE = -I/usr/include -I. -LIBS = -L/usr/local/lib -l:libarchive.so.13.1.2 +LIBS = -larchive -#if PYTHON_VERSION -PYVER = $(PYTHON_VERSION) -#else -PYVER = 2.7 -#endif +PYVER ?= 2.7 all: __libarchive.so From 5013165958158e2d328531308c63d920ca445c7c Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 10:33:07 -0500 Subject: [PATCH 07/16] Fix tests for python 2 and 3 --- libarchive/__init__.py | 39 +++++++++++++------ libarchive/_libarchive_wrap.c | 17 +++++++-- tests.py | 71 +++++++++++++++++++++-------------- 3 files changed, 83 insertions(+), 44 deletions(-) diff --git a/libarchive/__init__.py b/libarchive/__init__.py index 5bb0e1d..8cd8f95 100644 --- a/libarchive/__init__.py +++ b/libarchive/__init__.py @@ -30,10 +30,9 @@ import time import warnings from libarchive import _libarchive -try: - from io import StringIO -except ImportError: - from io import StringIO +from io import StringIO + +PY3 = sys.version_info[0] == 3 # Suggested block size for libarchive. Libarchive may adjust it. BLOCK_SIZE = 10240 @@ -165,7 +164,7 @@ def is_archive(f, formats=(None, ), filters=(None, )): filter = get_func(filter, FILTERS, 0) if filter is None: return False - list(filter(a)) + filter(a) try: try: call_and_check(_libarchive.archive_read_open_fd, a, a, f.fileno(), BLOCK_SIZE) @@ -175,6 +174,7 @@ def is_archive(f, formats=(None, ), filters=(None, )): finally: _libarchive.archive_read_close(a) _libarchive.archive_read_free(a) + f.close() class EntryReadStream(object): @@ -271,7 +271,7 @@ class EntryWriteStream(object): if self.buffer: self.buffer.write(data) else: - _libarchive.archive_write_data_from_str(self.archive._a, data) + _libarchive.archive_write_data_from_str(self.archive._a, data.encode('utf-8')) self.bytes += len(data) def close(self): @@ -280,7 +280,7 @@ class EntryWriteStream(object): if self.buffer: self.entry.size = self.buffer.tell() self.entry.to_archive(self.archive) - _libarchive.archive_write_data_from_str(self.archive._a, self.buffer.getvalue()) + _libarchive.archive_write_data_from_str(self.archive._a, self.buffer.getvalue().encode('utf-8')) _libarchive.archive_write_finish_entry(self.archive._a) # Call archive.close() with _defer True to let it know we have been @@ -312,8 +312,13 @@ class Entry(object): call_and_check(_libarchive.archive_read_next_header2, archive._a, archive._a, e) mode = _libarchive.archive_entry_filetype(e) mode |= _libarchive.archive_entry_perm(e) - entry = cls( + if PY3: + pathname=_libarchive.archive_entry_pathname(e) + else: pathname=_libarchive.archive_entry_pathname(e).decode(encoding), + + entry = cls( + pathname=pathname, size=_libarchive.archive_entry_size(e), mtime=_libarchive.archive_entry_mtime(e), mode=mode, @@ -353,7 +358,10 @@ class Entry(object): '''Creates an archive header and writes it to the given archive.''' e = _libarchive.archive_entry_new() try: - _libarchive.archive_entry_set_pathname(e, self.pathname.encode(self.encoding)) + if PY3: + _libarchive.archive_entry_set_pathname(e, self.pathname) + else: + _libarchive.archive_entry_set_pathname(e, self.pathname.encode(self.encoding)) _libarchive.archive_entry_set_filetype(e, stat.S_IFMT(self.mode)) _libarchive.archive_entry_set_perm(e, stat.S_IMODE(self.mode)) _libarchive.archive_entry_set_size(e, self.size) @@ -539,9 +547,12 @@ class Archive(object): if data: member.size = len(data) member.to_archive(self) - + if data: - _libarchive.archive_write_data_from_str(self._a, data) + if PY3: + result = _libarchive.archive_write_data_from_str(self._a, data.encode('utf8')) + else: + result = _libarchive.archive_write_data_from_str(self._a, data) _libarchive.archive_write_finish_entry(self._a) def writepath(self, f, pathname=None, folder=False): @@ -614,7 +625,11 @@ class SeekableArchive(Archive): def getentry(self, pathname): '''Take a name or entry object and returns an entry object.''' for entry in self: - if entry.pathname == pathname: + if PY3: + entry_pathname = entry.pathname + if not PY3: + entry_pathname = entry.pathname[0] + if entry_pathname == pathname: return entry raise KeyError(pathname) diff --git a/libarchive/_libarchive_wrap.c b/libarchive/_libarchive_wrap.c index 644f7cb..1c4c9e0 100644 --- a/libarchive/_libarchive_wrap.c +++ b/libarchive/_libarchive_wrap.c @@ -739,7 +739,7 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { #define PyString_Size(str) PyBytes_Size(str) #define PyString_InternFromString(key) PyUnicode_InternFromString(key) #define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE -#define PyString_AS_STRING(x) PyUnicode_AS_UNICODE(x) +#define PyString_AS_STRING(x) PyBytes_AsString(x) #define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x) #endif @@ -3274,7 +3274,11 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size) return pchar_descriptor ? SWIG_InternalNewPointerObj((char *)(carray), pchar_descriptor, 0) : SWIG_Py_Void(); } else { -return PyUnicode_FromStringAndSize(carray, (int)(size)); +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_FromStringAndSize(carray, (int)(size)); +#else + return PyString_FromStringAndSize(carray, (int)(size)); +#endif } } else { return SWIG_Py_Void(); @@ -3338,10 +3342,17 @@ SWIG_AsVal_unsigned_SS_short (PyObject * obj, unsigned short *val) PyObject *archive_read_data_into_str(struct archive *archive, int len) { PyObject *str = NULL; - if (!(str = PyUnicode_FromStringAndSize(NULL, len))) { +#if PY_VERSION_HEX >= 0x03000000 + if (!(str = PyBytes_FromStringAndSize(NULL, len))) { PyErr_SetString(PyExc_MemoryError, "could not allocate string."); return NULL; } +#else + if (!(str = PyString_FromStringAndSize(NULL, len))) { + PyErr_SetString(PyExc_MemoryError, "could not allocate string."); + return NULL; + } +#endif if (len != archive_read_data(archive, PyString_AS_STRING(str), len)) { PyErr_SetString(PyExc_RuntimeError, "could not read requested data."); return NULL; diff --git a/tests.py b/tests.py index cb41d61..fa8cba8 100644 --- a/tests.py +++ b/tests.py @@ -26,11 +26,13 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import os, unittest, tempfile, random, string, subprocess +import os, unittest, tempfile, random, string, subprocess, sys from libarchive import is_archive_name, is_archive from libarchive.zip import is_zipfile, ZipFile, ZipEntry +PY3 = sys.version_info[0] == 3 + TMPDIR = tempfile.mkdtemp() ZIPCMD = '/usr/bin/zip' ZIPFILE = 'test.zip' @@ -47,7 +49,8 @@ FILENAMES = [ def make_temp_files(): if not os.path.exists(ZIPPATH): for name in FILENAMES: - open(os.path.join(TMPDIR, name), 'w').write(''.join(random.sample(string.printable, 10))) + with open(os.path.join(TMPDIR, name), 'w') as f: + f.write(''.join(random.sample(string.ascii_letters, 10))) def make_temp_archive(): @@ -93,14 +96,17 @@ class TestIsArchiveTar(unittest.TestCase): class TestZipRead(unittest.TestCase): def setUp(self): make_temp_archive() + self.f = open(ZIPPATH, mode='r') + + def tearDown(self): + self.f.close() def test_iszipfile(self): self.assertEqual(is_zipfile('/dev/null'), False) self.assertEqual(is_zipfile(ZIPPATH), True) def test_iterate(self): - f = open(ZIPPATH, mode='r') - z = ZipFile(f, 'r') + z = ZipFile(self.f, 'r') count = 0 for e in z: count += 1 @@ -108,8 +114,7 @@ class TestZipRead(unittest.TestCase): def test_deferred_close_by_archive(self): """ Test archive deferred close without a stream. """ - f = open(ZIPPATH, mode='r') - z = ZipFile(f, 'r') + z = ZipFile(self.f, 'r') self.assertIsNotNone(z._a) self.assertIsNone(z._stream) z.close() @@ -117,8 +122,7 @@ class TestZipRead(unittest.TestCase): def test_deferred_close_by_stream(self): """ Ensure archive closes self if stream is closed first. """ - f = open(ZIPPATH, mode='r') - z = ZipFile(f, 'r') + z = ZipFile(self.f, 'r') stream = z.readstream(FILENAMES[0]) stream.close() # Make sure archive stays open after stream is closed. @@ -131,8 +135,7 @@ class TestZipRead(unittest.TestCase): def test_close_stream_first(self): """ Ensure that archive stays open after being closed if a stream is open. Further, ensure closing the stream closes the archive. """ - f = open(ZIPPATH, mode='r') - z = ZipFile(f, 'r') + z = ZipFile(self.f, 'r') stream = z.readstream(FILENAMES[0]) z.close() try: @@ -146,11 +149,13 @@ class TestZipRead(unittest.TestCase): self.assertIsNone(z._stream) def test_filenames(self): - f = open(ZIPPATH, mode='r') - z = ZipFile(f, 'r') + z = ZipFile(self.f, 'r') names = [] for e in z: - names.append(e.filename) + if PY3: + names.append(e.filename) + else: + names.append(e.filename[0]) self.assertEqual(names, FILENAMES, 'File names differ in archive.') #~ def test_non_ascii(self): @@ -163,23 +168,25 @@ class TestZipRead(unittest.TestCase): class TestZipWrite(unittest.TestCase): def setUp(self): make_temp_files() + self.f = open(ZIPPATH, mode='w') + + def tearDown(self): + self.f.close() def test_writepath(self): - f = open(ZIPPATH, mode='w') - z = ZipFile(f, 'w') + z = ZipFile(self.f, 'w') for fname in FILENAMES: - z.writepath(file(os.path.join(TMPDIR, fname), 'r')) + with open(os.path.join(TMPDIR, fname), 'r') as f: + z.writepath(f) z.close() def test_writepath_directory(self): """ Test writing a directory. """ - - f = open(ZIPPATH, mode='w') - z = ZipFile(f, 'w') + z = ZipFile(self.f, 'w') z.writepath(None, pathname='/testdir', folder=True) z.writepath(None, pathname='/testdir/testinside', folder=True) z.close() - f.close() + self.f.close() f = open(ZIPPATH, mode='r') z = ZipFile(f, 'r') @@ -192,8 +199,7 @@ class TestZipWrite(unittest.TestCase): f.close() def test_writestream(self): - f = open(ZIPPATH, mode='w') - z = ZipFile(f, 'w') + z = ZipFile(self.f, 'w') for fname in FILENAMES: full_path = os.path.join(TMPDIR, fname) i = open(full_path) @@ -202,14 +208,16 @@ class TestZipWrite(unittest.TestCase): data = i.read(1) if not data: break - o.write(data) + if PY3: + o.write(data) + else: + o.write(unicode(data)) o.close() i.close() z.close() def test_writestream_unbuffered(self): - f = open(ZIPPATH, mode='w') - z = ZipFile(f, 'w') + z = ZipFile(self.f, 'w') for fname in FILENAMES: full_path = os.path.join(TMPDIR, fname) i = open(full_path) @@ -218,20 +226,25 @@ class TestZipWrite(unittest.TestCase): data = i.read(1) if not data: break - o.write(data) + if PY3: + o.write(data) + else: + o.write(unicode(data)) o.close() i.close() z.close() def test_deferred_close_by_archive(self): """ Test archive deferred close without a stream. """ - f = open(ZIPPATH, mode='w') - z = ZipFile(f, 'w') + z = ZipFile(self.f, 'w') o = z.writestream(FILENAMES[0]) z.close() self.assertIsNotNone(z._a) self.assertIsNotNone(z._stream) - o.write('testdata') + if PY3: + o.write('testdata') + else: + o.write(unicode('testdata')) o.close() self.assertIsNone(z._a) self.assertIsNone(z._stream) From 7dd5e87bdf4d37bd07de148854091e5ad2d81bee Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 10:33:58 -0500 Subject: [PATCH 08/16] Ignore built binary --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index e46e449..0bcc3a1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ venv build libarchive/__libarchive.so +libarchive/_libarchive_wrap.o python_libarchive.egg-info From 8c7a3bad153df422252f29f0fffb317a37f38918 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 10:34:12 -0500 Subject: [PATCH 09/16] Run tests for python 2 and 3 --- .travis.yml | 13 +++++++------ Makefile | 6 ++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 425a5c3..e2d474b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,15 @@ language: python -python: - - "2.7" -env: - - DJANGO=1.3 - - DJANGO=1.4 +jobs: + include: + - python: "2.7" + env: PYVER=2.7 + - python: "3.6" + env: PYVER=3.6 before_install: - sudo apt-get update -qq - sudo apt-get install -qq libarchive-dev install: - - pip install . + - make build script: - make test notifications: diff --git a/Makefile b/Makefile index 0b9ca94..d941090 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,6 @@ +build: + make -C libarchive + test: python tests.py @@ -11,3 +14,6 @@ install: publish: python setup.py register python setup.py sdist upload + +clean: + make -C libarchive clean From bf44649ce82722b5cb3b0a97b1868fb4acb6f5dd Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 11:11:23 -0500 Subject: [PATCH 10/16] Specify exact python version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e2d474b..0196f87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ jobs: - python: "2.7" env: PYVER=2.7 - python: "3.6" - env: PYVER=3.6 + env: PYVER=3.6.7 before_install: - sudo apt-get update -qq - sudo apt-get install -qq libarchive-dev From a823504ba2ea459c30d61f768b7dab1244f62e9c Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 11:14:18 -0500 Subject: [PATCH 11/16] Revert "Specify exact python version" This reverts commit bf44649ce82722b5cb3b0a97b1868fb4acb6f5dd. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0196f87..e2d474b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ jobs: - python: "2.7" env: PYVER=2.7 - python: "3.6" - env: PYVER=3.6.7 + env: PYVER=3.6 before_install: - sudo apt-get update -qq - sudo apt-get install -qq libarchive-dev From a2fe91f8cf1a95ad8c5262df1c831cc799b734bc Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 11:15:03 -0500 Subject: [PATCH 12/16] Install python development libraries --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e2d474b..2f49a20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ jobs: env: PYVER=3.6 before_install: - sudo apt-get update -qq - - sudo apt-get install -qq libarchive-dev + - sudo apt-get install -qq libarchive-dev python3-dev install: - make build script: From d4d0c7051526fa8cbd007b0e62ff150f7c6fb400 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 11:17:21 -0500 Subject: [PATCH 13/16] Revert "Install python development libraries" This reverts commit a2fe91f8cf1a95ad8c5262df1c831cc799b734bc. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2f49a20..e2d474b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ jobs: env: PYVER=3.6 before_install: - sudo apt-get update -qq - - sudo apt-get install -qq libarchive-dev python3-dev + - sudo apt-get install -qq libarchive-dev install: - make build script: From a80410112c7892aedbbe19feeabdf53b8ad3dd9c Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 11:20:31 -0500 Subject: [PATCH 14/16] Setup pyenv environment --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index e2d474b..dade59a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ jobs: before_install: - sudo apt-get update -qq - sudo apt-get install -qq libarchive-dev + - pyenv shell $PYTHON install: - make build script: From 8d95a43216a14c5ad1056d03543cf5e142f6adc1 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 11:24:15 -0500 Subject: [PATCH 15/16] Use correct travis variable --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dade59a..a6ab0c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ jobs: before_install: - sudo apt-get update -qq - sudo apt-get install -qq libarchive-dev - - pyenv shell $PYTHON + - pyenv shell $TRAVIS_PYTHON_VERSION install: - make build script: From d37e6b06b51841638feb93d11363ade519eef4e0 Mon Sep 17 00:00:00 2001 From: Clifton Barnes Date: Tue, 17 Dec 2019 11:31:20 -0500 Subject: [PATCH 16/16] Use version from python --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a6ab0c5..62200c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ jobs: before_install: - sudo apt-get update -qq - sudo apt-get install -qq libarchive-dev - - pyenv shell $TRAVIS_PYTHON_VERSION + - pyenv shell $(python -c 'import platform; print(platform.python_version())') install: - make build script: