Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Set up proper type checking (#112) #113

Merged
merged 4 commits into from
Jan 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,31 @@ jobs:
- '3.12'

steps:
- name: Install Python via conda.
uses: s-weigand/setup-conda@v1
- name: Install Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
conda-channels: defaults,bioconda,conda-forge
python-version: "${{ matrix.python-version }}"

- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
lfs: true
- name: Install mamba.
run: conda install -y mamba

- name: Install test dependencies via pip
run: pip install -r requirements/test_black.txt

- name: Lint
run: make lint

- name: Run tests
run: pytest
- name: Create text report
run: coverage report
- name: Create XML report for codacy
run: coverage xml
run: |
make test
coverage report
coverage xml

- name: Upload Python coverage reports to Codecov
uses: codecov/codecov-action@v3
with:
flags: python
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Check style with black
run: make black-check
- name: Check style with flake8
run: flake8 .
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ recursive-exclude * *.py[co]
recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif

include versioneer.py
include vcfpy/_version.py
include altamisa/_version.py
include altamisa/py.typed

include requirements.txt requirements/*.txt
50 changes: 44 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,21 +1,59 @@
.PHONY: default black flake8 test test-v test-vv
.PHONY: default
default: help

default: black flake8
.PHONY: help
help:
@echo "make help - show this help"
@echo "make lint - run all linting"
@echo "make format - run all formatting"
@echo "make lint-isort - run isort linting"
@echo "make format-isort - run isort formatting"
@echo "make lint-black - run black linting"
@echo "make format-black - run black formatting"
@echo "make lint-flake8 - run flake8 linting"
@echo "make lint-pyright - run pyright linting"
@echo "make test - run all tests"
@echo "make test-v - run all tests with verbose output"
@echo "make test-vv - run all tests with very verbose output"

black:
black -l 100 --exclude "versioneer.py|_version.py" .
.PHONY: lint
lint: lint-isort lint-black lint-flake8 lint-pyright

.PHONY: format
format: format-isort format-black

.PHONY: lint-isort
lint-isort:
isort --check-only --diff --force-sort-within-sections --profile=black .

.PHONY: format-isort
format-isort:
isort --force-sort-within-sections --profile=black .

black-check:
.PHONY: lint-black
lint-black:
black -l 100 --exclude "versioneer.py|_version.py" --check .

flake8:
.PHONY: format-black
format-black:
black -l 100 --exclude "versioneer.py|_version.py" .

.PHONY: lint-flake8
lint-flake8:
flake8 .

.PHONY: lint-pyright
lint-pyright:
pyright

.PHONY: test
test:
pytest

.PHONY: test-v
test-v:
pytest -v

.PHONY: test-vv
test-vv:
pytest -vv
2 changes: 1 addition & 1 deletion altamisa/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
"""Git implementation of _version.py."""

import errno
import functools
import os
import re
import subprocess
import sys
from typing import Any, Callable, Dict, List, Optional, Tuple
import functools


def get_keywords() -> Dict[str, str]:
Expand Down
130 changes: 83 additions & 47 deletions altamisa/apps/isatab2dot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,25 @@
"""Conversion of ISA-Tab to dot.
"""

from contextlib import ExitStack
import json
import sys
import os
import argparse
import sys

import attrs
import typer
from typing_extensions import Annotated

from altamisa.isatab import AssayReader, InvestigationReader, StudyReader

#: Typer application instance.
app = typer.Typer()

from altamisa.isatab import InvestigationReader, StudyReader, AssayReader

@attrs.define
class Arguments:
investigation_file: str
output_file: str


def print_dot(
Expand Down Expand Up @@ -49,55 +62,78 @@ def print_dot(
print("{}{} -> {};".format(indent, json.dumps(arc.tail), json.dumps(arc.head)), file=outf)


def run(args):
def run(args: Arguments):
with open(args.investigation_file, "rt") as inputf:
investigation = InvestigationReader.from_stream(inputf).read()

path = os.path.dirname(args.investigation_file)

print("digraph investigation {", file=args.output_file)
print(' rankdir = "LR";', file=args.output_file)

for s, study_info in enumerate(investigation.studies):
with open(os.path.join(path, study_info.info.path), "rt") as inputf:
study = StudyReader.from_stream("S{}".format(s + 1), inputf).read()
print(" /* study {} */".format(study_info.info.path), file=args.output_file)
print(" subgraph clusterStudy{} {{".format(s), file=args.output_file)
print(' label = "Study: {}"'.format(study_info.info.path), file=args.output_file)
print_dot(study, args.output_file)
print(" }", file=args.output_file)

for a, assay_info in enumerate(study_info.assays):
with open(os.path.join(path, assay_info.path), "rt") as inputf:
assay = AssayReader.from_stream(
"S{}".format(s + 1), "A{}".format(a + 1), inputf
).read()
print(" /* assay {} */".format(assay_info.path), file=args.output_file)
print(" subgraph clusterAssayS{}A{} {{".format(s, a), file=args.output_file)
print(' label = "Assay: {}"'.format(assay_info.path), file=args.output_file)
print_dot(assay, args.output_file)
print(" }", file=args.output_file)

print("}", file=args.output_file)


def main(argv=None):
parser = argparse.ArgumentParser()

parser.add_argument(
"-i", "--investigation-file", required=True, help="Path to investigation file"
)
parser.add_argument(
"-o",
"--output-file",
default="-",
type=argparse.FileType("wt"),
help='Path to output file, stdout ("-") by default',
with ExitStack() as stack:
if args.output_file == "-":
output_file = sys.stdout
else:
output_file = stack.enter_context(open(args.output_file, "wt"))

print("digraph investigation {", file=output_file)
print(' rankdir = "LR";', file=output_file)

for s, study_info in enumerate(investigation.studies):
if not study_info.info.path:
print(" /* no file for study {} */".format(s + 1), file=output_file)
continue
with open(os.path.join(path, study_info.info.path), "rt") as inputf:
study = StudyReader.from_stream("S{}".format(s + 1), inputf).read()
print(" /* study {} */".format(study_info.info.path), file=output_file)
print(" subgraph clusterStudy{} {{".format(s), file=output_file)
print(' label = "Study: {}"'.format(study_info.info.path), file=output_file)
print_dot(study, output_file)
print(" }", file=output_file)

for a, assay_info in enumerate(study_info.assays):
if not assay_info.path:
print(" /* no file for assay {} */".format(a + 1), file=output_file)
continue
with open(os.path.join(path, assay_info.path), "rt") as inputf:
assay = AssayReader.from_stream(
"S{}".format(s + 1), "A{}".format(a + 1), inputf
).read()
print(" /* assay {} */".format(assay_info.path), file=output_file)
print(" subgraph clusterAssayS{}A{} {{".format(s, a), file=output_file)
print(' label = "Assay: {}"'.format(assay_info.path), file=output_file)
print_dot(assay, output_file)
print(" }", file=output_file)

print("}", file=output_file)


@app.command()
def main(
investigation_file: Annotated[
str,
typer.Option(
"--investigation-file",
"-i",
help="Path to input investigation file",
),
],
output_file: Annotated[
str,
typer.Option(
"--output-file",
"-o",
help="Path to output file, stdout ('-') by default",
),
] = "-",
):
"""Main entry point."""
# Convert to `Arguments` object.
args = Arguments(
investigation_file=investigation_file,
output_file=output_file,
)

args = parser.parse_args(argv)
return run(args)
# Actually run.
run(args)


if __name__ == "__main__":
sys.exit(main()) # pragma: no cover
if __name__ == "__main__": # pragma: no cover
typer.run(main)
Loading
Loading