Skip to content

chore(deps-dev): Bump no-defaults from 1.0.1 to 2.0.0 - #3136

Merged
github-actions[bot] merged 1 commit into
mainfrom
dependabot/pip/no-defaults-2.0.0
Aug 10, 2026
Merged

chore(deps-dev): Bump no-defaults from 1.0.1 to 2.0.0#3136
github-actions[bot] merged 1 commit into
mainfrom
dependabot/pip/no-defaults-2.0.0

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 10, 2026

Copy link
Copy Markdown
Contributor

Bumps no-defaults from 1.0.1 to 2.0.0.

Release notes

Sourced from no-defaults's releases.

v2.0.0

What's Changed

Full Changelog: adamtheturtle/no-defaults@v1.1.0...v2.0.0

v1.1.0

What's Changed

... (truncated)

Changelog

Sourced from no-defaults's changelog.

2.0.0 - 2026-08-07

This release changes what the linter reports, what --fix writes, and which configurations it accepts. Read ### Changed before upgrading a project that pins an earlier version.

Added

  • Defaults on pydantic models are reported. A class is now checked for fields when it names a base class from field_base_classes, which defaults to [ "pydantic.BaseModel" ], as well as when it carries @dataclass. Its violations are named class field where a dataclass's are named dataclass field. Codebases built on BaseModel will see violations that earlier versions passed over in silence; field_base_classes = [] restores the old behaviour, and the same setting extends the rule to msgspec.Struct, sqlmodel.SQLModel, or anything else that carries fields through a base class.
  • Field(default=…) and Field(default_factory=…) are fixed the way field(...) is, removing only those arguments and keeping the rest of the metadata. Pydantic writes a field with no default as Field(...) or Field(default=...), and neither is reported. A model's call sites gain the removed default as a keyword argument like any other.
  • --show-settings reports field-base-classes.
  • --fix now updates call sites. Every call in the checked files that relied on a removed default gains it as an explicit argument, so connect("h") becomes connect("h", timeout=30) and Job("j") becomes Job("j", retries=3). A default_factory becomes the value it produces. Arguments are appended as keywords except for positional-only parameters. --diff previews these edits too. This supersedes the 1.1.0 warning that call sites were left alone.
  • Calls are resolved through the calling file's own imports rather than by matching the bare name, so a project with its own connect does not have socket.connect rewritten, and two modules that each define helper are told apart. A method is rewritten when reached through self, cls, or a class the file can name, whether local, imported, or reached through an imported module, and what it already receives is accounted for, so instance.fetch(url), Client.fetch(instance, url), and a staticmethod reached through either are each filled in correctly.
  • --fix warns, naming the file and line, about each call it left alone: one it cannot tie to the definition that was fixed, a call unpacking *args or **kwargs, a removed default that is not a literal, a positional-only argument that cannot be appended, a dataclass that inherits fields, or a function named without being called such as a bare @decorator. It still warns that callers outside the checked files, and dynamic calls, are beyond its reach.
  • Fields that __init__ never accepts are never added to a call: field(..., init=False), a _: KW_ONLY marker, and a class whose decorator says init=False.
  • A file exempted with per_file_enforcement = "none" keeps its own defaults but still has its call sites updated when a callable it uses is fixed elsewhere.
  • respect_reexports, and the matching --respect-reexports flag, treat a name that a package's __init__.py re-exports as public in private-only mode. A helper in _upload.py that the package root exports through an import or __all__ keeps its defaults, because they are public API. A module re-exported under its own name, as in from . import _upload, makes what it holds public in the same way. Names behind a from ... import * cannot be listed, so every name in that package counts as re-exported. Off by default.
  • --show-settings reports respect-reexports alongside the enforcement level.
  • A package's __init__.pyi is read where it has no __init__.py, so a stub-only distribution is treated as a package too. A namespace package, which has neither, no longer hides what the packages above it re-export.
  • Defaults on lambda parameters are reported. A lambda takes the same parameter kinds as a def and carries the same late-binding hazard, and the rule was documented as covering defaults in function signatures without excluding them. Because a lambda is anonymous, --fix cannot resolve its call sites, so removing one is reported as a call it left alone. The loop-capture idiom lambda x=x: ... needs a # noqa: NOD001.

