Skip to content

Commit c3c37e5

Browse files
authored
chore: add more checks and formatters (#191)
Signed-off-by: Henry Schreiner <[email protected]>
1 parent 82d1d8e commit c3c37e5

File tree

10 files changed

+132
-63
lines changed

10 files changed

+132
-63
lines changed

.github/workflows/tests.yml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,21 @@ jobs:
1818
fail-fast: false
1919
matrix:
2020
os:
21-
- 'windows-latest'
22-
- 'ubuntu-latest'
21+
- "windows-latest"
22+
- "ubuntu-latest"
2323
python:
24-
- '3.7'
25-
- '3.8'
26-
- '3.9'
27-
- '3.10'
28-
- '3.11'
29-
- '3.12'
30-
- '3.13'
24+
- "3.7"
25+
- "3.8"
26+
- "3.9"
27+
- "3.10"
28+
- "3.11"
29+
- "3.12"
30+
- "3.13"
3131
include:
3232
- os: macos-13
33-
python: '3.7'
33+
python: "3.7"
3434
- os: macos-14
35-
python: '3.12'
35+
python: "3.12"
3636

3737
steps:
3838
- name: Checkout
@@ -56,7 +56,6 @@ jobs:
5656
env_vars: PYTHON
5757
name: ${{ matrix.python }}
5858

59-
6059
# https://github.com/marketplace/actions/alls-green#why
6160
required-checks-pass: # This job does nothing and is only used for the branch protection
6261
if: always()

.pre-commit-config.yaml

Lines changed: 78 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,82 @@
11
ci:
22
autofix_prs: false
3-
autoupdate_commit_msg: 'pre-commit: bump repositories'
3+
autoupdate_commit_msg: "pre-commit: bump repositories"
44

55
repos:
6-
- repo: https://github.com/pre-commit/pre-commit-hooks
7-
rev: v4.6.0
8-
hooks:
9-
- id: check-ast
10-
- id: check-builtin-literals
11-
- id: check-docstring-first
12-
- id: check-merge-conflict
13-
- id: check-yaml
14-
- id: check-toml
15-
- id: debug-statements
16-
- id: end-of-file-fixer
17-
- id: trailing-whitespace
18-
19-
- repo: https://github.com/astral-sh/ruff-pre-commit
20-
rev: "v0.6.8"
21-
hooks:
22-
- id: ruff
23-
args: ["--fix", "--show-fixes"]
24-
- id: ruff-format
6+
- repo: https://github.com/pre-commit/pre-commit-hooks
7+
rev: v4.6.0
8+
hooks:
9+
- id: check-ast
10+
- id: check-builtin-literals
11+
- id: check-docstring-first
12+
- id: check-merge-conflict
13+
- id: check-yaml
14+
- id: check-toml
15+
- id: debug-statements
16+
- id: end-of-file-fixer
17+
- id: trailing-whitespace
18+
19+
- repo: https://github.com/astral-sh/ruff-pre-commit
20+
rev: "v0.6.8"
21+
hooks:
22+
- id: ruff
23+
args: ["--fix", "--show-fixes"]
24+
- id: ruff-format
25+
26+
- repo: https://github.com/pre-commit/pygrep-hooks
27+
rev: v1.10.0
28+
hooks:
29+
- id: rst-backticks
30+
- id: rst-directive-colons
31+
- id: rst-inline-touching-normal
32+
33+
- repo: https://github.com/adamchainz/blacken-docs
34+
rev: 1.18.0
35+
hooks:
36+
- id: blacken-docs
37+
additional_dependencies: [black==24.*]
38+
39+
- repo: https://github.com/rbubley/mirrors-prettier
40+
rev: "v3.3.3"
41+
hooks:
42+
- id: prettier
43+
types_or: [yaml, markdown, html, css, scss, javascript, json]
44+
args: [--prose-wrap=always]
45+
46+
- repo: https://github.com/henryiii/check-sdist
47+
rev: "v1.0.0"
48+
hooks:
49+
- id: check-sdist
50+
args: [--inject-junk]
51+
additional_dependencies:
52+
- flit-core
53+
54+
- repo: https://github.com/codespell-project/codespell
55+
rev: v2.3.0
56+
hooks:
57+
- id: codespell
58+
exclude: ^(LICENSE$|src/scikit_build_core/resources/find_python|tests/test_skbuild_settings.py$)
59+
60+
- repo: https://github.com/shellcheck-py/shellcheck-py
61+
rev: v0.10.0.1
62+
hooks:
63+
- id: shellcheck
64+
65+
- repo: https://github.com/henryiii/validate-pyproject-schema-store
66+
rev: 2024.09.23
67+
hooks:
68+
- id: validate-pyproject
69+
70+
- repo: https://github.com/python-jsonschema/check-jsonschema
71+
rev: 0.29.3
72+
hooks:
73+
- id: check-dependabot
74+
- id: check-github-workflows
75+
- id: check-readthedocs
76+
- id: check-metaschema
77+
files: \.schema\.json
78+
79+
- repo: https://github.com/scientific-python/cookie
80+
rev: 2024.08.19
81+
hooks:
82+
- id: sp-repo-review

README.md

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,30 @@
77
[![Documentation Status][rtd-badge]][rtd-link]
88
[![PyPI version][pypi-version]][pypi-link]
99

10-
1110
> Dataclass for PEP 621 metadata with support for [core metadata] generation
1211
13-
This project does not implement the parsing of `pyproject.toml`
14-
containing PEP 621 metadata.
12+
This project does not implement the parsing of `pyproject.toml` containing PEP
13+
621 metadata.
1514

1615
Instead, given a Python data structure representing PEP 621 metadata (already
1716
parsed), it will validate this input and generate a PEP 643-compliant metadata
1817
file (e.g. `PKG-INFO`).
1918

20-
2119
## Usage
2220

23-
After [installing `pyproject-metadata`](https://pypi.org/project/pyproject-metadata/),
21+
After
22+
[installing `pyproject-metadata`](https://pypi.org/project/pyproject-metadata/),
2423
you can use it as a library in your scripts and programs:
2524

2625
```python
2726
from pyproject_metadata import StandardMetadata
2827

29-
parsed_pyproject = { ... } # you can use parsers like `tomli` to obtain this dict
30-
metadata = StandardMetadata.from_pyproject(parsed_pyproject, allow_extra_keys = False)
28+
parsed_pyproject = {...} # you can use parsers like `tomli` to obtain this dict
29+
metadata = StandardMetadata.from_pyproject(parsed_pyproject, allow_extra_keys=False)
3130
print(metadata.entrypoints) # same fields as defined in PEP 621
3231

3332
pkg_info = metadata.as_rfc822()
34-
print(str(pkg_info))) # core metadata
33+
print(str(pkg_info)) # core metadata
3534
```
3635

3736
## SPDX licenses (METADATA 2.4+)
@@ -50,24 +49,25 @@ A backend is also expected to copy entries from `project.licence_files`, which
5049
are paths relative to the project directory, into the `dist-info/licenses`
5150
folder, preserving the original source structure.
5251

53-
5452
## Modifying metadata
5553

5654
By default, `StandardMetadata` metadata fields are immutable unless a field is
5755
listed in `dynaimc` (not to be confused with `dynamic_metadata`). If you want to
5856
modify fields that are not dynamic, you can use the `dataclasses.replace` /
5957
`copy.replace` (Python 3.13+) function.
6058

61-
6259
## Dynamic Metadata (METADATA 2.2+)
6360

64-
Pyproject-metadata supports dynamic metadata. To use it, specify your METADATA fields in `dynamic_metadata`. If you want to convert `pyproject.toml` field names to METADATA field(s), use `pyproject_metadata.pyproject_to_metadata("field-name")`, which will return a frozenset of metadata names that are touched by that field.
65-
61+
Pyproject-metadata supports dynamic metadata. To use it, specify your METADATA
62+
fields in `dynamic_metadata`. If you want to convert `pyproject.toml` field
63+
names to METADATA field(s), use
64+
`pyproject_metadata.pyproject_to_metadata("field-name")`, which will return a
65+
frozenset of metadata names that are touched by that field.
6666

6767
## Adding extra fields
6868

69-
You can add extra fields to the Message returned by `to_rfc822()`, as long as they are valid metadata entries.
70-
69+
You can add extra fields to the Message returned by `to_rfc822()`, as long as
70+
they are valid metadata entries.
7171

7272
## Collecting multiple errors
7373

@@ -76,7 +76,6 @@ the metadata parse at once, instead of raising an exception on the first one.
7676
The exception type will be `pyproject_metadata.errors.ExceptionGroup` (which is
7777
just `ExceptionGroup` on Python 3.11+).
7878

79-
8079
## Validating extra fields
8180

8281
By default, a warning (`pyproject_metadata.errors.ExtraKeyWarning`) will be
@@ -85,27 +84,35 @@ to either avoid the check (`True`) or hard error (`False`). If you want to
8584
detect extra keys, you can get them with `pyproject_metadata.extra_top_level`
8685
and `pyproject_metadata.extra_build_sytem`.
8786

88-
8987
## Validating classifiers
9088

91-
If you want to validate classifiers, then install the `trove_classifiers` library (the canonical source for classifiers), and run:
89+
If you want to validate classifiers, then install the `trove_classifiers`
90+
library (the canonical source for classifiers), and run:
9291

9392
```python
9493
import trove_classifiers
9594

96-
metadata_classifieres = {c for c in metadata.classifiers if not c.startswith("Private ::")}
95+
metadata_classifieres = {
96+
c for c in metadata.classifiers if not c.startswith("Private ::")
97+
}
9798
invalid_classifiers = set(metadata.classifiers) - trove_classifiers.classifiers
9899

99100
# Also the deprecated dict if you want it
100101
dep_names = set(metadata.classifiers) & set(trove_classifiers.deprecated_classifiers)
101-
deprecated_classifiers = {k: trove_classifiers.deprecated_classifiers[k] for k in dep_names}
102+
deprecated_classifiers = {
103+
k: trove_classifiers.deprecated_classifiers[k] for k in dep_names
104+
}
102105
```
103106

104-
If you are writing a build backend, you should not validate classifiers with a `Private ::` prefix; these are only restricted for upload to PyPI (such as `Private :: Do Not Upload`).
105-
106-
Since classifiers are a moving target, it is probably best for build backends (which may be shipped by third party distributors like Debian or Fedora) to either ignore or have optional classifier validation.
107+
If you are writing a build backend, you should not validate classifiers with a
108+
`Private ::` prefix; these are only restricted for upload to PyPI (such as
109+
`Private :: Do Not Upload`).
107110

111+
Since classifiers are a moving target, it is probably best for build backends
112+
(which may be shipped by third party distributors like Debian or Fedora) to
113+
either ignore or have optional classifier validation.
108114

115+
<!-- prettier-ignore-start -->
109116
[core metadata]: https://packaging.python.org/specifications/core-metadata/
110117
[gha-checks-link]: https://github.com/pypa/pyproject-metadata/actions/workflows/checks.yml
111118
[gha-checks-badge]: https://github.com/pypa/pyproject-metadata/actions/workflows/checks.yml/badge.svg
@@ -119,3 +126,4 @@ Since classifiers are a moving target, it is probably best for build backends (w
119126
[pypi-version]: https://badge.fury.io/py/pyproject-metadata.svg
120127
[rtd-link]: https://pep621.readthedocs.io/en/latest/?badge=latest
121128
[rtd-badge]: https://readthedocs.org/projects/pep621/badge/?version=latest
129+
<!-- prettier-ignore-end -->

docs/changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ Docs:
1111

1212
- Better API section
1313

14-
1514
## 0.9.0 (WIP)
1615

1716
This release adds PEP 639 support (METADATA 2.4), refactors the RFC messages,
@@ -69,6 +68,7 @@ Internal and CI:
6968
- Require 100% coverage
7069

7170
Docs:
71+
7272
- Include extra badge in readme
7373
- Rework docs, include README and more classes
7474
- Changelog is now in markdown

docs/index.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
```
44

5-
65
```{toctree}
76
:caption: Contents:
87
:maxdepth: 2

pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ testpaths = ["tests"]
6262

6363
[tool.mypy]
6464
strict = true
65+
warn_unreachable = false
66+
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
6567

6668

6769
[tool.ruff.lint]
@@ -103,3 +105,6 @@ html.show_contexts = true
103105
report.exclude_also = [
104106
"if typing.TYPE_CHECKING:",
105107
]
108+
109+
[tool.repo-review]
110+
ignore = ["PC140"]

pyproject_metadata/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,19 +242,19 @@ class StandardMetadata:
242242

243243
dynamic_metadata: list[str] = dataclasses.field(default_factory=list)
244244
"""
245-
This is a list of METADATA fields that can change inbetween SDist and wheel. Requires metadata_version 2.2+.
245+
This is a list of METADATA fields that can change in between SDist and wheel. Requires metadata_version 2.2+.
246246
"""
247247
metadata_version: str | None = None
248248
"""
249-
Thi is the target metadata version. If None, it will be computed as a minimum based on the fields set.
249+
This is the target metadata version. If None, it will be computed as a minimum based on the fields set.
250250
"""
251251
all_errors: bool = False
252252
"""
253253
If True, all errors will be collected and raised in an ExceptionGroup.
254254
"""
255255
_locked_metadata: bool = False
256256
"""
257-
Interal flag to prevent setting non-dynamic fields after initialization.
257+
Internal flag to prevent setting non-dynamic fields after initialization.
258258
"""
259259

260260
def __post_init__(self) -> None:

pyproject_metadata/errors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
"""
44
This module defines exceptions and error handling utilities. It is the
5-
recommened path to access ``ConfiguraitonError``, ``ConfigurationWarning``, and
5+
recommend path to access ``ConfiguratonError``, ``ConfigurationWarning``, and
66
``ExceptionGroup``. For backward compatibility, ``ConfigurationError`` is
77
re-exported in the top-level package.
88
"""

tests/test_rfc822.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
],
120120
)
121121
def test_headers(
122-
items: list[tuple[str, str]], data: str, monkeypatch: pytest.MonkeyPatch
122+
items: list[tuple[str, None | str]], data: str, monkeypatch: pytest.MonkeyPatch
123123
) -> None:
124124
message = pyproject_metadata.RFC822Message()
125125
smart_message = pyproject_metadata._SmartMessageSetter(message)

tests/test_standard_metadata.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,7 @@ def all_errors(request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch)
749749
license-files = ['/LICENSE']
750750
""",
751751
"'/LICENSE' is an invalid \"project.license-files\" glob: the pattern must match files within the project directory",
752-
id="Aboslute license-files glob",
752+
id="Absolute license-files glob",
753753
),
754754
pytest.param(
755755
"""
@@ -960,7 +960,7 @@ def test_load_with_metadata_version(
960960
""",
961961
"'License ::' classifiers are deprecated for metadata >= 2.4, use a SPDX license expression for \"project.license\" instead",
962962
"2.4",
963-
id="License trove classfiers with metadata 2.4",
963+
id="License trove classifiers with metadata 2.4",
964964
),
965965
],
966966
)

0 commit comments

Comments
 (0)