tesorotools-python 0.0.39__tar.gz → 0.0.40__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 (68) hide show
  1. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/PKG-INFO +1 -1
  2. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/pyproject.toml +1 -1
  3. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/table.py +35 -52
  4. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/.gitignore +0 -0
  5. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/__init__.py +0 -0
  6. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/_build_context.py +0 -0
  7. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/_registry.py +0 -0
  8. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/artists/__init__.py +0 -0
  9. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/artists/_common.py +0 -0
  10. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/artists/barh_plot.py +0 -0
  11. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/artists/line_plot.py +0 -0
  12. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/artists/stacked.py +0 -0
  13. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/artists/type_curve.py +0 -0
  14. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/README.md +0 -0
  15. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Black.otf +0 -0
  16. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Bold.otf +0 -0
  17. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Extrabold.otf +0 -0
  18. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Extralight.otf +0 -0
  19. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Light.otf +0 -0
  20. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Medium.otf +0 -0
  21. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Regular.otf +0 -0
  22. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/CabinetGrotesk-Thin.otf +0 -0
  23. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/fonts/README.md +0 -0
  24. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/plots.yaml +0 -0
  25. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/assets/tesoro.mplstyle +0 -0
  26. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/data_sources/__init__.py +0 -0
  27. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/data_sources/debug.py +0 -0
  28. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/database/__init__.py +0 -0
  29. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/database/local.py +0 -0
  30. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/database/push.py +0 -0
  31. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/database/shared.py +0 -0
  32. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/dependencies/__init__.py +0 -0
  33. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/dependencies/node.py +0 -0
  34. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/dependencies/resolution.py +0 -0
  35. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/driver.py +0 -0
  36. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/manifest.py +0 -0
  37. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/offsets/__init__.py +0 -0
  38. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/offsets/offsets.py +0 -0
  39. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/offsets/outliers.py +0 -0
  40. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/orchestration.py +0 -0
  41. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/pipeline/__init__.py +0 -0
  42. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/pipeline/diagnose.py +0 -0
  43. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/pipeline/engine.py +0 -0
  44. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/pipeline/rules.py +0 -0
  45. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/providers/__init__.py +0 -0
  46. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/providers/base.py +0 -0
  47. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/providers/bde.py +0 -0
  48. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/providers/ecb.py +0 -0
  49. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/py.typed +0 -0
  50. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/__init__.py +0 -0
  51. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/__init__.py +0 -0
  52. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/content.py +0 -0
  53. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/images.py +0 -0
  54. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/section.py +0 -0
  55. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/subtitle.py +0 -0
  56. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/text.py +0 -0
  57. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/content/title.py +0 -0
  58. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/render/report.py +0 -0
  59. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/testing/__init__.py +0 -0
  60. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/testing/compare.py +0 -0
  61. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/__init__.py +0 -0
  62. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/config.py +0 -0
  63. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/format.py +0 -0
  64. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/globals.py +0 -0
  65. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/matplotlib.py +0 -0
  66. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/series.py +0 -0
  67. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/shortcuts.py +0 -0
  68. {tesorotools_python-0.0.39 → tesorotools_python-0.0.40}/src/tesorotools/utils/template.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tesorotools-python
3
- Version: 0.0.39
3
+ Version: 0.0.40
4
4
  Requires-Python: >=3.13
5
5
  Requires-Dist: babel>=2.17
6
6
  Requires-Dist: matplotlib>=3.10
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "tesorotools-python"
3
3
  requires-python = ">=3.13"
