Skip to content

Commit 380829f

Browse files
authored
Merge pull request dfurtado#15 from dfurtado/prop-init-handling
Handling of fields with init set to False
2 parents c932e21 + 23f5a8f commit 380829f

File tree

3 files changed

+52
-8
lines changed

3 files changed

+52
-8
lines changed

dataclass_csv/dataclass_reader.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(
3232
self.optional_fields = self._get_optional_fields()
3333
self.field_mapping = {}
3434

35+
3536
self.reader = csv.DictReader(
3637
f, fieldnames, restkey, restval, dialect, *args, **kwds
3738
)
@@ -135,6 +136,9 @@ def _process_row(self, row):
135136
values = []
136137

137138
for field in dataclasses.fields(self.cls):
139+
if not field.init:
140+
continue
141+
138142
try:
139143
value = self._get_value(row, field)
140144
except ValueError as ex:

tests/mocks.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,19 @@ class DataclassWithBooleanValueNoneDefault:
6969
boolValue: bool = None
7070

7171

72+
@dataclasses.dataclass
73+
class UserWithInitFalse:
74+
firstname: str
75+
lastname: str
76+
age: int = dataclasses.field(init=False)
77+
78+
79+
@dataclasses.dataclass
80+
class UserWithInitFalseAndDefaultValue:
81+
firstname: str
82+
lastname: str
83+
age: int = dataclasses.field(init=False, default=0)
84+
7285
@dataclasses.dataclass
7386
class UserWithOptionalAge:
7487
name: str

tests/test_dataclass_reader.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33

44
from dataclass_csv import DataclassReader, CsvValueError
55

6-
from .mocks import User, UserWithOptionalAge, DataclassWithBooleanValue, DataclassWithBooleanValueNoneDefault
6+
from .mocks import (
7+
User,
8+
UserWithOptionalAge,
9+
DataclassWithBooleanValue,
10+
DataclassWithBooleanValueNoneDefault,
11+
UserWithInitFalse,
12+
UserWithInitFalseAndDefaultValue,
13+
)
714

815

916
def test_reader_with_non_dataclass(create_csv):
@@ -114,16 +121,12 @@ def test_parse_bool_value_false(create_csv):
114121
def test_parse_bool_value_invalid(create_csv):
115122
csv_file = create_csv({'boolValue': 'notValidBoolean'})
116123
with csv_file.open() as f:
117-
try:
124+
with pytest.raises(CsvValueError):
118125
reader = DataclassReader(f, DataclassWithBooleanValue)
119126
list(reader)
120-
assert False # Should not be able to successfully parse
121-
except CsvValueError:
122-
pass
123127

124128

125129
def test_parse_bool_value_none_default(create_csv):
126-
"""Verify that blank/null values are parsed as None for optional fields"""
127130
csv_file = create_csv({'boolValue': ''})
128131
with csv_file.open() as f:
129132
reader = DataclassReader(f, DataclassWithBooleanValueNoneDefault)
@@ -132,11 +135,35 @@ def test_parse_bool_value_none_default(create_csv):
132135
assert dataclass_instance.boolValue is None
133136

134137

138+
def test_skip_dataclass_field_when_init_is_false(create_csv):
139+
csv_file = create_csv({'firstname': 'User1', 'lastname': 'TestUser'})
140+
with csv_file.open() as f:
141+
reader = DataclassReader(f, UserWithInitFalse)
142+
items = list(reader)
143+
144+
145+
def test_try_to_access_not_initialized_prop_raise_attr_error(create_csv):
146+
csv_file = create_csv({'firstname': 'User1', 'lastname': 'TestUser'})
147+
with csv_file.open() as f:
148+
reader = DataclassReader(f, UserWithInitFalse)
149+
items = list(reader)
150+
with pytest.raises(AttributeError):
151+
user = items[0]
152+
user_age = user.age
153+
154+
155+
def test_try_to_access_not_initialized_prop_with_default_value(create_csv):
156+
csv_file = create_csv({'firstname': 'User1', 'lastname': 'TestUser'})
157+
with csv_file.open() as f:
158+
reader = DataclassReader(f, UserWithInitFalseAndDefaultValue)
159+
items = list(reader)
160+
user = items[0]
161+
assert user.age == 0
162+
163+
135164
def test_reader_with_optional_types(create_csv):
136165
csv_file = create_csv({'name': 'User', 'age': 40})
137166

138167
with csv_file.open() as f:
139168
reader = DataclassReader(f, UserWithOptionalAge)
140169
list(reader)
141-
142-

0 commit comments

Comments
 (0)