revseq 1.0.0__tar.gz → 1.3.1__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.
@@ -1,26 +1,26 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: revseq
3
- Version: 1.0.0
3
+ Version: 1.3.1
4
4
  Summary: reverse and/or complement dna sequence
5
- Project-URL: homepage, https://github.com/milescsmith/revseq
6
- Project-URL: repository, https://github.com/milescsmith/revseq
7
- Project-URL: changelog, https://github.com/milescsmith/revseq/releases
5
+ Author: Miles Smith
8
6
  Author-email: Miles Smith <mileschristiansmith@gmail.com>
9
- License-Expression: GPL-3.0
10
- License-File: LICENSE
7
+ License: GPL-3.0-or-later
8
+ Classifier: Programming Language :: Python :: Implementation :: CPython
9
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
11
10
  Classifier: Development Status :: 5 - Production/Stable
12
11
  Classifier: Environment :: Console
13
12
  Classifier: Intended Audience :: Science/Research
14
13
  Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
15
- Classifier: Programming Language :: Python :: Implementation :: CPython
16
- Classifier: Programming Language :: Python :: Implementation :: PyPy
17
14
  Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
18
15
  Classifier: Typing :: Typed
16
+ Requires-Dist: typer>=0.29.0
17
+ Requires-Dist: icontract>=2.7.3
18
+ Requires-Dist: rich>=15.0.0
19
+ Requires-Dist: typeguard>=4.6.0
19
20
  Requires-Python: >=3.10
20
- Requires-Dist: icontract>=2.6.6
21
- Requires-Dist: rich>=13.7.1
22
- Requires-Dist: typeguard>=4.2.1
23
- Requires-Dist: typer>=0.11.0
21
+ Project-URL: homepage, https://github.com/milescsmith/revseq
22
+ Project-URL: repository, https://github.com/milescsmith/revseq
23
+ Project-URL: changelog, https://github.com/milescsmith/revseq/releases
24
24
  Description-Content-Type: text/x-rst
25
25
 
26
26
  revseq
@@ -45,8 +45,8 @@ A simple script to generate the (reverse) (complement) of a sequence
45
45
  .. |License| image:: https://img.shields.io/pypi/l/revseq
46
46
  :target: https://opensource.org/licenses/GPL-3.0
47
47
  :alt: License
48
- .. |Tests| image:: https://github.com/milescsmith/revseq/workflows/Tests/badge.svg
49
- :target: https://github.com/milescsmith/revseq/actions?workflow=Tests
48
+ .. |Tests| image:: https://github.com/milescsmith/revseq/actions/workflows/python-package.yml/badge.svg
49
+ :target: https://github.com/milescsmith/revseq/actions?workflow=python-package
50
50
  :alt: Tests
51
51
  .. |Codecov| image:: https://codecov.io/gh/milescsmith/revseq/branch/main/graph/badge.svg
52
52
  :target: https://codecov.io/gh/milescsmith/revseq
@@ -136,4 +136,4 @@ Credits
136
136
  .. _file an issue: https://github.com/milescsmith/revseq/issues
137
137
  .. _pip: https://pip.pypa.io/
138
138
  .. github-only
139
- .. _Contributor Guide: CONTRIBUTING.rst
139
+ .. _Contributor Guide: CONTRIBUTING.rst
@@ -20,8 +20,8 @@ A simple script to generate the (reverse) (complement) of a sequence
20
20
  .. |License| image:: https://img.shields.io/pypi/l/revseq
21
21
  :target: https://opensource.org/licenses/GPL-3.0
22
22
  :alt: License
23
- .. |Tests| image:: https://github.com/milescsmith/revseq/workflows/Tests/badge.svg
24
- :target: https://github.com/milescsmith/revseq/actions?workflow=Tests
23
+ .. |Tests| image:: https://github.com/milescsmith/revseq/actions/workflows/python-package.yml/badge.svg
24
+ :target: https://github.com/milescsmith/revseq/actions?workflow=python-package
25
25
  :alt: Tests
