From fe0ebd95f67e7a443628de82e025bf374ae91301 Mon Sep 17 00:00:00 2001 From: Steven Clontz Date: Sat, 17 Jan 2026 15:55:03 -0600 Subject: [PATCH 1/6] Refactor version extraction with regex Updated version extraction logic from requirements.txt to use regex. --- pretext/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pretext/utils.py b/pretext/utils.py index 86b2b6e0..ecfb99ad 100644 --- a/pretext/utils.py +++ b/pretext/utils.py @@ -16,6 +16,7 @@ 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 @@ -133,9 +134,10 @@ 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 for line in f.readlines(): - if ("pretext ==" in line) or ("pretextbook ==" in line): - return line.split("==")[1].strip() + if re.match(REGEX, line): + return re.match(REGEX, line).group("version") except Exception as e: log.debug("Could not read `requirements.txt`:") log.debug(e) From 9daf62491702d9301df6fb86be3fcbb97e3d8759 Mon Sep 17 00:00:00 2001 From: Oscar Levin Date: Wed, 4 Mar 2026 19:15:23 -0700 Subject: [PATCH 2/6] Update pretext/utils.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pretext/utils.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pretext/utils.py b/pretext/utils.py index ecfb99ad..b6890305 100644 --- a/pretext/utils.py +++ b/pretext/utils.py @@ -136,8 +136,9 @@ def requirements_version(dirpath: Optional[Path] = None) -> Optional[str]: with open(pp / "requirements.txt", "r") as f: REGEX = r"\s*pretext(book)?(\[.*\])?\s*==\s*(?P[\d\.]*)\s*"gm for line in f.readlines(): - if re.match(REGEX, line): - return re.match(REGEX, line).group("version") + match = re.match(REGEX, line) + if match: + return match.group("version") except Exception as e: log.debug("Could not read `requirements.txt`:") log.debug(e) From 5e47f3e66044c665fc413dc3ca644e366d729027 Mon Sep 17 00:00:00 2001 From: Oscar Levin Date: Wed, 4 Mar 2026 19:17:11 -0700 Subject: [PATCH 3/6] Update pretext/utils.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pretext/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pretext/utils.py b/pretext/utils.py index b6890305..eddd30fb 100644 --- a/pretext/utils.py +++ b/pretext/utils.py @@ -134,7 +134,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*"gm for line in f.readlines(): match = re.match(REGEX, line) if match: From 8671c2e1956e8d94f1ffcbd312a71573eaf8f490 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 4 Mar 2026 19:26:41 -0700 Subject: [PATCH 4/6] Fix regex-based version extraction in requirements.txt parsing (#1122) * Initial plan * Fix review comments: remove duplicate import, fix regex syntax, add tests Co-authored-by: oscarlevin <6504596+oscarlevin@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: oscarlevin <6504596+oscarlevin@users.noreply.github.com> Co-authored-by: Oscar Levin --- 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 eddd30fb..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}" From 1b8c43d74630dab414144d74e9b9d0ca806d3e24 Mon Sep 17 00:00:00 2001 From: Oscar Levin Date: Fri, 6 Mar 2026 21:03:26 -0700 Subject: [PATCH 5/6] format --- tests/test_utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 702e3dff..489812d5 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -70,4 +70,6 @@ def test_requirements_version(tmp_path: Path) -> None: 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}" + assert ( + utils.requirements_version(tmp_path) is None + ), f"Should not match: {line!r}" From 3bd8a1b6e877a2ffbdf8cc45756b51aea6fc6e37 Mon Sep 17 00:00:00 2001 From: Oscar Levin Date: Fri, 6 Mar 2026 21:20:05 -0700 Subject: [PATCH 6/6] lint --- pretext/utils.py | 4 ++-- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pretext/utils.py b/pretext/utils.py index 0e7a61f8..27772d87 100644 --- a/pretext/utils.py +++ b/pretext/utils.py @@ -133,9 +133,9 @@ 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*" + regex = r"\s*pretext(book)?(\[.*\])?\s*==\s*(?P[\d\.]+)\s*" for line in f.readlines(): - match = re.match(REGEX, line) + match = re.match(regex, line) if match: return match.group("version") except Exception as e: diff --git a/pyproject.toml b/pyproject.toml index 1c2ca4af..5c8e106e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ # ---------------- [tool.poetry] name = "pretext" -version = "2.36.1" +version = "2.37.2" description = "A package to author, build, and deploy PreTeXt projects." readme = "README.md" homepage = "https://pretextbook.org"