@@ -285,8 +285,10 @@ def ZipFile(*args, **kwargs):
285285 ZipFile = zipfile .ZipFile
286286
287287
288- def _get_handle (source , mode , encoding = None , compression = None , memory_map = False ):
289- """Gets file handle for given path and mode.
288+ def _get_handle (source , mode , encoding = None , compression = None ,
289+ memory_map = False ):
290+ """
291+ Get file handle for given path/buffer and mode.
290292 """
291293
292294 f = source
@@ -295,74 +297,72 @@ def _get_handle(source, mode, encoding=None, compression=None, memory_map=False)
295297 # in Python 3, convert BytesIO or fileobjects passed with an encoding
296298 if compat .PY3 and isinstance (source , compat .BytesIO ):
297299 from io import TextIOWrapper
298-
299300 return TextIOWrapper (source , encoding = encoding )
300301
301- elif compression is not None :
302+ elif compression :
302303 compression = compression .lower ()
303- if encoding is not None and not compat .PY3 and not is_path :
304- msg = 'encoding + compression not yet supported in Python 2'
304+
305+ if compat .PY2 and not is_path and encoding :
306+ msg = 'compression with encoding is not yet supported in Python 2'
305307 raise ValueError (msg )
306308
307309 # GZ Compression
308310 if compression == 'gzip' :
309311 import gzip
310-
311- f = gzip .GzipFile (source , mode ) \
312- if is_path else gzip .GzipFile (fileobj = source )
312+ if is_path :
313+ f = gzip .open (source , mode )
314+ else :
315+ f = gzip .GzipFile (fileobj = source )
313316
314317 # BZ Compression
315318 elif compression == 'bz2' :
316319 import bz2
317-
318320 if is_path :
319321 f = bz2 .BZ2File (source , mode )
320-
321- else :
322- f = bz2 .BZ2File (source ) if compat .PY3 else StringIO (
323- bz2 .decompress (source .read ()))
322+ elif compat .PY2 :
324323 # Python 2's bz2 module can't take file objects, so have to
325324 # run through decompress manually
325+ f = StringIO (bz2 .decompress (source .read ()))
326+ else :
327+ f = bz2 .BZ2File (source )
326328
327329 # ZIP Compression
328330 elif compression == 'zip' :
329- import zipfile
330331 zip_file = zipfile .ZipFile (source )
331- zip_names = zip_file .namelist ()
332-
333- if len (zip_names ) == 1 :
334- f = zip_file .open (zip_names .pop ())
335- elif len (zip_names ) == 0 :
336- raise ValueError ('Zero files found in ZIP file {}'
337- .format (source ))
338- else :
339- raise ValueError ('Multiple files found in ZIP file.'
340- ' Only one file per ZIP :{}'
341- .format (zip_names ))
332+ try :
333+ name , = zip_file .namelist ()
334+ except ValueError :
335+ msg = 'Zip file must contain exactly one file {}' .format (source )
336+ raise ValueError (msg )
337+ f = zip_file .open (zip_names .pop ())
342338
343339 # XZ Compression
344340 elif compression == 'xz' :
345341 lzma = compat .import_lzma ()
346342 f = lzma .LZMAFile (source , mode )
347-
343+
344+ # Unrecognized Compression
348345 else :
349- raise ValueError ('Unrecognized compression: %s' % compression )
346+ msg = 'Unrecognized compression: {}' .format (compression )
347+ raise ValueError (msg )
350348
349+ # In Python 3
351350 if compat .PY3 :
352351 from io import TextIOWrapper
353-
354352 f = TextIOWrapper (f , encoding = encoding )
355353
356354 return f
357355
358356 elif is_path :
359- if compat .PY3 :
360- if encoding :
361- f = open (source , mode , encoding = encoding )
362- else :
363- f = open (source , mode , errors = 'replace' )
364- else :
357+ if compat .PY2 :
358+ # Python 2
365359 f = open (source , mode )
360+ elif encoding :
361+ # Python 3 and encoding
362+ f = open (source , mode , encoding = encoding )
363+ else :
364+ # Python 3 and no explicit encoding
365+ f = open (source , mode , errors = 'replace' )
366366
367367 if memory_map and hasattr (f , 'fileno' ):
368368 try :
0 commit comments