Add legacy-cgi dev dep and expand erdr2pml tests
erdr2pml imports the stdlib `cgi` module, removed in Python 3.13, so its tests were skipped on modern interpreters. Add the `legacy-cgi` backport as a dev dependency so the module imports, and flesh out its tests: deXOR involution, fixKey known vector / length, cleanPML high-ASCII escaping, and sanitizeFileName separator/colon/control-char/angle-bracket handling. The skip guard is kept as a safety net for environments without the backport. Suite is now 44 passing, 0 skipped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Generated
+13
-1
@@ -115,6 +115,18 @@ files = [
|
|||||||
{file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"},
|
{file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "legacy-cgi"
|
||||||
|
version = "2.6.4"
|
||||||
|
description = "Fork of the standard library cgi and cgitb modules removed in Python 3.13"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
groups = ["dev"]
|
||||||
|
files = [
|
||||||
|
{file = "legacy_cgi-2.6.4-py3-none-any.whl", hash = "sha256:7e235ce58bf1e25d1fc9b2d299015e4e2cd37305eccafec1e6bac3fc04b878cd"},
|
||||||
|
{file = "legacy_cgi-2.6.4.tar.gz", hash = "sha256:abb9dfc7835772f7c9317977c63253fd22a7484b5c9bbcdca60a29dcce97c577"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lxml"
|
name = "lxml"
|
||||||
version = "6.1.1"
|
version = "6.1.1"
|
||||||
@@ -441,4 +453,4 @@ files = [
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = ">=3.8,<4.0"
|
python-versions = ">=3.8,<4.0"
|
||||||
content-hash = "d54bcac8b306449a805fd6f145f6d910dcbebbccc907b790b028c988c7ef1985"
|
content-hash = "a7172bce7871b58ba975c81418c1477022b8cd6ce275dcca76bcedcb766764e4"
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ apsw = ">=3.46"
|
|||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
pytest = ">=8.0"
|
pytest = ">=8.0"
|
||||||
|
# Backport of the stdlib `cgi` module (removed in Python 3.13) so erdr2pml and
|
||||||
|
# other modules that still import it can be loaded and tested.
|
||||||
|
legacy-cgi = ">=2.6"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
testpaths = ["tests"]
|
testpaths = ["tests"]
|
||||||
|
|||||||
+34
-8
@@ -1,8 +1,9 @@
|
|||||||
"""Tests for erdr2pml helpers.
|
"""Tests for erdr2pml (eReader) helpers.
|
||||||
|
|
||||||
erdr2pml imports the stdlib ``cgi`` module, which was removed in Python 3.13.
|
erdr2pml imports the stdlib ``cgi`` module, which was removed in Python 3.13.
|
||||||
On such interpreters the whole module is unimportable, so these tests are
|
The ``legacy-cgi`` backport is a dev dependency so the module imports on modern
|
||||||
skipped (calibre currently ships Python 3.8-3.11, where they run).
|
interpreters; the skip guard below keeps the suite green if it is ever run
|
||||||
|
without that backport (e.g. a bare Python 3.13+ with no dev extras).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -12,7 +13,7 @@ import dedrm_test_utils as U
|
|||||||
try:
|
try:
|
||||||
erdr2pml = U.load("erdr2pml", package="dedrm")
|
erdr2pml = U.load("erdr2pml", package="dedrm")
|
||||||
_skip_reason = None
|
_skip_reason = None
|
||||||
except Exception as exc: # pragma: no cover - depends on interpreter version
|
except Exception as exc: # pragma: no cover - depends on interpreter / deps
|
||||||
erdr2pml = None
|
erdr2pml = None
|
||||||
_skip_reason = "erdr2pml not importable: {0}".format(exc)
|
_skip_reason = "erdr2pml not importable: {0}".format(exc)
|
||||||
|
|
||||||
@@ -27,7 +28,32 @@ def test_dexor_is_involutive():
|
|||||||
assert erdr2pml.deXOR(once, 0, table) == text
|
assert erdr2pml.deXOR(once, 0, table) == text
|
||||||
|
|
||||||
|
|
||||||
def test_sanitize_filename_strips_separators():
|
def test_fix_key_known_vector():
|
||||||
name = erdr2pml.sanitizeFileName("a/b\\c")
|
assert erdr2pml.fixKey(bytes([0, 1, 2, 3, 255, 128, 64])) == bytes(
|
||||||
assert "/" not in name
|
[0x80, 0x01, 0x02, 0x83, 0x7F, 0x80, 0x40]
|
||||||
assert "\\" not in name
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_fix_key_preserves_length():
|
||||||
|
assert len(erdr2pml.fixKey(b"\x00" * 16)) == 16
|
||||||
|
|
||||||
|
|
||||||
|
def test_clean_pml_escapes_high_ascii():
|
||||||
|
# bytes 128..255 become \aNNN PML codes; bytes < 128 are left untouched.
|
||||||
|
assert erdr2pml.cleanPML(b"abc\x80\xff\x7f") == b"abc\\a128\\a255\x7f"
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanitize_filename_replaces_separators():
|
||||||
|
assert erdr2pml.sanitizeFileName("a/b\\c|d") == "a_b_c_d"
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanitize_filename_removes_colon():
|
||||||
|
assert ":" not in erdr2pml.sanitizeFileName("foo: bar")
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanitize_filename_strips_control_chars_and_dots():
|
||||||
|
assert erdr2pml.sanitizeFileName("...\x01na\tme.") == "name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_sanitize_filename_replaces_angle_brackets():
|
||||||
|
assert erdr2pml.sanitizeFileName("<tag>") == "[tag]"
|
||||||
|
|||||||
Reference in New Issue
Block a user