1

Consider the following example:

from dataclasses import dataclass import dataclasses from typing import Self @dataclass class Dataclass: a: int b: str c: list[int] def update_attrs(self, **kwargs) -> Self: return self.__class__(**(dataclasses.asdict(self) | kwargs)) 

I can then do something like this:

x = Dataclass(0, "1", [2]) y = x.update_attrs(b="hello") 
Dataclass(a=0, b='hello', c=[2]) 

I would like to automatically annotate the update_attrs method, so that instead of taking **kwargs as it currently does, it takes exactly: a: int, b: str, c: list[int] without writing it all out manually (one can imagine that in our actual usecase there are a lot of attributes to type out).

This way, I get the benefit of autocompletion in my editor when calling Dataclass.update_attrs.

Is something like this possible?

4
  • As an aside, update_attrs returns a modified copy of the original object, but then you use it as if it updates the object in place. Which is the intent? Commented May 15 at 18:44
  • 3
    You do realize there's dataclasses.replace doing what your update_attrs does (more efficiently)? That one is supported by mypy plugin AFAIC, and that's your only option; nothing if you want to support pyright. Commented May 15 at 18:55
  • That thing is resolved in the language with **kwargs itself. You should bug the people who maintain the tooling around the language to improve them to support this kind of thing- from the code there, how kwargs is to be used can be inferred. That said, for new Python (I think its 3.13 only) you can use copy.replace instead of a custom update_attrs method: Tooling should support that automatically instead of trying static annotation gimmickries. Commented May 15 at 18:58
  • Ah, yes - dataclass.replace will work for older Python versions - no need to be in 3.13. Commented May 15 at 18:59

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.