pyOpenVBA 1.0.0__py3-none-any.whl

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.
@@ -0,0 +1,285 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyOpenVBA
3
+ Version: 1.0.0
4
+ Summary: Read and write VBA macros inside Excel workbooks (.xlsm, .xlsb, .xlam, .xls) in pure Python, no dependencies.
5
+ Project-URL: Homepage, https://github.com/WilliamSmithEdward/pyOpenVBA
6
+ Project-URL: Repository, https://github.com/WilliamSmithEdward/pyOpenVBA
7
+ Project-URL: Issues, https://github.com/WilliamSmithEdward/pyOpenVBA/issues
8
+ Project-URL: Documentation, https://github.com/WilliamSmithEdward/pyOpenVBA#readme
9
+ Author-email: William Smith <williamsmithe@icloud.com>
10
+ License: MIT
11
+ License-File: LICENSE.md
12
+ Keywords: excel,macros,ms-cfb,ms-ovba,office,vba,xlam,xls,xlsb,xlsm
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Topic :: Office/Business
26
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
+ Classifier: Topic :: System :: Archiving
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.10
30
+ Description-Content-Type: text/markdown
31
+
32
+ # pyOpenVBA
33
+
34
+ **Read and write the VBA macros inside Excel workbooks, in pure Python.**
35
+
36
+ No external dependencies. No Excel install required. Works on Windows,
37
+ macOS, and Linux. Python 3.10 or newer.
38
+
39
+ Supports `.xlsm`, `.xlsb`, `.xlam`, and legacy `.xls`.
40
+
41
+ ---
42
+
43
+ ## Why use this?
44
+
45
+ Several excellent Python tools already exist for **reading** VBA out of
46
+ Excel files (oletools, olefile, and friends), and they remain the right
47
+ choice for forensics, malware analysis, and audit use-cases. pyOpenVBA
48
+ focuses on the next step: safely **writing** changes back so the
49
+ workbook still opens cleanly in Excel.
50
+
51
+ The write path is the whole point of the library:
52
+
53
+ - **Replace** a module's source in place.
54
+ - **Add** a new standard module, class module, or document/UserForm
55
+ code-behind.
56
+ - **Rename** any module (the CFB stream, `dir` record, `PROJECT`
57
+ declaration, `PROJECTwm` name map, and `Attribute VB_Name` are all
58
+ updated in lockstep).
59
+ - **Delete** a module cleanly.
60
+ - **Save** the workbook and have it reopen in Excel with no "we found
61
+ a problem with some content" repair dialog. Every supported format
62
+ (`.xlsm`, `.xlsb`, `.xlam`, `.xls`) is verified against live Excel.
63
+ - **Safely refuse** to corrupt password-protected or digitally signed
64
+ projects unless you explicitly opt in.
65
+
66
+ That makes it a good fit for:
67
+
68
+ - **Version-controlling your VBA** in git like normal source code, then
69
+ pushing edits back without ever opening Excel.
70
+ - **Diffing** two workbooks to see what changed in `Module1`.
71
+ - **Generating or updating macros from a script** without scripting
72
+ Excel through COM automation.
73
+ - **Reading and writing macros on a server** (Linux / CI) where Excel
74
+ is not installed.
75
+
76
+ pyOpenVBA is a complete read-and-write library, so it covers the full
77
+ lifecycle of a VBA project in one place: extract, edit, version, write
78
+ back, and verify. If you only ever need to read, the existing tools
79
+ remain a solid choice; if you might ever need to write, start here and
80
+ you will not have to switch later.
81
+
82
+ ## Installation
83
+
84
+ ```bash
85
+ pip install pyOpenVBA
86
+ ```
87
+
88
+ Or from source:
89
+
90
+ ```bash
91
+ git clone https://github.com/WilliamSmithEdward/pyOpenVBA
92
+ cd pyOpenVBA
93
+ pip install -e .
94
+ ```
95
+
96
+ That's it. There are no other dependencies.
97
+
98
+ ---
99
+
100
+ ## 30-second tour
101
+
102
+ ```python
103
+ from pyopenvba import ExcelFile
104
+
105
+ with ExcelFile("workbook.xlsm") as wb:
106
+ # 1. List all VBA modules in the workbook.
107
+ print(wb.module_names())
108
+ # ['ThisWorkbook', 'Sheet1', 'Module1']
109
+
110
+ # 2. Read a module's source as a string.
111
+ source = wb.get_module("Module1")
112
+ print(source)
113
+
114
+ # 3. Edit a module and save the workbook.
115
+ wb.set_module("Module1", 'Sub Hello()\r\n MsgBox "hi"\r\nEnd Sub\r\n')
116
+ wb.save() # overwrites the original file
117
+ # wb.save("edited.xlsm") # ...or save to a new file
118
+ ```
119
+
120
+ That is the entire core API. Three methods.
121
+
122
+ ---
123
+
124
+ ## Add, rename, or delete a module
125
+
126
+ ```python
127
+ from pyopenvba import ExcelFile, VBAModuleKind
128
+
129
+ with ExcelFile("workbook.xlsm") as wb:
130
+ project = wb.vba_project()
131
+
132
+ project.add_module(
133
+ "NewModule",
134
+ "Sub Hi()\r\n MsgBox \"hi\"\r\nEnd Sub\r\n",
135
+ kind=VBAModuleKind.standard,
136
+ )
137
+ project.rename_module("OldName", "NewName")
138
+ project.delete_module("Obsolete")
139
+
140
+ wb.save("out.xlsm")
141
+ ```
142
+
143
+ ---
144
+
145
+ ## Edit your macros as files on disk (recommended workflow)
146
+
147
+ This is the easiest way to manage VBA in a git repo. Export every
148
+ module to a folder, edit the files in any text editor, then push the
149
+ changes back into the workbook.
150
+
151
+ From the command line:
152
+
153
+ ```bash
154
+ # 1. Pull every module out of the workbook into ./vba/
155
+ python -m pyopenvba pull workbook.xlsm ./vba
156
+
157
+ # 2. ...edit ./vba/Module1.bas in your editor of choice...
158
+
159
+ # 3. Push your edits back into the workbook
160
+ python -m pyopenvba push ./vba workbook.xlsm
161
+
162
+ # Bonus: list modules without extracting anything
163
+ python -m pyopenvba ls workbook.xlsm
164
+ ```
165
+
166
+ From Python:
167
+
168
+ ```python
169
+ from pyopenvba import pull, push
170
+
171
+ pull("workbook.xlsm", "./vba")
172
+ # ...edit files...
173
+ push("./vba", "workbook.xlsm") # in place
174
+ push("./vba", "workbook.xlsm", out="edited.xlsm") # to a new file
175
+ ```
176
+
177
+ Module files use the extensions VBA already uses: `.bas` for standard
178
+ modules, `.cls` for class modules, `.frm` for UserForm code-behind.
179
+
180
+ ---
181
+
182
+ ## Supported formats
183
+
184
+ | Extension | What it is | Read | Write |
185
+ |-----------|------------------------------|:----:|:-----:|
186
+ | `.xlsm` | Macro-enabled workbook | yes | yes |
187
+ | `.xlsb` | Binary workbook | yes | yes |
188
+ | `.xlam` | Macro-enabled add-in | yes | yes |
189
+ | `.xls` | Legacy (Excel 97-2003) | yes | yes |
190
+
191
+ Every save is verified to reopen in Excel **without** the "we found a
192
+ problem with some content" repair dialog.
193
+
194
+ ---
195
+
196
+ ## Safety guards
197
+
198
+ `save()` refuses to silently produce a broken workbook.
199
+
200
+ ### Password-protected projects
201
+
202
+ If the VBA project is password-protected, any mutation will raise
203
+ `VBAProjectError` unless you explicitly opt in:
204
+
205
+ ```python
206
+ wb.save(allow_protected=True)
207
+ ```
208
+
209
+ The library never tries to decrypt or change the password - it just
210
+ preserves the existing protection bytes verbatim. The resulting
211
+ workbook still requires the original password to open the VBE.
212
+
213
+ ### Digitally-signed projects
214
+
215
+ A digital signature is invalidated by *any* change to the macros. On
216
+ mutation, the library drops the stale signature streams and emits a
217
+ `UserWarning` so you know trust has been removed:
218
+
219
+ ```python
220
+ import warnings
221
+ warnings.filterwarnings("error", category=UserWarning) # treat as fatal
222
+
223
+ # ...or silence the warning if you accept the consequence:
224
+ wb.save(allow_invalidate_signature=True)
225
+ ```
226
+
227
+ ---
228
+
229
+ ## What's out of scope
230
+
231
+ This library is intentionally focused on **module source code**. The
232
+ following are preserved byte-for-byte but not interpreted:
233
+
234
+ - UserForm **layout** (controls, properties, positions). Editing the
235
+ **code-behind** of a UserForm works fine; editing the design surface
236
+ does not.
237
+ - VBA project password decryption / re-encryption.
238
+ - Re-signing digitally signed projects.
239
+ - ActiveX license editing.
240
+
241
+ See [docs/roadmap.md](docs/roadmap.md) for the full feature matrix.
242
+
243
+ ---
244
+
245
+ ## Architecture
246
+
247
+ ```
248
+ src/pyopenvba/
249
+ __init__.py public API (ExcelFile, pull, push, exceptions)
250
+ excel.py ExcelFile facade (ZIP / CFB dispatch, pull/push helpers)
251
+ vba.py VBA project parser + MS-OVBA codec
252
+ cfb.py MS-CFB (Compound File Binary) parser/writer
253
+ exceptions.py custom exception hierarchy
254
+ __main__.py `python -m pyopenvba {pull,push,ls}` CLI
255
+ ```
256
+
257
+ For deeper documentation:
258
+
259
+ - [docs/architecture.md](docs/architecture.md) - internal module layout.
260
+ - [docs/ms-ovba-implementation-guide_v2.md](docs/ms-ovba-implementation-guide_v2.md) -
261
+ language-agnostic guide for re-implementing MS-OVBA in another
262
+ language.
263
+ - [docs/roadmap.md](docs/roadmap.md) - per-feature implementation status.
264
+
265
+ ---
266
+
267
+ ## Contributing
268
+
269
+ Bug reports, weird workbooks that break the library, and PRs are all
270
+ welcome. Please include the workbook (or a minimal redacted version)
271
+ when filing a parsing bug.
272
+
273
+ Run the test suite:
274
+
275
+ ```bash
276
+ pip install pytest pyright
277
+ pytest
278
+ pyright src tests
279
+ ```
280
+
281
+ ---
282
+
283
+ ## License
284
+
285
+ [MIT](LICENSE.md).
@@ -0,0 +1,11 @@
1
+ pyopenvba/__init__.py,sha256=_ic4PN3vrry9q4jv1N66T2EAuMXiA6U8ZJvp4ckHvZw,2097
2
+ pyopenvba/__main__.py,sha256=3IvYyGbPF0XNRmiSPy8qoxb61zswRp_6IvbS6SBnEPQ,2122
3
+ pyopenvba/cfb.py,sha256=b6LE2kPOD8jxBq-4Vq1VaooxrY_U2CrOG0OLBLvjwvk,39032
4
+ pyopenvba/excel.py,sha256=yBOb0F5u9aIN02yadqcKOqkr-6ILXGrnrQgvm0hj1h0,19613
5
+ pyopenvba/exceptions.py,sha256=h8EOq3WiYFjfJjl03Tg1jPjXmeKJj4R6R0kRLAcNFsw,470
6
+ pyopenvba/vba.py,sha256=ZSv8guLYiyGdsnKjA_GE1JyoxjQ3Yvq1iiEk34TLpEQ,63390
7
+ pyopenvba-1.0.0.dist-info/METADATA,sha256=ZAP9l5QMOIsL9qzb2_R2sgvnZfi6buDDNeo0s2SWESM,8705
8
+ pyopenvba-1.0.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
9
+ pyopenvba-1.0.0.dist-info/entry_points.txt,sha256=NdoWgUhj7gb56JACSFIXgdFUTZKK5-NsoEqHqcBs9QE,54
10
+ pyopenvba-1.0.0.dist-info/licenses/LICENSE.md,sha256=jZd8SfdtiVsA1mjfXJiAHPCV4jxZlB44A9s4c3bnoVA,1093
11
+ pyopenvba-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pyopenvba = pyopenvba.__main__:main
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright (c) 2026 William Smith
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.