@@ -287,8 +287,10 @@ def ZipFile(*args, **kwargs):
287287 ZipFile = zipfile .ZipFile
288288
289289
290- def _get_handle (source , mode , encoding = None , compression = None , memory_map = False ):
291- """Gets file handle for given path and mode.
290+ def _get_handle (source , mode , encoding = None , compression = None ,
291+ memory_map = False ):
292+ """
293+ Get file handle for given path/buffer and mode.
292294 """
293295
294296 f = source
@@ -297,74 +299,72 @@ def _get_handle(source, mode, encoding=None, compression=None, memory_map=False)
297299 # in Python 3, convert BytesIO or fileobjects passed with an encoding
298300 if compat .PY3 and isinstance (source , compat .BytesIO ):
299301 from io import TextIOWrapper
300-
301302 return TextIOWrapper (source , encoding = encoding )
302303
303- elif compression is not None :
304+ elif compression :
304305 compression = compression .lower ()
305- if encoding is not None and not compat .PY3 and not is_path :
306- msg = 'encoding + compression not yet supported in Python 2'
306+
307+ if compat .PY2 and not is_path and encoding :
308+ msg = 'compression with encoding is not yet supported in Python 2'
307309 raise ValueError (msg )
308310
309311 # GZ Compression
310312 if compression == 'gzip' :
311313 import gzip
312-
313- f = gzip .GzipFile (source , mode ) \
314- if is_path else gzip .GzipFile (fileobj = source )
314+ if is_path :
315+ f = gzip .open (source , mode )
316+ else :
317+ f = gzip .GzipFile (fileobj = source )
315318
316319 # BZ Compression
317320 elif compression == 'bz2' :
318321 import bz2
319-
320322 if is_path :
321323 f = bz2 .BZ2File (source , mode )
322-
323- else :
324- f = bz2 .BZ2File (source ) if compat .PY3 else StringIO (
325- bz2 .decompress (source .read ()))
324+ elif compat .PY2 :
326325 # Python 2's bz2 module can't take file objects, so have to
327326 # run through decompress manually
327+ f = StringIO (bz2 .decompress (source .read ()))
328+ else :
329+ f = bz2 .BZ2File (source )
328330
329331 # ZIP Compression
330332 elif compression == 'zip' :
331- import zipfile
332333 zip_file = zipfile .ZipFile (source )
333- zip_names = zip_file .namelist ()
334-
335- if len (zip_names ) == 1 :
336- f = zip_file .open (zip_names .pop ())
337- elif len (zip_names ) == 0 :
338- raise ValueError ('Zero files found in ZIP file {}'
339- .format (source ))
340- else :
341- raise ValueError ('Multiple files found in ZIP file.'
342- ' Only one file per ZIP :{}'
343- .format (zip_names ))
334+ try :
335+ name , = zip_file .namelist ()
336+ except ValueError :
337+ msg = 'Zip file must contain exactly one file {}' .format (source )
338+ raise ValueError (msg )
339+ f = zip_file .open (zip_names .pop ())
344340
345341 # XZ Compression
346342 elif compression == 'xz' :
347343 lzma = compat .import_lzma ()
348344 f = lzma .LZMAFile (source , mode )
349-
345+
346+ # Unrecognized Compression
350347 else :
351- raise ValueError ('Unrecognized compression: %s' % compression )
348+ msg = 'Unrecognized compression: {}' .format (compression )
349+ raise ValueError (msg )
352350
351+ # In Python 3
353352 if compat .PY3 :
354353 from io import TextIOWrapper
355-
356354 f = TextIOWrapper (f , encoding = encoding )
357355
358356 return f
359357
360358 elif is_path :
361- if compat .PY3 :
362- if encoding :
363- f = open (source , mode , encoding = encoding )
364- else :
365- f = open (source , mode , errors = 'replace' )
366- else :
359+ if compat .PY2 :
360+ # Python 2
367361 f = open (source , mode )
362+ elif encoding :
363+ # Python 3 and encoding
364+ f = open (source , mode , encoding = encoding )
365+ else :
366+ # Python 3 and no explicit encoding
367+ f = open (source , mode , errors = 'replace' )
368368
369369 if memory_map and hasattr (f , 'fileno' ):
370370 try :
0 commit comments