seqpad 1.1.0__tar.gz → 1.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seqpad-1.2.0/MANIFEST.in +4 -0
- {seqpad-1.1.0/src/seqpad.egg-info → seqpad-1.2.0}/PKG-INFO +1 -3
- seqpad-1.2.0/docs/v1.2.rst +112 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/pyproject.toml +2 -5
- seqpad-1.2.0/run_tests.py +9 -0
- seqpad-1.2.0/src/seqpad/__init__.py +11 -0
- seqpad-1.2.0/src/seqpad/__main__.py +10 -0
- seqpad-1.2.0/src/seqpad/core/__init__.py +57 -0
- seqpad-1.2.0/src/seqpad/tests/__init__.py +15 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/src/seqpad/tests/test_triplets.py +14 -7
- seqpad-1.2.0/src/seqpad/tests/test_version.py +36 -0
- {seqpad-1.1.0 → seqpad-1.2.0/src/seqpad.egg-info}/PKG-INFO +1 -3
- {seqpad-1.1.0 → seqpad-1.2.0}/src/seqpad.egg-info/SOURCES.txt +4 -2
- seqpad-1.1.0/MANIFEST.in +0 -2
- seqpad-1.1.0/src/seqpad/__init__.py +0 -5
- seqpad-1.1.0/src/seqpad/__main__.py +0 -4
- seqpad-1.1.0/src/seqpad/core/__init__.py +0 -23
- seqpad-1.1.0/src/seqpad/tests/__init__.py +0 -11
- seqpad-1.1.0/src/seqpad.egg-info/requires.txt +0 -2
- {seqpad-1.1.0 → seqpad-1.2.0}/LICENSE.txt +0 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/README.rst +0 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/docs/v1.0.rst +0 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/docs/v1.1.rst +0 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/setup.cfg +0 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/src/seqpad/py.typed +0 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/src/seqpad.egg-info/dependency_links.txt +0 -0
- {seqpad-1.1.0 → seqpad-1.2.0}/src/seqpad.egg-info/top_level.txt +0 -0
seqpad-1.2.0/MANIFEST.in
ADDED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seqpad
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: This project pads nucleotide sequences.
|
|
5
5
|
Author-email: Johannes <johannes.programming@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -18,8 +18,6 @@ Classifier: Typing :: Typed
|
|
|
18
18
|
Requires-Python: >=3.11
|
|
19
19
|
Description-Content-Type: text/x-rst
|
|
20
20
|
License-File: LICENSE.txt
|
|
21
|
-
Requires-Dist: click<9,>=8.2
|
|
22
|
-
Requires-Dist: preparse<2,>=1.1
|
|
23
21
|
Dynamic: license-file
|
|
24
22
|
|
|
25
23
|
======
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Overview
|
|
2
|
+
--------
|
|
3
|
+
|
|
4
|
+
This project pads nucleotide sequences.
|
|
5
|
+
|
|
6
|
+
Installation
|
|
7
|
+
------------
|
|
8
|
+
|
|
9
|
+
To install ``seqpad``, you can use ``pip``.
|
|
10
|
+
Open your terminal and run:
|
|
11
|
+
|
|
12
|
+
.. code-block:: shell
|
|
13
|
+
|
|
14
|
+
pip install seqpad
|
|
15
|
+
|
|
16
|
+
Typing
|
|
17
|
+
------
|
|
18
|
+
|
|
19
|
+
The typing conforms strictly to ``mypy``.
|
|
20
|
+
|
|
21
|
+
.. container:: versionadded
|
|
22
|
+
|
|
23
|
+
**Added in version 1.1.**
|
|
24
|
+
|
|
25
|
+
Features
|
|
26
|
+
--------
|
|
27
|
+
|
|
28
|
+
``seqpad.core``
|
|
29
|
+
~~~~~~~~~~~~~~~
|
|
30
|
+
|
|
31
|
+
The functions in ``seqpad.core`` can also be imported from ``seqpad`` directly.
|
|
32
|
+
|
|
33
|
+
``seqpad.core.main(args: Iterable[str] | None = None) -> int``
|
|
34
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
35
|
+
|
|
36
|
+
The project also provides a CLI that can also be accessed from within Python.
|
|
37
|
+
For more information, read the help message that can be accessed through one of the two following ways.
|
|
38
|
+
|
|
39
|
+
.. code-block:: shell
|
|
40
|
+
|
|
41
|
+
# bash
|
|
42
|
+
python3 -m seqpad -h
|
|
43
|
+
|
|
44
|
+
.. code-block:: python
|
|
45
|
+
|
|
46
|
+
# python
|
|
47
|
+
import seqpad
|
|
48
|
+
seqpad.main(['-h'])
|
|
49
|
+
|
|
50
|
+
``seqpad.core.parse_args(args: Iterable[str] | None = None) -> Namespace``
|
|
51
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
52
|
+
|
|
53
|
+
.. container:: versionadded
|
|
54
|
+
|
|
55
|
+
**Added in version 1.2.**
|
|
56
|
+
|
|
57
|
+
``seqpad.core.run(seq: str | None = None) -> None``
|
|
58
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
59
|
+
|
|
60
|
+
.. container:: versionadded
|
|
61
|
+
|
|
62
|
+
**Added in version 1.2.**
|
|
63
|
+
|
|
64
|
+
``seqpad.core.seqpad(seq: Any) -> Any``
|
|
65
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
66
|
+
|
|
67
|
+
The core function of this project is implemented as follows:
|
|
68
|
+
|
|
69
|
+
.. code-block:: python
|
|
70
|
+
|
|
71
|
+
def seqpad(seq: Any) -> Any:
|
|
72
|
+
while len(seq) % 3 != 0:
|
|
73
|
+
seq += "N"
|
|
74
|
+
return seq
|
|
75
|
+
|
|
76
|
+
``seqpad.tests``
|
|
77
|
+
~~~~~~~~~~~~~~~~
|
|
78
|
+
|
|
79
|
+
``seqpad.tests.test() -> unittest.TextTestResult``
|
|
80
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
81
|
+
|
|
82
|
+
This project can be tested through its ``test`` function.
|
|
83
|
+
|
|
84
|
+
The following code can also be executed by running the project's ``run_tests.py``:
|
|
85
|
+
|
|
86
|
+
.. code-block:: python
|
|
87
|
+
|
|
88
|
+
import seqpad.tests
|
|
89
|
+
seqpad.tests.test()
|
|
90
|
+
|
|
91
|
+
License
|
|
92
|
+
-------
|
|
93
|
+
|
|
94
|
+
This project is licensed under the MIT License.
|
|
95
|
+
|
|
96
|
+
Links
|
|
97
|
+
-----
|
|
98
|
+
|
|
99
|
+
- Download: https://pypi.org/project/seqpad/#files
|
|
100
|
+
- Index: https://pypi.org/project/seqpad/
|
|
101
|
+
- Source: https://github.com/johannes-programming/seqpad/
|
|
102
|
+
- Website: https://seqpad.johannes-programming.online/
|
|
103
|
+
|
|
104
|
+
Impressum
|
|
105
|
+
---------
|
|
106
|
+
|
|
107
|
+
**Johannes Programming**
|
|
108
|
+
|
|
109
|
+
- Name: Johannes
|
|
110
|
+
- Email: johannes.programming@gmail.com
|
|
111
|
+
- Homepage: https://www.johannes-programming.online/
|
|
112
|
+
- Gravatar: https://www.johannes-programming.fyi/
|
|
@@ -17,10 +17,7 @@ classifiers = [
|
|
|
17
17
|
"Programming Language :: Python :: 3 :: Only",
|
|
18
18
|
"Typing :: Typed",
|
|
19
19
|
]
|
|
20
|
-
dependencies = [
|
|
21
|
-
"click>=8.2,<9",
|
|
22
|
-
"preparse>=1.1,<2",
|
|
23
|
-
]
|
|
20
|
+
dependencies = []
|
|
24
21
|
description = "This project pads nucleotide sequences."
|
|
25
22
|
keywords = []
|
|
26
23
|
license = "MIT"
|
|
@@ -30,7 +27,7 @@ license-files = [
|
|
|
30
27
|
name = "seqpad"
|
|
31
28
|
readme = "README.rst"
|
|
32
29
|
requires-python = ">=3.11"
|
|
33
|
-
version = "1.
|
|
30
|
+
version = "1.2.0"
|
|
34
31
|
|
|
35
32
|
[project.urls]
|
|
36
33
|
Download = "https://pypi.org/project/seqpad/#files"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["main", "parse_args", "run", "seqpad", "test"]
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from seqpad.core import main, parse_args, run, seqpad
|
|
8
|
+
from seqpad.tests import test
|
|
9
|
+
|
|
10
|
+
if __name__ == "__main__":
|
|
11
|
+
sys.exit(main())
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["main", "parse_args", "run", "seqpad"]
|
|
4
|
+
|
|
5
|
+
import argparse
|
|
6
|
+
import logging
|
|
7
|
+
from collections import abc
|
|
8
|
+
from importlib import metadata
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main(args: abc.Iterable[str] | None = None) -> int:
|
|
13
|
+
space: argparse.Namespace
|
|
14
|
+
try:
|
|
15
|
+
space = parse_args(args)
|
|
16
|
+
except SystemExit as exit:
|
|
17
|
+
if isinstance(exit.code, int):
|
|
18
|
+
return exit.code
|
|
19
|
+
else:
|
|
20
|
+
return int(bool(exit.code))
|
|
21
|
+
try:
|
|
22
|
+
run(space.seq)
|
|
23
|
+
except Exception as exc:
|
|
24
|
+
logging.exception(exc)
|
|
25
|
+
return 1
|
|
26
|
+
return 0
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def parse_args(args: abc.Iterable[str] | None = None) -> argparse.Namespace:
|
|
30
|
+
parser: argparse.ArgumentParser
|
|
31
|
+
version: str
|
|
32
|
+
parser = argparse.ArgumentParser(
|
|
33
|
+
add_help=False,
|
|
34
|
+
fromfile_prefix_chars="@",
|
|
35
|
+
prog="seqpad",
|
|
36
|
+
)
|
|
37
|
+
parser.add_argument(
|
|
38
|
+
"-h",
|
|
39
|
+
"--help",
|
|
40
|
+
action="help",
|
|
41
|
+
help="show this help message and exit",
|
|
42
|
+
)
|
|
43
|
+
version = "%(prog)s, version " + metadata.version("seqpad")
|
|
44
|
+
parser.add_argument("-V", "--version", action="version", version=version)
|
|
45
|
+
parser.add_argument("seq", nargs="?")
|
|
46
|
+
return parser.parse_args(args)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def run(seq: str | None = None) -> None:
|
|
50
|
+
if seq is not None:
|
|
51
|
+
print(seqpad(seq))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def seqpad(seq: Any) -> Any:
|
|
55
|
+
while len(seq) % 3 != 0:
|
|
56
|
+
seq += "N"
|
|
57
|
+
return seq
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["test"]
|
|
4
|
+
|
|
5
|
+
import unittest
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test() -> unittest.TextTestResult:
|
|
9
|
+
loader: unittest.TestLoader
|
|
10
|
+
runner: unittest.TextTestRunner
|
|
11
|
+
tests: unittest.TestSuite
|
|
12
|
+
loader = unittest.TestLoader()
|
|
13
|
+
tests = loader.discover(start_dir="seqpad.tests")
|
|
14
|
+
runner = unittest.TextTestRunner()
|
|
15
|
+
return runner.run(tests)
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["TestSeqPad"]
|
|
4
|
+
|
|
1
5
|
import unittest
|
|
2
|
-
from typing import
|
|
6
|
+
from typing import Self
|
|
3
7
|
|
|
4
|
-
# Importing the function to be tested
|
|
5
8
|
from seqpad import seqpad
|
|
6
9
|
|
|
7
10
|
|
|
8
11
|
class TestSeqPad(unittest.TestCase):
|
|
9
12
|
|
|
10
|
-
def test_already_multiple_of_three(self: Self) -> None:
|
|
13
|
+
def test_already_multiple_of_three(self: Self, /) -> None:
|
|
11
14
|
# Test case where sequence length is already a multiple of three
|
|
12
15
|
self.assertEqual(seqpad("ATG"), "ATG")
|
|
13
16
|
self.assertEqual(len(seqpad("ATG")), 3)
|
|
14
17
|
|
|
15
|
-
def test_not_multiple_of_three(self: Self) -> None:
|
|
18
|
+
def test_not_multiple_of_three(self: Self, /) -> None:
|
|
16
19
|
# Test case where sequence length is not a multiple of three
|
|
17
20
|
self.assertEqual(seqpad("AT"), "ATN")
|
|
18
21
|
self.assertEqual(len(seqpad("AT")), 3)
|
|
@@ -22,13 +25,16 @@ class TestSeqPad(unittest.TestCase):
|
|
|
22
25
|
self.assertEqual(len(seqpad("ATGCA")), 6)
|
|
23
26
|
self.assertEqual(len(seqpad("ATGCAN")), 6)
|
|
24
27
|
|
|
25
|
-
def test_empty_sequence(self: Self) -> None:
|
|
28
|
+
def test_empty_sequence(self: Self, /) -> None:
|
|
26
29
|
# Test case where input sequence is empty
|
|
27
30
|
self.assertEqual(seqpad(""), "")
|
|
28
31
|
self.assertEqual(len(seqpad("")), 0)
|
|
29
32
|
|
|
30
|
-
def test_length_of_result(self: Self) -> None:
|
|
33
|
+
def test_length_of_result(self: Self, /) -> None:
|
|
31
34
|
# Check if the result has length that is a multiple of three
|
|
35
|
+
padded_seq: str
|
|
36
|
+
seq: str
|
|
37
|
+
test_sequences: list[str]
|
|
32
38
|
test_sequences = ["A", "AT", "ATGCA", "ATGCGTACG"]
|
|
33
39
|
|
|
34
40
|
for seq in test_sequences:
|
|
@@ -37,12 +43,13 @@ class TestSeqPad(unittest.TestCase):
|
|
|
37
43
|
len(padded_seq) % 3, 0, f"Failed for input: {seq}"
|
|
38
44
|
)
|
|
39
45
|
|
|
40
|
-
def test_edge_cases(self: Self) -> None:
|
|
46
|
+
def test_edge_cases(self: Self, /) -> None:
|
|
41
47
|
# Testing edge cases such as strings with non-standard nucleotides
|
|
42
48
|
self.assertEqual(seqpad("NNN"), "NNN")
|
|
43
49
|
self.assertEqual(seqpad("N"), "NNN")
|
|
44
50
|
self.assertEqual(len(seqpad("N")), 3)
|
|
45
51
|
self.assertEqual(len(seqpad("NNN")), 3)
|
|
52
|
+
self.assertListEqual(seqpad(["A"]), ["A", "N", "N"])
|
|
46
53
|
|
|
47
54
|
|
|
48
55
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
__all__: list[str] = ["TestVersion"]
|
|
4
|
+
|
|
5
|
+
import unittest
|
|
6
|
+
from collections import abc
|
|
7
|
+
from contextlib import redirect_stdout
|
|
8
|
+
from io import StringIO
|
|
9
|
+
from typing import Self
|
|
10
|
+
|
|
11
|
+
from seqpad import main
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestVersion(unittest.TestCase):
|
|
15
|
+
def go(self: Self, /, args: abc.Iterable[str]) -> str:
|
|
16
|
+
buffer: StringIO
|
|
17
|
+
text: str
|
|
18
|
+
buffer = StringIO()
|
|
19
|
+
with redirect_stdout(buffer):
|
|
20
|
+
main(args)
|
|
21
|
+
text = buffer.getvalue()
|
|
22
|
+
self.assertTrue(text.startswith("seqpad, "))
|
|
23
|
+
self.assertTrue(text.endswith("\n"))
|
|
24
|
+
self.assertEqual(text.count("\n"), 1)
|
|
25
|
+
return text[8:-1]
|
|
26
|
+
|
|
27
|
+
def test_0(self: Self, /) -> None:
|
|
28
|
+
versions: set[str]
|
|
29
|
+
versions = set()
|
|
30
|
+
versions.add(self.go(["-V"]))
|
|
31
|
+
versions.add(self.go(["--version"]))
|
|
32
|
+
self.assertEqual(len(versions), 1)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
unittest.main()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seqpad
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: This project pads nucleotide sequences.
|
|
5
5
|
Author-email: Johannes <johannes.programming@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -18,8 +18,6 @@ Classifier: Typing :: Typed
|
|
|
18
18
|
Requires-Python: >=3.11
|
|
19
19
|
Description-Content-Type: text/x-rst
|
|
20
20
|
License-File: LICENSE.txt
|
|
21
|
-
Requires-Dist: click<9,>=8.2
|
|
22
|
-
Requires-Dist: preparse<2,>=1.1
|
|
23
21
|
Dynamic: license-file
|
|
24
22
|
|
|
25
23
|
======
|
|
@@ -2,17 +2,19 @@ LICENSE.txt
|
|
|
2
2
|
MANIFEST.in
|
|
3
3
|
README.rst
|
|
4
4
|
pyproject.toml
|
|
5
|
+
run_tests.py
|
|
5
6
|
setup.cfg
|
|
6
7
|
docs/v1.0.rst
|
|
7
8
|
docs/v1.1.rst
|
|
9
|
+
docs/v1.2.rst
|
|
8
10
|
src/seqpad/__init__.py
|
|
9
11
|
src/seqpad/__main__.py
|
|
10
12
|
src/seqpad/py.typed
|
|
11
13
|
src/seqpad.egg-info/PKG-INFO
|
|
12
14
|
src/seqpad.egg-info/SOURCES.txt
|
|
13
15
|
src/seqpad.egg-info/dependency_links.txt
|
|
14
|
-
src/seqpad.egg-info/requires.txt
|
|
15
16
|
src/seqpad.egg-info/top_level.txt
|
|
16
17
|
src/seqpad/core/__init__.py
|
|
17
18
|
src/seqpad/tests/__init__.py
|
|
18
|
-
src/seqpad/tests/test_triplets.py
|
|
19
|
+
src/seqpad/tests/test_triplets.py
|
|
20
|
+
src/seqpad/tests/test_version.py
|
seqpad-1.1.0/MANIFEST.in
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
from typing import *
|
|
2
|
-
|
|
3
|
-
import click
|
|
4
|
-
import preparse
|
|
5
|
-
|
|
6
|
-
__all__ = ["seqpad", "main"]
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def seqpad(seq: Any) -> Any:
|
|
10
|
-
while len(seq) % 3 != 0:
|
|
11
|
-
seq += "N"
|
|
12
|
-
return seq
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@preparse.PreParser().click()
|
|
16
|
-
@click.command(add_help_option=False)
|
|
17
|
-
@click.help_option("-h", "--help")
|
|
18
|
-
@click.version_option(None, "-V", "--version")
|
|
19
|
-
@click.argument("seq", type=str, required=False)
|
|
20
|
-
def main(seq: Optional[str]) -> None:
|
|
21
|
-
"This program pads the given seq to a length that is a multiple of three."
|
|
22
|
-
if seq is not None:
|
|
23
|
-
click.echo(seqpad(seq))
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
|
|
3
|
-
__all__ = ["test"]
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
def test() -> unittest.TextTestResult:
|
|
7
|
-
loader: unittest.TestLoader = unittest.TestLoader()
|
|
8
|
-
tests: unittest.TestSuite = loader.discover(start_dir="seqpad.tests")
|
|
9
|
-
runner: unittest.TextTestRunner = unittest.TextTestRunner()
|
|
10
|
-
result: unittest.TextTestResult = runner.run(tests)
|
|
11
|
-
return result
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|