cfinterface 1.10.1__tar.gz → 1.10.3__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.10.1 → cfinterface-1.10.3}/CHANGELOG.md +12 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/PKG-INFO +2 -2
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/__init__.py +1 -1
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/components/line/repository.py +4 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/files/blockfile.py +7 -5
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/files/registerfile.py +7 -5
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/files/sectionfile.py +7 -5
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/guides/architecture.rst +2 -1
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_linerepository.py +8 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_tabular.py +9 -0
- cfinterface-1.10.3/tests/files/test_read_typing.py +38 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/.github/workflows/benchmark.yml +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/.github/workflows/docs.yml +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/.github/workflows/main.yml +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/.github/workflows/publish.yml +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/.gitignore +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/.pre-commit-config.yaml +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/CONTRIBUTING.md +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/LICENSE +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/README.md +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/benchmarks/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/benchmarks/bench_floatfield_write.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/_utils/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/components/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/components/line/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/components/repository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/reading/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/reading/repository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/writing/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/writing/repository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/block.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/datetimefield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/defaultblock.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/defaultregister.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/defaultsection.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/field.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/floatfield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/integerfield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/line.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/literalfield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/register.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/section.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/components/tabular.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/data/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/data/blockdata.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/data/registerdata.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/data/sectiondata.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/files/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/py.typed +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/reading/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/reading/blockreading.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/reading/registerreading.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/reading/sectionreading.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/storage.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/versioning.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/writing/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/writing/blockwriting.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/writing/registerwriting.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/writing/sectionwriting.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/_static/logo_cfinterface.svg +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/conf.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/getting_started/contributing.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/getting_started/tutorial.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/guides/faq.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/guides/migration-v1.9.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/guides/performance.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/install/install.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/adapters/files/components.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/adapters/files/line.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/adapters/files/reading.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/adapters/files/writing.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/adapters/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/blocks/files/block.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/blocks/files/blockdata.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/blocks/files/blockfile.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/blocks/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/datetimefield.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/field.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/floatfield.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/integerfield.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/literalfield.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/line/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/registers/files/register.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/registers/files/registerdata.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/registers/files/registerfile.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/registers/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/sections/files/section.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/sections/files/sectiondata.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/sections/files/sectionfile.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/sections/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/storage/files/storagetype.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/storage/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/tabular/files/tabularparser.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/tabular/files/tabularsection.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/tabular/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/versioning/files/versioning.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/versioning/index.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/examples/README.rst +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/examples/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/examples/plot_block_file.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/examples/plot_register_file.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/examples/plot_section_file.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/examples/plot_tabular_parsing.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/examples/plot_versioned_file.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/pyproject.toml +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/_utils/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/_utils/test_is_null.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_blockrepository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_factory.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_pattern_cache.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_registerrepository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_sectionrepository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/reading/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/reading/test_readingrepository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/writing/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/writing/test_writingrepository.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/conftest.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_block.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_datetimefield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_defaultblock.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_defaultregister.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_defaultsection.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_field.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_field_hypothesis.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_floatfield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_floatfield_benchmark.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_integerfield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_line.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_literalfield.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_register.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_section.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_storage_integration.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/components/test_tabular_hypothesis.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/conftest.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/data/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/data/test_blockdata.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/data/test_registerdata.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/data/test_sectiondata.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/files/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/files/test_blockfile.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/files/test_registerfile.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/files/test_sectionfile.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/mocks/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/mocks/mock_open.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/reading/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/reading/test_blockreading.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/reading/test_registerreading.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/reading/test_sectionreading.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/test_storage.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/test_storage_deprecation.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/test_versioning.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/writing/__init__.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/writing/test_blockwriting.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/writing/test_registerwriting.py +0 -0
- {cfinterface-1.10.1 → cfinterface-1.10.3}/tests/writing/test_sectionwriting.py +0 -0
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.10.3] - 2026-10-30
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- A delimited line with fewer values than its fields reads the missing fields as `None`; it used to keep the values the previous line of the same register or table left in them
|
|
15
|
+
|
|
16
|
+
## [1.10.2] - 2026-10-14
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Type `SectionFile.read()`, `RegisterFile.read()` and `BlockFile.read()` (and their `read_many()`) as returning the calling subclass instead of the base class, so mypy sees the attributes of files such as `Dadger` or `Caso` read through them
|
|
21
|
+
|
|
10
22
|
## [1.10.1] - 2026-04-13
|
|
11
23
|
|
|
12
24
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: cfinterface
|
|
3
|
-
Version: 1.10.
|
|
3
|
+
Version: 1.10.3
|
|
4
4
|
Summary: Interface for handling custom formatted files
|
|
5
5
|
Project-URL: Documentation, https://rjmalves.github.io/cfinterface/
|
|
6
6
|
Project-URL: Repository, https://github.com/rjmalves/cfinterface/
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/cfinterface/adapters/components/line/repository.py
RENAMED
|
@@ -56,6 +56,10 @@ class TextualRepository(Repository):
|
|
|
56
56
|
values = [v.strip() for v in line.split(delimiter)]
|
|
57
57
|
for field, value in zip(fields, values, strict=False):
|
|
58
58
|
field.read(value)
|
|
59
|
+
# A field past the end of a short line must be reset, or it keeps the
|
|
60
|
+
# value the previous line left in the shared field.
|
|
61
|
+
for field in fields[len(values) :]:
|
|
62
|
+
field.value = None
|
|
59
63
|
return self.values
|
|
60
64
|
|
|
61
65
|
def read(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
|
-
from typing import IO, TYPE_CHECKING, Any
|
|
2
|
+
from typing import IO, TYPE_CHECKING, Any, TypeVar
|
|
3
3
|
|
|
4
4
|
from cfinterface.components.block import Block
|
|
5
5
|
from cfinterface.components.defaultblock import DefaultBlock
|
|
@@ -12,6 +12,8 @@ from cfinterface.writing.blockwriting import BlockWriting
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from cfinterface.versioning import VersionMatchResult
|
|
14
14
|
|
|
15
|
+
_BlockFileT = TypeVar("_BlockFileT", bound="BlockFile")
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
class BlockFile:
|
|
17
19
|
"""
|
|
@@ -48,12 +50,12 @@ class BlockFile:
|
|
|
48
50
|
|
|
49
51
|
@classmethod
|
|
50
52
|
def read(
|
|
51
|
-
cls,
|
|
53
|
+
cls: type[_BlockFileT],
|
|
52
54
|
content: str | bytes,
|
|
53
55
|
*args: Any,
|
|
54
56
|
version: str | None = None,
|
|
55
57
|
**kwargs: Any,
|
|
56
|
-
) ->
|
|
58
|
+
) -> _BlockFileT:
|
|
57
59
|
"""Read from a file path or buffer. ``version`` selects a component set
|
|
58
60
|
from VERSIONS without mutating the class."""
|
|
59
61
|
components = cls.BLOCKS
|
|
@@ -86,11 +88,11 @@ class BlockFile:
|
|
|
86
88
|
|
|
87
89
|
@classmethod
|
|
88
90
|
def read_many(
|
|
89
|
-
cls,
|
|
91
|
+
cls: type[_BlockFileT],
|
|
90
92
|
paths: list[str],
|
|
91
93
|
*,
|
|
92
94
|
version: str | None = None,
|
|
93
|
-
) -> dict[str,
|
|
95
|
+
) -> dict[str, _BlockFileT]:
|
|
94
96
|
"""Read multiple files and return a dict keyed by file path.
|
|
95
97
|
|
|
96
98
|
Parameters
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
|
-
from typing import IO, TYPE_CHECKING, Any
|
|
2
|
+
from typing import IO, TYPE_CHECKING, Any, TypeVar
|
|
3
3
|
|
|
4
4
|
from cfinterface.components.defaultregister import DefaultRegister
|
|
5
5
|
from cfinterface.components.register import Register
|
|
@@ -12,6 +12,8 @@ from cfinterface.writing.registerwriting import RegisterWriting
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from cfinterface.versioning import VersionMatchResult
|
|
14
14
|
|
|
15
|
+
_RegisterFileT = TypeVar("_RegisterFileT", bound="RegisterFile")
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
class RegisterFile:
|
|
17
19
|
"""
|
|
@@ -65,12 +67,12 @@ class RegisterFile:
|
|
|
65
67
|
|
|
66
68
|
@classmethod
|
|
67
69
|
def read(
|
|
68
|
-
cls,
|
|
70
|
+
cls: type[_RegisterFileT],
|
|
69
71
|
content: str | bytes,
|
|
70
72
|
*args: Any,
|
|
71
73
|
version: str | None = None,
|
|
72
74
|
**kwargs: Any,
|
|
73
|
-
) ->
|
|
75
|
+
) -> _RegisterFileT:
|
|
74
76
|
"""Read from a file path or buffer. ``version`` selects a component set
|
|
75
77
|
from VERSIONS without mutating the class."""
|
|
76
78
|
components = cls.REGISTERS
|
|
@@ -103,11 +105,11 @@ class RegisterFile:
|
|
|
103
105
|
|
|
104
106
|
@classmethod
|
|
105
107
|
def read_many(
|
|
106
|
-
cls,
|
|
108
|
+
cls: type[_RegisterFileT],
|
|
107
109
|
paths: list[str],
|
|
108
110
|
*,
|
|
109
111
|
version: str | None = None,
|
|
110
|
-
) -> dict[str,
|
|
112
|
+
) -> dict[str, _RegisterFileT]:
|
|
111
113
|
"""Read multiple files and return a dict keyed by file path.
|
|
112
114
|
|
|
113
115
|
Parameters
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
|
-
from typing import IO, TYPE_CHECKING, Any
|
|
2
|
+
from typing import IO, TYPE_CHECKING, Any, TypeVar
|
|
3
3
|
|
|
4
4
|
from cfinterface.components.defaultsection import DefaultSection
|
|
5
5
|
from cfinterface.components.section import Section
|
|
@@ -12,6 +12,8 @@ from cfinterface.writing.sectionwriting import SectionWriting
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from cfinterface.versioning import VersionMatchResult
|
|
14
14
|
|
|
15
|
+
_SectionFileT = TypeVar("_SectionFileT", bound="SectionFile")
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
class SectionFile:
|
|
17
19
|
"""
|
|
@@ -48,12 +50,12 @@ class SectionFile:
|
|
|
48
50
|
|
|
49
51
|
@classmethod
|
|
50
52
|
def read(
|
|
51
|
-
cls,
|
|
53
|
+
cls: type[_SectionFileT],
|
|
52
54
|
content: str | bytes,
|
|
53
55
|
*args: Any,
|
|
54
56
|
version: str | None = None,
|
|
55
57
|
**kwargs: Any,
|
|
56
|
-
) ->
|
|
58
|
+
) -> _SectionFileT:
|
|
57
59
|
"""Read from a file path or buffer. ``version`` selects a component set
|
|
58
60
|
from VERSIONS without mutating the class."""
|
|
59
61
|
components = cls.SECTIONS
|
|
@@ -86,11 +88,11 @@ class SectionFile:
|
|
|
86
88
|
|
|
87
89
|
@classmethod
|
|
88
90
|
def read_many(
|
|
89
|
-
cls,
|
|
91
|
+
cls: type[_SectionFileT],
|
|
90
92
|
paths: list[str],
|
|
91
93
|
*,
|
|
92
94
|
version: str | None = None,
|
|
93
|
-
) -> dict[str,
|
|
95
|
+
) -> dict[str, _SectionFileT]:
|
|
94
96
|
"""Read multiple files and return a dict keyed by file path.
|
|
95
97
|
|
|
96
98
|
Parameters
|
|
@@ -88,7 +88,8 @@ configured ``StorageType``. That repository is what executes reading and writing
|
|
|
88
88
|
to the storage backend (textual or binary).
|
|
89
89
|
|
|
90
90
|
``Line`` accepts an optional ``delimiter``: when provided, fields are separated by that
|
|
91
|
-
character instead of occupying fixed positions.
|
|
91
|
+
character instead of occupying fixed positions. A line with fewer values than fields reads
|
|
92
|
+
each missing field as ``None``.
|
|
92
93
|
|
|
93
94
|
.. code-block:: python
|
|
94
95
|
|
|
@@ -2,6 +2,7 @@ from cfinterface.adapters.components.line.repository import (
|
|
|
2
2
|
BinaryRepository,
|
|
3
3
|
TextualRepository,
|
|
4
4
|
)
|
|
5
|
+
from cfinterface.components.integerfield import IntegerField
|
|
5
6
|
from cfinterface.components.literalfield import LiteralField
|
|
6
7
|
|
|
7
8
|
|
|
@@ -49,6 +50,13 @@ def test_delimitedrepository_read_with_fields():
|
|
|
49
50
|
assert values[1] == "world!"
|
|
50
51
|
|
|
51
52
|
|
|
53
|
+
def test_delimitedrepository_read_short_line_does_not_keep_previous_values():
|
|
54
|
+
fields = [LiteralField(6, 0), LiteralField(6, 7), IntegerField(4, 14)]
|
|
55
|
+
repo = TextualRepository(fields)
|
|
56
|
+
repo.read("a;b;7", delimiter=";")
|
|
57
|
+
assert repo.read("c", delimiter=";") == ["c", None, None]
|
|
58
|
+
|
|
59
|
+
|
|
52
60
|
def test_delimitedrepository_write_no_fields():
|
|
53
61
|
repo = TextualRepository([])
|
|
54
62
|
assert len(repo.write([], delimiter=";")) == 1
|
|
@@ -643,6 +643,15 @@ def test_parse_lines_delimited_missing_tokens_filled_with_none() -> None:
|
|
|
643
643
|
assert result["label"] == [None]
|
|
644
644
|
|
|
645
645
|
|
|
646
|
+
def test_parse_lines_delimited_short_line_after_full_line() -> None:
|
|
647
|
+
"""A short line after a full one does not keep the full line's values."""
|
|
648
|
+
parser = _make_semicolon_parser()
|
|
649
|
+
lines = ["1;1.25;alpha\n", "10;5.00\n"]
|
|
650
|
+
result = parser.parse_lines(lines)
|
|
651
|
+
assert result["id"] == [1, 10]
|
|
652
|
+
assert result["label"] == ["alpha", None]
|
|
653
|
+
|
|
654
|
+
|
|
646
655
|
def test_format_rows_semicolon_delimited() -> None:
|
|
647
656
|
"""format_rows with ';' delimiter joins fields with semicolons."""
|
|
648
657
|
parser = _make_semicolon_parser()
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from mypy import api
|
|
5
|
+
|
|
6
|
+
SUBCLASS_READS = """
|
|
7
|
+
from cfinterface.files.blockfile import BlockFile
|
|
8
|
+
from cfinterface.files.registerfile import RegisterFile
|
|
9
|
+
from cfinterface.files.sectionfile import SectionFile
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MySectionFile(SectionFile):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class MyRegisterFile(RegisterFile):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class MyBlockFile(BlockFile):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
section: MySectionFile = MySectionFile.read("file.txt")
|
|
25
|
+
register: MyRegisterFile = MyRegisterFile.read("file.txt")
|
|
26
|
+
block: MyBlockFile = MyBlockFile.read("file.txt")
|
|
27
|
+
sections: dict[str, MySectionFile] = MySectionFile.read_many(["file.txt"])
|
|
28
|
+
registers: dict[str, MyRegisterFile] = MyRegisterFile.read_many(["file.txt"])
|
|
29
|
+
blocks: dict[str, MyBlockFile] = MyBlockFile.read_many(["file.txt"])
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@pytest.mark.slow
|
|
34
|
+
def test_read_is_typed_as_returning_the_subclass(tmp_path: Path):
|
|
35
|
+
stdout, stderr, status = api.run(
|
|
36
|
+
["--cache-dir", str(tmp_path), "-c", SUBCLASS_READS]
|
|
37
|
+
)
|
|
38
|
+
assert status == 0, stdout + stderr
|
|
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
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/adapters/files/components.rst
RENAMED
|
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
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/datetimefield.rst
RENAMED
|
File without changes
|
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/floatfield.rst
RENAMED
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/integerfield.rst
RENAMED
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/fields/components/literalfield.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/registers/files/register.rst
RENAMED
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/registers/files/registerdata.rst
RENAMED
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/registers/files/registerfile.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/sections/files/sectiondata.rst
RENAMED
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/sections/files/sectionfile.rst
RENAMED
|
File without changes
|
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/storage/files/storagetype.rst
RENAMED
|
File without changes
|
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/tabular/files/tabularparser.rst
RENAMED
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/tabular/files/tabularsection.rst
RENAMED
|
File without changes
|
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/docs/source/reference/versioning/files/versioning.rst
RENAMED
|
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
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_registerrepository.py
RENAMED
|
File without changes
|
{cfinterface-1.10.1 → cfinterface-1.10.3}/tests/adapters/components/test_sectionrepository.py
RENAMED
|
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
|