[med-svn] [Git][med-team/python-dnaio][master] 4 commits: routine-update: New upstream version

Nilesh Patra gitlab at salsa.debian.org
Fri Nov 13 08:27:31 GMT 2020



Nilesh Patra pushed to branch master at Debian Med / python-dnaio


Commits:
a8861f6a by Nilesh Patra at 2020-11-13T13:52:33+05:30
routine-update: New upstream version

- - - - -
1e7f2c4a by Nilesh Patra at 2020-11-13T13:52:34+05:30
New upstream version 0.4.4
- - - - -
40494c68 by Nilesh Patra at 2020-11-13T13:52:34+05:30
Update upstream source from tag 'upstream/0.4.4'

Update to upstream version '0.4.4'
with Debian dir c7fd4fd0e889a72ec827c2c8412b671594a7972f
- - - - -
2ae84a47 by Nilesh Patra at 2020-11-13T13:52:37+05:30
routine-update: Ready to upload to unstable

- - - - -


11 changed files:

- + .codecov.yml
- .travis.yml
- debian/changelog
- src/dnaio/__init__.py
- + src/dnaio/_core.pyi
- src/dnaio/_util.py
- src/dnaio/readers.py
- src/dnaio/writers.py
- tests/test_internal.py
- + tests/test_util.py
- tox.ini


Changes:

=====================================
.codecov.yml
=====================================
@@ -0,0 +1,14 @@
+comment: off
+
+codecov:
+  require_ci_to_pass: no
+
+coverage:
+  precision: 1
+  round: down
+  range: "90...100"
+
+  status:
+    project: yes
+    patch: no
+    changes: no


=====================================
.travis.yml
=====================================
@@ -1,7 +1,5 @@
 language: python
 
-dist: xenial
-
 cache:
   directories:
     - $HOME/.cache/pip
@@ -11,6 +9,7 @@ python:
   - "3.6"
   - "3.7"
   - "3.8"
+  - "3.9"
   - "nightly"
 
 install:
