# Allow for positional- or keyword-only arguments in dataclasses

**URL:** <https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980>\
**Category:** Ideas\
**Created:** [January 8, 2020, 6:06pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980 "2020-01-08T18:06:04Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mikeholler](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mikeholler/32/1709_2.png) [@mikeholler](https://discuss.python.org/u/mikeholler)\
**Post date:** [January 8, 2020, 6:06pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/1 "2020-01-08T18:06:04Z")

</div>

There are some data classes where I want to have only keyword arguments, and some where I want only positional. Take for example:

```auto
@dataclass()
class XYZ:
    x: int
    y: int
    z: int

# For this dataclass, it might make sense to force positional-only such that
# this works:
XYZ(1, 2, 3)

# But these don't:
XYZ(1, 2, z=3)
XYZ(x=1, y=2, z=3)

```

Similarly, and more importantly, one might want to force keyword arguments:

```auto
@dataclass()
class Credentials:
    username: str
    password: str

# With this, we should allow:
Credentials(username="mikeholler", password="hunter2")

# But maybe not allow for concern of misuse and confusion:
Credentials("mikeholler", "hunter2")
Credentials("mikeholler", password="hunter2")

```

After reading `dataclasses.py` from the 3.8 sources, it seems like there’s no way to get at the constructor parameters to write special handling logic for myself (without using `init=False` and writing a custom init function every time, which is an unacceptable solution in my opinion). This means the solution would have to lie within an update to `dataclass` itself, some syntax to say “here is where forced positional arguments and” and “here is where forced kwargs end”.

This could be, perhaps, added to the `field(...)` function, but implementation details aside, the ability to specify which args in a dataclass’s constructor should be positional and which should be kwargs (or both when both are allowed) would be a great quality of life improvement.

Does anybody have good ideas for a syntax that would be best for this? Anyone also think this is a good idea?

---

<div class="post-metadata">

**Author:** ![mikeholler](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mikeholler/32/1709_2.png) [@mikeholler](https://discuss.python.org/u/mikeholler)\
**Post date:** [January 8, 2020, 6:11pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/2 "2020-01-08T18:11:09Z")

</div>

A note: one thing I also tried was providing my own ` __init__ ` function when `@dataclass(init=True)`, hoping the generated init class might do it’s thing and then call mine. But, alas, it seems like it only replaces it without error (so mine is not called at all).

Might be nice to have @dataclass generate a warning or error if it tries to set the ` __init__ ` function when one already exists to avoid confusion (probably the same for ` __repr__ `, etc.)

---

<div class="post-metadata">

**Author:** ![mikeholler](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/mikeholler/32/1709_2.png) [@mikeholler](https://discuss.python.org/u/mikeholler)\
**Post date:** [January 8, 2020, 9:26pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/3 "2020-01-08T21:26:39Z")

</div>

I found a workaround to allow this using a decorator. The problem is, the decorator breaks IDE support for parameters, but otherwise works as expected. See the gist here:

> <https://gist.github.com/mikeholler/4be180627d3f8fceb55704b729464adb>

I still think something like this would be nice in stdlib.

---

<div class="post-metadata">

**Author:** ![Maroloccio](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/maroloccio/32/27033_2.png) [@Maroloccio](https://discuss.python.org/u/Maroloccio)\
**Post date:** [January 9, 2020, 11:38am UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/4 "2020-01-09T11:38:14Z")

</div>

Hi Michael,

you write:

> one thing I also tried was providing my own ` __init__ ` function when `@dataclass(init=True)` , hoping the generated init class might do it’s thing and then call mine. But, alas, it seems like it only replaces it without error (so mine is not called at all).

Could this code perhaps help you in getting your own **init** method called? Let me know:

```
import dataclasses
@dataclasses.dataclass
class Data:
    number: int = 42
    def __post_init__ (self):
        print('Hello, world!')
print(Data().number)

```

outputs:

```
Hello, world!
42

```

I found this section of the PEP maybe applicable:

> **[PEP 557 – Data Classes | peps.python.org](https://peps.python.org/pep-0557/)**
>
> Python Enhancement Proposals (PEPs)

Regards,

Marco

---

<div class="post-metadata">

**Author:** ![reinhrst](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/reinhrst/32/2197_2.png) [@reinhrst](https://discuss.python.org/u/reinhrst)\
**Post date:** [May 10, 2020, 12:23pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/5 "2020-05-10T12:23:42Z")

</div>

I would very much support a kwonly dataclass, with the most important usecase being that one could have default values for a property without default values for the next properties:

```
import dataclasses
@dataclasses.dataclass(kwonly=true)
class Data:
    x: int = 42
    y: str
 
    @classmethod
    def create_from_dict(cls, configdata: dict):
        return cls(**configdata)
```

---

<div class="post-metadata">

**Author:** ![EpicWink](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/epicwink/32/17968_2.png) [@EpicWink](https://discuss.python.org/u/EpicWink)\
**Post date:** [May 11, 2020, 1:18am UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/6 "2020-05-11T01:18:49Z")

</div>

> [@reinhrst](#):
>
> have default values for a property without default values for the next properties

[My suggestion](https://discuss.python.org/t/make-succeeding-non-default-init-parameters-keyword-only-in-dataclasses-instead-of-raising/2952) solves that by automatically requiring non-defaulted properties (after defaulted properties) to be keyword-only

---

<div class="post-metadata">

**Author:** ![ericvsmith](https://avatars.discourse-cdn.com/v4/letter/e/34f0e0/32.png) [@ericvsmith](https://discuss.python.org/u/ericvsmith)\
**Post date:** [March 13, 2021, 12:52pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/7 "2021-03-13T12:52:53Z")

</div>

I’ve started a discussion of this on python-ideas, beginning at [Mailman 3 [Python-ideas] dataclasses: position-only and keyword-only fields - Python-ideas - python.org](https://mail.python.org/archives/list/python-ideas@python.org/message/I3RKK4VINZUBCGF2TBJN6HTDV3PVUEUQ/)

---

<div class="post-metadata">

**Author:** ![gwerbin](https://avatars.discourse-cdn.com/v4/letter/g/76d3ee/32.png) [@gwerbin](https://discuss.python.org/u/gwerbin)\
**Post date:** [March 19, 2021, 9:59pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/8 "2021-03-19T21:59:16Z")

</div>

Is there a practical use case for this? I don’t see many useful cases for keyword-only or positional-only args in the first place. It’s mostly useful when you need to cleanly separate kwargs that will be passed on to other functions, or in very particular cases like `sorted(a, b, key=foo)`.

---

<div class="post-metadata">

**Author:** ![EpicWink](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/epicwink/32/17968_2.png) [@EpicWink](https://discuss.python.org/u/EpicWink)\
**Post date:** [March 20, 2021, 11:54pm UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/9 "2021-03-20T23:54:56Z")

</div>

Subclassing a dataclass with optional field with another dataclass with required fields will give you trouble. Making those required fields keyword-only solves that issue.

On top of that, making parameters keyword-only forces better documentation when calling (instantiating in this case), and allowing developers to make the decision to use keyword-only parameters seems to me to be only a good thing.

---

<div class="post-metadata">

**Author:** ![ericvsmith](https://avatars.discourse-cdn.com/v4/letter/e/34f0e0/32.png) [@ericvsmith](https://discuss.python.org/u/ericvsmith)\
**Post date:** [March 21, 2021, 1:48am UTC](https://discuss.python.org/t/allow-for-positional-or-keyword-only-arguments-in-dataclasses/2980/10 "2021-03-21T01:48:02Z")

</div>

@EpicWink : Excellent point, thanks. I think there’s no question that keyword-only fields are needed.
