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