Repository navigation
🔧 build(lint): adopt simplint 0.8.0 - #361
Merged
Merged
Conversation
Ruff's undocumented-* rules conflict with simplint's function-docstring, which removes the docstrings of internal functions. undocumented-public-api (SMP903) covers the public API instead, in reST. The docstring style is set to reST to match the package's docstrings.
Applied with simplint check --fix --unsafe-fixes, then prek run to let the formatters settle.
simplint requires every suppression to say why it is there. Only the reasons are added; the codes and the code they cover are unchanged.
The package __init__ holds no code: __version__ is re-exported from the version module. autodata took the description of __version__ from the removed #: comment, so the docs use a data directive that carries it.
CmdStatus is exported, so simplint's undocumented-public-api asks for a docstring, and its abstract out_err uses the reST returns field.
run exceeded simplint's complexity limit of 20. The request parsing, command execution and response writing are separate steps, so each becomes a helper that run calls in order.
_send returns the value with its output and error text. A NamedTuple names those fields without changing the unpacking that callers already do.
Sphinx and the frontend read these names by value, so the annotation only records that they are constants for simplint's missing-final rule.
The helper receives either a description or the str type, so the union replaces Any.
simplint wants module-level names of a module without __all__ to be private and constants to be Final. The backend is loaded by path, so the names inside it are only read by its own hooks.
requires-python is 3.11 or newer, so the older expected requirement spelling never ran.
A patch without a spec accepts any call, so a wrong signature in the code under test passes.
simplint's split-composite-assert asks for one comparison per exception, so a failure shows all fields together.
simplint's parametrize-without-id asks for every case to be named, so failures list the case by name.
Each conditional in a test body moves into the parameters: the case states the expected path or cases, and the body asserts without branching.
Single-letter names are only allowed in comprehensions, and the input is built with an f-string.
The method is public, and its returns and raises fields had no text.
simplint's rst rules want every field of a public result type documented, and an empty :param or :ivar is flagged. The descriptions move from the #: comments into the docstrings, which Sphinx renders as the field list.
Values the backend returns arrive as JSON, so a recursive alias replaces Any where the protocol hands them over. The alias is exported from _frontend like ConfigSettings. The remaining Any annotations are kwargs, the TOML table and the pickled state, which are not JSON-only.
The autofix renamed main_parser to _main_parser, so pyproject_api.__main__.main_parser stopped being importable. The name is exported again. simplint's unused-export still reports it, because no module in the package imports it.
create_args_from_folder and metadata_from_built returned bare tuples whose positions had to be remembered. Both now return public NamedTuples, so the fields are named while positional unpacking and slicing keep working. The test that read metadata_from_built by index uses the metadata field.
tomllib yields a fixed set of types, so the pyproject.toml reader and _str_list take a recursive alias instead of dict[str, Any]. The alias stays private, since no public signature uses it.
main_parser is public API of the CLI module, so it stays in __all__ and the suppression says so. send_cmd is the generic transport for any backend command (the tests call echo and _exit), so its kwargs are not limited to the Frontend's own arguments.
Keeping only re-exports in __init__ dropped the version import, so pyproject_api.version stopped being importable. It is re-exported again next to __version__.
This was referenced Nov 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
simplint now checks every change in pre-commit and on pre-commit.ci, so the conventions Ruff cannot check are enforced before review: reST docstrings on the public API,
Finalon module constants and a fixed definition order. 🧹 The library's behavior does not change, and existing import paths and positional unpacking keep working. The code is changed so simplint 0.8.0 reports nothing, and the type-level changes a caller can notice are listed below.Hook and configuration
The hook is pinned to simplint-pre-commit v0.8.0. Each hook also gets an explicit
priority, the ordering key of prek: hooks with a lower number run first, hooks with the same number run together, and the numbers are chosen so that no two of them write the same file. Ruff lint runs before simplint and Ruff format after it, so simplint sees code Ruff has already fixed, and formatting has the last word. pre-commit ignorespriorityand runs hooks in file order.Ruff's
undocumented-*rules are off because they ask for a docstring on every name that looks public. simplint'sundocumented-public-api(SMP903) asks only for the public API, and[tool.simplint]setsdocstring-style = "rst"so the checks read the reStructuredText (reST):param:and:returns:fields the package already uses.Public names and signatures
No importable name is renamed or removed. The package
__init__now holds only imports and__all__, and it addsBuiltMetadataandFrontendArgsto its exports.pyproject_api.__main__gained an__all__listingmainandmain_parser, so a star import from it no longer brings in the module's imports.Four signatures change.
Frontend.create_args_from_folderandFrontend.metadata_from_builtreturn the named tuples described below.SubprocessFrontend.send_cmdannotates its result astuple[JsonValue, str, str]instead oftuple[Any, str, str], andBackendFailed.__reduce__annotates its pickled state withJsonValueinstead ofAny. Runtime values are unchanged, but a caller that assigned asend_cmdresult to a non-JSON type now needs a cast.Result types
Two methods that returned bare tuples now return
NamedTupleinstances, which are tuples with named fields, so positional unpacking keeps working.create_args_from_folderreturnsFrontendArgswith the root, backend paths, backend module, backend object, requirements and reuse flag.metadata_from_builtreturnsBuiltMetadatawith the metadata directory,outanderr.Type annotations
Values that come from the backend's JSON use
JsonValue, a recursive alias for JSON types, in place ofAny, and parsed TOML values use a precise union. The private_sendaccepts only paths and config settings as keyword arguments, and its annotation says so.Suppressions
Two findings keep their code and a
simplint: ignorecomment that gives the reason.main_parserstays in__all__because the CLI parser is public API, andsend_cmdkeeps**kwargs: Anybecause it is the generic transport for any backend command, so its keyword arguments are not limited to the frontend's own types.Module structure
Module constants that are never reassigned are marked
Final, which type checkers enforce as no reassignment. The backend'srunfunction is split into named helpers, one per step, and the API docs now describeCmdStatus, the fields of the result types and whatmetadata_from_builtreturns.