Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default values are passed to their constructor #32

Open
tewe opened this issue Jul 23, 2020 · 2 comments
Open

Default values are passed to their constructor #32

tewe opened this issue Jul 23, 2020 · 2 comments
Assignees
Labels
Evaluating Evaluating if the feature can be implemented

Comments

@tewe
Copy link

tewe commented Jul 23, 2020

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.

@dfurtado dfurtado added the Evaluating Evaluating if the feature can be implemented label Mar 27, 2021
@dfurtado dfurtado self-assigned this Mar 27, 2021
@qpwo
Copy link

qpwo commented May 4, 2021

Replicated

from dataclasses import dataclass
from io import StringIO
from dataclass_csv import DataclassReader
class C:
    def __init__(self, x):
        print(f"initialized with {x!r}")
        self.x = x
@dataclass
class Row:
    b: int
    c: C = C(5)
# initialized with 5
A = list(DataclassReader(StringIO("b,c\n1,"), Row))
# initialized with <__main__.C object at 0x10385ea90>
print(A[0].c.x)
# <__main__.C at 0x10385ea90>

@dfurtado
Copy link
Owner

dfurtado commented May 4, 2021

Hi @qpwo

Thanks for reporting the issue.

I started looking into it a few days ago and a fix for it should be available very soon.

//Daniel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Evaluating Evaluating if the feature can be implemented
Projects
None yet
Development

No branches or pull requests

3 participants