|
27 | 27 | import os |
28 | 28 | import sys |
29 | 29 |
|
30 | | -import _compression |
31 | | - |
32 | 30 | from . import isal_zlib |
33 | 31 |
|
34 | 32 | __all__ = ["IGzipFile", "open", "compress", "decompress", "BadGzipFile"] |
|
37 | 35 | _COMPRESS_LEVEL_TRADEOFF = isal_zlib.ISAL_DEFAULT_COMPRESSION |
38 | 36 | _COMPRESS_LEVEL_BEST = isal_zlib.ISAL_BEST_COMPRESSION |
39 | 37 |
|
40 | | -BUFFER_SIZE = _compression.BUFFER_SIZE |
41 | | - |
42 | 38 | try: |
43 | | - BadGzipFile = gzip.BadGzipFile |
| 39 | + BadGzipFile = gzip.BadGzipFile # type: ignore |
44 | 40 | except AttributeError: # Versions lower than 3.8 do not have BadGzipFile |
45 | 41 | BadGzipFile = OSError |
46 | 42 |
|
@@ -80,7 +76,8 @@ def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_TRADEOFF, |
80 | 76 | raise ValueError("Argument 'newline' not supported in binary mode") |
81 | 77 |
|
82 | 78 | gz_mode = mode.replace("t", "") |
83 | | - if isinstance(filename, (str, bytes, os.PathLike)): |
| 79 | + # __fspath__ method is os.PathLike |
| 80 | + if isinstance(filename, (str, bytes)) or hasattr(filename, "__fspath__"): |
84 | 81 | binary_file = IGzipFile(filename, gz_mode, compresslevel) |
85 | 82 | elif hasattr(filename, "read") or hasattr(filename, "write"): |
86 | 83 | binary_file = IGzipFile(None, gz_mode, compresslevel, filename) |
@@ -276,33 +273,46 @@ def main(): |
276 | 273 | "-d", "--decompress", action="store_false", |
277 | 274 | dest="compress", |
278 | 275 | help="Decompress the file instead of compressing.") |
| 276 | + parser.add_argument("-c", "--stdout", action="store_true", |
| 277 | + help="write on standard output") |
| 278 | + # -b flag not taken by either gzip or igzip. Hidden attribute. Above 32K |
| 279 | + # diminishing returns hit. _compression.BUFFER_SIZE = 8k. But 32K is about |
| 280 | + # ~6% faster. |
| 281 | + parser.add_argument("-b", "--buffer-size", |
| 282 | + default=32 * 1024, type=int, |
| 283 | + help=argparse.SUPPRESS) |
279 | 284 | args = parser.parse_args() |
280 | 285 |
|
281 | 286 | compresslevel = args.compresslevel or _COMPRESS_LEVEL_TRADEOFF |
282 | 287 |
|
283 | | - if args.file is None: |
284 | | - if args.compress: |
285 | | - in_file = sys.stdin.buffer |
286 | | - out_file = IGzipFile(mode="wb", compresslevel=compresslevel, |
287 | | - fileobj=sys.stdout.buffer) |
288 | | - else: |
289 | | - in_file = IGzipFile(mode="rb", fileobj=sys.stdin.buffer) |
290 | | - out_file = sys.stdout.buffer |
291 | | - else: |
292 | | - if args.compress: |
293 | | - in_file = io.open(args.file, mode="rb") |
294 | | - out_file = open(args.file + ".gz", mode="wb", |
295 | | - compresslevel=compresslevel) |
296 | | - else: |
297 | | - base, extension = os.path.splitext(args.file) |
298 | | - if extension != ".gz": |
299 | | - print(f"filename doesn't end in .gz: {args.file}") |
300 | | - return |
301 | | - in_file = open(args.file, "rb") |
302 | | - out_file = io.open(base, "wb") |
| 288 | + # Determine input file |
| 289 | + if args.compress and args.file is None: |
| 290 | + in_file = sys.stdin.buffer |
| 291 | + elif args.compress and args.file is not None: |
| 292 | + in_file = io.open(args.file, mode="rb") |
| 293 | + elif not args.compress and args.file is None: |
| 294 | + in_file = IGzipFile(mode="rb", fileobj=sys.stdin.buffer) |
| 295 | + elif not args.compress and args.file is not None: |
| 296 | + base, extension = os.path.splitext(args.file) |
| 297 | + if extension != ".gz": |
| 298 | + raise ValueError(f"filename doesn't end in .gz: {args.file}. ") |
| 299 | + in_file = open(args.file, "rb") |
| 300 | + |
| 301 | + # Determine output file |
| 302 | + if args.compress and (args.file is None or args.stdout): |
| 303 | + out_file = IGzipFile(mode="wb", compresslevel=compresslevel, |
| 304 | + fileobj=sys.stdout.buffer) |
| 305 | + elif args.compress and args.file is not None: |
| 306 | + out_file = open(args.file + ".gz", mode="wb", |
| 307 | + compresslevel=compresslevel) |
| 308 | + elif not args.compress and (args.file is None or args.stdout): |
| 309 | + out_file = sys.stdout.buffer |
| 310 | + elif not args.compress and args.file is not None: |
| 311 | + out_file = io.open(base, "wb") |
| 312 | + |
303 | 313 | try: |
304 | 314 | while True: |
305 | | - block = in_file.read(BUFFER_SIZE) |
| 315 | + block = in_file.read(args.buffer_size) |
306 | 316 | if block == b"": |
307 | 317 | break |
308 | 318 | out_file.write(block) |
|
0 commit comments