Skip to content

Fix kw_only=True not being overridable by per-attribute kw_only=False#1558

Closed
ShiLiguo123 wants to merge 1 commit into
python-attrs:mainfrom
ShiLiguo123:fix-kw-only-override
Closed

Fix kw_only=True not being overridable by per-attribute kw_only=False#1558
ShiLiguo123 wants to merge 1 commit into
python-attrs:mainfrom
ShiLiguo123:fix-kw-only-override

Conversation

@ShiLiguo123
Copy link
Copy Markdown

Summary

Fix kw_only=True at the class level being unconditionally applied to all attributes, ignoring per-attribute kw_only=False.

Root Cause

When a class is decorated with @attr.s(kw_only=True):

@attr.s(kw_only=True)
class A:
    a = attr.ib(kw_only=False)

Line 460-462 in _make.py force-sets kw_only=True on ALL attributes:

if kw_only is ClassProps.KeywordOnly.FORCE:
    own_attrs = [a.evolve(kw_only=True) for a in own_attrs]
    base_attrs = [a.evolve(kw_only=True) for a in base_attrs]

This ignores any attribute that has kw_only=False explicitly set.

Fix

Skip the force-update for attributes that already have an explicit kw_only=False:

a.evolve(kw_only=True) if a.kw_only is not False else a

Fixes #481

When a class is decorated with @attr.s(kw_only=True), attributes with
explicit kw_only=False should remain positional. However, the FORCE
path unconditionally sets kw_only=True on all attributes.

This fix checks each attribute's kw_only value: if it's explicitly
set to False by the user, respect that. Otherwise, force kw_only=True.

Fixes python-attrs#481
@hynek hynek closed this May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

kw_only=True in class cannot be overridden by attributes

2 participants