@@ -45,7 +44,8 @@ jobs:
           ls -l dist/
           python3 -m twine upload dist/*
 
-    - name: flake8
+    - stage: test
+      name: flake8
       python: "3.6"
       install: python3 -m pip install flake8
       script: flake8 src/ tests/


=====================================
debian/changelog
=====================================
@@ -1,3 +1,10 @@
+python-dnaio (0.4.4-1) unstable; urgency=medium
+
+  * Team upload.
+  * New upstream version
+
+ -- Nilesh Patra <npatra974 at gmail.com>  Fri, 13 Nov 2020 13:52:37 +0530
+
 python-dnaio (0.4.3-1) unstable; urgency=medium
 
   * Team upload.


=====================================
src/dnaio/__init__.py
=====================================
@@ -34,7 +34,7 @@ from .writers import FastaWriter, FastqWriter
 from .exceptions import UnknownFileFormat, FileFormatError, FastaFormatError, FastqFormatError
 from .chunks import read_chunks, read_paired_chunks
 from ._version import version as __version__
-
+from ._util import _is_path
 
 try:
     from os import fspath  # Exists in Python 3.6+
@@ -128,21 +128,6 @@ def _detect_format_from_name(name):
     return None
 
 
-def _is_path(obj):
-    """
-    Return whether the given object looks like a path (str, pathlib.Path or pathlib2.Path)
-    """
-    # pytest uses pathlib2.Path objects on Python 3.5 for its tmp_path fixture.
-    # On Python 3.6+, this function can be replaced with isinstance(obj, os.PathLike)
-    import sys
-    if "pathlib2" in sys.modules:
-        import pathlib2
-        path_classes = (str, pathlib.Path, pathlib2.Path)
-    else:
-        path_classes = (str, pathlib.Path)
-    return isinstance(obj, path_classes)
-
-
 def _open_single(file, opener, *, fileformat=None, mode="r", qualities=None):
     """
     Open a single sequence file. See description of open() above.
@@ -173,11 +158,11 @@ def _open_single(file, opener, *, fileformat=None, mode="r", qualities=None):
         'fastq': functools.partial(fastq_handler, _close_file=close_file),
         'fasta': functools.partial(fasta_handler, _close_file=close_file),
     }
-
     if fileformat:
         try:
             handler = handlers[fileformat.lower()]
         except KeyError:
+            file.close()
             raise UnknownFileFormat(
                 "File format {!r} is unknown (expected 'fasta' or 'fastq').".format(fileformat))
         return handler(file)
@@ -191,18 +176,22 @@ def _open_single(file, opener, *, fileformat=None, mode="r", qualities=None):
     if mode == 'r' and fileformat is None:
         fileformat = _detect_format_from_content(file)
         if fileformat is None:
+            name = getattr(file, "name", repr(file))
+            file.close()
             raise UnknownFileFormat(
-                'Could not determine whether file {!r} is FASTA or FASTQ. The file extension was '
+                'Could not determine whether file "{}" is FASTA or FASTQ. The file extension was '
                 'not available or not recognized and the first character in the file is '
-                'unexpected.'.format(file))
+                'unexpected.'.format(name))
 
     if fileformat is None:
         assert mode == 'w'
         extra = " because the output file name is not available" if path is None else ""
+        file.close()
         raise UnknownFileFormat(
             "Auto-detection of the output file format (FASTA/FASTQ) failed" + extra)
 
     if fileformat == 'fastq' and mode in "wa" and qualities is False:
+        file.close()
         raise ValueError(
             'Output format cannot be FASTQ since no quality values are available.')
 


=====================================
src/dnaio/_core.pyi
=====================================
@@ -0,0 +1,18 @@
+from typing import Optional, Tuple, Union, Iterable, BinaryIO
+
+class Sequence:
+    name: str
+    sequence: str
+    qualities: Optional[str]
+    def __init__(self, name: str, sequence: str, qualities: Optional[str] = ...) -> None: ...
+    def __getitem__(self, s: slice) -> Sequence: ...
+    def __repr__(self) -> str: ...
+    def __len__(self) -> int: ...
+    def __richcmp__(self, other: Sequence, op: int) -> bool: ...
+    def fastq_bytes(self) -> bytes: ...
+    def fastq_bytes_two_headers(self) -> bytes: ...
+
+def paired_fastq_heads(buf1: Union[bytes,bytearray], buf2: Union[bytes,bytearray], end1: int, end2: int) -> Tuple[int, int]: ...
+# TODO Sequence should be sequence_class, first yielded value is a bool
+def fastq_iter(file: BinaryIO, sequence_class, buffer_size: int) -> Iterable[Sequence]: ...
+def record_names_match(header1: str, header2: str) -> bool: ...


=====================================
src/dnaio/_util.py
=====================================
@@ -1,3 +1,21 @@
+import pathlib
+
+
+def _is_path(obj):
+    """
+    Return whether the given object looks like a path (str, pathlib.Path or pathlib2.Path)
+    """
+    # pytest uses pathlib2.Path objects on Python 3.5 for its tmp_path fixture.
+    # On Python 3.6+, this function can be replaced with isinstance(obj, os.PathLike)
+    import sys
+    if "pathlib2" in sys.modules:
+        import pathlib2
+        path_classes = (str, pathlib.Path, pathlib2.Path)
+    else:
+        path_classes = (str, pathlib.Path)
+    return isinstance(obj, path_classes)
+
+
 def shorten(s, n=100):
     """Shorten string s to at most n characters, appending "..." if necessary."""
     if s is None:


=====================================
src/dnaio/readers.py
=====================================
@@ -120,6 +120,9 @@ class FastqReader(BinaryFileReader):
             # Empty file
             self.two_headers = False
             self._iter = iter(())
+        except Exception:
+            self.close()
+            raise
 
     def __iter__(self):
         return self._iter


=====================================
src/dnaio/writers.py
=====================================
@@ -1,10 +1,12 @@
 from xopen import xopen
 
+from ._util import _is_path
+
 
 class FileWriter:
     def __init__(self, file, opener=xopen, _close_file=None):
         self._file = file
-        if isinstance(file, str):
+        if _is_path(file):
             self._file = opener(file, "wb")
             self._close_on_exit = True
         else:
@@ -40,7 +42,7 @@ class FastaWriter(FileWriter):
         self.line_length = line_length if line_length != 0 else None
 
     def __repr__(self):
-        return "FastaWriter({!r})".format(getattr(self._file, "name", self._file))
+        return "FastaWriter('{}')".format(getattr(self._file, "name", self._file))
 
     def write(self, name_or_record, sequence=None):
         """Write an entry to the the FASTA file.
@@ -89,6 +91,9 @@ class FastqWriter(FileWriter):
         self._two_headers = two_headers
         self.write = self._write_two_headers if self._two_headers else self._write
 
+    def __repr__(self):
+        return "FastqWriter('{}')".format(getattr(self._file, "name", self._file))
+
     def _write(self, record):
         """
         Write a Sequence record to the FASTQ file.


=====================================
tests/test_internal.py
=====================================
@@ -13,9 +13,11 @@ from dnaio import (
     FileFormatError, FastaFormatError, FastqFormatError,
     FastaReader, FastqReader, InterleavedSequenceReader,
     FastaWriter, FastqWriter, InterleavedSequenceWriter,
-    PairedSequenceReader)
+    PairedSequenceReader,
+)
 from dnaio import _record_names_match, Sequence
-
+from dnaio.writers import FileWriter
+from dnaio.readers import BinaryFileReader
 
 # files tests/data/simple.fast{q,a}
 simple_fastq = [
@@ -110,9 +112,10 @@ class TestFastqReader:
         assert reads == simple_fastq
 
     def test_fastqreader_buffersize_too_small(self):
-        with raises(ValueError):
+        with raises(ValueError) as e:
             with FastqReader("tests/data/simple.fastq", buffer_size=0) as f:
                 _ = list(f)  # pragma: no cover
+        assert "buffer size too small" in e.value.args[0]
 
     def test_fastqreader_dos(self):
         # DOS line breaks
@@ -257,12 +260,15 @@ class TestOpen:
         assert reads == simple_fastq
 
         # make the name attribute unavailable
-        f = BytesIO(open("tests/data/simple.fastq", 'rb').read())
-        reads = list(dnaio.open(f))
+        with open("tests/data/simple.fastq", 'rb') as f:
+            data = f.read()
+        bio = BytesIO(data)
+        reads = list(dnaio.open(bio))
         assert reads == simple_fastq
-
-        f = BytesIO(open("tests/data/simple.fasta", 'rb').read())
-        reads = list(dnaio.open(f))
+        with open("tests/data/simple.fasta", 'rb') as f:
+            data = f.read()
+        bio = BytesIO(data)
+        reads = list(dnaio.open(bio))
         assert reads == simple_fasta
 
     def test_autodetect_fasta_format(self, tmpdir):
@@ -307,7 +313,8 @@ class TestOpen:
     def test_fastq_qualities_missing(self):
         path = os.path.join(self._tmpdir, 'tmp.fastq')
         with raises(ValueError):
-            dnaio.open(path, mode='w', qualities=False)
+            with dnaio.open(path, mode='w', qualities=False):
+                pass
 
 
 class TestInterleavedReader:
@@ -507,10 +514,42 @@ def test_read_stdin(path):
         expected = len(list(f))
 
     # Use 'cat' to simulate that no file name is available for stdin of the subprocess
-    cat = subprocess.Popen(['cat', path], stdout=subprocess.PIPE)
-    py = subprocess.Popen(
-        [sys.executable, 'tests/read_from_stdin.py'], stdin=cat.stdout, stdout=subprocess.PIPE)
-    cat.stdout.close()
+    with subprocess.Popen(['cat', path], stdout=subprocess.PIPE) as cat:
+        with subprocess.Popen(
+            [sys.executable, 'tests/read_from_stdin.py'], stdin=cat.stdout, stdout=subprocess.PIPE
+        ) as py:
+            cat.stdout.close()
+            # Check that the read_from_stdin.py script prints the correct number of records
+            assert str(expected) == py.communicate()[0].decode().strip()
+
+
+def test_file_writer(tmp_path):
+    path = tmp_path / "out.txt"
+    fw = FileWriter(path)
+    repr(fw)
+    fw.close()
+    assert path.exists()
+    with raises(ValueError) as e:
+        with fw:
+            pass
+    assert "operation on closed file" in e.value.args[0]
+
+
+def test_binary_file_reader():
+    bfr = BinaryFileReader("tests/data/simple.fasta")
+    repr(bfr)
+    bfr.close()
+    with raises(ValueError) as e:
+        with bfr:
+            pass
+    assert "operation on closed" in e.value.args[0]
+
+
+def test_fasta_writer_repr(tmp_path):
+    with FastaWriter(tmp_path / "out.fasta") as fw:
+        repr(fw)
+
 
-    # Check that the read_from_stdin.py script prints the correct number of records
-    assert str(expected) == py.communicate()[0].decode().strip()
+def test_fastq_writer_repr(tmp_path):
+    with FastqWriter(tmp_path / "out.fastq") as fw:
+        repr(fw)


=====================================
tests/test_util.py
=====================================
@@ -0,0 +1,7 @@
+from dnaio._util import shorten
+
+
+def test_shorten():
+    assert shorten(None) is None
+    assert shorten("hello too long", 5) == "he..."
+    assert shorten("hello not too long") == "hello not too long"


=====================================
tox.ini
=====================================
@@ -1,5 +1,5 @@
 [tox]
-envlist = flake8,py35,py36,py37,py38
+envlist = flake8,py35,py36,py37,py38,py39
 
 [testenv]
 deps =
@@ -9,6 +9,7 @@ commands =
     coverage run --concurrency=multiprocessing -m pytest --doctest-modules --pyargs tests/
     coverage combine
     coverage report
+setenv = PYTHONDEVMODE = 1
 
 [testenv:flake8]
 basepython = python3.6
@@ -16,6 +17,7 @@ deps = flake8
 commands = flake8 src/ tests/
 
 [coverage:run]
+branch = True
 parallel = True
 include =
     */site-packages/dnaio/*



View it on GitLab: https://salsa.debian.org/med-team/python-dnaio/-/compare/ea2070280126b12a9e6b2454c12b9a7dc5a5eb9a...2ae84a47e202834b17cfe419bcc23bf3dbb354d7

-- 
View it on GitLab: https://salsa.debian.org/med-team/python-dnaio/-/compare/ea2070280126b12a9e6b2454c12b9a7dc5a5eb9a...2ae84a47e202834b17cfe419bcc23bf3dbb354d7
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20201113/b27c76e9/attachment-0001.html>


More information about the debian-med-commit mailing list