Skip to content

Commit e9320d2

Browse files
committed
Update to ruff, typer, and new type annotations
1 parent 84dd9f0 commit e9320d2

File tree

11 files changed

+367
-336
lines changed

11 files changed

+367
-336
lines changed

.github/workflows/ci.yaml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Package CI
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
12+
jobs:
13+
build:
14+
runs-on: ubuntu-latest
15+
16+
strategy:
17+
matrix:
18+
python-version:
19+
- "3.12"
20+
21+
steps:
22+
- uses: actions/checkout@v3
23+
24+
- name: Python ${{ matrix.python-version }} setup
25+
uses: actions/setup-python@v4
26+
with:
27+
python-version: ${{ matrix.python-version }}
28+
29+
- name: Setup uv
30+
uses: astral-sh/setup-uv@v5
31+
with:
32+
version: 0.6.14
33+
enable-cache: true
34+
cache-local-path: ~/.cache/uv
35+
cache-dependency-glob: pyproject.toml
36+
37+
- name: Install package
38+
run: uv sync --all-extras --dev
39+
40+
- name: Run ruff
41+
shell: bash
42+
run: |
43+
uv run ruff check .
44+
uv run ruff format . --check
45+
46+
- name: Run mypy
47+
shell: bash
48+
run: |
49+
uv run mypy src --config pyproject.toml
50+
51+
- name: Run pytest
52+
shell: bash
53+
run: |
54+
uv run pytest tests

