classification
Title: Add kwarg-only option to dataclass
Type: enhancement Stage: patch review
Components: Library (Lib) Versions: Python 3.8
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: alan_du, eric.smith, jimbo1qaz_, rhettinger, xtreak
Priority: normal Keywords: patch

Created on 2018-03-23 23:33 by alan_du, last changed 2018-07-27 01:58 by jimbo1qaz_.

Pull Requests
URL Status Linked Edit
PR 6238 open alan_du, 2018-03-25 16:11
Messages (8)
msg314341 - (view) Author: Alan Du (alan_du) Date: 2018-03-23 23:33
I'd like to request a new option to the `dataclasses.dataclass` decorator to make the `__init__` keyword-only.

The two use-cases I have in mind are:

(1) Using as a dataclass big-bag-of-config. In this scenario, forcing the user to specify the keywords is a lot nicer than passing in a dozen positional parameters.

(2) Having kwarg-only parameters means that inheritance and default parameters play nicely with each other again instead of raising a TypeError.
msg314342 - (view) Author: Alan Du (alan_du) Date: 2018-03-23 23:40
If this would be accepted, I'd be happy to contribute a patch adding a `kwarg_only` option to `dataclass` (although it might take me a while since I'm not super familiar with the Python development workflow). I believe I already have the code change necessary at https://github.com/alanhdu/cpython/commit/fa35b39e5204845690ff774812f882f40b0e5f90 (although it still needs tests and documentation).
msg314343 - (view) Author: Alan Du (alan_du) Date: 2018-03-23 23:41
Err... the right link would actually be https://github.com/alanhdu/cpython/tree/bpo-33129.
msg314346 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2018-03-24 00:27
Changing this to 3.8: there's not enough time to add this to 3.7.
msg316784 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2018-05-16 08:26
I'd forgotten about this issue and created #33493. I'll close it. Copied here is my comment from that issue:

I've had several requests for keyword-only arguments. This is a placeholder to remind me to work on it. I have not decided if it's a good idea or not.

I propose adding a keyword_only argument to field(), defaulting to False.

I'm thinking that the basic idea would be to put all keyword-only fields at the end of the arguments to __init__, but for all other uses, leave them where they appear in the class definition. That way comparison operations, in particular, would use the fields as they appear in the class definition (which is the current behavior). Since they'd be at the end of __init__, and since order doesn't matter (they're keyword-only, after all), then this would work as expected for base classes.

That is, given:

@dataclass
class B:
    a: field(type=int, keyword_only=True)
    b: int

@dataclass
class C(B):
    c: int
    d: field(type=int, keyword_only=True)

Then B's __init__ would take (b, c, *, a, d) as its arguments, but its comparison functions would compare the tuples as (a, b, c, d).

It would be an error for a ClassVar field to be keyword-only. I think it would be okay if an InitVar field were keyword-only, but I haven't given it a lot of thought.
msg321811 - (view) Author: Karthikeyan Singaravelan (xtreak) * (Python triager) Date: 2018-07-17 10:53
There is an open PR and some discussion about this feature in attrs repo : https://github.com/python-attrs/attrs/pull/281
msg322051 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2018-07-21 00:43
+1 from me -- think would occasionally be nice to have.
msg322455 - (view) Author: jimbo1qaz_ via Gmail (jimbo1qaz_) Date: 2018-07-27 01:58
first post in bugs.python.org... are people normally scary around here?

Another usecase of keyword-only arguments is that I can mix default and non-default fields in any order. This could be achieved by either marking all fields as read-only, or by implicitly adding an asterisk before the first "conflicting" non-default argument (or by translating .../etc into an asterisk).

(Is it a bad idea to create a private fork of `pip install dataclasses` with implicit asterisk, purely for my own project?)
History
Date User Action Args
2018-07-27 01:58:57jimbo1qaz_setnosy: + jimbo1qaz_
messages: + msg322455
2018-07-21 00:43:38rhettingersetnosy: + rhettinger
messages: + msg322051
2018-07-17 10:53:29xtreaksetnosy: + xtreak
messages: + msg321811
2018-05-16 08:27:07eric.smithlinkissue33493 superseder
2018-05-16 08:26:24eric.smithsetmessages: + msg316784
2018-03-25 16:11:58alan_dusetkeywords: + patch
stage: patch review
pull_requests: + pull_request5975
2018-03-24 00:27:22eric.smithsetassignee: eric.smith
2018-03-24 00:27:08eric.smithsetmessages: + msg314346
versions: - Python 3.7
2018-03-23 23:41:44alan_dusetmessages: + msg314343
2018-03-23 23:40:13alan_dusetmessages: + msg314342
2018-03-23 23:33:17alan_ducreate