Skip to content

Commit

Permalink
Merge branch 'main' into 480-assert-bad
Browse files Browse the repository at this point in the history
  • Loading branch information
jsstevenson committed Jan 31, 2025
2 parents 9ae00c3 + 51f08c9 commit 89ea006
Show file tree
Hide file tree
Showing 35 changed files with 2,166 additions and 1,473 deletions.
39 changes: 30 additions & 9 deletions .github/workflows/python-cqa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,34 @@ name: Python CQA

on: [push, pull_request]


# TODO: separate lint and test jobs; lint first, test "needs" lint
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobs

jobs:
test:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actions/setup-python@v5
- name: Update pip and setuptools
run: |
python -m pip install --upgrade pip setuptools
- name: Install dependencies
run: pip install -e '.[dev]'
- name: Check style
run: python3 -m ruff check --output-format=github
- name: Check formatting
run: python3 -m ruff format --check

test:
runs-on: ubuntu-latest
needs:
- lint
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
env:
SEQREPO_ROOT_DIR: ./tests/data/seqrepo/latest

steps:
- uses: actions/checkout@v4
with:
Expand All @@ -43,7 +56,15 @@ jobs:
precommit_hooks:
runs-on: ubuntu-latest
strategy:
matrix:
cmd:
- "end-of-file-fixer"
- "trailing-whitespace"
- "mixed-line-ending"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: pre-commit/[email protected]
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: pre-commit/[email protected]
with:
extra_args: ${{ matrix.cmd }} --all-files
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ repos:
args: [ --allow-missing-credentials ]
- id: mixed-line-ending
args: [ --fix=lf ]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.4 # ruff version
hooks:
- id: ruff-format
- id: ruff
args: [ --fix, --exit-non-zero-on-fix ]
minimum_pre_commit_version: 4.0.1
15 changes: 5 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ else
endif
XRM=xargs -0${_XRM_R} rm

PKG=ga4gh.vrs
PKGD=$(subst .,/,${PKG})
PYV:=3.12
VEDIR=venv/${PYV}

Expand Down Expand Up @@ -89,18 +87,15 @@ doctest:
############################################################################
#= UTILITY TARGETS

# N.B. Although code is stored in github, I use hg and hg-git on the command line
#=> reformat: reformat code with yapf and commit
.PHONY: reformat
reformat:
@if ! git diff --cached --exit-code; then echo "Repository not clean" 1>&2; exit 1; fi
yapf -i -r "${PKGD}" tests
git commit -a -m "reformatted with yapf"
#=> reformat: reformat code with ruff
.PHONY: format
format:
python3 -m ruff format

#=> lint -- static analysis check
.PHONY: lint
lint:
pylint src/ga4gh/{core,vrs} | tee $@
python3 -m ruff check --fix

#=> docs -- make sphinx docs
.PHONY: docs
Expand Down
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: "3"

