@@ -285,8 +285,10 @@ def ZipFile(*args, **kwargs):
285
285
ZipFile = zipfile .ZipFile
286
286
287
287
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.
290
292
"""
291
293
292
294
f = source
@@ -295,74 +297,72 @@ def _get_handle(source, mode, encoding=None, compression=None, memory_map=False)
295
297
# in Python 3, convert BytesIO or fileobjects passed with an encoding
296
298
if compat .PY3 and isinstance (source , compat .BytesIO ):
297
299
from io import TextIOWrapper
298
-
299
300
return TextIOWrapper (source , encoding = encoding )
300
301
301
- elif compression is not None :
302
+ elif compression :
302
303
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'
305
307
raise ValueError (msg )
306
308
307
309
# GZ Compression
308
310
if compression == 'gzip' :
309
311
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 )
313
316
314
317
# BZ Compression
315
318
elif compression == 'bz2' :
316
319
import bz2
317
-
318
320
if is_path :
319
321
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 :
324
323
# Python 2's bz2 module can't take file objects, so have to
325
324
# run through decompress manually
325
+ f = StringIO (bz2 .decompress (source .read ()))
326
+ else :
327
+ f = bz2 .BZ2File (source )
326
328
327
329
# ZIP Compression
328
330
elif compression == 'zip' :
329
- import zipfile
330
331
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 ())
342
338
343
339
# XZ Compression
344
340
elif compression == 'xz' :
345
341
lzma = compat .import_lzma ()
346
342
f = lzma .LZMAFile (source , mode )
347
-
343
+
344
+ # Unrecognized Compression
348
345
else :
349
- raise ValueError ('Unrecognized compression: %s' % compression )
346
+ msg = 'Unrecognized compression: {}' .format (compression )
347
+ raise ValueError (msg )
350
348
349
+ # In Python 3
351
350
if compat .PY3 :
352
351
from io import TextIOWrapper
353
-
354
352
f = TextIOWrapper (f , encoding = encoding )
355
353
356
354
return f
357
355
358
356
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
365
359
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' )
366
366
367
367
if memory_map and hasattr (f , 'fileno' ):
368
368
try :
0 commit comments