cfinterface 1.6.0__tar.gz → 1.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cfinterface-1.6 → cfinterface-1.7.1}/PKG-INFO +1 -1
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/__init__.py +1 -1
- cfinterface-1.7.1/cfinterface/components/datetimefield.py +96 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/files/registerfile.py +1 -1
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/files/sectionfile.py +1 -1
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface.egg-info/PKG-INFO +1 -1
- {cfinterface-1.6 → cfinterface-1.7.1}/setup.py +1 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_datetimefield.py +19 -0
- cfinterface-1.6/cfinterface/components/datetimefield.py +0 -68
- {cfinterface-1.6 → cfinterface-1.7.1}/LICENSE.md +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/README.md +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/_utils/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/components/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/components/line/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/components/line/repository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/components/repository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/reading/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/reading/repository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/writing/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/adapters/writing/repository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/block.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/defaultblock.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/defaultregister.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/defaultsection.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/field.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/floatfield.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/integerfield.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/line.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/literalfield.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/register.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/components/section.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/data/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/data/blockdata.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/data/registerdata.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/data/sectiondata.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/files/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/files/blockfile.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/py.typed +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/reading/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/reading/blockreading.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/reading/registerreading.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/reading/sectionreading.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/writing/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/writing/blockwriting.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/writing/registerwriting.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface/writing/sectionwriting.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface.egg-info/SOURCES.txt +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface.egg-info/dependency_links.txt +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface.egg-info/requires.txt +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/cfinterface.egg-info/top_level.txt +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/examples/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/setup.cfg +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/components/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/components/test_blockrepository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/components/test_linerepository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/components/test_registerrepository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/components/test_sectionrepository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/reading/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/reading/test_readingrepository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/writing/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/adapters/writing/test_writingrepository.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_block.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_defaultblock.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_defaultregister.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_defaultsection.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_field.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_floatfield.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_integerfield.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_line.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_literalfield.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_register.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/components/test_section.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/data/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/data/test_blockdata.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/data/test_registerdata.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/data/test_sectiondata.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/files/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/files/test_blockfile.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/files/test_registerfile.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/files/test_sectionfile.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/mocks/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/mocks/mock_open.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/reading/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/reading/test_blockreading.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/reading/test_registerreading.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/reading/test_sectionreading.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/writing/__init__.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/writing/test_blockwriting.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/writing/test_registerwriting.py +0 -0
- {cfinterface-1.6 → cfinterface-1.7.1}/tests/writing/test_sectionwriting.py +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
import pandas as pd # type: ignore
|
|
3
|
+
from typing import Optional, Union, List
|
|
4
|
+
|
|
5
|
+
from cfinterface.components.field import Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DatetimeField(Field):
|
|
9
|
+
"""
|
|
10
|
+
Class for representing an datetime field for being read from and
|
|
11
|
+
written to a file. The format to read and write the value is given
|
|
12
|
+
by an optional argument.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
__slots__ = ["__format"]
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
size: int = 16,
|
|
20
|
+
starting_position: int = 0,
|
|
21
|
+
format: Union[str, List[str]] = "%Y/%m/%d",
|
|
22
|
+
value: Optional[datetime] = None,
|
|
23
|
+
) -> None:
|
|
24
|
+
super().__init__(size, starting_position, value)
|
|
25
|
+
self.__format = format
|
|
26
|
+
|
|
27
|
+
# Override
|
|
28
|
+
def _binary_read(self, line: bytes) -> datetime:
|
|
29
|
+
formats = (
|
|
30
|
+
[self.__format]
|
|
31
|
+
if isinstance(self.__format, str)
|
|
32
|
+
else self.__format
|
|
33
|
+
)
|
|
34
|
+
for fmt in formats:
|
|
35
|
+
try:
|
|
36
|
+
return datetime.strptime(
|
|
37
|
+
line[self._starting_position : self._ending_position]
|
|
38
|
+
.decode("utf-8")
|
|
39
|
+
.strip(),
|
|
40
|
+
fmt,
|
|
41
|
+
)
|
|
42
|
+
except ValueError:
|
|
43
|
+
pass
|
|
44
|
+
raise ValueError("Could not read datetime")
|
|
45
|
+
|
|
46
|
+
# Override
|
|
47
|
+
def _textual_read(self, line: str) -> datetime:
|
|
48
|
+
formats = (
|
|
49
|
+
[self.__format]
|
|
50
|
+
if isinstance(self.__format, str)
|
|
51
|
+
else self.__format
|
|
52
|
+
)
|
|
53
|
+
for fmt in formats:
|
|
54
|
+
try:
|
|
55
|
+
return datetime.strptime(
|
|
56
|
+
line[
|
|
57
|
+
self._starting_position : self._ending_position
|
|
58
|
+
].strip(),
|
|
59
|
+
fmt,
|
|
60
|
+
)
|
|
61
|
+
except ValueError:
|
|
62
|
+
pass
|
|
63
|
+
raise ValueError("Could not read datetime")
|
|
64
|
+
|
|
65
|
+
# Override
|
|
66
|
+
def _binary_write(self) -> bytes:
|
|
67
|
+
if self.value is None or pd.isnull(self.value):
|
|
68
|
+
return b"".ljust(self.size)
|
|
69
|
+
else:
|
|
70
|
+
format = (
|
|
71
|
+
self.__format
|
|
72
|
+
if isinstance(self.__format, str)
|
|
73
|
+
else self.__format[0]
|
|
74
|
+
)
|
|
75
|
+
return self.value.strftime(format).ljust(self.size).encode("utf-8")
|
|
76
|
+
|
|
77
|
+
# Override
|
|
78
|
+
def _textual_write(self) -> str:
|
|
79
|
+
if self.value is None or pd.isnull(self.value):
|
|
80
|
+
value = ""
|
|
81
|
+
else:
|
|
82
|
+
format = (
|
|
83
|
+
self.__format
|
|
84
|
+
if isinstance(self.__format, str)
|
|
85
|
+
else self.__format[0]
|
|
86
|
+
)
|
|
87
|
+
value = self.value.strftime(format)
|
|
88
|
+
return value.ljust(self._size)
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def value(self) -> Optional[datetime]:
|
|
92
|
+
return self._value
|
|
93
|
+
|
|
94
|
+
@value.setter
|
|
95
|
+
def value(self, val: datetime):
|
|
96
|
+
self._value = val
|
|
@@ -73,7 +73,7 @@ class RegisterFile:
|
|
|
73
73
|
to a file or the IO buffer
|
|
74
74
|
:type to: str | IO
|
|
75
75
|
"""
|
|
76
|
-
writer = RegisterWriting(self.__data, self.__storage
|
|
76
|
+
writer = RegisterWriting(self.__data, self.__storage)
|
|
77
77
|
writer.write(to, self.__encoding, *args, **kwargs)
|
|
78
78
|
|
|
79
79
|
@property
|
|
@@ -46,7 +46,7 @@ class SectionFile:
|
|
|
46
46
|
reader = SectionReading(cls.SECTIONS, cls.STORAGE)
|
|
47
47
|
return cls(reader.read(content, cls.ENCODING, *args, **kwargs))
|
|
48
48
|
|
|
49
|
-
def write(self, to: Union[str, IO],
|
|
49
|
+
def write(self, to: Union[str, IO], *args, **kwargs):
|
|
50
50
|
"""
|
|
51
51
|
Write the sectionfile data to a given file or buffer.
|
|
52
52
|
|
|
@@ -21,6 +21,15 @@ def test_datetimefield_read():
|
|
|
21
21
|
assert field.value == datetime.strptime(data, format)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
def test_datetimefield_read_format_list():
|
|
25
|
+
data = "2020/01/10"
|
|
26
|
+
formats = ["%Y-%m-%d", "%Y/%m/%d"]
|
|
27
|
+
field = DatetimeField(10, 0, format=formats)
|
|
28
|
+
line = f"{data}-something-else"
|
|
29
|
+
field.read(line)
|
|
30
|
+
assert field.value == datetime.strptime(data, formats[1])
|
|
31
|
+
|
|
32
|
+
|
|
24
33
|
def test_datetimefield_write():
|
|
25
34
|
data = "2020/01/10"
|
|
26
35
|
format = "%Y/%m/%d"
|
|
@@ -31,6 +40,16 @@ def test_datetimefield_write():
|
|
|
31
40
|
assert line_before == line_after
|
|
32
41
|
|
|
33
42
|
|
|
43
|
+
def test_datetimefield_write_format_list():
|
|
44
|
+
data = "2020/01/10"
|
|
45
|
+
formats = ["%Y-%m-%d", "%Y/%m/%d"]
|
|
46
|
+
line_before = f"field-{data}-else"
|
|
47
|
+
date_data = datetime.strptime(data, formats[1])
|
|
48
|
+
field = DatetimeField(10, 6, format=formats, value=date_data)
|
|
49
|
+
line_after = field.write(line_before)
|
|
50
|
+
assert line_before.replace("/", "-") == line_after
|
|
51
|
+
|
|
52
|
+
|
|
34
53
|
def test_datetimefield_write_empty():
|
|
35
54
|
field = DatetimeField(5, 0)
|
|
36
55
|
assert len(field.write("")) == 5
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
import pandas as pd # type: ignore
|
|
3
|
-
from typing import Optional
|
|
4
|
-
|
|
5
|
-
from cfinterface.components.field import Field
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class DatetimeField(Field):
|
|
9
|
-
"""
|
|
10
|
-
Class for representing an datetime field for being read from and
|
|
11
|
-
written to a file. The format to read and write the value is given
|
|
12
|
-
by an optional argument.
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
__slots__ = ["__format"]
|
|
16
|
-
|
|
17
|
-
def __init__(
|
|
18
|
-
self,
|
|
19
|
-
size: int = 16,
|
|
20
|
-
starting_position: int = 0,
|
|
21
|
-
format: str = "%Y/%m/%d",
|
|
22
|
-
value: Optional[datetime] = None,
|
|
23
|
-
) -> None:
|
|
24
|
-
super().__init__(size, starting_position, value)
|
|
25
|
-
self.__format = format
|
|
26
|
-
|
|
27
|
-
# Override
|
|
28
|
-
def _binary_read(self, line: bytes) -> datetime:
|
|
29
|
-
return datetime.strptime(
|
|
30
|
-
line[self._starting_position : self._ending_position]
|
|
31
|
-
.decode("utf-8")
|
|
32
|
-
.strip(),
|
|
33
|
-
self.__format,
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
# Override
|
|
37
|
-
def _textual_read(self, line: str) -> datetime:
|
|
38
|
-
return datetime.strptime(
|
|
39
|
-
line[self._starting_position : self._ending_position].strip(),
|
|
40
|
-
self.__format,
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
# Override
|
|
44
|
-
def _binary_write(self) -> bytes:
|
|
45
|
-
if self.value is None or pd.isnull(self.value):
|
|
46
|
-
return b"".ljust(self.size)
|
|
47
|
-
else:
|
|
48
|
-
return (
|
|
49
|
-
self.value.strftime(self.__format)
|
|
50
|
-
.ljust(self.size)
|
|
51
|
-
.encode("utf-8")
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
# Override
|
|
55
|
-
def _textual_write(self) -> str:
|
|
56
|
-
if self.value is None or pd.isnull(self.value):
|
|
57
|
-
value = ""
|
|
58
|
-
else:
|
|
59
|
-
value = self.value.strftime(self.__format)
|
|
60
|
-
return value.ljust(self._size)
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def value(self) -> Optional[datetime]:
|
|
64
|
-
return self._value
|
|
65
|
-
|
|
66
|
-
@value.setter
|
|
67
|
-
def value(self, val: datetime):
|
|
68
|
-
self._value = val
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|