pyOpenVBA 3.0.1__tar.gz → 3.2.0__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.
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/.gitignore +4 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/PKG-INFO +37 -9
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/README.md +36 -8
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/docs/architecture.md +12 -16
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/docs/roadmap.md +1 -1
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/pyproject.toml +1 -1
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/__init__.py +1 -1
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/__main__.py +45 -15
- pyopenvba-3.0.1/src/pyopenvba/excel.py → pyopenvba-3.2.0/src/pyopenvba/_host.py +97 -96
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/access_read.py +15 -22
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/cfb.py +50 -50
- pyopenvba-3.2.0/src/pyopenvba/excel.py +76 -0
- pyopenvba-3.2.0/src/pyopenvba/powerpoint.py +69 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/vba.py +392 -77
- pyopenvba-3.2.0/src/pyopenvba/word.py +68 -0
- pyopenvba-3.0.1/src/pyopenvba/powerpoint.py +0 -479
- pyopenvba-3.0.1/src/pyopenvba/word.py +0 -478
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/LICENSE.md +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/docs/ms-ovba-implementation-guide_v2.md +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/_templates/__init__.py +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/_templates/blank_files/blank_database.accdb +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/_templates/blank_files/blank_document.docm +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/_templates/blank_files/blank_presentation.pptm +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/_templates/blank_files/blank_workbook.xlsb +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/_templates/blank_files/blank_workbook.xlsm +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/exceptions.py +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/src/pyopenvba/vba_pcode.py +0 -0
- {pyopenvba-3.0.1 → pyopenvba-3.2.0}/tests/fuzz_corpus/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyOpenVBA
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Read and write VBA macros inside Excel, Word, and PowerPoint files in pure Python, no dependencies.
|
|
5
5
|
Project-URL: Homepage, https://github.com/WilliamSmithEdward/pyOpenVBA
|
|
6
6
|
Project-URL: Repository, https://github.com/WilliamSmithEdward/pyOpenVBA
|
|
@@ -54,8 +54,6 @@ Supports:
|
|
|
54
54
|
* Word (`.docm`, `.dotm`, `.doc`)
|
|
55
55
|
* Access (`.accdb`) - **read-only**
|
|
56
56
|
|
|
57
|
-
<a href="https://github.com/sponsors/WilliamSmithEdward"><img src="https://img.shields.io/badge/Sponsor-%E2%9D%A4-pink?style=for-the-badge" alt="Sponsor WilliamSmithEdward"></a>
|
|
58
|
-
|
|
59
57
|
---
|
|
60
58
|
|
|
61
59
|
## Why use this?
|
|
@@ -257,6 +255,12 @@ with ExcelFile("workbook.xlsm") as wb:
|
|
|
257
255
|
wb.save("out.xlsm")
|
|
258
256
|
```
|
|
259
257
|
|
|
258
|
+
Class sources are accepted in any form: a bare body (the header is
|
|
259
|
+
synthesized), a `.cls` file exported straight from the VBE (the
|
|
260
|
+
`VERSION ... CLASS` preamble is stripped and the required
|
|
261
|
+
`Attribute VB_Base` line is added automatically), or a full
|
|
262
|
+
stream-form source.
|
|
263
|
+
|
|
260
264
|
---
|
|
261
265
|
|
|
262
266
|
## Edit your macros as files on disk (recommended workflow)
|
|
@@ -441,17 +445,21 @@ See [docs/roadmap.md](https://github.com/WilliamSmithEdward/pyOpenVBA/blob/main/
|
|
|
441
445
|
|
|
442
446
|
```
|
|
443
447
|
src/pyopenvba/
|
|
444
|
-
__init__.py public API (ExcelFile, WordFile, PowerPointFile,
|
|
448
|
+
__init__.py public API (ExcelFile, WordFile, PowerPointFile, AccessReader,
|
|
445
449
|
pull/push, pull_word/push_word, pull_ppt/push_ppt,
|
|
446
|
-
VBAModuleKind, synthesize_class_header,
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
+
pull_access, VBAModuleKind, synthesize_class_header,
|
|
451
|
+
exceptions)
|
|
452
|
+
_host.py VBAHostFile: shared open/edit/pull/push/save pipeline
|
|
453
|
+
excel.py ExcelFile (thin VBAHostFile subclass + create_new template)
|
|
454
|
+
word.py WordFile (thin VBAHostFile subclass + create_new template)
|
|
455
|
+
powerpoint.py PowerPointFile (thin VBAHostFile subclass + create_new template)
|
|
456
|
+
access_read.py AccessReader (read-only ACE/Jet page + LVAL reader)
|
|
450
457
|
vba.py VBA project parser + MS-OVBA codec
|
|
458
|
+
vba_pcode.py VBA7 p-code disassembler
|
|
451
459
|
cfb.py MS-CFB (Compound File Binary) parser/writer
|
|
452
460
|
exceptions.py custom exception hierarchy
|
|
453
461
|
_templates/ baked-in empty .xlsm/.xlsb/.docm/.pptm bytes for create_new()
|
|
454
|
-
__main__.py `python -m pyopenvba {pull,push,ls}` CLI
|
|
462
|
+
__main__.py `python -m pyopenvba {pull,push,ls,disasm,access-*}` CLI
|
|
455
463
|
```
|
|
456
464
|
|
|
457
465
|
For deeper documentation:
|
|
@@ -477,6 +485,15 @@ pyright src tests
|
|
|
477
485
|
pytest -p no:randomly
|
|
478
486
|
```
|
|
479
487
|
|
|
488
|
+
On a Windows machine with desktop Excel installed you can additionally run
|
|
489
|
+
the live compile-and-run gate (skipped by default and in CI). It builds a
|
|
490
|
+
workbook with pyOpenVBA, runs its macro in real Excel under a popup-aware
|
|
491
|
+
harness, and fails on any VBE dialog:
|
|
492
|
+
|
|
493
|
+
```powershell
|
|
494
|
+
$env:RUN_LIVE_EXCEL = "1"; pytest tests/test_live_excel_gate.py
|
|
495
|
+
```
|
|
496
|
+
|
|
480
497
|
CI runs the test matrix on Python 3.10 / 3.11 / 3.12 / 3.13 across
|
|
481
498
|
Linux, plus 3.12 on Windows and macOS, on every push and pull request.
|
|
482
499
|
Releases are published to PyPI automatically when a `v*.*.*` tag is
|
|
@@ -487,3 +504,14 @@ pushed.
|
|
|
487
504
|
## License
|
|
488
505
|
|
|
489
506
|
[MIT](https://github.com/WilliamSmithEdward/pyOpenVBA/blob/main/LICENSE.md).
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## Support Open Source
|
|
511
|
+
|
|
512
|
+
pyOpenVBA is open-source software. If it saves you time or helps your team keep
|
|
513
|
+
VBA workbooks maintainable, support helps keep the project moving.
|
|
514
|
+
|
|
515
|
+
- [GitHub Sponsors](https://github.com/sponsors/WilliamSmithEdward)
|
|
516
|
+
- [PayPal](https://www.paypal.com/donate/?business=ML855BRLNR838&no_recurring=0&item_name=VBA+has+always+treated+me+well.+It+was+how+I+first+grew+professional+as+a+programmer%2C+I%27m+happy+to+show+it+some+love+%E2%9D%A4%EF%B8%8F¤cy_code=USD)
|
|
517
|
+
- [Cash App](https://cash.app/$williamesmithjcil)
|
|
@@ -18,8 +18,6 @@ Supports:
|
|
|
18
18
|
* Word (`.docm`, `.dotm`, `.doc`)
|
|
19
19
|
* Access (`.accdb`) - **read-only**
|
|
20
20
|
|
|
21
|
-
<a href="https://github.com/sponsors/WilliamSmithEdward"><img src="https://img.shields.io/badge/Sponsor-%E2%9D%A4-pink?style=for-the-badge" alt="Sponsor WilliamSmithEdward"></a>
|
|
22
|
-
|
|
23
21
|
---
|
|
24
22
|
|
|
25
23
|
## Why use this?
|
|
@@ -221,6 +219,12 @@ with ExcelFile("workbook.xlsm") as wb:
|
|
|
221
219
|
wb.save("out.xlsm")
|
|
222
220
|
```
|
|
223
221
|
|
|
222
|
+
Class sources are accepted in any form: a bare body (the header is
|
|
223
|
+
synthesized), a `.cls` file exported straight from the VBE (the
|
|
224
|
+
`VERSION ... CLASS` preamble is stripped and the required
|
|
225
|
+
`Attribute VB_Base` line is added automatically), or a full
|
|
226
|
+
stream-form source.
|
|
227
|
+
|
|
224
228
|
---
|
|
225
229
|
|
|
226
230
|
## Edit your macros as files on disk (recommended workflow)
|
|
@@ -405,17 +409,21 @@ See [docs/roadmap.md](https://github.com/WilliamSmithEdward/pyOpenVBA/blob/main/
|
|
|
405
409
|
|
|
406
410
|
```
|
|
407
411
|
src/pyopenvba/
|
|
408
|
-
__init__.py public API (ExcelFile, WordFile, PowerPointFile,
|
|
412
|
+
__init__.py public API (ExcelFile, WordFile, PowerPointFile, AccessReader,
|
|
409
413
|
pull/push, pull_word/push_word, pull_ppt/push_ppt,
|
|
410
|
-
VBAModuleKind, synthesize_class_header,
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
+
pull_access, VBAModuleKind, synthesize_class_header,
|
|
415
|
+
exceptions)
|
|
416
|
+
_host.py VBAHostFile: shared open/edit/pull/push/save pipeline
|
|
417
|
+
excel.py ExcelFile (thin VBAHostFile subclass + create_new template)
|
|
418
|
+
word.py WordFile (thin VBAHostFile subclass + create_new template)
|
|
419
|
+
powerpoint.py PowerPointFile (thin VBAHostFile subclass + create_new template)
|
|
420
|
+
access_read.py AccessReader (read-only ACE/Jet page + LVAL reader)
|
|
414
421
|
vba.py VBA project parser + MS-OVBA codec
|
|
422
|
+
vba_pcode.py VBA7 p-code disassembler
|
|
415
423
|
cfb.py MS-CFB (Compound File Binary) parser/writer
|
|
416
424
|
exceptions.py custom exception hierarchy
|
|
417
425
|
_templates/ baked-in empty .xlsm/.xlsb/.docm/.pptm bytes for create_new()
|
|
418
|
-
__main__.py `python -m pyopenvba {pull,push,ls}` CLI
|
|
426
|
+
__main__.py `python -m pyopenvba {pull,push,ls,disasm,access-*}` CLI
|
|
419
427
|
```
|
|
420
428
|
|
|
421
429
|
For deeper documentation:
|
|
@@ -441,6 +449,15 @@ pyright src tests
|
|
|
441
449
|
pytest -p no:randomly
|
|
442
450
|
```
|
|
443
451
|
|
|
452
|
+
On a Windows machine with desktop Excel installed you can additionally run
|
|
453
|
+
the live compile-and-run gate (skipped by default and in CI). It builds a
|
|
454
|
+
workbook with pyOpenVBA, runs its macro in real Excel under a popup-aware
|
|
455
|
+
harness, and fails on any VBE dialog:
|
|
456
|
+
|
|
457
|
+
```powershell
|
|
458
|
+
$env:RUN_LIVE_EXCEL = "1"; pytest tests/test_live_excel_gate.py
|
|
459
|
+
```
|
|
460
|
+
|
|
444
461
|
CI runs the test matrix on Python 3.10 / 3.11 / 3.12 / 3.13 across
|
|
445
462
|
Linux, plus 3.12 on Windows and macOS, on every push and pull request.
|
|
446
463
|
Releases are published to PyPI automatically when a `v*.*.*` tag is
|
|
@@ -451,3 +468,14 @@ pushed.
|
|
|
451
468
|
## License
|
|
452
469
|
|
|
453
470
|
[MIT](https://github.com/WilliamSmithEdward/pyOpenVBA/blob/main/LICENSE.md).
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## Support Open Source
|
|
475
|
+
|
|
476
|
+
pyOpenVBA is open-source software. If it saves you time or helps your team keep
|
|
477
|
+
VBA workbooks maintainable, support helps keep the project moving.
|
|
478
|
+
|
|
479
|
+
- [GitHub Sponsors](https://github.com/sponsors/WilliamSmithEdward)
|
|
480
|
+
- [PayPal](https://www.paypal.com/donate/?business=ML855BRLNR838&no_recurring=0&item_name=VBA+has+always+treated+me+well.+It+was+how+I+first+grew+professional+as+a+programmer%2C+I%27m+happy+to+show+it+some+love+%E2%9D%A4%EF%B8%8F¤cy_code=USD)
|
|
481
|
+
- [Cash App](https://cash.app/$williamesmithjcil)
|
|
@@ -18,20 +18,17 @@ knows about the layer below it but not the layer above.
|
|
|
18
18
|
|
|
19
19
|
```
|
|
20
20
|
+--------------------------------------------------------+
|
|
21
|
-
| excel.py
|
|
22
|
-
| -
|
|
23
|
-
| -
|
|
24
|
-
|
|
|
21
|
+
| excel.py / word.py / powerpoint.py host facades |
|
|
22
|
+
| - thin subclasses of _host.VBAHostFile |
|
|
23
|
+
| - per-host constants: container extensions, |
|
|
24
|
+
| vbaProject.bin entry path, message wording |
|
|
25
|
+
| - create_new() from a baked-in template |
|
|
25
26
|
+--------------------------------------------------------+
|
|
26
|
-
|
|
|
27
|
+
| _host.py VBAHostFile shared implementation |
|
|
27
28
|
| - ZIP / raw-CFB dispatch by extension |
|
|
28
|
-
| -
|
|
29
|
-
| - pull / push disk workflow |
|
|
30
|
-
+--------------------------------------------------------+
|
|
31
|
-
| powerpoint.py PowerPointFile facade |
|
|
32
|
-
| - ZIP / raw-CFB dispatch by extension |
|
|
33
|
-
| - identical save() pipeline as ExcelFile |
|
|
29
|
+
| - save() pipeline (safety gates, structural rewrites)|
|
|
34
30
|
| - pull / push disk workflow |
|
|
31
|
+
| - class-source normalization at set_module / push |
|
|
35
32
|
+--------------------------------------------------------+
|
|
36
33
|
| access_read.py AccessReader facade (READ-ONLY) |
|
|
37
34
|
| - ACE / Jet 4 page reader (.accdb, .mdb) |
|
|
@@ -87,8 +84,9 @@ Other files:
|
|
|
87
84
|
- `cfb.py` is **completely VBA-agnostic** and could be lifted into a
|
|
88
85
|
separate library. It knows nothing about MS-OVBA.
|
|
89
86
|
- `vba.py` operates on a `CFB` instance but never opens files on disk.
|
|
90
|
-
- `
|
|
91
|
-
containers, or
|
|
87
|
+
- `_host.py` is the only module that touches the filesystem, ZIP
|
|
88
|
+
containers, or host file paths; the three facades only supply
|
|
89
|
+
constants and `create_new()` templates.
|
|
92
90
|
- Cross-layer leaks are a code smell. Adding a `pathlib.Path` import to
|
|
93
91
|
`vba.py` or `cfb.py` is a red flag.
|
|
94
92
|
|
|
@@ -407,9 +405,7 @@ files in the same commit:
|
|
|
407
405
|
| New layer / module | This file (sections 1 and 2), README architecture box |
|
|
408
406
|
| New roadmap gate or status change | `docs/roadmap.md` |
|
|
409
407
|
| New mutation safety gate | This file section 4, README "Safety guards" |
|
|
410
|
-
| New supported file extension
|
|
411
|
-
| New supported file extension (Word) | `word.py` dispatch, README table, this file section 5 |
|
|
412
|
-
| New supported file extension (PowerPoint) | `powerpoint.py` dispatch, README table, this file section 5 |
|
|
408
|
+
| New supported file extension | Facade `_zip_formats` / `_cfb_formats`, `__main__._HOST_BY_SUFFIX`, README table, this file section 5 |
|
|
413
409
|
| New test file or fuzz target | This file section 8 |
|
|
414
410
|
| Spec/behavior change worth telling other implementers | `docs/ms-ovba-implementation-guide_v2.md` |
|
|
415
411
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# pyOpenVBA Roadmap
|
|
2
2
|
|
|
3
3
|
This roadmap tracks pyOpenVBA's progress against the 26 hard gates defined in
|
|
4
|
-
[`xlsm_feature_completeness_gates.md`](
|
|
4
|
+
[`xlsm_feature_completeness_gates.md`](xlsm_feature_completeness_gates.md).
|
|
5
5
|
Per-gate status keys:
|
|
6
6
|
|
|
7
7
|
- **PASS** — implemented; gate tests in [`tests/test_gates.py`](../tests/test_gates.py) pass.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyOpenVBA"
|
|
7
|
-
version = "3.0
|
|
7
|
+
version = "3.2.0"
|
|
8
8
|
description = "Read and write VBA macros inside Excel, Word, and PowerPoint files in pure Python, no dependencies."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
@@ -3,13 +3,16 @@ Command-line entry point.
|
|
|
3
3
|
|
|
4
4
|
Usage::
|
|
5
5
|
|
|
6
|
-
python -m pyopenvba pull <
|
|
7
|
-
python -m pyopenvba push <src_dir> <
|
|
8
|
-
python -m pyopenvba ls <
|
|
6
|
+
python -m pyopenvba pull <office_file> <dest_dir>
|
|
7
|
+
python -m pyopenvba push <src_dir> <office_file> [--out <new_path>] [--strict]
|
|
8
|
+
python -m pyopenvba ls <office_file>
|
|
9
9
|
python -m pyopenvba access-ls <accdb>
|
|
10
10
|
python -m pyopenvba access-pull <accdb> <dest_dir>
|
|
11
11
|
python -m pyopenvba access-disasm <accdb> [--module <name>] [--with-source]
|
|
12
|
-
python -m pyopenvba disasm <
|
|
12
|
+
python -m pyopenvba disasm <office_file> [--module <name>] [--with-source]
|
|
13
|
+
|
|
14
|
+
``<office_file>`` may be any supported Excel, Word, or PowerPoint file;
|
|
15
|
+
the host is selected by extension (see ``_HOST_BY_SUFFIX``).
|
|
13
16
|
"""
|
|
14
17
|
|
|
15
18
|
from __future__ import annotations
|
|
@@ -18,26 +21,51 @@ import argparse
|
|
|
18
21
|
import sys
|
|
19
22
|
from pathlib import Path
|
|
20
23
|
|
|
21
|
-
from pyopenvba import ExcelFile, PowerPointFile, WordFile
|
|
24
|
+
from pyopenvba import ExcelFile, PowerPointFile, WordFile
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _resolve_host(path: Path) -> type | None:
|
|
28
|
+
"""Return the host file class for ``path`` by extension, or ``None``
|
|
29
|
+
(after printing an error) when the extension is unsupported."""
|
|
30
|
+
host_cls = _HOST_BY_SUFFIX.get(path.suffix.lower())
|
|
31
|
+
if host_cls is None:
|
|
32
|
+
print(
|
|
33
|
+
f"error: unsupported file type {path.suffix.lower()!r}; expected one of "
|
|
34
|
+
f"{sorted(_HOST_BY_SUFFIX)}",
|
|
35
|
+
file=sys.stderr,
|
|
36
|
+
)
|
|
37
|
+
return host_cls
|
|
22
38
|
|
|
23
39
|
|
|
24
40
|
def _cmd_pull(args: argparse.Namespace) -> int:
|
|
25
|
-
|
|
41
|
+
host_cls = _resolve_host(args.workbook)
|
|
42
|
+
if host_cls is None:
|
|
43
|
+
return 2
|
|
44
|
+
with host_cls(args.workbook) as host:
|
|
45
|
+
written = host.pull_modules(args.dest, overwrite=not args.no_overwrite)
|
|
26
46
|
for p in written:
|
|
27
47
|
print(p)
|
|
28
48
|
return 0
|
|
29
49
|
|
|
30
50
|
|
|
31
51
|
def _cmd_push(args: argparse.Namespace) -> int:
|
|
32
|
-
|
|
52
|
+
host_cls = _resolve_host(args.workbook)
|
|
53
|
+
if host_cls is None:
|
|
54
|
+
return 2
|
|
55
|
+
with host_cls(args.workbook) as host:
|
|
56
|
+
updated = host.push_modules(args.src, strict=args.strict)
|
|
57
|
+
host.save(args.out)
|
|
33
58
|
for name in updated:
|
|
34
59
|
print(name)
|
|
35
60
|
return 0
|
|
36
61
|
|
|
37
62
|
|
|
38
63
|
def _cmd_ls(args: argparse.Namespace) -> int:
|
|
39
|
-
|
|
40
|
-
|
|
64
|
+
host_cls = _resolve_host(args.workbook)
|
|
65
|
+
if host_cls is None:
|
|
66
|
+
return 2
|
|
67
|
+
with host_cls(args.workbook) as host:
|
|
68
|
+
for m in host.vba_project().modules:
|
|
41
69
|
print(f"{m.kind.name:8s} {m.name}")
|
|
42
70
|
return 0
|
|
43
71
|
|
|
@@ -55,10 +83,9 @@ def _cmd_access_pull(args: argparse.Namespace) -> int:
|
|
|
55
83
|
from pyopenvba.access_read import AccessReader
|
|
56
84
|
|
|
57
85
|
db = AccessReader(args.database)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
out.write_text(m.source, encoding="utf-8")
|
|
86
|
+
# pull_modules classifies standard modules as .bas and class modules
|
|
87
|
+
# as .cls, matching the Excel/Word/PowerPoint pull commands.
|
|
88
|
+
for out in db.pull_modules(args.dest):
|
|
62
89
|
print(out)
|
|
63
90
|
return 0
|
|
64
91
|
|
|
@@ -90,16 +117,19 @@ def _cmd_access_disasm(args: argparse.Namespace) -> int:
|
|
|
90
117
|
return 0
|
|
91
118
|
|
|
92
119
|
|
|
120
|
+
# Every extension listed here is accepted by the mapped host class;
|
|
121
|
+
# keep this in lockstep with each facade's _ZIP_FORMATS / _CFB_FORMATS.
|
|
93
122
|
_HOST_BY_SUFFIX: dict[str, type] = {
|
|
94
123
|
".xlsm": ExcelFile,
|
|
95
124
|
".xlsb": ExcelFile,
|
|
96
|
-
".xltm": ExcelFile,
|
|
97
125
|
".xlam": ExcelFile,
|
|
126
|
+
".xls": ExcelFile,
|
|
98
127
|
".docm": WordFile,
|
|
99
128
|
".dotm": WordFile,
|
|
129
|
+
".doc": WordFile,
|
|
100
130
|
".pptm": PowerPointFile,
|
|
101
131
|
".potm": PowerPointFile,
|
|
102
|
-
".
|
|
132
|
+
".ppt": PowerPointFile,
|
|
103
133
|
}
|
|
104
134
|
|
|
105
135
|
|