cfinterface 1.10.2__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.
Files changed (163) hide show
  1. {cfinterface-1.10.2 → cfinterface-1.10.3}/CHANGELOG.md +6 -0
  2. {cfinterface-1.10.2 → cfinterface-1.10.3}/PKG-INFO +1 -1
  3. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/__init__.py +1 -1
  4. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/components/line/repository.py +4 -0
  5. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/guides/architecture.rst +2 -1
  6. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/components/test_linerepository.py +8 -0
  7. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_tabular.py +9 -0
  8. {cfinterface-1.10.2 → cfinterface-1.10.3}/.github/workflows/benchmark.yml +0 -0
  9. {cfinterface-1.10.2 → cfinterface-1.10.3}/.github/workflows/docs.yml +0 -0
  10. {cfinterface-1.10.2 → cfinterface-1.10.3}/.github/workflows/main.yml +0 -0
  11. {cfinterface-1.10.2 → cfinterface-1.10.3}/.github/workflows/publish.yml +0 -0
  12. {cfinterface-1.10.2 → cfinterface-1.10.3}/.gitignore +0 -0
  13. {cfinterface-1.10.2 → cfinterface-1.10.3}/.pre-commit-config.yaml +0 -0
  14. {cfinterface-1.10.2 → cfinterface-1.10.3}/CONTRIBUTING.md +0 -0
  15. {cfinterface-1.10.2 → cfinterface-1.10.3}/LICENSE +0 -0
  16. {cfinterface-1.10.2 → cfinterface-1.10.3}/README.md +0 -0
  17. {cfinterface-1.10.2 → cfinterface-1.10.3}/benchmarks/__init__.py +0 -0
  18. {cfinterface-1.10.2 → cfinterface-1.10.3}/benchmarks/bench_floatfield_write.py +0 -0
  19. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/_utils/__init__.py +0 -0
  20. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/__init__.py +0 -0
  21. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/components/__init__.py +0 -0
  22. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/components/line/__init__.py +0 -0
  23. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/components/repository.py +0 -0
  24. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/reading/__init__.py +0 -0
  25. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/reading/repository.py +0 -0
  26. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/writing/__init__.py +0 -0
  27. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/adapters/writing/repository.py +0 -0
  28. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/__init__.py +0 -0
  29. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/block.py +0 -0
  30. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/datetimefield.py +0 -0
  31. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/defaultblock.py +0 -0
  32. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/defaultregister.py +0 -0
  33. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/defaultsection.py +0 -0
  34. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/field.py +0 -0
  35. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/floatfield.py +0 -0
  36. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/integerfield.py +0 -0
  37. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/line.py +0 -0
  38. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/literalfield.py +0 -0
  39. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/register.py +0 -0
  40. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/section.py +0 -0
  41. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/components/tabular.py +0 -0
  42. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/data/__init__.py +0 -0
  43. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/data/blockdata.py +0 -0
  44. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/data/registerdata.py +0 -0
  45. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/data/sectiondata.py +0 -0
  46. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/files/__init__.py +0 -0
  47. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/files/blockfile.py +0 -0
  48. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/files/registerfile.py +0 -0
  49. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/files/sectionfile.py +0 -0
  50. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/py.typed +0 -0
  51. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/reading/__init__.py +0 -0
  52. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/reading/blockreading.py +0 -0
  53. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/reading/registerreading.py +0 -0
  54. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/reading/sectionreading.py +0 -0
  55. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/storage.py +0 -0
  56. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/versioning.py +0 -0
  57. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/writing/__init__.py +0 -0
  58. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/writing/blockwriting.py +0 -0
  59. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/writing/registerwriting.py +0 -0
  60. {cfinterface-1.10.2 → cfinterface-1.10.3}/cfinterface/writing/sectionwriting.py +0 -0
  61. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/_static/logo_cfinterface.svg +0 -0
  62. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/conf.py +0 -0
  63. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/getting_started/contributing.rst +0 -0
  64. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/getting_started/tutorial.rst +0 -0
  65. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/guides/faq.rst +0 -0
  66. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/guides/migration-v1.9.rst +0 -0
  67. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/guides/performance.rst +0 -0
  68. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/index.rst +0 -0
  69. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/install/install.rst +0 -0
  70. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/adapters/files/components.rst +0 -0
  71. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/adapters/files/line.rst +0 -0
  72. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/adapters/files/reading.rst +0 -0
  73. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/adapters/files/writing.rst +0 -0
  74. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/adapters/index.rst +0 -0
  75. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/blocks/files/block.rst +0 -0
  76. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/blocks/files/blockdata.rst +0 -0
  77. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/blocks/files/blockfile.rst +0 -0
  78. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/blocks/index.rst +0 -0
  79. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/fields/components/datetimefield.rst +0 -0
  80. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/fields/components/field.rst +0 -0
  81. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/fields/components/floatfield.rst +0 -0
  82. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/fields/components/integerfield.rst +0 -0
  83. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/fields/components/literalfield.rst +0 -0
  84. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/fields/index.rst +0 -0
  85. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/line/index.rst +0 -0
  86. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/registers/files/register.rst +0 -0
  87. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/registers/files/registerdata.rst +0 -0
  88. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/registers/files/registerfile.rst +0 -0
  89. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/registers/index.rst +0 -0
  90. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/sections/files/section.rst +0 -0
  91. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/sections/files/sectiondata.rst +0 -0
  92. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/sections/files/sectionfile.rst +0 -0
  93. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/sections/index.rst +0 -0
  94. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/storage/files/storagetype.rst +0 -0
  95. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/storage/index.rst +0 -0
  96. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/tabular/files/tabularparser.rst +0 -0
  97. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/tabular/files/tabularsection.rst +0 -0
  98. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/tabular/index.rst +0 -0
  99. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/versioning/files/versioning.rst +0 -0
  100. {cfinterface-1.10.2 → cfinterface-1.10.3}/docs/source/reference/versioning/index.rst +0 -0
  101. {cfinterface-1.10.2 → cfinterface-1.10.3}/examples/README.rst +0 -0
  102. {cfinterface-1.10.2 → cfinterface-1.10.3}/examples/__init__.py +0 -0
  103. {cfinterface-1.10.2 → cfinterface-1.10.3}/examples/plot_block_file.py +0 -0
  104. {cfinterface-1.10.2 → cfinterface-1.10.3}/examples/plot_register_file.py +0 -0
  105. {cfinterface-1.10.2 → cfinterface-1.10.3}/examples/plot_section_file.py +0 -0
  106. {cfinterface-1.10.2 → cfinterface-1.10.3}/examples/plot_tabular_parsing.py +0 -0
  107. {cfinterface-1.10.2 → cfinterface-1.10.3}/examples/plot_versioned_file.py +0 -0
  108. {cfinterface-1.10.2 → cfinterface-1.10.3}/pyproject.toml +0 -0
  109. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/__init__.py +0 -0
  110. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/_utils/__init__.py +0 -0
  111. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/_utils/test_is_null.py +0 -0
  112. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/__init__.py +0 -0
  113. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/components/__init__.py +0 -0
  114. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/components/test_blockrepository.py +0 -0
  115. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/components/test_factory.py +0 -0
  116. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/components/test_pattern_cache.py +0 -0
  117. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/components/test_registerrepository.py +0 -0
  118. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/components/test_sectionrepository.py +0 -0
  119. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/reading/__init__.py +0 -0
  120. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/reading/test_readingrepository.py +0 -0
  121. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/writing/__init__.py +0 -0
  122. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/adapters/writing/test_writingrepository.py +0 -0
  123. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/__init__.py +0 -0
  124. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/conftest.py +0 -0
  125. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_block.py +0 -0
  126. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_datetimefield.py +0 -0
  127. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_defaultblock.py +0 -0
  128. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_defaultregister.py +0 -0
  129. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_defaultsection.py +0 -0
  130. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_field.py +0 -0
  131. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_field_hypothesis.py +0 -0
  132. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_floatfield.py +0 -0
  133. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_floatfield_benchmark.py +0 -0
  134. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_integerfield.py +0 -0
  135. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_line.py +0 -0
  136. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_literalfield.py +0 -0
  137. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_register.py +0 -0
  138. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_section.py +0 -0
  139. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_storage_integration.py +0 -0
  140. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/components/test_tabular_hypothesis.py +0 -0
  141. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/conftest.py +0 -0
  142. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/data/__init__.py +0 -0
  143. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/data/test_blockdata.py +0 -0
  144. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/data/test_registerdata.py +0 -0
  145. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/data/test_sectiondata.py +0 -0
  146. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/files/__init__.py +0 -0
  147. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/files/test_blockfile.py +0 -0
  148. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/files/test_read_typing.py +0 -0
  149. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/files/test_registerfile.py +0 -0
  150. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/files/test_sectionfile.py +0 -0
  151. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/mocks/__init__.py +0 -0
  152. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/mocks/mock_open.py +0 -0
  153. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/reading/__init__.py +0 -0
  154. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/reading/test_blockreading.py +0 -0
  155. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/reading/test_registerreading.py +0 -0
  156. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/reading/test_sectionreading.py +0 -0
  157. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/test_storage.py +0 -0
  158. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/test_storage_deprecation.py +0 -0
  159. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/test_versioning.py +0 -0
  160. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/writing/__init__.py +0 -0
  161. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/writing/test_blockwriting.py +0 -0
  162. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/writing/test_registerwriting.py +0 -0
  163. {cfinterface-1.10.2 → cfinterface-1.10.3}/tests/writing/test_sectionwriting.py +0 -0
@@ -7,6 +7,12 @@ 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
+
10
16
  ## [1.10.2] - 2026-10-14
11
17
 
12
18
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: cfinterface
3
- Version: 1.10.2
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/
@@ -6,7 +6,7 @@ cfi is a Python module for handling custom formatted files
6
6
  and provide reading, storing and writing utilities.
7
7
  """
8
8
 
9
- __version__ = "1.10.2"
9
+ __version__ = "1.10.3"
10
10
 
11
11
  from . import components # noqa
12
12
  from . import data # noqa
@@ -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(
@@ -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()
File without changes
File without changes
File without changes