Skip to content

Commit d30f141

Browse files
committed
Fix the PDF wrapper without pypdf and the CI findings on the audit work
The PyPdfError translation imported pypdf before calling the function, so without the optional package every PDF call raised ModuleNotFoundError instead of the explained RuntimeError, and the stubbed tests failed on CI. The action-JSON lint workflow installs its spec with --only-binary, which still builds a git ref but runs no dependency's setup script, and the report test parses with defusedxml.
1 parent 1c42e91 commit d30f141

4 files changed

Lines changed: 18 additions & 12 deletions

File tree

‎.github/workflows/action-json-lint.yml‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ jobs:
4141
python -m pip install --only-binary :all: --upgrade "pip==26.0.1"
4242
# The spec is a documented workflow input — pinned by default so a
4343
# lint run is reproducible, overridable so a caller can track their
44-
# own release or a git ref.
45-
python -m pip install "$AUTOCONTROL_REF"
44+
# own release or a git ref. --only-binary still builds a git ref's
45+
# own project (pip builds VCS requirements regardless) but runs no
46+
# dependency's setup script.
47+
python -m pip install --only-binary :all: "$AUTOCONTROL_REF"
4648
4749
- name: Lint action JSON files
4850
shell: bash

‎architecture_explore.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ iOS(WebDriverAgent)。核心能力是滑鼠/鍵盤控制、影像辨識、
2020
| 指標 | 數值 |
2121
| --- | ---: |
2222
| Python 模組總數(含周邊子專案) | 1,045 |
23-
| 程式碼總行數 | 142,845 |
23+
| 程式碼總行數 | 142,850 |
2424
| `je_auto_control/utils/` 子套件數 | 310 |
2525
| `AC_*` 動作指令數(`known_commands()` 實測) | 773 |
2626
| 套件門面 `__all__` 公開名稱數 | 1,239 |
@@ -597,7 +597,7 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
597597

598598
### 5.4.13 資料來源、結構驗證與 i18n
599599

600-
> 24 個套件、約 3,950 行。
600+
> 24 個套件、約 3,955 行。
601601
602602
| 模組 | 行數 | 職責 |
603603
| --- | ---: | --- |
@@ -619,7 +619,7 @@ socket server 有 8 MiB 讀取上限與 30 秒 handler timeout。
619619
| `utils/locale_parse/` | 68 | 地區感知數字/貨幣/日期解析與格式化(選用 babel) |
620620
| `utils/message_format/` | 236 | ICU-lite MessageFormat(plural/select/selectordinal) |
621621
| `utils/office/` | 162 | Office 文件無頭讀寫(Excel/Word/PowerPoint) |
622-
| `utils/pdf/` | 110 | PDF 讀取與斷言(選用 pypdf 後端) |
622+
| `utils/pdf/` | 115 | PDF 讀取與斷言(選用 pypdf 後端) |
623623
| `utils/referential/` | 75 | 跨資料集的參照完整性檢查 |
624624
| `utils/schema_compat/` | 162 | JSON Schema 相容性分級 |
625625
| `utils/sql/` | 84 | 對 SQLite 的臨時唯讀 SQL 查詢 |
@@ -1079,6 +1079,6 @@ socket 預設綁 `127.0.0.1`;資源一律用 `with`。
10791079
| `osx/` | 17 | 919 |
10801080
| `autocontrol-lsp/` | 8 | 744 |
10811081
| `utils/hotkey/` | 7 | 738 |
1082-
| 其餘模組(約 286 個 `utils/` 子套件 + `android/`/`ios/`/周邊小工具) | 674 | 48,301 |
1083-
| **總計** | **1,039** | **142,780** |
1082+
| 其餘模組(約 286 個 `utils/` 子套件 + `android/`/`ios/`/周邊小工具) | 674 | 48,306 |
1083+
| **總計** | **1,039** | **142,785** |
10841084

‎je_auto_control/utils/pdf/pdf_reader.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ def _pdf_errors_as_action_errors(function: Callable[..., _Result]) -> Callable[.
2626
"""
2727
@functools.wraps(function)
2828
def wrapper(*args: Any, **kwargs: Any) -> _Result:
29-
from pypdf.errors import PyPdfError
29+
try:
30+
from pypdf.errors import PyPdfError
31+
except ImportError:
32+
# Without pypdf there is nothing of its to translate: the function
33+
# either uses a stubbed reader or _open_pdf explains what is missing.
34+
return function(*args, **kwargs)
3035
try:
3136
return function(*args, **kwargs)
3237
except PyPdfError as error:

‎test/unit_test/headless/test_report_audit.py‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
file unreadable by CI. A report that could not be written was logged and
77
dropped, and exception text was quoted twice.
88
"""
9-
import xml.dom.minidom
10-
119
import pytest
10+
from defusedxml import minidom
1211

1312
from je_auto_control.utils.exception.exceptions import (
1413
AutoControlGenerateJsonReportException, AutoControlHTMLException, XMLException,
@@ -38,14 +37,14 @@ def test_the_xml_report_survives_control_characters(records, tmp_path):
3837
record_action_to_list("bad\x0b", None, repr(ValueError("x\x02")))
3938
generate_xml_report(str(tmp_path / "r"))
4039
for name in ("r_success.xml", "r_failure.xml"):
41-
xml.dom.minidom.parse(str(tmp_path / name)) # well-formed
40+
minidom.parse(str(tmp_path / name)) # well-formed
4241

4342

4443
def test_the_junit_report_survives_control_characters():
4544
result = suite_result.TestSuiteResult(name="suite\x01", cases=[
4645
suite_result.TestCaseResult(name="c\x1b", status="failed", message="got \x1b[31mred\x1b[0m"),
4746
])
48-
parsed = xml.dom.minidom.parseString(to_junit_xml(result))
47+
parsed = minidom.parseString(to_junit_xml(result))
4948
failure = parsed.getElementsByTagName("failure")[0]
5049
assert "red" in failure.getAttribute("message")
5150

0 commit comments

Comments
 (0)