zar3bski
zar3bski

Reputation: 3171

dataclass inheritance: Fields without default values cannot appear after fields with default values

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.

Upvotes: 13

Views: 8353

Answers (1)

zar3bski
zar3bski

Reputation: 3171

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

Upvotes: 10

Related Questions