Changed

  • A file the parser rejects is reported as a NOD000 syntax-error diagnostic and the run continues, instead of aborting with exit status 2 and printing nothing for any file. One unparseable file in a tree — a Python 2 module kept for reference, a template saved as .py, a file caught mid-edit — no longer hides every other file's diagnostics, which under pre-commit turned into a hook that silently stopped catching regressions. NOD000 carries no fix, so --fix leaves that file alone, counts it as remaining, and exits 1.
  • A leading UTF-8 byte-order mark is no longer counted as source, so diagnostics on the first line of a BOM-prefixed file report the right column instead of three too far right. --fix writes the mark back.
  • Diagnostic columns count characters rather than bytes, matching Ruff. Non-ASCII text earlier on a line no longer shifts the reported column in full, concise, json, and github output, or pushes the ^ in full output past what it points at, so editor and CI annotations land in the right place.
  • --fix writes through a symlink to the file it points at, instead of replacing the link with a regular file and leaving the real source unfixed. Directory walks never followed links, so this only affected a link named on the command line — which is exactly what pre-commit and shell globs produce.
  • Files are deduplicated by canonical path, so naming one file twice under different spellings — d.py and ./d.py, a relative and an absolute form, or a symlink and its target — checks and reports it once instead of twice. The first spelling in sorted order is what diagnostics name.
  • A path named on the command line that exists but is not a .py or .pyi file is now an operational error rather than being silently dropped. A run that checked nothing was previously indistinguishable from a clean one, so a mistyped path, a wrong types setting in .pre-commit-config.yaml, or a shell glob that matched the wrong thing reported success over code it never opened. Directory walks still filter to Python files.
  • An unrecognised key in [tool.no_defaults] is now an error rather than being silently ignored. Because the presence of that table is also what makes configuration discovery stop at a pyproject.toml, a misspelled option previously produced a run that looked configured but used the defaults throughout. This rejects configurations that earlier versions accepted.

