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

introduce ruff as a linter #936

Merged
merged 7 commits into from
Sep 30, 2023
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
5 changes: 5 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ repos:
hooks:
- id: pyupgrade
args: [--py38-plus]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.291
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "1.1.0"
hooks:
Expand Down
11 changes: 11 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
exclude *.nix
exclude .pre-commit-config.yaml
exclude changelog.d/*
exclude .git_archival.txt
exclude .readthedocs.yaml
include *.py
include testing/*.py
include tox.ini
Expand All @@ -10,5 +12,14 @@ include *.toml
include mypy.ini
include testing/Dockerfile.*
include src/setuptools_scm/.git_archival.txt
include README.md
include CHANGELOG.md


recursive-include testing *.bash
prune nextgen

recursive-include docs *.md
include docs/examples/version_scheme_code/*.py
include docs/examples/version_scheme_code/*.toml
include mkdocs.yml
4 changes: 4 additions & 0 deletions changelog.d/20230922_220934_opensource_try_ruff.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

### Changed

- introduce ruff as a linter
10 changes: 10 additions & 0 deletions hatch.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
[envs.test]
extras = ["test", "dev"]

[envs.test.scripts]
all = "pytest {args}"

[[env.test.matrix]]
python = ["3.8", "3.9", "3.10", "3.11"]


[envs.docs]
python = "3.11"
extras = ["docs"]
Expand Down
22 changes: 21 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ dependencies = [
"packaging>=20",
"setuptools",
'tomli>=1; python_version < "3.11"',
'typing-extensions; python_version < "3.11"',
"typing-extensions",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"typing extensions always needed"

Can you clarify what this means? I still do not see anywhere that it is needed at runtime, and you appear to have reverted the work from #850 as this is now once again needed at runtime

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do agree, by the way, that it's not clear the dependencies were correct -- it seems to be unconditionally used, but only at mypy/lint time rather than at runtime. So instead of a versioned dependency, it should have been a test extra.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im happy to make it optional again once i have the time to make sure it works as intended

]
[project.optional-dependencies]
docs = [
Expand Down Expand Up @@ -108,5 +108,25 @@ version = { attr = "_own_version_helper.version"}

[tool.setuptools_scm]

[tool.ruff]
select = ["E", "F", "B", "U", "YTT", "C", "DTZ", "PYI", "PT"]
ignore = ["B028"]

[tool.pytest.ini_options]
testpaths = ["testing"]
filterwarnings = [
"error",
"ignore:.*tool\\.setuptools_scm.*",
"ignore:.*git archive did not support describe output.*:UserWarning",
]
log_level = "debug"
log_cli_level = "info"
# disable unraisable until investigated
addopts = ["-p", "no:unraisableexception"]
markers = [
"issue(id): reference to github issue",
"skip_commit: allows to skip committing in the helpers",
]

[tool.scriv]
format = "md"
3 changes: 1 addition & 2 deletions src/setuptools_scm/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ def _check_absolute_root(root: _t.PathT, relative_to: _t.PathT | None) -> str:
and not os.path.commonpath([root, relative_to]) == root
):
warnings.warn(
"absolute root path '%s' overrides relative_to '%s'"
% (root, relative_to)
f"absolute root path '{root}' overrides relative_to '{relative_to}'"
)
if os.path.isdir(relative_to):
warnings.warn(
Expand Down
2 changes: 1 addition & 1 deletion src/setuptools_scm/_file_finders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def scm_find_files(
# dirpath with symlinks resolved
realdirpath = os.path.normcase(os.path.realpath(dirpath))

def _link_not_in_scm(n: str) -> bool:
def _link_not_in_scm(n: str, realdirpath: str = realdirpath) -> bool:
fn = os.path.join(realdirpath, os.path.normcase(n))
return os.path.islink(fn) and fn not in scm_files

Expand Down
2 changes: 1 addition & 1 deletion src/setuptools_scm/_file_finders/hg.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def _hg_ls_files_and_dirs(toplevel: str) -> tuple[set[str], set[str]]:
hg_dirs = {toplevel}
res = _run(["hg", "files"], cwd=toplevel)
if res.returncode:
(), ()
return set(), set()
for name in res.stdout.splitlines():
name = os.path.normcase(name).replace("/", os.path.sep)
fullname = os.path.join(toplevel, name)
Expand Down
4 changes: 3 additions & 1 deletion src/setuptools_scm/_version_cls.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ def _validate_version_cls(
try:
return cast(Type[_VersionT], import_name(version_cls))
except: # noqa
raise ValueError(f"Unable to import version_cls='{version_cls}'")
raise ValueError(
f"Unable to import version_cls='{version_cls}'"
) from None
else:
return version_cls
3 changes: 2 additions & 1 deletion src/setuptools_scm/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import warnings
from datetime import date
from datetime import datetime
from datetime import timezone
from os.path import samefile
from pathlib import Path
from typing import Callable
Expand Down Expand Up @@ -268,7 +269,7 @@ def _git_parse_inner(
tag=tag, distance=distance, dirty=dirty, node=node, config=config
)
branch = wd.get_branch()
node_date = wd.get_head_date() or date.today()
node_date = wd.get_head_date() or datetime.now(timezone.utc).date()
return dataclasses.replace(version, branch=branch, node_date=node_date)


Expand Down
13 changes: 8 additions & 5 deletions src/setuptools_scm/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def guess_next_simple_semver(
try:
parts = [int(i) for i in str(version.tag).split(".")[:retain]]
except ValueError:
raise ValueError(f"{version} can't be parsed as numeric version")
raise ValueError(f"{version} can't be parsed as numeric version") from None
while len(parts) < retain:
parts.append(0)
if increment:
Expand Down Expand Up @@ -355,17 +355,20 @@ def guess_next_date_ver(
if match is None:
tag_date = today
else:
tag_date = datetime.strptime(match.group("date"), date_fmt).date()
tag_date = (
datetime.strptime(match.group("date"), date_fmt)
.replace(tzinfo=timezone.utc)
.date()
)
if tag_date == head_date:
patch = "0" if match is None else (match.group("patch") or "0")
patch = int(patch) + 1
else:
if tag_date > head_date and match is not None:
# warn on future times
warnings.warn(
"your previous tag ({}) is ahead your node date ({})".format(
tag_date, head_date
)
f"your previous tag ({tag_date})"
f" is ahead your node date ({head_date})"
)
patch = 0
next_version = "{node_date:{date_fmt}}.{patch}".format(
Expand Down
7 changes: 4 additions & 3 deletions testing/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from typing import Iterator

import pytest
from typing_extensions import Self

from .wd_wrapper import WorkDir
from setuptools_scm._run_cmd import run
Expand Down Expand Up @@ -46,7 +47,7 @@ class DebugMode(contextlib.AbstractContextManager): # type: ignore[type-arg]
def __init__(self) -> None:
self.__stack = contextlib.ExitStack()

def __enter__(self) -> DebugMode:
def __enter__(self) -> Self:
self.enable()
return self

Expand All @@ -71,14 +72,14 @@ def debug_mode() -> Iterator[DebugMode]:
yield debug_mode


@pytest.fixture
@pytest.fixture()
def wd(tmp_path: Path) -> WorkDir:
target_wd = tmp_path.resolve() / "wd"
target_wd.mkdir()
return WorkDir(target_wd)


@pytest.fixture
@pytest.fixture()
def repositories_hg_git(tmp_path: Path) -> tuple[WorkDir, WorkDir]:
tmp_path = tmp_path.resolve()
path_git = tmp_path / "repo_git"
Expand Down
8 changes: 6 additions & 2 deletions testing/test_basic_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,18 @@ def test_custom_version_cls() -> None:
"""Test that `normalize` and `version_cls` work as expected"""

class MyVersion:
def __init__(self, tag_str: str):
def __init__(self, tag_str: str) -> None:
self.version = tag_str

def __repr__(self) -> str:
return f"hello,{self.version}"

# you can not use normalize=False and version_cls at the same time
with pytest.raises(ValueError):
with pytest.raises(
ValueError,
match="Providing a custom `version_cls`"
" is not permitted when `normalize=False`",
):
setuptools_scm.get_version(normalize=False, version_cls=MyVersion)

# TODO unfortunately with PRETEND_KEY the preformatted flag becomes True
Expand Down
2 changes: 1 addition & 1 deletion testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


@pytest.mark.parametrize(
"tag, expected_version",
("tag", "expected_version"),
[
("apache-arrow-0.9.0", "0.9.0"),
("arrow-0.9.0", "0.9.0"),
Expand Down
11 changes: 5 additions & 6 deletions testing/test_file_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import os
import sys
from typing import Generator
from typing import Iterable

import pytest
Expand All @@ -14,8 +13,8 @@
@pytest.fixture(params=["git", "hg"])
def inwd(
request: pytest.FixtureRequest, wd: WorkDir, monkeypatch: pytest.MonkeyPatch
) -> Generator[WorkDir, None, None]:
param: str = getattr(request, "param") # todo: fix
) -> WorkDir:
param: str = request.param # type: ignore
if param == "git":
try:
wd("git init")
Expand All @@ -42,7 +41,7 @@ def inwd(
if request.node.get_closest_marker("skip_commit") is None:
wd.add_and_commit()
monkeypatch.chdir(wd.cwd)
yield wd
return wd


def _sep(paths: Iterable[str]) -> set[str]:
Expand Down Expand Up @@ -198,7 +197,7 @@ def test_symlink_not_in_scm_while_target_is(inwd: WorkDir) -> None:


@pytest.mark.issue(587)
@pytest.mark.skip_commit
@pytest.mark.skip_commit()
def test_not_commited(inwd: WorkDir) -> None:
assert find_files() == []

Expand All @@ -212,7 +211,7 @@ def test_unexpanded_git_archival(wd: WorkDir, monkeypatch: pytest.MonkeyPatch) -
assert find_files() == []


@pytest.mark.parametrize("archive_file", (".git_archival.txt", ".hg_archival.txt"))
@pytest.mark.parametrize("archive_file", [".git_archival.txt", ".hg_archival.txt"])
def test_archive(
wd: WorkDir, monkeypatch: pytest.MonkeyPatch, archive_file: str
) -> None:
Expand Down
6 changes: 3 additions & 3 deletions testing/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


@pytest.mark.parametrize(
"tag, expected",
("tag", "expected"),
[
("1.1", "1.2"),
("1.2.dev", "1.2"),
Expand Down Expand Up @@ -48,7 +48,7 @@ def test_next_tag(tag: str, expected: str) -> None:


@pytest.mark.parametrize(
"version,version_scheme, local_scheme,expected",
("version", "version_scheme", "local_scheme", "expected"),
[
("exact", "guess-next-dev", "node-and-date", "1.1"),
("dirty", "guess-next-dev", "node-and-date", "1.2.dev0+d20090213"),
Expand Down Expand Up @@ -172,7 +172,7 @@ def test_has_command_logs_stderr(caplog: pytest.LogCaptureFixture) -> None:


@pytest.mark.parametrize(
"tag, expected_version",
("tag", "expected_version"),
[
("1.1", "1.1"),
("release-1.1", "1.1"),
Expand Down
18 changes: 10 additions & 8 deletions testing/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def wd(wd: WorkDir, monkeypatch: pytest.MonkeyPatch, debug_mode: DebugMode) -> W


@pytest.mark.parametrize(
"given, tag, number, node, dirty",
("given", "tag", "number", "node", "dirty"),
[
("3.3.1-rc26-0-g9df187b", "3.3.1-rc26", 0, "g9df187b", False),
("17.33.0-rc-17-g38c3047c0", "17.33.0-rc", 17, "g38c3047c0", False),
Expand Down Expand Up @@ -158,7 +158,8 @@ def test_version_from_git(wd: WorkDir) -> None:
assert wd.get_version() == "0.1.dev0+d20090213"

parsed = git.parse(str(wd.cwd), Configuration(), git.DEFAULT_DESCRIBE)
assert parsed is not None and parsed.branch in ("master", "main")
assert parsed is not None
assert parsed.branch in ("master", "main")

wd.commit_testfile()
assert wd.get_version().startswith("0.1.dev1+g")
Expand Down Expand Up @@ -285,7 +286,8 @@ def test_git_dirty_notag(
tag = datetime.now(timezone.utc).date().strftime(".d%Y%m%d")
else:
tag = ".d20090213"
assert version.startswith("0.1.dev1+g") and version.endswith(tag)
assert version.startswith("0.1.dev1+g")
assert version.endswith(tag)


@pytest.mark.issue(193)
Expand All @@ -300,7 +302,7 @@ def test_git_worktree_support(wd: WorkDir, tmp_path: Path) -> None:
assert str(worktree) in res.stdout


@pytest.fixture
@pytest.fixture()
def shallow_wd(wd: WorkDir, tmp_path: Path) -> Path:
wd.commit_testfile()
wd.commit_testfile()
Expand Down Expand Up @@ -461,7 +463,7 @@ def test_gitdir(monkeypatch: pytest.MonkeyPatch, wd: WorkDir) -> None:

def test_git_getdate(wd: WorkDir) -> None:
# TODO: case coverage for git wd parse
today = date.today()
today = datetime.now(timezone.utc).date()

def parse_date() -> date:
parsed = git.parse(os.fspath(wd.cwd), Configuration())
Expand Down Expand Up @@ -492,7 +494,7 @@ def test_git_getdate_badgit(
assert git_wd.get_head_date() is None


@pytest.fixture
@pytest.fixture()
def signed_commit_wd(monkeypatch: pytest.MonkeyPatch, wd: WorkDir) -> WorkDir:
if not has_command("gpg", args=["--version"], warn=False):
pytest.skip("gpg executable not found")
Expand All @@ -519,14 +521,14 @@ def signed_commit_wd(monkeypatch: pytest.MonkeyPatch, wd: WorkDir) -> WorkDir:

@pytest.mark.issue("https://github.com/pypa/setuptools_scm/issues/548")
def test_git_getdate_signed_commit(signed_commit_wd: WorkDir) -> None:
today = date.today()
today = datetime.now(timezone.utc).date()
signed_commit_wd.commit_testfile(signed=True)
git_wd = git.GitWorkdir(signed_commit_wd.cwd)
assert git_wd.get_head_date() == today


@pytest.mark.parametrize(
"expected, from_data",
("expected", "from_data"),
[
(
"1.0",
Expand Down
2 changes: 1 addition & 1 deletion testing/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
c = Configuration()


@pytest.fixture
@pytest.fixture()
def wd(wd: WorkDir) -> WorkDir:
wd("git init")
wd("git config user.email test@example.com")
Expand Down
Loading
Loading