From 9075c86842762aaacb2500192d6f0d1df6a20a89 Mon Sep 17 00:00:00 2001 From: Stefan Jansen Date: Mon, 7 Sep 2026 13:02:50 -0400 Subject: [PATCH 1/2] ml4t-coursework 0.3.0 The long panel, the runner, market specs, and contracts that no longer name a Foundations unit. data_panel returns (date, asset) rows with a close column instead of a wide frame, which is why this is a minor bump rather than a patch: anything calling it has to unstack. setup() also falls back instead of raising where google.colab imports but no Drive can be mounted, which is what blocks three Foundations notebooks on the published Colab image today. The version is declared in two places and a test now compares them: the run row records the module's value, the wheel metadata carries pyproject's, and the release workflow only checks the tag against the module. --- pyproject.toml | 2 +- src/ml4t_coursework/__init__.py | 2 +- tests/test_helper.py | 15 +++++++++++++++ uv.lock | 2 +- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 181d25a..e09fee5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "ml4t-coursework" -version = "0.2.0" +version = "0.3.0" description = "Project folder, component conformance checks and results log for the ML4T courses" readme = "README.md" requires-python = ">=3.10" diff --git a/src/ml4t_coursework/__init__.py b/src/ml4t_coursework/__init__.py index d509d7b..2fe5b65 100644 --- a/src/ml4t_coursework/__init__.py +++ b/src/ml4t_coursework/__init__.py @@ -11,7 +11,7 @@ rather than for a course, because more than one course installs it. """ -__version__ = "0.2.0" +__version__ = "0.3.0" from .components import catalog, load_component, save_component, source_of, status from .contracts import add_source diff --git a/tests/test_helper.py b/tests/test_helper.py index 95666e1..2e1171c 100644 --- a/tests/test_helper.py +++ b/tests/test_helper.py @@ -206,3 +206,18 @@ def test_the_fingerprint_check_reads_the_columns_the_fingerprint_has(): assert "checked 100 of 100" in text assert "Worth a look" in text, "400 random sessions should not look like the course's panel" assert set(reference.columns) >= {"sessions", "annualized_vol", "mean_abs_return"} + + +def test_the_declared_version_and_the_packaged_version_agree(): + """`helper_version` on every run row comes from the module, the wheel's metadata comes from + pyproject, and the release workflow checks the tag against the module only. Two static strings + that nothing compares will drift, and a student's recorded version would then name something + pip never installed.""" + import tomllib + from pathlib import Path + + import ml4t_coursework + + pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml" + declared = tomllib.loads(pyproject.read_text())["project"]["version"] + assert ml4t_coursework.__version__ == declared diff --git a/uv.lock b/uv.lock index 67f3e35..dbb5402 100644 --- a/uv.lock +++ b/uv.lock @@ -715,7 +715,7 @@ wheels = [ [[package]] name = "ml4t-coursework" -version = "0.2.0" +version = "0.3.0" source = { editable = "." } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, From 73ada43e43b56a9ddfa69e53a2844e3937a5abfe Mon Sep 17 00:00:00 2001 From: Stefan Jansen Date: Mon, 7 Sep 2026 13:07:45 -0400 Subject: [PATCH 2/2] The version test reads installed metadata, not pyproject tomllib is 3.11+ and this package supports 3.10, so the first version failed the matrix on every platform. Reading importlib.metadata compares the module against what pip reports, which is the number that matters and also catches a build stale against the source. --- tests/test_helper.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/test_helper.py b/tests/test_helper.py index 2e1171c..9d9419f 100644 --- a/tests/test_helper.py +++ b/tests/test_helper.py @@ -208,16 +208,14 @@ def test_the_fingerprint_check_reads_the_columns_the_fingerprint_has(): assert set(reference.columns) >= {"sessions", "annualized_vol", "mean_abs_return"} -def test_the_declared_version_and_the_packaged_version_agree(): - """`helper_version` on every run row comes from the module, the wheel's metadata comes from - pyproject, and the release workflow checks the tag against the module only. Two static strings - that nothing compares will drift, and a student's recorded version would then name something - pip never installed.""" - import tomllib - from pathlib import Path +def test_the_declared_version_and_the_installed_version_agree(): + """`helper_version` on every run row comes from the module, the distribution metadata comes + from pyproject, and the release workflow checks the tag against the module only. Two static + strings that nothing compares will drift, and a student's recorded version would then name + something pip never installed. Reading the metadata rather than pyproject also catches a build + that is stale against the source tree.""" + from importlib.metadata import version import ml4t_coursework - pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml" - declared = tomllib.loads(pyproject.read_text())["project"]["version"] - assert ml4t_coursework.__version__ == declared + assert ml4t_coursework.__version__ == version("ml4t-coursework")