4
- version = "0.0.39"
4
+ version = "0.0.40"
5
5
  dependencies = [
6
6
  # database and ORM
7
7
  "psycopg[binary]>=3.1",
@@ -15,6 +15,7 @@ from docx.oxml.ns import nsdecls, qn
15
15
  from docx.shared import Inches, Pt, RGBColor
16
16
  from docx.table import Table as TableDocx
17
17
  from docx.table import _Cell as TableCell
18
+ from docx.table import _Row as TableRow
18
19
  from yaml import MappingNode
19
20
 
20
21
  from tesorotools.utils.config import read_config
@@ -49,46 +50,6 @@ TEXTO_TABLAS: int = 9
49
50
  CENTER = WD_ALIGN_PARAGRAPH.CENTER
50
51
 
51
52
 
52
- def _set_cell_border(cell: TableCell, **kwargs: Any) -> None:
53
- """
54
- Set cell`s border
55
- Usage:
56
-
57
- set_cell_border(
58
- cell,
59
- top={"sz": 12, "val": "single", "color": "#FF0000", "space": "0"},
60
- bottom={"sz": 12, "color": "#00FF00", "val": "single"},
61
- start={"sz": 24, "val": "dashed", "shadow": "true"},
62
- end={"sz": 12, "val": "dashed"},
63
- )
64
- """
65
- tc = cell._tc
66
- tcPr = tc.get_or_add_tcPr()
67
-
68
- # check for tag existence, if none found, create one
69
- tcBorders: Any = tcPr.first_child_found_in("w:tcBorders") # type: ignore[reportUnknownMemberType]
70
- if tcBorders is None:
71
- tcBorders = OxmlElement("w:tcBorders") # type: ignore[reportUnknownVariableType]
72
- tcPr.append(tcBorders) # type: ignore[reportUnknownMemberType]
73
-
74
- # list over all available tags
75
- for edge in ("start", "top", "end", "bottom", "insideH", "insideV"):
76
- edge_data: Any = kwargs.get(edge)
77
- if edge_data:
78
- tag = "w:{}".format(edge)
79
-
80
- # check for tag existence, if none found, then create one
81
- element: Any = tcBorders.find(qn(tag)) # type: ignore[reportUnknownMemberType]
82
- if element is None:
83
- element = OxmlElement(tag) # type: ignore[reportUnknownVariableType]
84
- tcBorders.append(element) # type: ignore[reportUnknownMemberType]
85
-
86
- # looks like order of attributes is important
87
- for key in ["sz", "val", "color", "space", "shadow"]:
88
- if key in edge_data:
89
- element.set(qn("w:{}".format(key)), str(edge_data[key])) # type: ignore[reportUnknownMemberType]
90
-
91
-
92
53
  def _style_horizontal_blocks_header(cell: TableCell) -> None:
93
54
  cell.paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
94
55
  cell.paragraphs[0].runs[0].font.size = Pt(12)
@@ -192,25 +153,47 @@ def _separate_blocks(
192
153
  "got a flat Index. Set block_sep=False or wrap rows in a "
193
154
  "MultiIndex with the block name as level 0."
194
155
  )
156
+ _disable_implicit_last_row(table_docx)
195
157
  blocks: list[str] = list(index.get_level_values(level=0).unique())
196
158
  previous_rows: int = 0
197
159
  for block in blocks[:-1]:
198
160
  block_size: int = len(index[index.get_level_values(level=0) == block])
199
- for cell in table_docx.rows[block_size + previous_rows].cells:
200
- _separate_cell(cell)
161
+ _separate_row(table_docx.rows[block_size + previous_rows])
201
162
  previous_rows += block_size
202
163
 
203
164
 
204
- def _separate_cell(cell: TableCell) -> None:
205
- _set_cell_border(
206
- cell,
207
- bottom={
208
- "sz": 1,
209
- "val": "double",
210
- "color": "#000000",
211
- "space": 2,
212
- },
213
- )
165
+ def _separate_row(row: TableRow) -> None:
166
+ """Mark *row* as ``lastRow`` via conditional-formatting reference.
167
+
168
+ The visible separator border belongs to the active table style
169
+ (``<w:tblStylePr w:type="lastRow">`` in ``styles.xml``). Emitting
170
+ only ``<w:cnfStyle>`` on ``<w:trPr>`` keeps direct formatting out of
171
+ ``<w:tcPr>``, which is the construct Word's co-authoring merge
172
+ engine corrupts in shared OneDrive/SharePoint documents. The
173
+ consumer's ``template.docx`` must define the ``lastRow`` conditional
174
+ formatting on the table style referenced by ``plots.yaml``.
175
+ """
176
+ trPr: Any = row._tr.get_or_add_trPr() # type: ignore[reportUnknownMemberType]
177
+ cnfStyle: Any = OxmlElement("w:cnfStyle") # type: ignore[reportUnknownVariableType]
178
+ # 12-bit mask, ECMA-376 §17.4.7. Bit 1 (zero-indexed) = lastRow.
179
+ cnfStyle.set(qn("w:val"), "010000000000") # type: ignore[reportUnknownMemberType]
180
+ trPr.append(cnfStyle) # type: ignore[reportUnknownMemberType]
181
+
182
+
183
+ def _disable_implicit_last_row(table_docx: TableDocx) -> None:
184
+ """Force ``<w:tblLook w:lastRow="0"/>`` so the real last row stays plain.
185
+
186
+ With block_sep we mark *interior* rows as ``lastRow`` via
187
+ ``cnfStyle``. The table's own last row must not pick up the same
188
+ conditional formatting automatically, so we disable the implicit
189
+ ``lastRow`` flag at the ``<w:tblLook>`` level.
190
+ """
191
+ tblPr: Any = table_docx._element.tblPr # type: ignore[reportUnknownMemberType]
192
+ tblLook: Any = tblPr.find(qn("w:tblLook")) # type: ignore[reportUnknownMemberType]
193
+ if tblLook is None:
194
+ tblLook = OxmlElement("w:tblLook") # type: ignore[reportUnknownVariableType]
195
+ tblPr.append(tblLook) # type: ignore[reportUnknownMemberType]
196
+ tblLook.set(qn("w:lastRow"), "0") # type: ignore[reportUnknownMemberType]
214
197
 
215
198
 
216
199
  def _is_bright(hex_color: str) -> bool: