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.
@@ -0,0 +1,4 @@
1
+ include run_tests.py
2
+ recursive-include docs *.rst
3
+ recursive-include src *.toml
4
+ recursive-include tests *.toml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seqpad
3
- Version: 1.1.0
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.1.0"
30
+ version = "1.2.0"
34
31
 
35
32
  [project.urls]
36
33
  Download = "https://pypi.org/project/seqpad/#files"
@@ -0,0 +1,9 @@
1
+ from __future__ import annotations
2
+
3
+ __all__: list[str] = []
4
+
5
+ import sys
6
+
7
+ import seqpad.tests
8
+
9
+ sys.exit(1 - seqpad.tests.test().wasSuccessful())
@@ -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,10 @@
1
+ from __future__ import annotations
2
+
3
+ __all__: list[str] = []
4
+
5
+ import sys
6
+
7
+ from seqpad import main
8
+
9
+ if __name__ == "__main__":
10
+ 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.1.0
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,2 +0,0 @@
1
- recursive-include docs *.rst
2
- recursive-include src/seqpad *.toml
@@ -1,5 +0,0 @@
1
- from seqpad.core import *
2
- from seqpad.tests import *
3
-
4
- if __name__ == "__main__":
5
- main()
@@ -1,4 +0,0 @@
1
- from seqpad import main
2
-
3
- if __name__ == "__main__":
4
- main()
@@ -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
@@ -1,2 +0,0 @@
1
- click<9,>=8.2
2
- preparse<2,>=1.1
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes