3030import warnings
3131
3232from libarchive import _libarchive
33- try :
34- from cStringIO import StringIO
35- except ImportError :
36- from StringIO import StringIO
33+ from io import StringIO
34+
35+ PY3 = sys .version_info [0 ] == 3
3736
3837# Suggested block size for libarchive. Libarchive may adjust it.
3938BLOCK_SIZE = 10240
@@ -134,7 +133,7 @@ def is_archive_name(filename, formats=None):
134133 This function will return the name of the most likely archive format, None if the file is
135134 unlikely to be an archive.'''
136135 if formats is None :
137- formats = FORMAT_EXTENSIONS .values ()
136+ formats = list ( FORMAT_EXTENSIONS .values () )
138137 format , filter = guess_format (filename )
139138 if format in formats :
140139 return format
@@ -153,8 +152,8 @@ def is_archive(f, formats=(None, ), filters=(None, )):
153152
154153 This function will return True if the file can be opened as an archive using the given
155154 format(s)/filter(s).'''
156- if isinstance (f , basestring ):
157- f = file (f , 'r' )
155+ if isinstance (f , str ):
156+ f = open (f , 'r' )
158157 a = _libarchive .archive_read_new ()
159158 for format in formats :
160159 format = get_func (format , FORMATS , 0 )
@@ -175,6 +174,7 @@ def is_archive(f, formats=(None, ), filters=(None, )):
175174 finally :
176175 _libarchive .archive_read_close (a )
177176 _libarchive .archive_read_free (a )
177+ f .close ()
178178
179179
180180class EntryReadStream (object ):
@@ -271,7 +271,7 @@ def write(self, data):
271271 if self .buffer :
272272 self .buffer .write (data )
273273 else :
274- _libarchive .archive_write_data_from_str (self .archive ._a , data )
274+ _libarchive .archive_write_data_from_str (self .archive ._a , data . encode ( 'utf-8' ) )
275275 self .bytes += len (data )
276276
277277 def close (self ):
@@ -280,7 +280,7 @@ def close(self):
280280 if self .buffer :
281281 self .entry .size = self .buffer .tell ()
282282 self .entry .to_archive (self .archive )
283- _libarchive .archive_write_data_from_str (self .archive ._a , self .buffer .getvalue ())
283+ _libarchive .archive_write_data_from_str (self .archive ._a , self .buffer .getvalue (). encode ( 'utf-8' ) )
284284 _libarchive .archive_write_finish_entry (self .archive ._a )
285285
286286 # Call archive.close() with _defer True to let it know we have been
@@ -312,8 +312,13 @@ def from_archive(cls, archive, encoding=ENCODING):
312312 call_and_check (_libarchive .archive_read_next_header2 , archive ._a , archive ._a , e )
313313 mode = _libarchive .archive_entry_filetype (e )
314314 mode |= _libarchive .archive_entry_perm (e )
315- entry = cls (
315+ if PY3 :
316+ pathname = _libarchive .archive_entry_pathname (e )
317+ else :
316318 pathname = _libarchive .archive_entry_pathname (e ).decode (encoding ),
319+
320+ entry = cls (
321+ pathname = pathname ,
317322 size = _libarchive .archive_entry_size (e ),
318323 mtime = _libarchive .archive_entry_mtime (e ),
319324 mode = mode ,
@@ -330,7 +335,7 @@ def from_file(cls, f, entry=None, encoding=ENCODING):
330335 if entry is None :
331336 entry = cls (encoding = encoding )
332337 if entry .pathname is None :
333- if isinstance (f , basestring ):
338+ if isinstance (f , str ):
334339 st = os .stat (f )
335340 entry .pathname = f
336341 entry .size = st .st_size
@@ -353,7 +358,10 @@ def to_archive(self, archive):
353358 '''Creates an archive header and writes it to the given archive.'''
354359 e = _libarchive .archive_entry_new ()
355360 try :
356- _libarchive .archive_entry_set_pathname (e , self .pathname .encode (self .encoding ))
361+ if PY3 :
362+ _libarchive .archive_entry_set_pathname (e , self .pathname )
363+ else :
364+ _libarchive .archive_entry_set_pathname (e , self .pathname .encode (self .encoding ))
357365 _libarchive .archive_entry_set_filetype (e , stat .S_IFMT (self .mode ))
358366 _libarchive .archive_entry_set_perm (e , stat .S_IMODE (self .mode ))
359367 _libarchive .archive_entry_set_size (e , self .size )
@@ -390,9 +398,9 @@ def __init__(self, f, mode='r', format=None, filter=None, entry_class=Entry, enc
390398 self ._stream = None
391399 self .encoding = encoding
392400 self .blocksize = blocksize
393- if isinstance (f , basestring ):
401+ if isinstance (f , str ):
394402 self .filename = f
395- f = file (f , mode )
403+ f = open (f , mode )
396404 # Only close it if we opened it...
397405 self ._defer_close = True
398406 elif hasattr (f , 'fileno' ):
@@ -520,11 +528,11 @@ def read(self, size):
520528 def readpath (self , f ):
521529 '''Write current archive entry contents to file. f can be a file-like object or
522530 a path.'''
523- if isinstance (f , basestring ):
531+ if isinstance (f , str ):
524532 basedir = os .path .basename (f )
525533 if not os .path .exists (basedir ):
526534 os .makedirs (basedir )
527- f = file (f , 'w' )
535+ f = open (f , 'w' )
528536 return _libarchive .archive_read_data_into_fd (self ._a , f .fileno ())
529537
530538 def readstream (self , size ):
@@ -534,23 +542,26 @@ def readstream(self, size):
534542
535543 def write (self , member , data = None ):
536544 '''Writes a string buffer to the archive as the given entry.'''
537- if isinstance (member , basestring ):
545+ if isinstance (member , str ):
538546 member = self .entry_class (pathname = member , encoding = self .encoding )
539547 if data :
540548 member .size = len (data )
541549 member .to_archive (self )
542-
550+
543551 if data :
544- _libarchive .archive_write_data_from_str (self ._a , data )
552+ if PY3 :
553+ result = _libarchive .archive_write_data_from_str (self ._a , data .encode ('utf8' ))
554+ else :
555+ result = _libarchive .archive_write_data_from_str (self ._a , data )
545556 _libarchive .archive_write_finish_entry (self ._a )
546557
547558 def writepath (self , f , pathname = None , folder = False ):
548559 '''Writes a file to the archive. f can be a file-like object or a path. Uses
549560 write() to do the actual writing.'''
550561 member = self .entry_class .from_file (f , encoding = self .encoding )
551- if isinstance (f , basestring ):
562+ if isinstance (f , str ):
552563 if os .path .isfile (f ):
553- f = file (f , 'r' )
564+ f = open (f , 'r' )
554565 if pathname :
555566 member .pathname = pathname
556567 if folder and not member .isdir ():
@@ -587,8 +598,8 @@ def __init__(self, f, **kwargs):
587598 self ._stream = None
588599 # Convert file to open file. We need this to reopen the archive.
589600 mode = kwargs .setdefault ('mode' , 'r' )
590- if isinstance (f , basestring ):
591- f = file (f , mode )
601+ if isinstance (f , str ):
602+ f = open (f , mode )
592603 super (SeekableArchive , self ).__init__ (f , ** kwargs )
593604 self .entries = []
594605 self .eof = False
@@ -614,7 +625,11 @@ def reopen(self):
614625 def getentry (self , pathname ):
615626 '''Take a name or entry object and returns an entry object.'''
616627 for entry in self :
617- if entry .pathname == pathname :
628+ if PY3 :
629+ entry_pathname = entry .pathname
630+ if not PY3 :
631+ entry_pathname = entry .pathname [0 ]
632+ if entry_pathname == pathname :
618633 return entry
619634 raise KeyError (pathname )
620635
0 commit comments