Reducing repetition when using dataclass

current scenario -

from dataclasses import dataclass
@dataclass
class X:
   a: str
   b: str

expected scenario -

@dataclass
class X:
   (a, b): str

So the idea is that a single type annotation could be unpacked onto an arbitrary number of variables. Would it also extend to other things, like functions?

def myfunc((a, b): int):
   ...

Would this only be possible if the variables are not given initial values, or should this also work?

(a, b): int = 1, 2

If so, would that also extend to functions?

def myfunc((a, b): int = 1, 2):
    ...

Seems like a big change.

There is some relevant discussion related to this on the PEP526 pull request. Guido is not a fan:

Multiple types/variables

An obvious question is whether to allow combining type declarations with tuple unpacking (e.g. a, b, c = x). This leads to (real or perceived) ambiguity, and I propose not to support this. If there’s a type annotation there can only be one variable to its left, and one value to its right. This still allows tuple packing (just put the tuple in parentheses) but it disallows tuple unpacking. (It’s been proposed to allow multiple parenthesized variable names, or types inside parentheses, but none of these look attractive to me.)

I’ve definitely written some dataclasses that would benefit from something like this, though.

2 Likes

I prefer the ‘current situation’. The analogy to unpacking seems wrong to me.

  1. People will expect (a,b):int = 1,2 to work.
  2. A better analogy in terms of declaratory function is to global a,b, which has an entirely different syntax.

Indeed. It makes me wonder, was C-style type syntax ever considered when PEP526 was being prepared? Like so:

int x

def myfunc(int x, float y = 5.5):
    ...

This would combine naturally with global and nonlocal, and also make it natural to allow what the OP wants:

global int x
int y, z

I realize this ship has sailed. But would be interesting to know if this was considered, and if so why it was discarded in favor of the current syntax.

You can see for yourself in PEP 526. At a glance, it doesn’t look like it was.

C declarations are extremely messy and I don’t think anyone considers them an example to be followed. I presume you meant the adapted form where the type is entirely to the left side and the identifier to the right?

It is perhaps too minimalistic for Python. Consider:

def f(x y):

A comma is missing, yet the compiler would not notice, it would simply see x as the type.
Python is terse, but not to a fault.

2 Likes