Fixed

  • --fix no longer stops the removal of a noqa directive at a # that is part of a comment's prose. # noqa: NOD001 see [#35](https://github.com/adamtheturtle/no-defaults/issues/35) # type: ignore left [#35](https://github.com/adamtheturtle/no-defaults/issues/35) # type: ignore behind; a new comment segment now has to open with whitespace or a pragma's word:.
  • A local name that a file binds to more than one dataclasses or pydantic member resolves to neither, instead of to whichever import came last.
  • A base class named Generic, Protocol, ABC, or object that the file itself defines at module level is no longer taken for the typing construct, so a dataclass built on one keeps its construction sites intact.
  • A call whose bare generator expression already supplies every default that was removed is no longer reported as left alone, because nothing needed appending to it.
  • A nested def, class, or lambda no longer shadows names in the scope holding it, so a call in the outer scope that really does reach a fixed callable is still updated.
  • An absolute import is resolved against the ancestors of the importing file that are not themselves packages, rather than stopping at the first directory without an __init__.py. A sibling module at the project root is found from inside a namespace package, a top-level import inside a package no longer resolves to that package's own module, and an import that two candidate roots could answer resolves to neither.
  • The Found N errors (N fixed, N remaining) summary reaches standard error under --output-format json and github, as documented, rather than being dropped.
  • Module privacy is judged from the path below the project root rather than from every component of the path as written. A checkout living under a directory whose name starts with an underscore — _work/proj — no longer has every symbol in it treated as private under private_only, and the answer no longer depends on whether a relative or an absolute path was passed on the command line.
  • A renaming import of a dataclasses or pydantic member is followed, so from dataclasses import dataclass as dc makes @dc a dataclass decorator. The class was previously not treated as a dataclass at all, and its field defaults went unreported. The same applies to field, Field, and the KW_ONLY marker, including imports inside an if TYPE_CHECKING: block.
  • --fix accounts for keyword-only dataclass fields when filling in construction sites. The positional order was built from the fields in source order with nothing consulting kw_only, but dataclasses moves such a field past the * in the generated __init__, so every field after it really sat one slot lower than assumed. For @dataclass class C: a = field(kw_only=True, default=1); b = 2, C(5) became C(5, b=2) — which raises TypeError: got multiple values for argument 'b' — while the default a now needs was dropped. field(kw_only=...), @dataclass(kw_only=True), and the _: KW_ONLY marker are all honoured, with the per-field setting winning.
  • An absolute import is resolved against the importing file's own import root before falling back to matching its dotted name against the checked files' paths, and a one-component import such as from utils import helper is only ever resolved against that root. Matching one filename at any depth meant import utils resolved to anything/at/any/depth/utils.py, silently rewriting calls to an unrelated function — with no warning, because from the resolver's point of view the call resolved cleanly. A dotted import still reaches another source tree, so a test under tests/ still reaches a package under src/.
  • --fix leaves alone a call to a name that an enclosing function, class, or lambda binds. Resolution had no notion of local scope, so a parameter, assignment, for target, with ... as, comprehension variable, or except ... as that shared a name with a fixed callable resolved to that callable and had its call rewritten — passing an unexpected keyword to an unrelated object, which the README's "Nothing is guessed" promise said would not happen. Such a call is now skipped with the existing warning.
  • --fix updates call sites reached through from . import module, the idiomatic way to import a sibling. The submodule check was guarded on the import naming a module, which a purely relative import does not, so the name was bound as a symbol of the package and every call through it was skipped with a warning — while the same call through from package import module was rewritten. from .sub import module worked already and is now covered by a test.
  • A call taking a bare generator expression, as in f(x for x in y), is left alone with a warning instead of being rewritten into f(x for x in y, timeout=30), which does not parse. The post-fix parse guard caught that, but by turning the whole run into an operational error: nothing was fixed, in any file, and the exit status was 2. One such call anywhere in a project blocked fixing everything else. A parenthesized generator is still filled in.
  • --fix updates the construction sites of a dataclass whose only bases declare no fields. Any base at all previously marked the constructor unknown, so a generic dataclass built on Generic[T] — or on Protocol, ABC, or object — had its fields made required while Box() was left as it was, raising TypeError at runtime with only a warning to mark it. That safe path could never be escaped, however the project was laid out. A base that may carry fields still gives up.
  • --fix no longer strips = ... from a .pyi stub. In a stub that is the convention for "this parameter has a default, unspecified here", not a default value, so removing it made the parameter required and stopped the stub matching the implementation it describes. It is still reported; it is now counted as remaining rather than fixed. Outside a stub, = ... is an ordinary default and is still removed.
  • --fix honours --output-format. It returned before diagnostics were ever reported, so --output-format json --fix printed human-readable text and --output-format github --fix produced no annotations at all. Under the machine formats the diagnostics are now all that reaches standard output, with the N fixed summary and the call-site count moved to standard error so the output stays parseable; the text formats are unchanged.
  • --fix no longer panics or silently deletes unrelated code when a noqa directive sits inside a multi-line default. Removing the default already removes the directive, so the two deletions overlapped; applying both in turn used the offsets the first had already invalidated. Overlapping deletions are now merged into the span they cover.
  • --fix no longer deletes a pragma that follows an unused # noqa: NOD001 on the same line. A # runs to end of line, so # noqa: NOD001 # type: ignore[misc] is one comment, and removing the directive took the mypy suppression — or a # pylint: disable, a # pragma: no cover, or a plain explanation — with it. The deletion now stops at the next #.

... (truncated)

Commits
  • 4e74da7 Prepare the 2.0.0 release (#71)
  • 72a818d Address review findings from the issue-fixing series (#70)
  • 30e1bf5 Account for keyword-only fields in a dataclass constructor (#69)
  • 0461a36 Resolve an absolute import at the importer's own root first (#68)
  • b08ef1f Do not rewrite calls to names an enclosing scope binds (#67)
  • 38ba6ca Resolve from . import module to the sibling module (#66)
  • 7cab61b Leave a call taking a bare generator expression alone (#65)
  • 1796622 Treat bases that declare no fields as non-inheriting (#64)
  • 7f4395a Index each file's line starts instead of rescanning per diagnostic (#63)
  • 9c20bc1 Report but do not fix = ... in stub files (#62)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [no-defaults](https://github.com/adamtheturtle/no-defaults) from 1.0.1 to 2.0.0.
- [Release notes](https://github.com/adamtheturtle/no-defaults/releases)
- [Changelog](https://github.com/adamtheturtle/no-defaults/blob/main/CHANGELOG.md)
- [Commits](adamtheturtle/no-defaults@v1.0.1...v2.0.0)

---
updated-dependencies:
- dependency-name: no-defaults
  dependency-version: 2.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file python Pull requests that update Python code labels Aug 10, 2026
@github-actions
github-actions Bot enabled auto-merge August 10, 2026 10:33
@github-actions
github-actions Bot merged commit c20a91a into main Aug 10, 2026
13 checks passed
@github-actions
github-actions Bot deleted the dependabot/pip/no-defaults-2.0.0 branch August 10, 2026 10:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file python Pull requests that update Python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants