From 0ae600f3cbb0a82af065f76d9026602e04f0796c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 02:16:38 +0000 Subject: [PATCH 1/2] Initial plan From a5b12f98de0016e682a42d8fba17d489c76c6a40 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Mar 2026 02:20:17 +0000 Subject: [PATCH 2/2] Fix review comments: remove duplicate import, fix regex syntax, add tests Co-authored-by: oscarlevin <6504596+oscarlevin@users.noreply.github.com> --- pretext/utils.py | 3 +-- tests/test_utils.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/pretext/utils.py b/pretext/utils.py index b6890305..0e7a61f8 100644 --- a/pretext/utils.py +++ b/pretext/utils.py @@ -16,7 +16,6 @@ import logging import logging.handlers import psutil -import re import typing as t from . import types as pt # PreTeXt types from lxml import etree as ET # noqa: N812 @@ -134,7 +133,7 @@ def requirements_version(dirpath: Optional[Path] = None) -> Optional[str]: return None try: with open(pp / "requirements.txt", "r") as f: - REGEX = r"\s*pretext(book)?(\[.*\])?\s*==\s*(?P[\d\.]*)\s*"gm + REGEX = r"\s*pretext(book)?(\[.*\])?\s*==\s*(?P[\d\.]+)\s*" for line in f.readlines(): match = re.match(REGEX, line) if match: diff --git a/tests/test_utils.py b/tests/test_utils.py index 998feda8..702e3dff 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -42,3 +42,32 @@ def test_is_unmodified() -> None: b"foo\n\nbar" ) assert utils.is_unmodified("foo", magic_comment) + + +def test_requirements_version(tmp_path: Path) -> None: + # Create a minimal project.ptx so project_path() can find the project root + (tmp_path / "project.ptx").write_text("") + + cases = [ + ("pretext == 2.36.0", "2.36.0"), + ("pretextbook == 1.2.3", "1.2.3"), + ("pretext[prefigure] == 2.36.0", "2.36.0"), + (" pretext == 3.0.0 ", "3.0.0"), + ("pretext[prefigure,extra] == 0.9.1", "0.9.1"), + ] + + for line, expected in cases: + req_file = tmp_path / "requirements.txt" + req_file.write_text(line + "\n") + assert utils.requirements_version(tmp_path) == expected, f"Failed for: {line!r}" + + # Lines that should NOT match + non_matching = [ + "numpy == 1.0.0", + "pretext ==", + "pretext", + ] + for line in non_matching: + req_file = tmp_path / "requirements.txt" + req_file.write_text(line + "\n") + assert utils.requirements_version(tmp_path) is None, f"Should not match: {line!r}"