services:
seqrepo:
image: biocommons/seqrepo:2024-02-20
Expand Down
145 changes: 137 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ dev = [
"pyyaml",
# style
"pre-commit>=4.0.1",
"pylint",
"yapf",
"ruff==0.9.4",
# docs
"sphinx",
"sphinx_rtd_theme",
Expand Down Expand Up @@ -96,9 +95,139 @@ addopts = "--cov-report=term-missing --cov=ga4gh"
testpaths = ["tests", "src"]
doctest_optionflags = "ALLOW_UNICODE ALLOW_BYTES ELLIPSIS IGNORE_EXCEPTION_DETAIL NORMALIZE_WHITESPACE"

[tool.yapf]
based_on_style = "pep8"
column_limit = 120
spaces_before_comment = 4
split_before_logical_operator = true
split_before_named_assigns = true
[tool.ruff]
src = ["src"]
exclude = ["docs", "misc", "notebooks", "submodules"]

[tool.ruff.lint]
select = [
"F", # https://docs.astral.sh/ruff/rules/#pyflakes-f
"E", "W", # https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
"I", # https://docs.astral.sh/ruff/rules/#isort-i
"N", # https://docs.astral.sh/ruff/rules/#pep8-naming-n
"D", # https://docs.astral.sh/ruff/rules/#pydocstyle-d
"UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up
"ANN", # https://docs.astral.sh/ruff/rules/#flake8-annotations-ann
"ASYNC", # https://docs.astral.sh/ruff/rules/#flake8-async-async
"S", # https://docs.astral.sh/ruff/rules/#flake8-bandit-s
"B", # https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
"A", # https://docs.astral.sh/ruff/rules/#flake8-builtins-a
"C4", # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
"DTZ", # https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz
"T10", # https://docs.astral.sh/ruff/rules/#flake8-datetimez-dtz
"EM", # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
"LOG", # https://docs.astral.sh/ruff/rules/#flake8-logging-log
"G", # https://docs.astral.sh/ruff/rules/#flake8-logging-format-g
"INP", # https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp
"PIE", # https://docs.astral.sh/ruff/rules/#flake8-pie-pie
"T20", # https://docs.astral.sh/ruff/rules/#flake8-print-t20
"PT", # https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
"Q", # https://docs.astral.sh/ruff/rules/#flake8-quotes-q
"RSE", # https://docs.astral.sh/ruff/rules/#flake8-raise-rse
"RET", # https://docs.astral.sh/ruff/rules/#flake8-return-ret
"SLF", # https://docs.astral.sh/ruff/rules/#flake8-self-slf
"SLOT", # https://docs.astral.sh/ruff/rules/#flake8-slots-slot
"SIM", # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
"ARG", # https://docs.astral.sh/ruff/rules/#flake8-unused-arguments-arg
"PTH", # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
"PGH", # https://docs.astral.sh/ruff/rules/#pygrep-hooks-pgh
"PLC", # https://docs.astral.sh/ruff/rules/#convention-c
"PLE", # https://docs.astral.sh/ruff/rules/#error-e_1
"TRY", # https://docs.astral.sh/ruff/rules/#tryceratops-try
"PERF", # https://docs.astral.sh/ruff/rules/#perflint-perf
"FURB", # https://docs.astral.sh/ruff/rules/#refurb-furb
"RUF", # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf
]
fixable = ["ALL"]
# ANN002 - missing-type-args
# ANN003 - missing-type-kwargs
# D203 - one-blank-line-before-class
# D205 - blank-line-after-summary
# D206 - indent-with-spaces*
# D213 - multi-line-summary-second-line
# D300 - triple-single-quotes*
# D400 - ends-in-period
# D415 - ends-in-punctuation
# E111 - indentation-with-invalid-multiple*
# E114 - indentation-with-invalid-multiple-comment*
# E117 - over-indented*
# E501 - line-too-long*
# W191 - tab-indentation*
# S321 - suspicious-ftp-lib-usage
# PLC0206 - dict-index-missing-items
# *ignored for compatibility with formatter
ignore = [
"ANN002", "ANN003",
"D203", "D205", "D206", "D213", "D300", "D400", "D415",
"E111", "E114", "E117", "E501",
"W191",
"S321",
"PLC0206",
]
exclude = [
"src/ga4gh/vrs/models.py", # there be monsters here
]

[tool.ruff.lint.per-file-ignores]
# ANN001 - missing-type-function-argument
# ANN2 - missing-return-type
# D100 - undocumented-public-module
# D102 - undocumented-public-class
# D103 - undocumented-public-function
# S101 - assert
# B011 - assert-false
# INP001 - implicit-namespace-package
# SLF001 - private-member-access
"tests/*" = [
"ANN001",
"ANN2",
"D100",
"D102",
"D103",
"S101",
"B011",
"INP001",
"SLF001",
]
"src/ga4gh/vrs/utils/hgvs_tools.py" = [
"ANN001",
"ANN201",
"ANN202",
"D102",
]
"src/ga4gh/vrs/normalize.py" = [
"ANN001",
"ANN201",
"ANN202",
]
"src/ga4gh/vrs/extras/vcf_annotation.py" = [
"PTH123", # see https://github.com/ga4gh/vrs-python/issues/482
]
"src/ga4gh/vrs/extras/translator.py" = [
"ANN001",
"ANN101",
"ANN2",
]
"src/ga4gh/vrs/extras/object_store.py" = [
"ANN",
"D",
]
"src/ga4gh/vrs/enderef.py" = [
"ANN",
"D",
]
"src/ga4gh/vrs/dataproxy.py" = [
"B019",
]
"src/ga4gh/core/pydantic.py" = [
"ANN401",
]
"src/ga4gh/core/models.py" = [
"UP007",
]

[tool.ruff.lint.flake8-annotations]
mypy-init-return = true

[tool.ruff.format]
docstring-code-format = true
60 changes: 32 additions & 28 deletions src/ga4gh/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,51 @@
"""Python support used across GA4GH projects
"""Python support used across GA4GH projects"""

"""
from importlib.metadata import PackageNotFoundError, version

from importlib.metadata import version, PackageNotFoundError

from .digests import sha512t24u
from .enderef import ga4gh_enref, ga4gh_deref
from .identifiers import (
ga4gh_digest, ga4gh_identify, ga4gh_serialize, is_ga4gh_identifier,
VrsObjectIdentifierIs, use_ga4gh_compute_identifier_when,
CURIE_NAMESPACE, CURIE_SEP, GA4GH_PREFIX_SEP, GA4GH_IR_REGEXP, GA4GH_DIGEST_REGEXP,
PrevVrsVersion
)
from .pydantic import (
is_pydantic_instance, is_curie_type, pydantic_copy
import ga4gh.core.models as core_models
from ga4gh.core.digests import sha512t24u
from ga4gh.core.enderef import ga4gh_deref, ga4gh_enref
from ga4gh.core.identifiers import (
CURIE_NAMESPACE,
CURIE_SEP,
GA4GH_DIGEST_REGEXP,
GA4GH_IR_REGEXP,
GA4GH_PREFIX_SEP,
PrevVrsVersion,
VrsObjectIdentifierIs,
ga4gh_digest,
ga4gh_identify,
ga4gh_serialize,
is_ga4gh_identifier,
use_ga4gh_compute_identifier_when,
)
from . import models as core_models
from ga4gh.core.pydantic import is_curie_type, is_pydantic_instance, pydantic_copy

__all__ = [
"sha512t24u",
"ga4gh_enref",
"CURIE_NAMESPACE",
"CURIE_SEP",
"GA4GH_DIGEST_REGEXP",
"GA4GH_IR_REGEXP",
"GA4GH_PREFIX_SEP",
"PrevVrsVersion",
"VrsObjectIdentifierIs",
"core_models",
"ga4gh_deref",
"ga4gh_digest",
"ga4gh_enref",
"ga4gh_identify",
"ga4gh_serialize",
"is_curie_type",
"is_ga4gh_identifier",
"VrsObjectIdentifierIs",
"use_ga4gh_compute_identifier_when",
"CURIE_NAMESPACE",
"CURIE_SEP",
"GA4GH_PREFIX_SEP",
"GA4GH_IR_REGEXP",
"GA4GH_DIGEST_REGEXP",
"PrevVrsVersion",
"is_pydantic_instance",
"is_curie_type",
"pydantic_copy",
"core_models",
"sha512t24u",
"use_ga4gh_compute_identifier_when",
]

try:
__version__ = version(__name__)
except PackageNotFoundError: # pragma: nocover
except PackageNotFoundError: # pragma: nocover
__version__ = "unknown"
finally:
del version, PackageNotFoundError
7 changes: 3 additions & 4 deletions src/ga4gh/core/digests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import hashlib


def sha512t24u(blob):
"""generate a base64url-encode, truncated SHA-512 digest for given
def sha512t24u(blob: bytes) -> str:
"""Generate a base64url-encode, truncated SHA-512 digest for given
binary data
The sha512t24u digest is a convention for constructing and
Expand All @@ -21,14 +21,13 @@ def sha512t24u(blob):
* encode using base64url encoding
Examples:
>>> sha512t24u(b'')
>>> sha512t24u(b"")
'z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXc'
>>> sha512t24u(b"ACGT")
'aKF498dAxcJAqme6QYQ7EZ07-fiw8Kw2'
"""

digest_size = 24
digest = hashlib.sha512(blob).digest()
tdigest_b64us = base64.urlsafe_b64encode(digest[:digest_size])
Expand Down
Loading

0 comments on commit 89ea006

Please sign in to comment.