Skip to content

Commit

Permalink
Let PipedCompressionWriter/-Reader derive from IOBase
Browse files Browse the repository at this point in the history
This is the proper thing to do and also gives us a couple of methods for
free, in particular readlines().

This also allows us to get rid of the Closing mixin.

Closes #129
  • Loading branch information
marcelm committed Nov 23, 2023
1 parent 0f10540 commit dcd6b23
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 30 deletions.
34 changes: 4 additions & 30 deletions src/xopen/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
import subprocess
import tempfile
import time
from abc import ABC, abstractmethod
from subprocess import Popen, PIPE, DEVNULL
from typing import (
Optional,
Expand Down Expand Up @@ -157,30 +156,7 @@ def _can_read_concatenated_gz(program: str) -> bool:
os.remove(temp_path)


class Closing(ABC):
"""
Inherit from this class and implement a close() method to offer context
manager functionality.
"""

def __enter__(self):
return self

def __exit__(self, *exc_info):
self.close()

def __del__(self):
try:
self.close()
except Exception:
pass

@abstractmethod
def close(self):
"""Called when exiting the context manager"""


class PipedCompressionWriter(Closing):
class PipedCompressionWriter(io.IOBase):
"""
Write Compressed files by running an external process and piping into it.
"""
Expand Down Expand Up @@ -216,7 +192,6 @@ def __init__(

# TODO use a context manager
self.outfile = open(path, mode[0] + "b")
self.closed: bool = False
self.name: str = str(os.fspath(path))
self._mode: str = mode
self._program_args: List[str] = program_args
Expand Down Expand Up @@ -283,7 +258,7 @@ def write(self, arg: AnyStr) -> int:
def close(self) -> None:
if self.closed:
return
self.closed = True
super().close()
self._file.close()
retcode = self.process.wait()
self.outfile.close()
Expand Down Expand Up @@ -311,7 +286,7 @@ def __next__(self):
raise io.UnsupportedOperation("not readable")


class PipedCompressionReader(Closing):
class PipedCompressionReader(io.IOBase):
"""
Open a pipe to a process for reading a compressed file.
"""
Expand Down Expand Up @@ -371,7 +346,6 @@ def __init__(
)
else:
self._file = self.process.stdout
self.closed = False
self._wait_for_output_or_process_exit()
self._raise_if_error()

Expand All @@ -387,7 +361,7 @@ def __repr__(self):
def close(self) -> None:
if self.closed:
return
self.closed = True
super().close()
retcode = self.process.poll()
check_allowed_code_and_message = False
if retcode is None:
Expand Down
6 changes: 6 additions & 0 deletions tests/test_piped.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,12 @@ def test_reader_readline_text(reader):
assert f.readline() == CONTENT_LINES[0]


def test_reader_readlines(reader):
opener, extension = reader
with opener(TEST_DIR / f"file.txt{extension}", "r") as f:
assert f.readlines() == CONTENT_LINES


@pytest.mark.parametrize("threads", [None, 1, 2])
def test_piped_reader_iter(threads, threaded_reader):
opener, extension = threaded_reader
Expand Down

0 comments on commit dcd6b23

Please sign in to comment.