9

Context

I created two data classes to handle table metadata. TableMetadata apply to any kind of tables, while RestTableMetadata contains information relevant for data extracted from REST apis

@dataclass
class TableMetadata:
    """
    - entity: business entity represented by the table
    - origin: path / query / url from which data withdrawn
    - id: field to be used as ID (unique)
    - historicity: full, delta
    - upload: should the table be uploaded
    """

    entity: str
    origin: str
    view: str
    id: str = None
    historicity: str = "full"
    upload: bool = True
    columns: list = field(default_factory=list)


@dataclass
class RestTableMetadata(TableMetadata):
    """
    - method: HTTP method to be used
    - payloadpath: portion of the response payload to use to build the dataframe
    """

    method: str
    payloadpath: str = None

Problem

Because of inheritance, method (without default values) comes after columns, resulting in the following Pylance error: Fields without default values cannot appear after fields with default values

I'm looking for a way to fix it without overriding __init__ (if there is such a way). I also noticed a method called __init_subclass__ (This method is called when a class is subclassed.) that might affect how RestTableMetadata.__init__ and other subclasses is generated.

zar3bski
  • 2,773
  • 7
  • 25
  • 58
  • 2
    I think this answer has a lot of detail, such as use of `__post_init__` and `attrs` library: https://stackoverflow.com/questions/51575931/class-inheritance-in-python-3-7-dataclasses. EDIT: Looks like Python 3.10 offers some new options as well. Details in the linked question. – Mr. Fegur Jun 02 '22 at 07:39

1 Answers1

5

Here is a working solution for python > 3.10

@dataclass(kw_only=True)
class TableMetadata:
    """
    - entity: business entity represented by the table
    - origin: path / query / url from which data withdrawn
    - id: field to be used as ID (unique)
    - historicity: full, delta
    - upload: should the table be uploaded
    """

    entity: str
    origin: str
    view: str
    id: str = None
    historicity: str = "full"
    upload: bool = True
    columns: list = field(default_factory=list)


@dataclass(kw_only=True)
class RestTableMetadata(TableMetadata):
    """
    - method: HTTP method to be used
    - payloadpath: portion of the response payload to use to build the dataframe
    """

    method: str
    payloadpath: str = None
zar3bski
  • 2,773
  • 7
  • 25
  • 58