26
26
  .. |Codecov| image:: https://codecov.io/gh/milescsmith/revseq/branch/main/graph/badge.svg
27
27
  :target: https://codecov.io/gh/milescsmith/revseq
@@ -111,4 +111,4 @@ Credits
111
111
  .. _file an issue: https://github.com/milescsmith/revseq/issues
112
112
  .. _pip: https://pip.pypa.io/
113
113
  .. github-only
114
- .. _Contributor Guide: CONTRIBUTING.rst
114
+ .. _Contributor Guide: CONTRIBUTING.rst
@@ -0,0 +1,75 @@
1
+ [build-system]
2
+ requires = ["uv_build>=0.7.0,<0.14.0"]
3
+ build-backend = "uv_build"
4
+
5
+ [project]
6
+ name = "revseq"
7
+ version = "1.3.1"
8
+ description = "reverse and/or complement dna sequence"
9
+ readme = "README.rst"
10
+ requires-python = ">= 3.10"
11
+ dependencies = [
12
+ "typer>=0.29.0",
13
+ "icontract>=2.7.3",
14
+ "rich>=15.0.0",
15
+ "typeguard>=4.6.0",
16
+ ]
17
+ classifiers = [
18
+ "Programming Language :: Python :: Implementation :: CPython",
19
+ "Programming Language :: Python :: Implementation :: PyPy",
20
+ "Development Status :: 5 - Production/Stable",
21
+ "Environment :: Console",
22
+ "Intended Audience :: Science/Research",
23
+ "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
24
+ "Topic :: Scientific/Engineering :: Bio-Informatics",
25
+ "Typing :: Typed",
26
+ ]
27
+
28
+ [[project.authors]]
29
+ name = "Miles Smith"
30
+ email = "mileschristiansmith@gmail.com"
31
+
32
+ [project.license]
33
+ text = "GPL-3.0-or-later"
34
+
35
+ [project.urls]
36
+ homepage = "https://github.com/milescsmith/revseq"
37
+ repository = "https://github.com/milescsmith/revseq"
38
+ changelog = "https://github.com/milescsmith/revseq/releases"
39
+
40
+ [project.scripts]
41
+ revseq = "revseq.__main__:app"
42
+
43
+ [tool.coverage.paths]
44
+ source = [
45
+ "src",
46
+ "*/site-packages",
47
+ ]
48
+
49
+ [tool.coverage.run]
50
+ branch = true
51
+ source = ["revseq"]
52
+
53
+ [tool.coverage.report]
54
+ show_missing = true
55
+ fail_under = 100
56
+
57
+ [tool.mypy]
58
+ strict = true
59
+ warn_unreachable = true
60
+ pretty = true
61
+ show_column_numbers = true
62
+ show_error_codes = true
63
+ show_error_context = true
64
+
65
+ [dependency-groups]
66
+ dev = [
67
+ "codecov>=2.1.13",
68
+ "coverage>=7.16.2",
69
+ "hypothesis>=6.168.5",
70
+ "nox>=2026.10.20",
71
+ "pytest>=9.2.0",
72
+ "pytest-cov>=7.1.0",
73
+ "ruff>=0.17.4",
74
+ "ty>=0.0.100",
75
+ ]
@@ -1,22 +1,22 @@
1
1
  [build-system]
2
- requires = ["hatchling"]
3
- build-backend = "hatchling.build"
2
+ requires = ["uv_build>=0.7.0,<0.14.0"]
3
+ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "revseq"
7
- version = "1.0.0"
7
+ version = "1.3.1"
8
8
  description = "reverse and/or complement dna sequence"
9
9
  authors = [
10
10
  { name = "Miles Smith", email = "mileschristiansmith@gmail.com" }
11
11
  ]
12
- license = "GPL-3.0"
13
12
  readme = "README.rst"
14
13
  requires-python = ">= 3.10"
