pyOfficeEditor 0.2.0__tar.gz → 0.2.2__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.
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/PKG-INFO +1 -1
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/docs/changelog.md +36 -1
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/pyproject.toml +1 -1
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/__init__.py +15 -1
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_shapes.py +69 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/.gitignore +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/LICENSE.md +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/README.md +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/docs/architecture.md +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/_xml.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/_zip.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/__init__.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_addresses.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_conditional.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_dimensions.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_dxf.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_formats.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_formulas.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_hyperlinks.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_names.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_pagesetup.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_protection.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_reference.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_rowcol.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_schema.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_sharedstrings.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_styles.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_tables.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_tokens.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_validation.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/_values.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/workbook.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/excel/worksheet.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/exceptions.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/opc.py +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/src/pyofficeeditor/py.typed +0 -0
- {pyofficeeditor-0.2.0 → pyofficeeditor-0.2.2}/tests/fixtures/excel/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pyOfficeEditor
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Edit the document surface of Excel, Word, PowerPoint and Access in pure Python, no dependencies.
|
|
5
5
|
Project-URL: Homepage, https://github.com/WilliamSmithEdward/pyOfficeEditor
|
|
6
6
|
Project-URL: Repository, https://github.com/WilliamSmithEdward/pyOfficeEditor
|
|
@@ -11,7 +11,9 @@ package and writing it back unchanged reproduces the input exactly.
|
|
|
11
11
|
workflow extracts one section by reading to the next "## [" heading, so
|
|
12
12
|
anything trailing the file is swept into the oldest release's notes. -->
|
|
13
13
|
|
|
14
|
-
[Unreleased]: https://github.com/WilliamSmithEdward/pyOfficeEditor/compare/v0.2.
|
|
14
|
+
[Unreleased]: https://github.com/WilliamSmithEdward/pyOfficeEditor/compare/v0.2.2...HEAD
|
|
15
|
+
[0.2.2]: https://github.com/WilliamSmithEdward/pyOfficeEditor/compare/v0.2.1...v0.2.2
|
|
16
|
+
[0.2.1]: https://github.com/WilliamSmithEdward/pyOfficeEditor/compare/v0.2.0...v0.2.1
|
|
15
17
|
[0.2.0]: https://github.com/WilliamSmithEdward/pyOfficeEditor/compare/v0.1.1...v0.2.0
|
|
16
18
|
[0.1.1]: https://github.com/WilliamSmithEdward/pyOfficeEditor/compare/v0.1.0...v0.1.1
|
|
17
19
|
[0.1.0]: https://github.com/WilliamSmithEdward/pyOfficeEditor/releases/tag/v0.1.0
|
|
@@ -20,6 +22,39 @@ anything trailing the file is swept into the oldest release's notes. -->
|
|
|
20
22
|
|
|
21
23
|
Nothing yet.
|
|
22
24
|
|
|
25
|
+
## [0.2.2] - 2026-09-20
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **`__version__` reported 0.1.0 on every release since.** It was a literal
|
|
30
|
+
in `__init__.py` that nothing linked to the version in
|
|
31
|
+
`pyproject.toml`, so 0.1.1, 0.2.0 and 0.2.1 all imported saying 0.1.0.
|
|
32
|
+
The distribution metadata was right throughout; only the attribute was
|
|
33
|
+
wrong, so `pip` and the PyPI page were never affected and anything
|
|
34
|
+
reading `pyofficeeditor.__version__` was.
|
|
35
|
+
|
|
36
|
+
It is read from the installed distribution now, which cannot drift, and
|
|
37
|
+
`tests/test_version.py` fails if the attribute, the metadata and
|
|
38
|
+
`pyproject.toml` ever disagree. That test is the thing that was missing:
|
|
39
|
+
nothing checked, so nothing failed.
|
|
40
|
+
|
|
41
|
+
## [0.2.1] - 2026-09-19
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- **The preset geometry each MsoAutoShapeType maps to**, and
|
|
46
|
+
`Shape.auto_shape_type` reporting it back, measured by having Excel make
|
|
47
|
+
one shape of each of 33 types and reading the drawing.
|
|
48
|
+
|
|
49
|
+
This is an addition rather than a fix: pyOfficeEditor never carried the
|
|
50
|
+
table. It is worth measuring rather than transcribing, because every
|
|
51
|
+
plausible wrong answer is a real preset name belonging to some other
|
|
52
|
+
shape. A table pairing 11 with `cross`, 12 with `star5`, 16 with `can`
|
|
53
|
+
and 17 with `cube` looks right and is wrong on all four: Excel writes
|
|
54
|
+
`plus`, `pentagon`, `foldedCorner` and `smileyFace`. Nothing complains,
|
|
55
|
+
the file is valid, and the wrong shape appears. The five-pointed star is
|
|
56
|
+
92, not 12.
|
|
57
|
+
|
|
23
58
|
## [0.2.0] - 2026-09-19
|
|
24
59
|
|
|
25
60
|
Conditional formatting, data validation, sheet protection, page setup,
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyOfficeEditor"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "Edit the document surface of Excel, Word, PowerPoint and Access in pure Python, no dependencies."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -19,6 +19,8 @@ Access follow in that order.
|
|
|
19
19
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
23
|
+
|
|
22
24
|
from pyofficeeditor._xml import Element, XmlDocument
|
|
23
25
|
from pyofficeeditor.exceptions import (
|
|
24
26
|
PackageError,
|
|
@@ -29,7 +31,19 @@ from pyofficeeditor.exceptions import (
|
|
|
29
31
|
)
|
|
30
32
|
from pyofficeeditor.opc import OpcPackage, Relationship, Relationships
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
try:
|
|
35
|
+
#: Read from the installed distribution rather than written here.
|
|
36
|
+
#:
|
|
37
|
+
#: A literal has to be remembered at every release and was not: 0.1.1,
|
|
38
|
+
#: 0.2.0 and 0.2.1 all shipped saying 0.1.0, because nothing links a
|
|
39
|
+
#: string in this file to the version in pyproject.toml. Asking the
|
|
40
|
+
#: metadata cannot drift, and ``tests/test_version.py`` fails if the
|
|
41
|
+
#: two ever disagree.
|
|
42
|
+
__version__ = version("pyOfficeEditor")
|
|
43
|
+
except PackageNotFoundError: # pragma: no cover - a source tree, uninstalled
|
|
44
|
+
# Importable straight from a checkout, where there is no distribution to
|
|
45
|
+
# ask. Saying so beats guessing a number.
|
|
46
|
+
__version__ = "0.0.0+source"
|
|
33
47
|
|
|
34
48
|
__all__ = [
|
|
35
49
|
"Element",
|
|
@@ -97,6 +97,63 @@ _ELEMENT_KINDS: dict[str, ShapeKind] = {
|
|
|
97
97
|
"graphicFrame": "chart",
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
|
|
101
|
+
#: The preset geometry Excel writes for each ``MsoAutoShapeType``, measured
|
|
102
|
+
#: by making one shape of each and reading the drawing back.
|
|
103
|
+
#:
|
|
104
|
+
#: Worth measuring rather than transcribing, because every plausible wrong
|
|
105
|
+
#: answer here is a real preset name belonging to some other shape. A table
|
|
106
|
+
#: that pairs 11 with ``cross``, 12 with ``star5``, 16 with ``can`` and 17
|
|
107
|
+
#: with ``cube`` looks right and is wrong on all four: Excel writes ``plus``,
|
|
108
|
+
#: ``pentagon``, ``foldedCorner`` and ``smileyFace``. Nothing complains. The
|
|
109
|
+
#: file is valid and the wrong shape appears.
|
|
110
|
+
#:
|
|
111
|
+
#: The five-pointed star is 92, not 12. The numbers are not contiguous:
|
|
112
|
+
#: ``MsoAutoShapeType`` leaves gaps, and only the ones Excel actually made
|
|
113
|
+
#: when asked are here.
|
|
114
|
+
PRESET_GEOMETRY: dict[int, str] = {
|
|
115
|
+
1: "rect", # msoShapeRectangle
|
|
116
|
+
2: "parallelogram",
|
|
117
|
+
3: "trapezoid",
|
|
118
|
+
4: "diamond",
|
|
119
|
+
5: "roundRect", # msoShapeRoundedRectangle
|
|
120
|
+
6: "octagon",
|
|
121
|
+
7: "triangle", # msoShapeIsoscelesTriangle
|
|
122
|
+
8: "rtTriangle",
|
|
123
|
+
9: "ellipse", # msoShapeOval
|
|
124
|
+
10: "hexagon",
|
|
125
|
+
11: "plus", # msoShapeCross
|
|
126
|
+
12: "pentagon", # msoShapeRegularPentagon
|
|
127
|
+
13: "can",
|
|
128
|
+
14: "cube",
|
|
129
|
+
15: "bevel",
|
|
130
|
+
16: "foldedCorner",
|
|
131
|
+
17: "smileyFace",
|
|
132
|
+
18: "donut",
|
|
133
|
+
19: "noSmoking",
|
|
134
|
+
20: "blockArc",
|
|
135
|
+
21: "heart",
|
|
136
|
+
22: "lightningBolt",
|
|
137
|
+
23: "sun",
|
|
138
|
+
24: "moon",
|
|
139
|
+
25: "arc",
|
|
140
|
+
26: "bracketPair",
|
|
141
|
+
27: "bracePair",
|
|
142
|
+
28: "plaque",
|
|
143
|
+
92: "star5", # msoShape5pointStar
|
|
144
|
+
93: "star8",
|
|
145
|
+
94: "star16",
|
|
146
|
+
95: "star24",
|
|
147
|
+
96: "star32",
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
#: The same the other way round, for reporting what a shape read from a
|
|
151
|
+
#: file would answer for ``AutoShapeType``.
|
|
152
|
+
AUTO_SHAPE_TYPES: dict[str, int] = {
|
|
153
|
+
preset: number for number, preset in PRESET_GEOMETRY.items()
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
|
|
100
157
|
#: The anchors a drawing is made of.
|
|
101
158
|
ANCHORS = ("twoCellAnchor", "oneCellAnchor", "absoluteAnchor")
|
|
102
159
|
|
|
@@ -221,6 +278,16 @@ class Shape:
|
|
|
221
278
|
"""What ``Shape.Type`` answers for this kind."""
|
|
222
279
|
return MSO_TYPE.get(self.kind, 1)
|
|
223
280
|
|
|
281
|
+
@property
|
|
282
|
+
def auto_shape_type(self) -> int | None:
|
|
283
|
+
"""What ``Shape.AutoShapeType`` answers, or ``None`` for a geometry
|
|
284
|
+
this does not name.
|
|
285
|
+
|
|
286
|
+
A text box answers 1 as well as an AutoShape does, which is what
|
|
287
|
+
Excel reports, because both are drawn as a rectangle.
|
|
288
|
+
"""
|
|
289
|
+
return AUTO_SHAPE_TYPES.get(self.geometry)
|
|
290
|
+
|
|
224
291
|
def __repr__(self) -> str:
|
|
225
292
|
where = f"{self.left:g},{self.top:g} {self.width:g}x{self.height:g}"
|
|
226
293
|
macro = f" macro={self.macro}" if self.macro else ""
|
|
@@ -470,10 +537,12 @@ def _as_float(raw: str | None, fallback: float) -> float:
|
|
|
470
537
|
|
|
471
538
|
__all__ = [
|
|
472
539
|
"ANCHORS",
|
|
540
|
+
"AUTO_SHAPE_TYPES",
|
|
473
541
|
"DEFAULT_COLUMN_POINTS",
|
|
474
542
|
"DEFAULT_ROW_POINTS",
|
|
475
543
|
"EMU_PER_POINT",
|
|
476
544
|
"MSO_TYPE",
|
|
545
|
+
"PRESET_GEOMETRY",
|
|
477
546
|
"Shape",
|
|
478
547
|
"ShapeKind",
|
|
479
548
|
"SheetGrid",
|
|
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
|