Skip to content

Default values are passed to their constructor #32

@tewe

Description

@tewe

This generalises #20.

I completed the example from the README. The following works.

import dataclasses
import io
import re

from dataclass_csv import DataclassReader


class SSN:
    def __init__(self, val):
        if re.match(r"\d{9}", val):
            self.val = f"{val[0:3]}-{val[3:5]}-{val[5:9]}"
        elif re.match(r"\d{3}-\d{2}-\d{4}", val):
            self.val = val
        else:
            raise ValueError(f"Invalid SSN: {val!r}")


@dataclasses.dataclass
class User:
    name: str
    ssn: SSN


print(list(DataclassReader(io.StringIO("name,ssn\nAlice,123456789"), User)))

After replacing the SSN in the data with a default value, the error below occurs.

class User:
    name: str
    ssn: SSN = SSN("123456789")


print(list(DataclassReader(io.StringIO("name,ssn\nAlice,"), User)))
  File "readme.py", line 10, in __init__
    if re.match(r"\d{9}", val):
TypeError: expected string or bytes-like object

The reason being that the SSN constructor is called with the default value, which is an object. The next snippet works around that.

class User:
    name: str
    ssn: SSN = "123456789"

But now this class can no longer be instantiated directly without creating broken objects, and type checkers will complain.

I think if a default value exists it should be used as is, and not passed to the constructor of its class.

Metadata

Metadata

Assignees

Labels

EvaluatingEvaluating if the feature can be implemented

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions