Skip to content
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
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ repos:
exclude: "^tests"

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.3
rev: v0.1.4
hooks:
- id: ruff
args: ["--fix", "--show-fixes"]
Expand Down
5 changes: 3 additions & 2 deletions docs/ext/conftabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ast
import textwrap
from typing import Any

from docutils import nodes
from docutils.statemachine import StringList
Expand All @@ -12,7 +13,7 @@ class ConfTabs(SphinxDirective):
required_arguments = 2
final_argument_whitespace = True

def run(self):
def run(self) -> list[nodes.Node]:
name, result = self.arguments
env_name = f"SKBUILD_{name.replace('.', '_').replace('-', '_').upper()}"
value_result = ast.literal_eval(result)
Expand Down Expand Up @@ -82,7 +83,7 @@ def run(self):
return [content]


def setup(app):
def setup(app: Any) -> dict[str, Any]:
app.add_directive("conftabs", ConfTabs)

return {
Expand Down
49 changes: 31 additions & 18 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -203,48 +203,59 @@ ignore = ["W002"] # Triggers on __init__.py's

[tool.ruff]
src = ["src"]
exclude = []
exclude = [] # Required due to "build" module

[tool.ruff.lint]
select = [
"E", "F", "W", # flake8
"B", # flake8-bugbear
"I", # isort
extend-select = [
"ANN", # flake8-annotations
"ARG", # flake8-unused-arguments
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"EM", # flake8-errmsg
"FBT", # flake8-boolean-trap
"FLY", # flynt
"I", # isort
"ICN", # flake8-import-conventions
"ISC", # flake8-implicit-str-concat
"N", # flake8-naming
"PERF", # perflint
"PGH", # pygrep-hooks
"PIE", # flake8-pie
"PL", # pylint
"PT", # flake8-pytest-style
"PTH", # flake8-use-pathlib
"PYI", # flake8-pyi
"RET", # flake8-return
"RUF", # Ruff-specific
"S", # eval -> literal_eval
"SIM", # flake8-simplify
"TID251", # flake8-tidy-imports.banned-api
"T20", # flake8-print
"UP", # pyupgrade
"YTT", # flake8-2020
"ANN204", # Add -> None to __init__
"S307", # eval -> literal_eval
"TCH", # flake8-type-checking
"PERF", # perflint
"FLY", # flynt
"TID251", # flake8-tidy-imports.banned-api
"TRY", # tryceratops
"FBT", # flake8-boolean-trap
"PYI", # flake8-pyi
"UP", # pyupgrade
"YTT", # flake8-2020
# (in preview till 0.2.0) "FURB", # refurb
]
ignore = [
"PLR", # Design rules for pylint
"PLE1205", # Format check doesn't work with our custom logger
"E501", # Line too long
"PT004", # Incorrect, just usefixtures instead.
"RUF009", # Too easy to get a false positive
"PYI025", # Wants Set to be renamed AbstractSet
"ISC001", # Conflicts with formatter
"PLR0911", # Too many return statements
"PLR0912", # Too many branches
"PLR0913", # Too many arguments
"PLR0915", # Too many local statements
"PLR2004", # Magic value used in comparison
"PLC0415", # Import should be at top of file
"ANN101", # Missing type annotation for `self` in method
"ANN102", # Missing type annotation for `cls` in classmethod
"ANN401", # Disallow dynamically typed expressions
"S101", # Use of assert detected
"S603", # subprocess untrusted input
"S607", # subprocess call
]
unfixable = ["T20", "F841"]
typing-modules = ["scikit_build_core._compat.typing"]

[tool.ruff.lint.flake8-tidy-imports.banned-api]
Expand Down Expand Up @@ -272,13 +283,15 @@ typing-modules = ["scikit_build_core._compat.typing"]


[tool.ruff.lint.per-file-ignores]
"tests/**" = ["T20"]
"tests/**" = ["T20", "ANN"]
"noxfile.py" = ["T20", "TID251"]
"src/scikit_build_core/resources/*.py" = ["PTH", "ARG002", "FBT", "TID251"]
"src/scikit_build_core/_compat/**.py" = ["TID251"]
"tests/conftest.py" = ["TID251"]
"tests/packages/**.py" = ["TID251"]
"docs/conf.py" = ["TID251"]
"docs/examples/**" = ["ANN"]
"src/scikit_build_core/file_api/model/*.py" = ["N"]


[tool.check-sdist]
Expand Down
1 change: 0 additions & 1 deletion src/scikit_build_core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
scikit-build-core: PEP 517 builder for Scikit-Build
"""


from __future__ import annotations

from ._version import version as __version__
Expand Down
2 changes: 1 addition & 1 deletion src/scikit_build_core/_compat/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
else:
Self = object

def assert_never(_: typing.Any) -> None:
def assert_never(_: object) -> None:
msg = "Expected code to be unreachable"
raise AssertionError(msg)

Expand Down
4 changes: 2 additions & 2 deletions src/scikit_build_core/_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ def exception(self, msg: str, *args: object, **kwargs: object) -> None:
def log(self, level: int, msg: str, *args: object, **kwargs: object) -> None:
self.logger.log(level, FStringMessage(msg, *args, **kwargs), **opts)

def setLevel(self, level: int) -> None:
def setLevel(self, level: int) -> None: # noqa: N802
self.logger.setLevel(level)

def addHandler(self, handler: logging.Handler) -> None:
def addHandler(self, handler: logging.Handler) -> None: # noqa: N802
self.logger.addHandler(handler)


Expand Down
1 change: 0 additions & 1 deletion src/scikit_build_core/build/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
This is the entry point for the build backend. Items in this module are designed for the build backend API.
"""


from __future__ import annotations

import sys
Expand Down
2 changes: 1 addition & 1 deletion src/scikit_build_core/builder/wheel_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def tags_dict(self) -> dict[str, list[str]]:

def as_tags_set(self) -> frozenset[packaging.tags.Tag]:
vals = itertools.product(self.pyvers, self.abis, self.archs)
return frozenset(packaging.tags.Tag(*v) for v in vals)
return frozenset(itertools.starmap(packaging.tags.Tag, vals))


if __name__ == "__main__":
Expand Down
6 changes: 3 additions & 3 deletions src/scikit_build_core/file_api/reply.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def make_class(self, data: InputDict, target: Type[T]) -> T:
Convert a dict to a dataclass. Automatically load a few nested jsonFile classes.
"""
if (
target in (CodeModel, Target, Cache, CMakeFiles, Directory)
target in {CodeModel, Target, Cache, CMakeFiles, Directory}
and "jsonFile" in data
and data["jsonFile"] is not None
):
Expand Down Expand Up @@ -91,9 +91,9 @@ def _convert_any(self, item: Any, target: Type[T]) -> T:
return self.make_class(item, target) # type: ignore[return-value]
origin = get_origin(target)
if origin is not None:
if origin == list:
if origin is list:
return [self._convert_any(i, get_args(target)[0]) for i in item] # type: ignore[return-value]
if origin == Union:
if origin is Union:
return self._convert_any(item, get_args(target)[0]) # type: ignore[no-any-return]

return target(item) # type: ignore[call-arg]
Expand Down
2 changes: 1 addition & 1 deletion src/scikit_build_core/resources/_editable_redirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
else:
from typing import TypedDict

class KWDict_1(TypedDict, total=False):
class KWDict_1(TypedDict, total=False): # noqa: N801
submodule_search_locations: list[str]

else:
Expand Down
8 changes: 4 additions & 4 deletions src/scikit_build_core/settings/json_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
from .._compat.typing import Literal, get_args, get_origin
from .documentation import pull_docs

__all__ = ["to_json_schema", "convert_type", "FailedConversion"]
__all__ = ["to_json_schema", "convert_type", "FailedConversionError"]


def __dir__() -> list[str]:
return __all__


class FailedConversion(TypeError):
class FailedConversionError(TypeError):
pass


Expand All @@ -36,7 +36,7 @@ def to_json_schema(dclass: type[Any], *, normalize_keys: bool) -> dict[str, Any]

try:
props[field.name] = convert_type(field.type, normalize_keys=normalize_keys)
except FailedConversion as err:
except FailedConversionError as err:
if sys.version_info < (3, 11):
notes = "__notes__" # set so linter's won't try to be clever
setattr(err, notes, [*getattr(err, notes, []), f"Field: {field.name}"])
Expand Down Expand Up @@ -119,4 +119,4 @@ def convert_type(t: Any, *, normalize_keys: bool) -> dict[str, Any]:
return {"enum": list(args)}

msg = f"Cannot convert type {t} to JSON Schema"
raise FailedConversion(msg)
raise FailedConversionError(msg)
20 changes: 10 additions & 10 deletions src/scikit_build_core/settings/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
Integers/floats would be easy to add, but haven't been needed yet.
"""


from __future__ import annotations

import dataclasses
Expand Down Expand Up @@ -125,9 +124,9 @@ def _get_inner_type(__target: type[Any]) -> type[Any]:

raw_target = _get_target_raw_type(__target)
target = _process_union(__target)
if raw_target == list:
if raw_target is list:
return get_args(target)[0] # type: ignore[no-any-return]
if raw_target == dict:
if raw_target is dict:
return get_args(target)[1] # type: ignore[no-any-return]
msg = f"Expected a list or dict, got {target!r}"
raise AssertionError(msg)
Expand Down Expand Up @@ -219,11 +218,11 @@ def convert(cls, item: str, target: type[Any]) -> object:
if dataclasses.is_dataclass(raw_target):
msg = f"Array of dataclasses are not supported in configuration settings ({raw_target})"
raise TypeError(msg)
if raw_target == list:
if raw_target is list:
return [
cls.convert(i.strip(), _get_inner_type(target)) for i in item.split(";")
]
if raw_target == dict:
if raw_target is dict:
items = (i.strip().split("=") for i in item.split(";"))
return {k: cls.convert(v, _get_inner_type(target)) for k, v in items}

Expand Down Expand Up @@ -334,7 +333,7 @@ def convert(
if dataclasses.is_dataclass(raw_target):
msg = f"Array of dataclasses are not supported in configuration settings ({raw_target})"
raise TypeError(msg)
if raw_target == list:
if raw_target is list:
if isinstance(item, list):
return [cls.convert(i, _get_inner_type(target)) for i in item]
if isinstance(item, dict):
Expand All @@ -343,7 +342,7 @@ def convert(
return [
cls.convert(i.strip(), _get_inner_type(target)) for i in item.split(";")
]
if raw_target == dict:
if raw_target is dict:
assert not isinstance(item, (str, list))
return {k: cls.convert(v, _get_inner_type(target)) for k, v in item.items()}
if isinstance(item, (list, dict)):
Expand Down Expand Up @@ -379,7 +378,7 @@ def unrecognized_options(self, options: object) -> Generator[str, None, None]:
except KeyError:
yield keystr
continue
if _get_target_raw_type(outer_option) == dict:
if _get_target_raw_type(outer_option) is dict:
continue

def all_option_names(self, target: type[Any]) -> Iterator[str]:
Expand All @@ -393,7 +392,8 @@ def __init__(self, *prefixes: str, settings: Mapping[str, Any]) -> None:
self.prefixes = prefixes
self.settings = _dig_not_strict(settings, *prefixes)

def _get_name(self, *fields: str) -> list[str]:
@staticmethod
def _get_name(*fields: str) -> list[str]:
return [field.replace("_", "-") for field in fields]

def has_item(self, *fields: str, is_dict: bool) -> bool: # noqa: ARG002
Expand Down Expand Up @@ -500,7 +500,7 @@ def convert_target(self, target: type[T], *prefixes: str) -> T:
errors.append(e)
continue

is_dict = _get_target_raw_type(field.type) == dict
is_dict = _get_target_raw_type(field.type) is dict

for source in self.sources:
if source.has_item(*prefixes, field.name, is_dict=is_dict):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_fileapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def test_included_dir():
assert codemodel.kind == "codemodel"
assert codemodel.version.major == 2
assert codemodel.version.minor == 4
assert codemodel.configurations[0].name == ""
assert not codemodel.configurations[0].name

cache = index.reply.cache_v2
assert cache is not None
Expand Down
2 changes: 1 addition & 1 deletion tests/test_get_requires.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


def which_mock(name: str) -> str | None:
if name in ("ninja", "ninja-build", "cmake3", "samu", "gmake", "make"):
if name in {"ninja", "ninja-build", "cmake3", "samu", "gmake", "make"}:
return None
if name == "cmake":
return "cmake/path"
Expand Down
4 changes: 2 additions & 2 deletions tests/test_json_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest
from packaging.version import Version

from scikit_build_core.settings.json_schema import FailedConversion, convert_type
from scikit_build_core.settings.json_schema import FailedConversionError, convert_type


def test_convert_str():
Expand Down Expand Up @@ -57,5 +57,5 @@ def test_convert_dict():


def test_convert_invalid():
with pytest.raises(FailedConversion):
with pytest.raises(FailedConversionError):
convert_type(object, normalize_keys=False)