Skip to content

Commit

Permalink
Switch project to use pyproject.toml (#141)
Browse files Browse the repository at this point in the history
* Switch project to use pyproject.toml

* Fix codespell errors

* Fix ruff errors

* Extend CONTRIBUTING

* Fix package dependencies

* Clean up setup files

* Fix pytest config

* Fix codespell setting
  • Loading branch information
hagenw authored Jul 26, 2023
1 parent fe196a8 commit a118b6d
Show file tree
Hide file tree
Showing 23 changed files with 297 additions and 125 deletions.
10 changes: 10 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[flake8]
exclude =
.eggs,
build,
extend-ignore =
# math, https://github.com/PyCQA/pycodestyle/issues/513
W503,
per-file-ignores =
# ignore unused imports
__init__.py: F401
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Flake8
name: Linter

on:
push:
Expand Down
10 changes: 6 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ on:

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
with:
Expand All @@ -21,18 +23,18 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
pip install build twine virtualenv
# PyPI package
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
python -m build
python -m twine upload dist/*
# Docuemntation
# Documentation
- name: Install doc dependencies
run: |
pip install -r requirements.txt
Expand Down Expand Up @@ -60,7 +62,7 @@ jobs:
CHANGELOG="${CHANGELOG//$'\n'/'%0A'}"
CHANGELOG="${CHANGELOG//$'\r'/'%0D'}"
echo "Got changelog: $CHANGELOG"
echo "::set-output name=body::$CHANGELOG"
echo "body=$CHANGELOG" >> $GITHUB_OUTPUT
- name: Create release on Github
id: create_release
Expand Down
16 changes: 13 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@
# $ pre-commit install
# $ pre-commit run --all-files
#
#
default_language_version:
python: python3.8

repos:
- repo: https://github.com/pycqa/flake8
rev: '5.0.4'
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.276
hooks:
- id: ruff
- repo: https://github.com/codespell-project/codespell
rev: v2.2.4
hooks:
- id: flake8
- id: codespell
additional_dependencies:
- tomli
62 changes: 41 additions & 21 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ Contributing

Everyone is invited to contribute to this project.
Feel free to create a `pull request`_ .
If you find errors, omissions, inconsistencies or other things
that need improvement, please create an issue_.
If you find errors,
omissions,
inconsistencies,
or other things
that need improvement,
please create an issue_.

.. _issue: https://github.com/audeering/audbackend/issues/new/
.. _pull request: https://github.com/audeering/audbackend/compare/
Expand All @@ -13,30 +17,35 @@ that need improvement, please create an issue_.
Development Installation
------------------------

Instead of pip-installing the latest release from PyPI,
Instead of pip-installing the latest release from PyPI_,
you should get the newest development version from Github_::

git clone https://github.com/audeering/audbackend/
cd audbackend
# Create virutal environment for this project
# Create virtual environment for this project
# e.g.
# virtualenv --python="python3" $HOME/.envs/audbackend
# source $HOME/.envs/audeer/bin/activate
# source $HOME/.envs/audbackend/bin/activate
pip install -r requirements.txt

.. _Github: https://github.com/audeering/audbackend

This way, your installation always stays up-to-date,
This way,
your installation always stays up-to-date,
even if you pull new changes from the Github repository.

.. _PyPI: https://pypi.org/project/audbackend/
.. _Github: https://github.com/audeering/audbackend/


Coding Convention
-----------------

We follow the PEP8_ convention for Python code
and check for correct syntax with flake8_.
Exceptions are defined under the ``[flake8]`` section
in :file:`setup.cfg`.
and check for correct syntax with ruff_.
In addition,
we check for common spelling errors with codespell_.
Both tools and possible exceptions
are defined in :file:`pyproject.toml`.

The checks are executed in the CI using `pre-commit`_.
You can enable those checks locally by executing::
Expand All @@ -45,22 +54,26 @@ You can enable those checks locally by executing::
pre-commit install
pre-commit run --all-files

Afterwards flake8_ is executed
Afterwards ruff_ and codespell_ are executed
every time you create a commit.

You can also install flake8_
You can also install ruff_ and codespell_
and call it directly::

pip install flake8 # consider system wide installation
flake8
pip install ruff codespell # consider system wide installation
ruff check .
codespell

It can be restricted to specific folders::

flake8 audfoo/ tests/
ruff check audfoo/ tests/
codespell audfoo/ tests/


.. _codespell: https://github.com/codespell-project/codespell/
.. _PEP8: http://www.python.org/dev/peps/pep-0008/
.. _flake8: https://flake8.pycqa.org/en/latest/index.html
.. _pre-commit: https://pre-commit.com
.. _ruff: https://beta.ruff.rs


Building the Documentation
Expand All @@ -70,21 +83,20 @@ If you make changes to the documentation,
you can re-create the HTML pages using Sphinx_.
You can install it and a few other necessary packages with::

pip install -r requirements.txt
pip install -r docs/requirements.txt

To create the HTML pages, use::

python -m sphinx docs/ build/sphinx/html -b html
python -m sphinx docs/ build/sphinx/html -b html

The generated files will be available
in the directory :file:`build/sphinx/html/`.

It is also possible to automatically check if all links are still valid::

python -m sphinx docs/ build/sphinx/linkcheck -b linkcheck
python -m sphinx docs/ build/sphinx/html -b linkcheck

.. _Sphinx: http://sphinx-doc.org/
.. _Sphinx: http://sphinx-doc.org


Running the Tests
Expand All @@ -108,7 +120,15 @@ To execute the tests, simply run::

python -m pytest

.. _pytest: https://pytest.org/
It might be that the cleanup process
after or during the tests
fails.
To remove leftover files on the Artifactory server
run::

python tests/misc/cleanup_artifactory.py

.. _pytest: https://pytest.org


Creating a New Release
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ Have a look at the installation_ instructions.
.. |tests| image:: https://github.com/audeering/audbackend/workflows/Test/badge.svg
:target: https://github.com/audeering/audbackend/actions?query=workflow%3ATest
:alt: Test status
.. |coverage| image:: https://codecov.io/gh/audeering/audbackend/branch/master/graph/badge.svg?token=pCTgGG7Sd1
.. |coverage| image:: https://codecov.io/gh/audeering/audbackend/branch/main/graph/badge.svg?token=pCTgGG7Sd1
:target: https://codecov.io/gh/audeering/audbackend/
:alt: code coverage
.. |docs| image:: https://img.shields.io/pypi/v/audbackend?label=docs
:target: https://audeering.github.io/audbackend/
:alt: audbackend's documentation
.. |license| image:: https://img.shields.io/badge/license-MIT-green.svg
:target: https://github.com/audeering/audbackend/blob/master/LICENSE
:target: https://github.com/audeering/audbackend/blob/main/LICENSE
:alt: audbackend's MIT license
.. |python-versions| image:: https://img.shields.io/pypi/pyversions/audbackend.svg
:target: https://pypi.org/project/audbackend/
Expand Down
12 changes: 5 additions & 7 deletions audbackend/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from audbackend.core.api import (
access,
available,
create,
delete,
register,
)
from audbackend.core.api import access
from audbackend.core.api import available
from audbackend.core.api import create
from audbackend.core.api import delete
from audbackend.core.api import register
from audbackend.core.artifactory import Artifactory
from audbackend.core.backend import Backend
from audbackend.core.errors import BackendError
Expand Down
3 changes: 1 addition & 2 deletions audbackend/core/api.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import typing

from audbackend.core import utils
from audbackend.core.artifactory import Artifactory
from audbackend.core.backend import Backend
from audbackend.core.filesystem import FileSystem
from audbackend.core import utils


backends = {}
Expand All @@ -22,7 +22,6 @@ def _backend(
repository: str,
) -> Backend:
r"""Get backend instance."""

if name not in backend_registry:
raise ValueError(
f"A backend class with name "
Expand Down
6 changes: 0 additions & 6 deletions audbackend/core/artifactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def _artifactory_path(
apikey,
) -> artifactory.ArtifactoryPath:
r"""Authenticate at Artifactory and get path object."""

return artifactory.ArtifactoryPath(
path,
auth=(username, apikey),
Expand All @@ -25,7 +24,6 @@ def _artifactory_path(

def _authentication(host) -> typing.Tuple[str, str]:
"""Look for username and API key."""

username = os.getenv('ARTIFACTORY_USERNAME', None)
api_key = os.getenv('ARTIFACTORY_API_KEY', None)
config_file = os.getenv(
Expand Down Expand Up @@ -63,7 +61,6 @@ def _deploy(
verbose: bool = False,
):
r"""Deploy local file as an artifact."""

if verbose: # pragma: no cover
desc = audeer.format_display_message(
f'Deploy {src_path}',
Expand All @@ -90,7 +87,6 @@ def _download(
verbose=False,
):
r"""Download an artifact."""

src_size = artifactory.ArtifactoryPath.stat(src_path).size

with audeer.progress_bar(total=src_size, disable=not verbose) as pbar:
Expand Down Expand Up @@ -272,7 +268,6 @@ def _legacy_split_ext(
name: str,
) -> typing.Tuple[str, str]:
r"""Split name into basename and extension."""

ext = None
for custom_ext in self._legacy_extensions:
# check for custom extension
Expand All @@ -296,7 +291,6 @@ def _ls(
path: str,
) -> typing.List[typing.Tuple[str, str]]:
r"""List all files under (sub-)path."""

if path.endswith('/'): # find files under sub-path

path = self._expand(path)
Expand Down
2 changes: 1 addition & 1 deletion audbackend/core/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(
self.repository = repository
r"""Repository name."""

def __repr__(self) -> str:
def __repr__(self) -> str: # noqa: D105
name = f'{self.__class__.__module__}.{self.__class__.__name__}'
return str((name, self.host, self.repository))

Expand Down
3 changes: 2 additions & 1 deletion audbackend/core/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

import pytest

import audbackend
import audeer

import audbackend


class DoctestFileSystem(audbackend.FileSystem):

Expand Down
1 change: 0 additions & 1 deletion audbackend/core/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ def _ls(
path: str,
) -> typing.List[typing.Tuple[str, str]]:
r"""List all files under (sub-)path."""

if path.endswith('/'): # find files under sub-path

path = self._expand(path)
Expand Down
2 changes: 1 addition & 1 deletion audbackend/core/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __init__(
self.backend = backend
r"""Repository backend."""

def __repr__(self):
def __repr__(self): # noqa: D105
return (
f"Repository("
f"'{self.name}', "
Expand Down
3 changes: 0 additions & 3 deletions audbackend/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ def call_function_on_backend(

def check_path(path: str) -> str:
r"""Check path."""

# Assert path starts with sep and does not contain invalid characters.
if not path.startswith(BACKEND_SEPARATOR):
raise ValueError(
Expand All @@ -60,7 +59,6 @@ def check_path(path: str) -> str:

def check_version(version: str) -> str:
r"""Check version."""

# Assert version is not empty and does not contain invalid characters.
if not version:
raise ValueError('Version must not be empty.')
Expand All @@ -79,7 +77,6 @@ def date_format(date: datetime.datetime) -> str:

def file_owner(path: str) -> str:
r"""Get file owner."""

if os.name == 'nt': # pragma: no cover

import win32security
Expand Down
Loading

0 comments on commit a118b6d

Please sign in to comment.