.vscode/extensions.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
{
22
"recommendations": [
3+
"charliermarsh.ruff",
34
"esbenp.prettier-vscode",
4-
"ms-python.black-formatter",
5-
"ms-python.isort",
65
"ms-python.mypy-type-checker",
7-
"ms-python.pylint",
86
"ms-python.python",
97
"tamasfe.even-better-toml",
108
"yzhang.markdown-all-in-one"

.vscode/settings.json

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
{
2-
"[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
32
"[markdown]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
4-
"[python]": { "editor.defaultFormatter": "ms-python.black-formatter" },
3+
"[python]": { "editor.defaultFormatter": "charliermarsh.ruff" },
54
"[toml]": { "editor.defaultFormatter": "tamasfe.even-better-toml" },
65
"editor.codeActionsOnSave": {
7-
"source.organizeImports": "explicit"
6+
"source.organizeImports": "explicit",
7+
"source.fixAll": "explicit"
88
},
9-
"black-formatter.args": ["--config", "pyproject.toml"],
10-
"cSpell.words": ["randn"],
119
"editor.defaultFormatter": "esbenp.prettier-vscode",
12-
"flake8.args": ["--max-line-length", "120"],
1310
"editor.detectIndentation": true,
1411
"editor.formatOnSave": true,
1512
"editor.insertSpaces": true,
1613
"editor.rulers": [120],
17-
"isort.args": ["--settings-file", "pyproject.toml"],
1814
"mypy-type-checker.args": ["--config-file", "pyproject.toml"],
1915
"prettier.printWidth": 120,
20-
"pylint.path": ["pylint"],
21-
"pylint.args": ["--rcfile", "pyproject.toml"]
16+
"ruff.configuration": "pyproject.toml",
17+
"ruff.nativeServer": true,
18+
"python.testing.pytestArgs": ["tests"],
19+
"python.testing.unittestEnabled": false,
20+
"python.testing.pytestEnabled": true
2221
}

pyproject.toml

Lines changed: 57 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,83 @@
22
authors = [
33
{ name = "Chris Gregory", email = "christopher.b.gregory@gmail.com" },
44
]
5-
classifiers = [
6-
"Intended Audience :: Developers",
7-
"Topic :: Software Development",
8-
"Programming Language :: Python",
9-
"Programming Language :: Python :: 3.11",
10-
"Programming Language :: Python :: 3.12",
11-
"Programming Language :: Python :: 3.13",
12-
]
13-
dependencies = ["click>=8.2.1", "numpy>=2.3.0"]
5+
dependencies = ["numpy>=2.3.0", "rich>=14.0.0", "typer>=0.16.0"]
146
description = "Artificial genetics simulation."
157
keywords = ["artificial", "genetics", "simulation"]
168
name = "typogenetics"
179
readme = "README.md"
18-
requires-python = ">=3.11"
10+
requires-python = ">=3.12"
1911
version = "0.1.0"
2012

21-
[project.urls]
22-
Repository = "https://github.com/gregorybchris/typogenetics"
23-
24-
[project.scripts]
25-
typo = "typogenetics.cli:main"
26-
27-
[dependency-groups]
28-
dev = ["black>=25.1.0", "mypy>=1.16.0", "pylint>=3.3.7", "pytest>=8.4.0"]
29-
30-
[tool.hatch.build.targets.sdist]
31-
include = ["typogenetics"]
32-
33-
[tool.hatch.build.targets.wheel]
34-
include = ["typogenetics"]
13+
[tool.uv]
14+
dev-dependencies = [
15+
"mypy>=1.16.0",
16+
"pytest>=8.4.0",
17+
"ruff>=0.11.13",
18+
"semver>=3.0.4",
19+
]
3520

3621
[build-system]
3722
build-backend = "hatchling.build"
3823
requires = ["hatchling"]
3924

40-
[tool.black]
41-
line-length = 120
25+
[project.urls]
26+
repository = "https://github.com/gregorybchris/typogenetics"
4227

43-
[tool.isort]
44-
line_length = 120
45-
profile = "black"
46-
src_paths = "*"
28+
[project.scripts]
29+
typo = "typogenetics.cli:app"
4730

4831
[tool.mypy]
4932
disallow_incomplete_defs = true
5033
disallow_untyped_calls = true
5134
disallow_untyped_defs = true
5235
ignore_missing_imports = true
5336

54-
[tool.pylint.basic]
55-
good-names = ["f", "i"]
56-
notes = ["FIXME"]
37+
[tool.ruff]
38+
line-length = 120
39+
src = ["src"]
5740

58-
[tool.pylint.format]
41+
[tool.ruff.lint]
42+
ignore = ["D100", "D104", "FIX002", "TD002", "TD003"]
43+
select = [
44+
"A",
45+
"ARG",
46+
"B",
47+
"BLE",
48+
"C4",
49+
"E",
50+
"EM",
51+
"ERA",
52+
"F",
53+
"FIX",
54+
"G",
55+
"I",
56+
"ICN",
57+
"ISC",
58+
"LOG",
59+
"N",
60+
"PL",
61+
"PT",
62+
"PTH",
63+
"PLR",
64+
"RET",
65+
"RUF",
66+
"SIM",
67+
"SLF",
68+
"T20",
69+
"TCH",
70+
"TD",
71+
"TID",
72+
"W",
73+
]
74+
75+
[tool.ruff.lint.pycodestyle]
5976
max-line-length = 120
6077

61-
[tool.pylint.messages_control]
62-
disable = [
63-
"missing-function-docstring",
64-
"missing-module-docstring",
65-
"missing-class-docstring",
66-
"logging-fstring-interpolation",
67-
]
78+
[tool.ruff.lint.pydocstyle]
79+
convention = "google"
6880

69-
[tool.pylint.reports]
70-
output-format = "colorized"
81+
[tool.ruff.lint.extend-per-file-ignores]
82+
"**/*.py" = ["A001", "A002"]
83+
"**/tests/**/*.py" = ["SLF", "PLR2004", "PLR6301"]
84+
"src/typogenetics/cli.py" = ["T201", "T203"]

src/typogenetics/cli.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import logging
2+
from typing import Annotated, Optional
3+
4+
import numpy as np
5+
from rich.console import Console
6+
from rich.logging import RichHandler
7+
from typer import Argument, Option, Typer
8+
9+
from typogenetics.search import Search
10+
from typogenetics.typogenetics import Enzyme, Folder, Rewriter, Strand, Translator
11+
12+
logger = logging.getLogger(__name__)
13+
14+
app = Typer(pretty_exceptions_enable=False)
15+
console = Console()
16+
17+
18+
def set_logger_config(info: bool, debug: bool) -> None:
19+
handlers = [RichHandler(rich_tracebacks=True)]
20+
log_format = "%(message)s"
21+
22+
if info:
23+
logging.basicConfig(level=logging.INFO, handlers=handlers, format=log_format)
24+
if debug:
25+
logging.basicConfig(level=logging.DEBUG, handlers=handlers, format=log_format)
26+
27+
28+
@app.command()
29+
def translate(
30+
strand_str: Annotated[str, Argument(...)],
31+
info: Annotated[bool, Option("--info/--no-info")] = True,
32+
debug: Annotated[bool, Option("--debug/--no-debug")] = False,
33+
) -> None:
34+
set_logger_config(info, debug)
35+
36+
strand = Strand.from_str(strand_str)
37+
enzymes = Translator.translate(strand)
38+
for enzyme in enzymes:
39+
console.print(enzyme)
40+
41+
42+
@app.command()
43+
def rewrite(
44+
enzyme_str: Annotated[str, Argument(...)],
45+
strand_str: Annotated[str, Argument(...)],
46+
info: Annotated[bool, Option("--info/--no-info")] = True,
47+
debug: Annotated[bool, Option("--debug/--no-debug")] = False,
48+
) -> None:
49+
set_logger_config(info, debug)
50+
51+
enzyme = Enzyme.from_str(enzyme_str)
52+
strand = Strand.from_str(strand_str)
53+
new_strands = Rewriter.rewrite(enzyme, strand)
54+
console.print("New strands:")
55+
for new_strand in new_strands:
56+
console.print(f"- {new_strand}")
57+
58+
59+
@app.command()
60+
def simulate( # noqa: PLR0913
61+
init_strand_str: Annotated[str, Argument(...)],
62+
n_iterations: Annotated[int, Option("--iter")] = 100_000,
63+
seed: Annotated[Optional[int], Option("--seed")] = None,
64+
print_strands: Annotated[bool, Option("--print-strands/--no-print-strands")] = False,
65+
info: Annotated[bool, Option("--info/--no-info")] = True,
66+
debug: Annotated[bool, Option("--debug/--no-debug")] = False,
67+
) -> None:
68+
set_logger_config(info, debug)
69+
70+
rng = np.random.default_rng(seed)
71+
init_strand = Strand.from_str(init_strand_str)
72+
73+
Search.random(init_strand, n_iterations, rng, print_strands=print_strands)
74+
75+
76+
@app.command()
77+
def search( # noqa: PLR0913
78+
init_strand_str: Annotated[str, Argument(...)],
79+
apply_strand_str: Annotated[str, Argument(...)],
80+
target_depth: Annotated[int, Option("--depth")] = 10,
81+
seed: Annotated[Optional[int], Option("--seed")] = None,
82+
n_edits: Annotated[int, Option("--edits")] = 10,
83+
print_strands: Annotated[bool, Option("--print-strands/--no-print-strands")] = False,
84+
info: Annotated[bool, Option("--info/--no-info")] = True,
85+
debug: Annotated[bool, Option("--debug/--no-debug")] = False,
86+
) -> None:
87+
set_logger_config(info, debug)
88+
89+
rng = np.random.default_rng(seed)
90+
init_strand = Strand.from_str(init_strand_str)
91+
apply_strand = Strand.from_str(apply_strand_str)
92+
93+
Search.bfs(init_strand, apply_strand, target_depth, n_edits, rng, print_strands=print_strands)
94+
95+
96+
@app.command()
97+
def go(
98+
info: Annotated[bool, Option("--info/--no-info")] = True,
99+
debug: Annotated[bool, Option("--debug/--no-debug")] = False,
100+
) -> None:
101+
set_logger_config(info, debug)
102+
103+
strand = Strand.from_str("CAAGGGTATACCCCATATCCT")
104+
console.print(strand)
105+
106+
enzymes = Translator.translate(strand)
107+
console.print(enzymes)
108+
109+
enzyme = enzymes[0]
110+
unit = Folder.get_binding_site(enzyme, strand)
111+
console.print(unit)
112+
113+
new_strands = Rewriter.rewrite(enzyme, strand)
114+
console.print(new_strands)

0 commit comments

Comments
 (0)