14
+ license = { text = "GPL-3.0-or-later" }
15
15
  dependencies = [
16
- "typer>=0.11.0",
17
- "icontract>=2.6.6",
18
- "rich>=13.7.1",
19
- "typeguard>=4.2.1",
16
+ "typer>=0.29.0",
17
+ "icontract>=2.7.3",
18
+ "rich>=15.0.0",
19
+ "typeguard>=4.6.0",
20
20
  ]
21
21
  classifiers = [
22
22
  "Programming Language :: Python :: Implementation :: CPython",
@@ -48,27 +48,6 @@ source = ["revseq"]
48
48
  show_missing = true
49
49
  fail_under = 100
50
50
 
51
- [tool.rye]
52
- managed = true
53
- dev-dependencies = [
54
- "codecov>=2.1.13",
55
- "hypothesis>=6.99.13",
56
- "nox>=2024.3.2",
57
- "pytest>=8.1.1",
58
- "mypy>=1.9.0",
59
- "coverage>=7.4.4",
60
- "pytest-cov>=4.1.0",
61
- "ruff>=0.3.4",
62
- ]
63
-
64
- [tool.rye.scripts]
65
- lint = { chain = ["lint:ruff", "lint:black"] }
66
- "lint:black" = "black --check src"
67
- "lint:ruff" = "ruff --fix src"
68
-
69
- [tool.hatch.metadata]
70
- allow-direct-references = true
71
-
72
51
  [tool.mypy]
73
52
  strict = true
74
53
  warn_unreachable = true
@@ -77,5 +56,15 @@ show_column_numbers = true
77
56
  show_error_codes = true
78
57
  show_error_context = true
79
58
 
80
- [tool.hatch.build.targets.wheel]
81
- packages = ["src/revseq"]
59
+ [dependency-groups]
60
+ dev = [
61
+ "codecov>=2.1.13",
62
+ "coverage>=7.16.2",
63
+ "hypothesis>=6.168.5",
64
+ "nox>=2026.10.20",
65
+ "pytest>=9.2.0",
66
+ "pytest-cov>=7.1.0",
67
+ "ruff>=0.17.4",
68
+ "ty>=0.0.100",
69
+ ]
70
+
@@ -0,0 +1,168 @@
1
+ from collections import deque
2
+ from importlib.metadata import version
3
+ from typing import Annotated
4
+
5
+ import typer
6
+ from icontract import require
7
+ from rich import print as rprint
8
+ from typeguard import typechecked
9
+
10
+
11
+ def version_callback(value: bool) -> None:
12
+ """Prints the version of the package."""
13
+ if value:
14
+ rprint(f"[red]'revseq'[/red] version: {version('revseq')}")
15
+ raise typer.Exit()
16
+
17
+
18
+ app = typer.Typer(
19
+ name="revseq", help="Generate reversed, reverse complement, and complement sequences", no_args_is_help=True
20
+ )
21
+
22
+
23
+ @app.callback(invoke_without_command=True)
24
+ @app.command(no_args_is_help=True)
25
+ @require(
26
+ lambda seq: len(set(seq) - set("AGCTagctUuWwSsMmKkRrYyBbDdHhVvNn")) == 0,
27
+ error=lambda seq: ValueError(f"{seq} has non-standard DNA bases."),
28
+ )
29
+ def main(
30
+ seq: Annotated[str, typer.Argument()],
31
+ rev: Annotated[bool, typer.Option("-r", "--reverse", help="reverse sequence")] = False,
32
+ comp: Annotated[bool, typer.Option("-c", "--complement", help="complement sequence")] = False,
33
+ colorize: Annotated[bool, typer.Option("-l", "--colorize", help="add color to the sequence")] = False,
34
+ version: Annotated[
35
+ bool | None,
36
+ typer.Option(
37
+ "-v",
38
+ "--version",
39
+ callback=version_callback,
40
+ is_eager=True,
41
+ help="Prints the version.",
42
+ ),
43
+ ] = None,
44
+ ) -> None:
45
+
46
+ rprint(revseq(seq, rev, comp, colorize))
47
+
48
+
49
+ @require(
50
+ lambda seq: len(seq) != 0,
51
+ error=lambda _: ValueError("Nothing to do with an empty sequence"),
52
+ )
53
+ @typechecked
54
+ def revseq(
55
+ seq: str,
56
+ rev: bool = False,
57
+ comp: bool = False,
58
+ colorize: bool = False,
59
+ ) -> str:
60
+ """Generate a (reverse) (complement) of DNA sequence
61
+
62
+ Parameters
63
+ ----------
64
+ seq : str, required
65
+ sequence to manipulate
66
+ rev : bool, optional
67
+ return the reversed sequence
68
+ comp : bool, optional
69
+ return the complemented sequence
70
+ version : bool, optional
71
+ display version number
72
+
73
+ Returns
74
+ -------
75
+ str
76
+ the (reverse) (complement) sequence
77
+ """
78
+
79
+ seq_deque = deque(seq)
80
+
81
+ complement_dict = {
82
+ "A": "T",
83
+ "C": "G",
84
+ "G": "C",
85
+ "T": "A",
86
+ "a": "t",
87
+ "c": "g",
88
+ "g": "c",
89
+ "t": "a",
90
+ "U": "A",
91
+ "u": "a",
92
+ "W": "W",
93
+ "w": "w",
94
+ "S": "S",
95
+ "s": "s",
96
+ "M": "K",
97
+ "m": "k",
98
+ "K": "M",
99
+ "k": "m",
100
+ "R": "Y",
101
+ "r": "y",
102
+ "Y": "R",
103
+ "y": "r",
104
+ "B": "V",
105
+ "b": "v",
106
+ "D": "H",
107
+ "d": "h",
108
+ "H": "D",
109
+ "h": "d",
110
+ "V": "B",
111
+ "v": "b",
112
+ "N": "N",
113
+ "n": "n",
114
+ }
115
+
116
+ if rev:
117
+ seq_deque.reverse()
118
+
119
+ if comp:
120
+ seq_deque = deque([complement_dict[_] if _ in complement_dict else _ for _ in seq_deque])
121
+
122
+ if colorize:
123
+ seq_deque = add_color(seq_deque)
124
+
125
+ return "".join(seq_deque)
126
+
127
+
128
+ def add_color(seq: deque[str]) -> deque[str]:
129
+ repl_dict = {
130
+ "A": r"[red]A[/]",
131
+ "a": r"[red]a[/]",
132
+ "C": r"[yellow1]C[/]",
133
+ "c": r"[yellow1]c[/]",
134
+ "G": r"[green3]G[/]",
135
+ "g": r"[green3]g[/]",
136
+ "T": r"[dodger_blue2]T[/]",
137
+ "t": r"[dodger_blue2]t[/]",
138
+ "U": r"[dark_khaki]U[/]",
139
+ "u": r"[dark_khaki]u[/]",
140
+ "W": r"[dark_cyan]W[/]",
141
+ "w": r"[dark_cyan]w[/]",
142
+ "S": r"[orange]S[/]",
143
+ "s": r"[orange]s[/]",
144
+ "M": r"[chartreuse1]M[/]",
145
+ "m": r"[chartreuse1]m[/]",
146
+ "K": r"[purple]K[/]",
147
+ "k": r"[purple]k[/]",
148
+ "R": r"[dark_red]R[/]",
149
+ "r": r"[dark_red]r[/]",
150
+ "Y": r"[dark_green]Y[/]",
151
+ "y": r"[dark_green]y[/]",
152
+ "B": r"[yellow4]B[/]",
153
+ "b": r"[yellow4]b[/]",
154
+ "D": r"[magenta]D[/]",
155
+ "d": r"[magenta]d[/]",
156
+ "H": r"[gold1]H[/]",
157
+ "h": r"[gold1]h[/]",
158
+ "V": r"[#b8860b]V[/]",
159
+ "v": r"[#b8860b]v[/]",
160
+ "N": r"[#2f4f4f]N[/]",
161
+ "n": r"[#2f4f4f]n[/]",
162
+ }
163
+
164
+ return deque([repl_dict[x] for x in seq])
165
+
166
+
167
+ if __name__ == "__main__":
168
+ app() # pragma: no cover
@@ -1 +0,0 @@
1
- * text=auto eol=lf
@@ -1,47 +0,0 @@
1
- # This workflow will install Python dependencies, run tests and lint with a variety of Python versions
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3
- # modeled after https://github.com/python-poetry/poetry/blob/master/.github/workflows/release.yml
4
- name: Python package
5
-
6
- on:
7
- push:
8
- branches: [ "main" ]
9
- pull_request:
10
- branches: [ "main" ]
11
-
12
- jobs:
13
- build:
14
- runs-on: ubuntu-latest
15
- strategy:
16
- fail-fast: false
17
- matrix:
18
- python-version: ["3.8", "3.9", "3.10"]
19
- steps:
20
- - name: checkout code
21
- uses: actions/checkout@v3
22
-
23
- - name: Set up Python ${{ matrix.python-version }}
24
- uses: actions/setup-python@v3
25
- with:
26
- python-version: ${{ matrix.python-version }}
27
-
28
- - name: Install Poetry
29
- uses: abatilo/actions-poetry@v2.1.6
30
-
31
- - name: Install dependencies
32
- run: |
33
- poetry config virtualenvs.create false
34
- poetry install
35
-
36
- - name: Run tests and collect coverage
37
- run: pytest --cov --cov-report=xml --cov-fail-under=50
38
-
39
- - name: Upload coverage reports to Codecov with GitHub Action
40
- uses: codecov/codecov-action@v3
41
- with:
42
- token: ${{ secrets.CODECOV_TOKEN }} # not required for public repos
43
- files: ./coverage.xml
44
- flags: unittests # optional
45
- name: codecov-umbrella # optional
46
- fail_ci_if_error: true # optional (default = false)
47
- verbose: true # optional (default = false)
revseq-1.0.0/.gitignore DELETED
@@ -1,139 +0,0 @@
1
- # Byte-compiled / optimized / DLL files
2
- __pycache__/
3
- *.py[cod]
4
- *$py.class
5
-
6
- # C extensions*.so
7
-
8
- # Distribution / packaging
9
- .Python
10
- build/
11
- develop-eggs/
12
- dist/
13
- downloads/
14
- eggs/
15
- .eggs/
16
- lib/
17
- lib64/
18
- parts/
19
- sdist/
20
- var/
21
- wheels/
22
- share/python-wheels/
23
- *.egg-info/
24
- .installed.cfg
25
- *.egg
26
- MANIFEST
27
-
28
- # PyInstaller
29
- # Usually these files are written by a python script from a template
30
- # before PyInstaller builds the exe, so as to inject date/other infos into it.
31
- *.manifest
32
- *.spec
33
-
34
- # Installer logs
35
- pip-log.txt
36
- pip-delete-this-directory.txt
37
-
38
- # Unit test / coverage reports
39
- htmlcov/
40
- .tox/
41
- .nox/
42
- .coverage
43
- .coverage.*
44
- .cache
45
- nosetests.xml
46
- coverage.xml
47
- *.cover
48
- *.py,cover
49
- .hypothesis/
50
- .pytest_cache/
51
- cover/
52
-
53
- # Translations
54
- *.mo
55
- *.pot
56
-
57
- # Django stuff:
58
- *.log
59
- local_settings.py
60
- db.sqlite3
61
- db.sqlite3-journal
62
-
63
- # Flask stuff:
64
- instance/
65
- .webassets-cache
66
-
67
- # Scrapy stuff:
68
- .scrapy
69
-
70
- # Sphinx documentation
71
- docs/_build/
72
-
73
- # PyBuilder
74
- .pybuilder/
75
- target/
76
-
77
- # Jupyter Notebook
78
- .ipynb_checkpoints
79
-
80
- # IPython
81
- profile_default/
82
- ipython_config.py
83
-
84
- # pyenv
85
- # For a library or package, you might want to ignore these files since the code is
86
- # intended to run in multiple environments; otherwise, check them in:
87
- # .python-version
88
-
89
- # pipenv
90
- # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
91
- # However, in case of collaboration, if having platform-specific dependencies or dependencies
92
- # having no cross-platform support, pipenv may install dependencies that don't work, or not
93
- # install all needed dependencies.
94
- #Pipfile.lock
95
-
96
- # PEP 582; used by e.g. github.com/David-OConnor/pyflow
97
- __pypackages__/
98
-
99
- # Celery stuff
100
- celerybeat-schedule
101
- celerybeat.pid
102
-
103
- # SageMath parsed files
104
- *.sage.py
105
-
106
- # Environments
107
- .env
108
- .venv
109
- env/
110
- venv/
111
- ENV/
112
- env.bak/
113
- venv.bak/
114
-
115
- # Spyder project settings
116
- .spyderproject
117
- .spyproject
118
-
119
- # Rope project settings
120
- .ropeproject
121
-
122
- # mkdocs documentation
123
- /site
124
-
125
- # mypy
126
- .mypy_cache/
127
- .dmypy.json
128
- dmypy.json
129
-
130
- # Pyre type checker
131
- .pyre/
132
-
133
- # pytype static type analyzer
134
- .pytype/
135
-
136
- # Cython debug symbols
137
- cython_debug/
138
-
139
- debug.py
@@ -1,51 +0,0 @@
1
- repos:
2
- - repo: local
3
- hooks:
4
- # - id: black
5
- # name: black
6
- # entry: black
7
- # language: system
8
- # types: [python]
9
- # require_serial: true
10
- - id: check-added-large-files
11
- name: Check for added large files
12
- entry: check-added-large-files
13
- language: system
14
- - id: check-toml
15
- name: Check Toml
16
- entry: check-toml
17
- language: system
18
- types: [toml]
19
- - id: check-yaml
20
- name: Check Yaml
21
- entry: check-yaml
22
- language: system
23
- types: [yaml]
24
- # - id: end-of-file-fixer
25
- # name: Fix End of Files
26
- # entry: end-of-file-fixer
27
- # language: system
28
- # types: [text]
29
- # stages: [commit, push, manual]
30
- - id: flake8
31
- name: flake8
32
- entry: flake8
33
- language: system
34
- types: [python]
35
- require_serial: true
36
- # - id: reorder-python-imports
37
- # name: Reorder python imports
38
- # entry: reorder-python-imports
39
- # language: system
40
- # types: [python]
41
- # args: [--application-directories=src]
42
- - id: trailing-whitespace
43
- name: Trim Trailing Whitespace
44
- entry: trailing-whitespace-fixer
45
- language: system
46
- types: [text]
47
- stages: [commit, push, manual]
48
- # - repo: https://github.com/pre-commit/mirrors-prettier
49
- # rev: v2.4.1
50
- # hooks:
51
- # - id: prettier
@@ -1,20 +0,0 @@
1
- {
2
- // Use IntelliSense to learn about possible attributes.
3
- // Hover to view descriptions of existing attributes.
4
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5
- "version": "0.2.0",
6
- "configurations": [
7
- {
8
- "name": "this file",
9
- "type": "python",
10
- "request": "launch",
11
- "module": "pyplier.${fileBasenameNoExtension}",
12
- // "cwd": "${workspaceFolder}",
13
- // "console": "integratedTerminal",
14
- "justMyCode": true,
15
- "envFile": "${workspaceFolder}/.env",
16
- "env": {"PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT": "2"}
17
- }
18
- ]
19
- }
20
-
@@ -1,3 +0,0 @@
1
- {
2
- "esbonio.sphinx.confDir": ""
3
- }
revseq-1.0.0/.zprofile DELETED
@@ -1 +0,0 @@
1
- source '/home/milo/.rye/env'