Skip to content

Commit

Permalink
Switch to pyproject.toml (#240)
Browse files Browse the repository at this point in the history
* Switch to `pyproject.toml
* Add pytest-xdist as test dependency & improve GH Actions
GH Actions:
- Use more processes in xdist for speedup
- Upload coverage to Codecov in separate job
- Add build test
- General 
* Support python 3.
* Consolidate pytest & bandit configs into `pyproject.toml
* Coverage: improve exclusions
  • Loading branch information
MetRonnie authored Oct 20, 2023
1 parent 9e259e7 commit 05627f1
Show file tree
Hide file tree
Showing 10 changed files with 233 additions and 199 deletions.
1 change: 0 additions & 1 deletion .bandit

This file was deleted.

18 changes: 17 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,26 @@ source=
[report]
exclude_lines =
pragma: no cover

def __repr__
raise NotImplementedError
@(abc\.)?abstractmethod

# Ignore code that can only run in CLI:
if __name__ == .__main__.:

# Don't complain if tests don't hit defensive assertion code:
raise NotImplementedError
return NotImplemented

# Ignore type checking code:
if (typing\.)?TYPE_CHECKING:
@overload( |$)

# Don't complain about ellipsis (exception classes, typing overloads etc):
\.\.\.

def parse_args

omit=
metomi/isodatetime/tests
precision=2
51 changes: 51 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Build

# build the project whenever the configuration is changed

on:
workflow_dispatch:
pull_request:
paths:
- 'README.md' # check markdown is valid
- 'MANIFEST.in' # check packaging
- 'pyproject.toml' # check build config

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
FORCE_COLOR: 2

jobs:
build:
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
matrix:
os: ['ubuntu-latest']
python: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
include:
- os: 'macos-latest'
python: '3.7'
name: ${{ matrix.os }} py-${{ matrix.python }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}

- name: Build
uses: cylc/release-actions/build-python-package@v1
with:
check-dependencies: false

- name: Inspect
run: |
unzip -l dist/*.whl | tee files
grep 'metomi/isodatetime/data.py' files
grep 'metomi_isodatetime.*.dist-info/LICENSE' files
# grep 'metomi/isodatetime/py.typed' files # (not yet added)
80 changes: 58 additions & 22 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,41 @@ on:
pull_request:
push:
branches: [master]
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
FORCE_COLOR: 2

jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 45
timeout-minutes: 40
strategy:
matrix:
os: [ubuntu-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
coverage: [false]
include:
# Modify existing configurations:
- os: ubuntu-latest
python-version: '3.11'
python-version: '3.12'
coverage: false
tz: 'XXX-05:30' # UTC+05:30
# Add new configurations:
- os: ubuntu-latest
python-version: '3.11'
python-version: '3.12'
coverage: true
- os: macos-latest
python-version: '3.11'
python-version: '3.12'
coverage: false
name: ${{ matrix.os }} py-${{ matrix.python-version }} ${{ matrix.tz }} ${{ matrix.coverage && '(coverage)' || '' }}
env:
PYTEST_ADDOPTS: -n 5 -m 'slow or not slow'
steps:

- name: Checkout repo
uses: actions/checkout@v4

Expand All @@ -38,27 +48,53 @@ jobs:
python-version: ${{ matrix.python-version }}

- name: Install
run: |
pip install --upgrade pip setuptools
pip install -e .[all]
pip install pytest-xdist
run: pip install -e .[all]

- name: Style test
run: flake8 metomi/isodatetime
- name: Style
if: ${{ !matrix.coverage }}
run: flake8

- name: Bandit
if: ${{ !matrix.coverage }}
run: bandit -r metomi/isodatetime -c pyproject.toml

- name: Run tests
env:
TZ: ${{ matrix.tz }}
run: |
PYTEST_ARGS=(-n 2 -m 'slow or not slow')
if ${{ matrix.coverage }}; then
PYTEST_ARGS+=('--cov=metomi/isodatetime')
fi
PYTEST_ADDOPTS: ${{ matrix.coverage && format('{0} --cov=metomi/isodatetime', env.PYTEST_ADDOPTS) || env.PYTEST_ADDOPTS }}
run: pytest

pytest "${PYTEST_ARGS[@]}"
- name: Upload coverage report
- name: Coverage report
if: matrix.coverage
run: |
coverage xml --ignore-errors
bash <(curl -s https://codecov.io/bash)
coverage xml
coverage report
- name: Upload coverage artifact
if: matrix.coverage
uses: actions/upload-artifact@v3
with:
name: coverage_${{ matrix.os }}_py-${{ matrix.python-version }}
path: coverage.xml
retention-days: 4

codecov-upload:
needs: test
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Download coverage artifacts
uses: actions/download-artifact@v3

- name: Codecov upload
uses: codecov/codecov-action@v3
with:
name: ${{ github.workflow }}
fail_ci_if_error: true
verbose: true
# Token not required for public repos, but avoids upload failure due
# to rate-limiting (but not for PRs opened from forks)
token: ${{ secrets.CODECOV_TOKEN }}
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ isodatetime
[![Test](https://github.com/metomi/isodatetime/workflows/Test/badge.svg?event=push)](https://github.com/metomi/isodatetime/actions?query=workflow%3ATest)
[![codecov](https://codecov.io/gh/metomi/isodatetime/branch/master/graph/badge.svg)](https://codecov.io/gh/metomi/isodatetime)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.597555.svg)](https://doi.org/10.5281/zenodo.597555)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/1fd1147b75474d4d9a0f64bececf3bb5)](https://www.codacy.com/app/metomi/isodatetime?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=metomi/isodatetime&amp;utm_campaign=Badge_Grade)
[![PYPI Badge](https://img.shields.io/pypi/v/metomi-isodatetime)](https://pypi.org/project/metomi-isodatetime/)

Python [ISO8601 (2004)](https://www.iso.org/standard/40874.html)
Expand All @@ -19,13 +18,7 @@ Install from PyPI:
$ pip install metomi-isodatetime
```

Or build yourself:

```console
$ git clone https://github.com/metomi/isodatetime.git isodatetime
$ cd isodatetime
$ python setup.py install
```
Or with conda: see https://github.com/conda-forge/metomi-isodatetime-feedstock

## Usage

Expand Down
2 changes: 2 additions & 0 deletions metomi/isodatetime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@
"""Python ISO 8601 date time parser and data model/manipulation utilities."""

__version__ = "3.1.0"

FULL_VERSION = f"1!{__version__}"
104 changes: 104 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Copyright (C) British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

[build-system]
requires = ["setuptools >= 49.0"]
build-backend = "setuptools.build_meta"


[project]
name = "metomi-isodatetime"
authors = [
{name = "Met Office", email = "metomi@metoffice.gov.uk"}
]
description = "Python ISO 8601 date time parser and data model/manipulation utilities"
license = {text = "LGPLv3"}
readme = "README.md"
keywords = ["isodatetime", "datetime", "iso8601", "date", "time", "parser"]
requires-python = ">=3.7"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Other Environment",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Utilities"
]
dynamic = ["version"]


[project.urls]
Homepage = "https://github.com/metomi/isodatetime"
Repository = "https://github.com/metomi/isodatetime"
Changelog = "https://github.com/metomi/isodatetime/blob/master/CHANGES.md"


[tool.setuptools]
platforms = ["any"]


[tool.setuptools.dynamic]
version = {attr = "metomi.isodatetime.FULL_VERSION"}


[tool.setuptools.packages.find]
include = ["metomi*"]
exclude = ["metomi.isodatetime.tests*"]


[tool.setuptools.package-data]
"metomi.isodatetime" = ["py.typed"]


[project.scripts]
isodatetime = "metomi.isodatetime.main:main"


[project.optional-dependencies]
test = [
"coverage",
"pytest>=6",
"pytest-env",
"pytest-cov",
"pytest-xdist",
"flake8",
"bandit>=1.7.1",
]
all = [
"metomi-isodatetime[test]",
]


[tool.pytest.ini_options]
addopts = "-v -s -ra --color=auto --doctest-glob='*.md' -m 'not slow'"
markers = [
"slow: mark a test as slow - it will be skipped by default (use '-m \"slow or not slow\"' to run all tests)"
]
testpaths = [
"metomi/isodatetime/tests",
"README.md",
]


[tool.bandit]
exclude_dirs = ["metomi/isodatetime/tests"]
28 changes: 0 additions & 28 deletions pytest.ini

This file was deleted.

24 changes: 0 additions & 24 deletions setup.cfg

This file was deleted.

Loading

0 comments on commit 05627f1

Please sign in to comment.