no-defaults
A fast, standalone Python linter that forbids defaults in function signatures and dataclasses. It is implemented in Rust and parses Python with Ruff's parser.
from dataclasses import dataclass, field
def connect(timeout=30): # NOD001
pass
@dataclass
class Job:
retries: int = 3 # NOD001
tags: list[str] = field(default_factory=list) # NOD001
Installation
uv tool install no-defaults
Usage
no-defaults .
no-defaults --fix .
no-defaults --diff .
no-defaults --private-only src tests
no-defaults --output-format json .
no-defaults --output-format github .
no-defaults --show-settings src/package/api.py
Exit status is 0 when clean, 1 when violations are found, and 2 for an operational error.
Directories are walked in parallel, respecting .gitignore and standard hidden-file filters.
Diagnostics use Ruff's concise format and include a summary:
src/example.py:4:17: NOD001 parameter `timeout` of function `connect` has a default
Found 1 error.
Pass --fix to remove defaults automatically. Function parameters and ordinary dataclass assignments become required. For field(...), only the positional default, default=, or default_factory= argument is removed; other metadata is preserved:
retries: int = field(default=3, kw_only=True)
# becomes
retries: int = field(kw_only=True)
After a successful fix, the command exits with status 0 and prints a Ruff-style summary such as Found 2 errors (2 fixed, 0 remaining). Writes use an atomic same-directory replacement. --diff prints a unified diff, writes nothing, and exits with status 1 when changes are available.
The default full output includes source excerpts and carets. concise emits one diagnostic per line, json emits a machine-readable array, and github emits workflow commands for GitHub Actions annotations.
The linter detects defaults on positional-only, positional-or-keyword, and keyword-only parameters.
For classes decorated with @dataclass or @dataclasses.dataclass, it detects assigned defaults plus field(default=...) and field(default_factory=...).
ClassVar assignments are ignored because they are not dataclass fields.
Suppress an individual violation with either a blanket # noqa or the rule-specific # noqa: NOD001 on the line containing the default:
def compatible(timeout=30): # noqa: NOD001
pass
Suppress the rule for an entire file with # ruff: noqa or # ruff: noqa: NOD001.
Configuration
Configuration lives in pyproject.toml:
[tool.no_defaults]
private_only = true
[tool.no_defaults.per_file_enforcement]
"tests/**" = "all"
"src/**" = "private"
Private means a name that starts with one underscore. In private-only mode, the rule applies to private modules and packages, private functions and methods, all members of private classes, and private dataclass fields. For example, all defaults in _module.py and _package/module.py are checked. Dunder names such as __init__.py are not considered private by themselves.
per_file_enforcement accepts Ruff-style glob patterns relative to the directory containing pyproject.toml. Use "all" to reject every default in matching files or "private" to reject defaults only in private scopes. Patterns without a slash match file names at any depth. An initial ! negates a pattern. If multiple patterns match, the most specific pattern wins; equally specific patterns are resolved lexicographically so results never depend on TOML table order.
The --private-only CLI flag overrides the configuration for every checked file.
Like Ruff, no-defaults discovers the closest pyproject.toml containing [tool.no_defaults] separately for each file. This supports monorepos with nested configuration; files without a local table continue searching parent directories.
Performance
An optimized 1.0.0 development build checked a pinned Typeshed checkout containing 5,368 Python and stub files (12.5 MiB) in a median 0.29 seconds across five warm runs on an Apple Silicon Mac, or roughly 18,000 files per second. It produced 50,974 diagnostics; an earlier full-output measurement used approximately 41 MiB maximum RSS.
The scheduled Typeshed benchmark workflow repeats this against a pinned upstream revision and fails on parser errors, unexpected results, or a gross performance regression.
pre-commit
repos:
- repo: https://github.com/adamtheturtle/no-defaults
rev: v1.0.0
hooks:
- id: no-defaults
License
MIT
See CONTRIBUTING.md, SECURITY.md, and CHANGELOG.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file no_defaults-1.0.0.tar.gz.
File metadata
- Download URL: no_defaults-1.0.0.tar.gz
- Upload date:
- Size: 25.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dfaaa9ad0e009c3af3e498d304368fb8d3a6973e029a8d3273aec6b6fc3bd282
|
|
| MD5 |
b71914fa07d8b4486b740e7bca6a38cd
|
|
| BLAKE2b-256 |
a231a26d2ccff9c4935006385b77e121b20ca1b73677ea0cd76b53255769043a
|
Provenance
The following attestation bundles were made for no_defaults-1.0.0.tar.gz:
Publisher:
release.yml on adamtheturtle/no-defaults
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
no_defaults-1.0.0.tar.gz -
Subject digest:
dfaaa9ad0e009c3af3e498d304368fb8d3a6973e029a8d3273aec6b6fc3bd282 - Sigstore transparency entry: 2347505880
- Sigstore integration time:
-
Permalink:
adamtheturtle/no-defaults@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adamtheturtle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file no_defaults-1.0.0-py3-none-win_amd64.whl.
File metadata
- Download URL: no_defaults-1.0.0-py3-none-win_amd64.whl
- Upload date:
- Size: 1.9 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2e300d41386161bd9d9726939c2e6b10632d17acc154dd4ac3542a6eeb862f57
|
|
| MD5 |
0ff7a7e0993394a78ea79ec55c39923a
|
|
| BLAKE2b-256 |
9ec026ef1e7cf4508b60ec15458fddd8988136493f14cd799b21fb7a0d60c620
|
Provenance
The following attestation bundles were made for no_defaults-1.0.0-py3-none-win_amd64.whl:
Publisher:
release.yml on adamtheturtle/no-defaults
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
no_defaults-1.0.0-py3-none-win_amd64.whl -
Subject digest:
2e300d41386161bd9d9726939c2e6b10632d17acc154dd4ac3542a6eeb862f57 - Sigstore transparency entry: 2347507328
- Sigstore integration time:
-
Permalink:
adamtheturtle/no-defaults@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adamtheturtle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file no_defaults-1.0.0-py3-none-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: no_defaults-1.0.0-py3-none-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 2.2 MB
- Tags: Python 3, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a43a1ef8b9a99d0e6a106bade1840e4ccf25933d32247b310e66f8abf9edb48
|
|
| MD5 |
de82ca2f8d7e6e88f9fc3a6952e66c89
|
|
| BLAKE2b-256 |
3cdee51079006752bcbd4f46285b7abf945772a298650e16de4f58fb163b74c0
|
Provenance
The following attestation bundles were made for no_defaults-1.0.0-py3-none-manylinux_2_34_x86_64.whl:
Publisher:
release.yml on adamtheturtle/no-defaults
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
no_defaults-1.0.0-py3-none-manylinux_2_34_x86_64.whl -
Subject digest:
0a43a1ef8b9a99d0e6a106bade1840e4ccf25933d32247b310e66f8abf9edb48 - Sigstore transparency entry: 2347506433
- Sigstore integration time:
-
Permalink:
adamtheturtle/no-defaults@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adamtheturtle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file no_defaults-1.0.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: no_defaults-1.0.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 2.0 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e29dc5a41f1f55f01e81a4172f695c981f6475e5293b44ae3b00b1b381ef459
|
|
| MD5 |
fde072b1384a2e11c8149b71625c2562
|
|
| BLAKE2b-256 |
29a94383807e8f257e7112e7f18c20cd4a0fe1151fa0a906d88b1eaae394f39e
|
Provenance
The following attestation bundles were made for no_defaults-1.0.0-py3-none-macosx_11_0_arm64.whl:
Publisher:
release.yml on adamtheturtle/no-defaults
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
no_defaults-1.0.0-py3-none-macosx_11_0_arm64.whl -
Subject digest:
8e29dc5a41f1f55f01e81a4172f695c981f6475e5293b44ae3b00b1b381ef459 - Sigstore transparency entry: 2347507977
- Sigstore integration time:
-
Permalink:
adamtheturtle/no-defaults@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/adamtheturtle
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ae8b5abe612530810c4e015abf32fc9a3a1e969f -
Trigger Event:
workflow_dispatch
-
Statement type: