Data-quality roadmap: R-A–R-F + DQ-5 fixes (citations 590→1075, section signal 10%→95%) #16

Merged
user2595 merged 31 commits from integration/roadmap into main 2026-06-27 07:12:31 +00:00
2 changed files with 36 additions and 4 deletions
Showing only changes of commit 121b582f46 - Show all commits

View File

@@ -8,6 +8,7 @@ Provides:
from __future__ import annotations
import gzip
import io
import logging
import tarfile
@@ -157,12 +158,19 @@ def fetch_source(arxiv_id: str) -> str | None:
# Inline \input/\include so multi-file projects yield the full body,
# not just the primary file's skeleton of include directives (R-C).
return flatten_inputs(files[primary_name], files)
except tarfile.TarError as exc:
logger.warning("Failed to open tar archive for %s: %s", arxiv_id, exc)
except tarfile.TarError:
# Old arXiv submissions are served as a single bare gzipped .tex with no
# tar wrapper (e.g. legacy math/* papers) — gunzip the body directly.
try:
single = gzip.decompress(raw).decode("utf-8", errors="replace")
except (OSError, EOFError) as exc:
logger.warning("Failed to read arXiv source for %s: %s", arxiv_id, exc)
return None
if "\\" in single[:5000]: # looks like LaTeX (has backslash commands)
return single
logger.debug("arXiv source for %s is not LaTeX", arxiv_id)
return None
return None # unreachable but satisfies type checker
def fetch_pdf_url(arxiv_id: str) -> str:
"""Return the canonical PDF URL for an arXiv paper.

View File

@@ -86,6 +86,30 @@ def test_fetch_source_flattens_multifile(monkeypatch: pytest.MonkeyPatch) -> Non
assert "\\input" not in result and "\\include" not in result
def test_fetch_source_bare_gzip_single_file(monkeypatch: pytest.MonkeyPatch) -> None:
"""Legacy arXiv submissions are served as a single bare gzipped .tex (no tar
wrapper); fetch_source must gunzip the body directly rather than fail."""
import gzip
latex = b"\\documentstyle[a4]{article}\n\\section{Intro}\nOld single-file paper body."
gz_bytes = gzip.compress(latex)
def mock_get(
url: str,
*,
timeout: int = 60,
follow_redirects: bool = True,
) -> httpx.Response:
return httpx.Response(200, content=gz_bytes)
monkeypatch.setattr(httpx, "get", mock_get)
result = arxiv.fetch_source("math/0001176")
assert result is not None
assert "Old single-file paper body." in result
# ---------------------------------------------------------------------------
# fetch_source — 404 → None
# ---------------------------------------------------------------------------