test(assets): the lossless guard gets a stdlib arm that always runs
19 passed in this file, 0 skipped. Green on arrival and stated as such: no production code changes here, so there is nothing for a red commit to precede -- the defect is that the property was never MEASURED on a core install. Measured by PM 2026-09-19 on one: 4 of the 13 guards in this file were SKIPPED, the lossless one among them, because they decode through Pillow -- which this package neither uses nor ships and which arrives only as a transitive dependency of `pdfplumber` under `[extract]`. A plain `pip install llm-ingestion-okf` therefore never measured the property this round is named after. The new arm decodes the carried PNG with `zlib` and the five filters of PNG SS 9.2, and compares against pixels written out in this file: `rle8_indices` for the RLE8 source and `RGB_ROWS` for the 24-bit one. Still independent in the way that matters -- the package compresses rows it filtered, the test reverses filters it decompressed. Two arms: one over `read_image`, one over what the BUILD wrote. The environment is MADE rather than assumed: a `sys.meta_path` finder raising for every `PIL` name, with a known-positive that it fires before the guards re-run under it. Control, run once and not committed: a Pillow-dependent line placed inside the blocked section turns the guard red. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
76e407f368
commit
b486fea939
1 changed files with 160 additions and 0 deletions
|
|
@ -612,3 +612,163 @@ def test_the_uncompressed_path_refuses_the_same_shape() -> None:
|
|||
with pytest.raises(ExtractionError) as caught:
|
||||
read_image(short, name="kort.bmp")
|
||||
assert caught.value.code == CODE_SAMPLES_INVALID, caught.value.code
|
||||
|
||||
|
||||
# --- 8. the lossless guard, with no optional dependency in sight ------------
|
||||
|
||||
|
||||
def png_rgb(data: bytes) -> tuple[tuple[int, int], bytes]:
|
||||
"""An INDEPENDENT PNG decoding using the stdlib alone: `zlib` and the five
|
||||
filters of PNG SS 9.2, with the palette applied.
|
||||
|
||||
Guard 2 above decodes through Pillow, which this package neither uses nor
|
||||
ships -- the right independence, and it is an OPTIONAL dependency here
|
||||
(transitive under `pdfplumber` in `[extract]`). Measured 2026-09-19 on a
|
||||
core install: 4 of the 13 guards in this file, the lossless one among them,
|
||||
were SKIPPED, so a plain `pip install llm-ingestion-okf` never measured the
|
||||
property the round is named after. This arm always runs.
|
||||
|
||||
It is independent in the way that matters: the package writes a PNG by
|
||||
compressing rows it filtered, and this reads one by reversing filters it
|
||||
decompressed. The expected pixels come from `rle8_indices` and from
|
||||
`RGB_ROWS`, both written in this file.
|
||||
"""
|
||||
import zlib
|
||||
|
||||
assert data[:8] == b"\x89PNG\r\n\x1a\n"
|
||||
position, idat, palette, header = 8, b"", b"", None
|
||||
while position < len(data):
|
||||
length = int.from_bytes(data[position : position + 4], "big")
|
||||
kind = data[position + 4 : position + 8]
|
||||
payload = data[position + 8 : position + 8 + length]
|
||||
position += 12 + length
|
||||
if kind == b"IHDR":
|
||||
header = struct.unpack(">IIBBBBB", payload)
|
||||
elif kind == b"PLTE":
|
||||
palette = payload
|
||||
elif kind == b"IDAT":
|
||||
idat += payload
|
||||
elif kind == b"IEND":
|
||||
break
|
||||
assert header is not None
|
||||
width, height, depth, colour = header[0], header[1], header[2], header[3]
|
||||
assert depth == 8, depth
|
||||
channels = {0: 1, 2: 3, 3: 1}[colour]
|
||||
raw = zlib.decompress(idat)
|
||||
stride = width * channels
|
||||
out, previous, at = bytearray(), bytearray(stride), 0
|
||||
for _ in range(height):
|
||||
kind_byte = raw[at]
|
||||
line = bytearray(raw[at + 1 : at + 1 + stride])
|
||||
at += 1 + stride
|
||||
for i in range(stride):
|
||||
left = line[i - channels] if i >= channels else 0
|
||||
up = previous[i]
|
||||
upleft = previous[i - channels] if i >= channels else 0
|
||||
if kind_byte == 1:
|
||||
line[i] = (line[i] + left) & 0xFF
|
||||
elif kind_byte == 2:
|
||||
line[i] = (line[i] + up) & 0xFF
|
||||
elif kind_byte == 3:
|
||||
line[i] = (line[i] + (left + up) // 2) & 0xFF
|
||||
elif kind_byte == 4:
|
||||
estimate = left + up - upleft
|
||||
distances = (abs(estimate - left), abs(estimate - up), abs(estimate - upleft))
|
||||
nearest = (left, up, upleft)[distances.index(min(distances))]
|
||||
line[i] = (line[i] + nearest) & 0xFF
|
||||
out += line
|
||||
previous = line
|
||||
if colour == 3:
|
||||
return (width, height), bytes(b for i in out for b in palette[i * 3 : i * 3 + 3])
|
||||
return (width, height), bytes(out)
|
||||
|
||||
|
||||
def test_the_conversion_is_lossless_measured_with_the_stdlib_alone() -> None:
|
||||
"""Eval point 2 again, on a path with no optional dependency on either side.
|
||||
|
||||
The package encodes a PNG with `zlib`; this decodes one with `zlib` and the
|
||||
filter definitions, and compares against pixels written out in THIS file.
|
||||
Pillow appears nowhere, so the guard measures on a core install.
|
||||
"""
|
||||
indices = rle8_indices(RLE8_STREAM, 8, 4)
|
||||
assert indices == bytes(index for row in EXPECTED_INDICES for index in row)
|
||||
expected = b"".join(PALETTE[index * 3 : index * 3 + 3] for index in indices)
|
||||
assert expected == expected_rgb()
|
||||
|
||||
converted = read_image(bmp_rle8(8, 4, PALETTE, RLE8_STREAM), name="figur-rle8.bmp")
|
||||
assert converted.media_type == "image/png"
|
||||
assert png_rgb(converted.data) == ((8, 4), expected)
|
||||
|
||||
flat = read_image(bmp_24(RGB_ROWS), name="figur-flat.bmp")
|
||||
assert flat.media_type == "image/png"
|
||||
flat_expected = b"".join(bytes(pixel) for row in RGB_ROWS for pixel in row)
|
||||
assert png_rgb(flat.data) == ((5, 3), flat_expected)
|
||||
|
||||
# The negative control: without it, two broken decoders could agree.
|
||||
assert png_rgb(converted.data)[1] != flat_expected
|
||||
|
||||
|
||||
def test_the_bundle_holds_those_pixels_measured_with_the_stdlib_alone(tmp_path: Path) -> None:
|
||||
"""The same claim about what the BUILD wrote, not about `read_image`.
|
||||
|
||||
Pinned exactly like guard 2 and with no importorskip for Pillow: for each
|
||||
source, exactly one carried asset decodes to its pixels, and the holder
|
||||
has to be in the viewable set -- a BMP carried verbatim would hold its own
|
||||
pixels trivially.
|
||||
"""
|
||||
pytest.importorskip("llm_ingestion_guard")
|
||||
bundle = tmp_path / "bundle"
|
||||
assert _build(_inbox(tmp_path), bundle) == 0
|
||||
indices = rle8_indices(RLE8_STREAM, 8, 4)
|
||||
sources = {
|
||||
"rle8": ((8, 4), b"".join(PALETTE[i * 3 : i * 3 + 3] for i in indices)),
|
||||
"flat24": ((5, 3), b"".join(bytes(pixel) for row in RGB_ROWS for pixel in row)),
|
||||
}
|
||||
carried = [path.read_bytes() for path in _assets(bundle)]
|
||||
assert len(carried) == 2, carried
|
||||
for label, expected in sources.items():
|
||||
hits = [
|
||||
data
|
||||
for data in carried
|
||||
if (sniff(data) or (None,))[0] in VIEWABLE and png_rgb(data) == expected
|
||||
]
|
||||
assert len(hits) == 1, f"{label}: {len(hits)} carried assets hold these pixels"
|
||||
|
||||
|
||||
def test_the_stdlib_arm_runs_with_Pillow_unimportable() -> None:
|
||||
"""SHOWN, not asserted: the two guards above re-run with `PIL` blocked.
|
||||
|
||||
"Runs on a core install" is a claim about an environment, and this file
|
||||
is usually run in one where `[extract]` -- and therefore Pillow, under
|
||||
`pdfplumber` -- is installed. So the environment is made here: a finder
|
||||
that raises for every `PIL` name, with a known-positive proving it fires
|
||||
before the guards are re-run under it.
|
||||
"""
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
class NoPillow:
|
||||
def find_spec(self, name: str, path: object = None, target: object = None) -> None:
|
||||
if name == "PIL" or name.startswith("PIL."):
|
||||
raise ImportError(f"{name} is blocked for this guard")
|
||||
return None
|
||||
|
||||
purged = {name: module for name, module in sys.modules.items() if name.split(".")[0] == "PIL"}
|
||||
for name in purged:
|
||||
del sys.modules[name]
|
||||
sys.meta_path.insert(0, NoPillow())
|
||||
try:
|
||||
# KNOWN-POSITIVE: the blocker blocks. Without this the guard below
|
||||
# would pass in an environment where Pillow was simply present.
|
||||
with pytest.raises(ImportError):
|
||||
importlib.import_module("PIL.Image")
|
||||
test_the_conversion_is_lossless_measured_with_the_stdlib_alone()
|
||||
indices = rle8_indices(RLE8_STREAM, 8, 4)
|
||||
expected = b"".join(PALETTE[index * 3 : index * 3 + 3] for index in indices)
|
||||
assert png_rgb(read_image(bmp_rle8(8, 4, PALETTE, RLE8_STREAM), name="x.bmp").data) == (
|
||||
(8, 4),
|
||||
expected,
|
||||
)
|
||||
finally:
|
||||
sys.meta_path.pop(0)
|
||||
sys.modules.update(purged)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue