Thursday, 12 August 2021

Python dataclasses: What type to use if __post_init__ performs type conversion?

I have a Python class, with a field which can be passed one of several sequence types. To simplify I'll stick with tuples and lists. __init__ converts the parameter to MyList.

from typing import Union
from dataclasses import dataclass, InitVar, field

class MyList(list):
    pass

@dataclass
class Struct:
    field: Union[tuple, list, MyList]

    def __post_init__(self):
        self.field = MyList(self.field)

What type should I use for the field declaration?

  • If I supply a union of all possible input types, the code does not document that field is always a MyList when accessed.
  • If I only supply the final MyList type, PyCharm complains when I pass Struct() a list.

I could instead use:

_field: InitVar[Union[tuple, list, MyList]] = None
field: MyList = field(init=False)

def __post_init__(self, _field):
    self.field = MyList(_field)

but this is tremendously ugly, especially when repeated across 3 fields. Additionally I have to construct a struct like Struct(_field=field) instead of Struct(field=field).

In April 2018, "tm" commented on this issue on PyCharm's announcement: https://blog.jetbrains.com/pycharm/2018/04/python-37-introducing-data-class/#comment-323957



from Python dataclasses: What type to use if __post_init__ performs type conversion?

No comments:

Post a Comment