From 36d89a69e8d88a762806ace12e876e1b5c10054d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 21:06:19 +0200 Subject: [PATCH 1/3] Replace Flake8 with Ruff --- .flake8 | 2 -- .pre-commit-config.yaml | 40 ++++++++++++++-------------------------- pyproject.toml | 27 +++++++++++++++++++++++++-- src/pylast/__init__.py | 12 +++++++----- tests/test_album.py | 2 ++ tests/test_artist.py | 2 ++ tests/test_country.py | 2 ++ tests/test_library.py | 2 ++ tests/test_librefm.py | 2 ++ tests/test_network.py | 3 +++ tests/test_pylast.py | 2 ++ tests/test_tag.py | 2 ++ tests/test_track.py | 3 +++ tests/test_user.py | 2 ++ tests/unicode_test.py | 4 +++- 15 files changed, 71 insertions(+), 36 deletions(-) delete mode 100644 .flake8 diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 2bcd70e..0000000 --- a/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 88 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c5ed648..5caa25a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - - repo: https://github.com/asottile/pyupgrade - rev: v3.15.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.2.0 hooks: - - id: pyupgrade - args: [--py38-plus] + - id: ruff + args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black-pre-commit-mirror - rev: 23.12.1 + rev: 24.1.1 hooks: - id: black @@ -15,24 +15,7 @@ repos: hooks: - id: blacken-docs args: [--target-version=py38] - additional_dependencies: [black==23.3.0] - - - repo: https://github.com/PyCQA/isort - rev: 5.13.2 - hooks: - - id: isort - - - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 - hooks: - - id: flake8 - additional_dependencies: [flake8-2020, flake8-implicit-str-concat] - - - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.10.0 - hooks: - - id: python-check-blanket-noqa - - id: python-no-log-warn + additional_dependencies: [black] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 @@ -42,19 +25,19 @@ repos: - id: check-json - id: check-toml - id: check-yaml + - id: debug-statements - id: end-of-file-fixer - - id: requirements-txt-fixer - id: trailing-whitespace exclude: .github/(ISSUE_TEMPLATE|PULL_REQUEST_TEMPLATE).md - repo: https://github.com/tox-dev/pyproject-fmt - rev: 1.5.3 + rev: 1.7.0 hooks: - id: pyproject-fmt additional_dependencies: [tox] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.15 + rev: v0.16 hooks: - id: validate-pyproject @@ -63,5 +46,10 @@ repos: hooks: - id: tox-ini-fmt + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes + ci: autoupdate_schedule: quarterly diff --git a/pyproject.toml b/pyproject.toml index 52292bb..3413855 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,5 +59,28 @@ version.source = "vcs" [tool.hatch.version.raw-options] local_scheme = "no-local-version" -[tool.isort] -profile = "black" +[tool.ruff.lint] +select = [ + "C4", # flake8-comprehensions + "E", # pycodestyle errors + "EM", # flake8-errmsg + "F", # pyflakes errors + "I", # isort + "ISC", # flake8-implicit-str-concat + "LOG", # flake8-logging + "PGH", # pygrep-hooks + "RUF100", # unused noqa (yesqa) + "UP", # pyupgrade + "W", # pycodestyle warnings + "YTT", # flake8-2020 +] +extend-ignore = [ + "E203", # Whitespace before ':' + "E221", # Multiple spaces before operator + "E226", # Missing whitespace around arithmetic operator + "E241", # Multiple spaces after ',' +] + +[tool.ruff.lint.isort] +known-first-party = ["pylast"] +required-imports = ["from __future__ import annotations"] diff --git a/src/pylast/__init__.py b/src/pylast/__init__.py index d180a48..0396f5b 100644 --- a/src/pylast/__init__.py +++ b/src/pylast/__init__.py @@ -628,7 +628,6 @@ class _Network: class LastFMNetwork(_Network): - """A Last.fm network object api_key: a provided API_KEY @@ -1243,8 +1242,10 @@ class _Chartable(_BaseObject): from_date value to the to_date value. chart_kind should be one of "album", "artist" or "track" """ + import sys + method = ".getWeekly" + chart_kind.title() + "Chart" - chart_type = eval(chart_kind.title()) # string to type + chart_type = getattr(sys.modules[__name__], chart_kind.title()) params = self._get_params() if from_date and to_date: @@ -1356,11 +1357,11 @@ class _Taggable(_BaseObject): new_tags.append(tag) for i in range(0, len(old_tags)): - if not c_old_tags[i] in c_new_tags: + if c_old_tags[i] not in c_new_tags: to_remove.append(old_tags[i]) for i in range(0, len(new_tags)): - if not c_new_tags[i] in c_old_tags: + if c_new_tags[i] not in c_old_tags: to_add.append(new_tags[i]) self.remove_tags(to_remove) @@ -2778,7 +2779,8 @@ def _collect_nodes( main.getAttribute("totalPages") or main.getAttribute("totalpages") ) else: - raise PyLastError("No total pages attribute") + msg = "No total pages attribute" + raise PyLastError(msg) for node in main.childNodes: if not node.nodeType == xml.dom.Node.TEXT_NODE and ( diff --git a/tests/test_album.py b/tests/test_album.py index a56faf1..1146f12 100755 --- a/tests/test_album.py +++ b/tests/test_album.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_artist.py b/tests/test_artist.py index e72474e..d4f9134 100755 --- a/tests/test_artist.py +++ b/tests/test_artist.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pytest import pylast diff --git a/tests/test_country.py b/tests/test_country.py index 6d36ef3..1636b96 100755 --- a/tests/test_country.py +++ b/tests/test_country.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_library.py b/tests/test_library.py index cc35233..592436d 100755 --- a/tests/test_library.py +++ b/tests/test_library.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_librefm.py b/tests/test_librefm.py index 01c43d9..0d9e839 100755 --- a/tests/test_librefm.py +++ b/tests/test_librefm.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + from flaky import flaky import pylast diff --git a/tests/test_network.py b/tests/test_network.py index 51f0b18..05672d6 100755 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -1,6 +1,9 @@ """ Integration (not unit) tests for pylast.py """ + +from __future__ import annotations + import re import time diff --git a/tests/test_pylast.py b/tests/test_pylast.py index 4beeed7..c06a9c3 100755 --- a/tests/test_pylast.py +++ b/tests/test_pylast.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import os import time diff --git a/tests/test_tag.py b/tests/test_tag.py index 89080f6..7a9675c 100755 --- a/tests/test_tag.py +++ b/tests/test_tag.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import pylast from .test_pylast import TestPyLastWithLastFm diff --git a/tests/test_track.py b/tests/test_track.py index dae2c9c..db9c69c 100755 --- a/tests/test_track.py +++ b/tests/test_track.py @@ -1,6 +1,9 @@ """ Integration (not unit) tests for pylast.py """ + +from __future__ import annotations + import time import pytest diff --git a/tests/test_user.py b/tests/test_user.py index 12308eb..f5069d5 100755 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -2,6 +2,8 @@ """ Integration (not unit) tests for pylast.py """ +from __future__ import annotations + import calendar import datetime as dt import inspect diff --git a/tests/unicode_test.py b/tests/unicode_test.py index bc93dfa..67f234b 100644 --- a/tests/unicode_test.py +++ b/tests/unicode_test.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from unittest import mock import pytest @@ -25,7 +27,7 @@ def test_get_cache_key(artist) -> None: @pytest.mark.parametrize("obj", [pylast.Artist("B\xe9l", mock_network())]) def test_cast_and_hash(obj) -> None: - assert type(str(obj)) is str + assert isinstance(str(obj), str) assert isinstance(hash(obj), int) From 5bccda1102ca7b67c8b92b3fd18733f75df3225b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 22:02:41 +0200 Subject: [PATCH 2/3] Update config --- .github/workflows/deploy.yml | 11 +++++++---- .github/workflows/labels.yml | 3 +++ .github/workflows/lint.yml | 3 +++ .github/workflows/require-pr-label.yml | 1 + 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3e3174a..8b9a278 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -30,12 +30,14 @@ jobs: # Upload to Test PyPI on every commit on main. release-test-pypi: name: Publish in-dev package to test.pypi.org - if: github.event_name == 'push' && github.ref == 'refs/heads/main' + if: | + github.repository_owner == 'pylast' + && github.event_name == 'push' + && github.ref == 'refs/heads/main' runs-on: ubuntu-latest needs: build-package permissions: - # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: @@ -53,12 +55,13 @@ jobs: # Upload to real PyPI on GitHub Releases. release-pypi: name: Publish released package to pypi.org - if: github.event.action == 'published' + if: | + github.repository_owner == 'pylast' + && github.event.action == 'published' runs-on: ubuntu-latest needs: build-package permissions: - # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 9ca7454..859c948 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -1,5 +1,8 @@ name: Sync labels +permissions: + pull-requests: write + on: push: branches: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f8f9a2b..dae63b0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,6 +2,9 @@ name: Lint on: [push, pull_request, workflow_dispatch] +env: + FORCE_COLOR: 1 + permissions: contents: read diff --git a/.github/workflows/require-pr-label.yml b/.github/workflows/require-pr-label.yml index 85c3e3e..0d910db 100644 --- a/.github/workflows/require-pr-label.yml +++ b/.github/workflows/require-pr-label.yml @@ -10,6 +10,7 @@ jobs: permissions: issues: write + pull-requests: write steps: - uses: mheap/github-action-required-labels@v5 From 3890cb4c04fa72bd1003ecaa42a8020b78e79e5d Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Sun, 4 Feb 2024 22:03:26 +0200 Subject: [PATCH 3/3] Add {envpython} and --cov-report html, multiline for clarity --- tox.ini | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index b0d3588..e3972c0 100644 --- a/tox.ini +++ b/tox.ini @@ -15,7 +15,14 @@ pass_env = PYLAST_PASSWORD_HASH PYLAST_USERNAME commands = - pytest -v -s -W all --cov pylast --cov tests --cov-report term-missing --cov-report xml --random-order {posargs} + {envpython} -m pytest -v -s -W all \ + --cov pylast \ + --cov tests \ + --cov-report html \ + --cov-report term-missing \ + --cov-report xml \ + --random-order \ + {posargs} [testenv:lint] skip_install = true