Skip to content

Commit d0e0fde

Browse files
authored
Add type hinting to external API (dfurtado#37)
This should allow dataclass-csv consumers to rely on type hinting more fully rather than ignoring the import as Any's. We also check that our code remains type safe with mypy. Note that flake8 doesn't work, who knows for how long, so we run mypy first since that is clean.
1 parent 6f95a00 commit d0e0fde

File tree

7 files changed

+149
-42
lines changed

7 files changed

+149
-42
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ clean-test: ## remove test and coverage artifacts
5050
rm -fr htmlcov/
5151
rm -fr .pytest_cache
5252

53-
lint: ## check style with flake8
53+
lint: ## check style with mypy and flake8
54+
mypy dataclass_csv tests
5455
flake8 dataclass-csv tests
5556

5657
test: ## run tests quickly with the default Python

Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ name = "pypi"
55

66
[dev-packages]
77
pytest = "*"
8+
mypy = "*"
89

910
[packages]
1011

Pipfile.lock

Lines changed: 126 additions & 27 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dataclass_csv/dataclass_reader.py

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

44
from datetime import datetime
55
from distutils.util import strtobool
6-
from typing import Union
6+
from typing import Union, Type, Optional, Sequence, Dict, Any, List
77

88
from .field_mapper import FieldMapper
99
from .exceptions import CsvValueError
@@ -13,13 +13,13 @@ class DataclassReader:
1313
def __init__(
1414
self,
1515
f,
16-
cls,
17-
fieldnames=None,
18-
restkey=None,
19-
restval=None,
20-
dialect='excel',
21-
*args,
22-
**kwds,
16+
cls: Type[object],
17+
fieldnames: Optional[Sequence[str]]=None,
18+
restkey: Optional[str]=None,
19+
restval: Optional[Any]=None,
20+
dialect: str='excel',
21+
*args: List[Any],
22+
**kwds: Dict[str, Any],
2323
):
2424

2525
if not f:
@@ -30,7 +30,7 @@ def __init__(
3030

3131
self.cls = cls
3232
self.optional_fields = self._get_optional_fields()
33-
self.field_mapping = {}
33+
self.field_mapping: Dict[str, Dict[str, Any]] = {}
3434

3535
self.reader = csv.DictReader(
3636
f, fieldnames, restkey, restval, dialect, *args, **kwds
@@ -206,7 +206,7 @@ def __next__(self):
206206
def __iter__(self):
207207
return self
208208

209-
def map(self, csv_fieldname):
209+
def map(self, csv_fieldname: str) -> FieldMapper:
210210
"""Used to map a field in the CSV file to a `dataclass` field
211211
:param csv_fieldname: The name of the CSV field
212212
"""

dataclass_csv/decorators.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
def dateformat(date_format):
1+
from typing import Any, Callable, TypeVar, Type
2+
3+
F = TypeVar('F', bound=Callable[..., Any])
4+
5+
def dateformat(date_format: str) -> Callable[[F], F]:
26
"""The dateformat decorator is used to specify the format
37
the `DataclassReader` should use when parsing datetime strings.
48
@@ -25,7 +29,7 @@ def func(cls):
2529
return func
2630

2731

28-
def accept_whitespaces(_cls=None):
32+
def accept_whitespaces(_cls: Type[Any]=None) -> Callable[[F], F]:
2933
"""The accept_whitespaces decorator tells the `DataclassReader`
3034
that `str` fields defined in the `dataclass` should accept
3135
values containing only white spaces.

dataclass_csv/field_mapper.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
from typing import Any, Callable
2+
13
class FieldMapper:
24
"""The `FieldMapper` class is used to explicitly map a field
35
in the CSV file to a specific `dataclass` field.
46
"""
57

6-
def __init__(self, callback):
8+
def __init__(self, callback: Callable[[str], Any]):
79
def to(property_name):
810
"""Specify the dataclass field to receive the value
911
:param property_name: The dataclass property that

tests/mocks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class DataclassWithBooleanValue:
6767

6868
@dataclasses.dataclass
6969
class DataclassWithBooleanValueNoneDefault:
70-
boolValue: bool = None
70+
boolValue: Optional[bool] = None
7171

7272

7373
@dataclasses.dataclass

0 commit comments

Comments
 (0)