From 4c945c5fd53e1aa722fa126f46cc0622e050d72f Mon Sep 17 00:00:00 2001 From: PredictiveManish Date: Fri, 27 Feb 2026 21:24:01 +0530 Subject: [PATCH 1/3] Added README python test --- tests/test_readme_examples.py | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 tests/test_readme_examples.py diff --git a/tests/test_readme_examples.py b/tests/test_readme_examples.py new file mode 100644 index 00000000..6d5db962 --- /dev/null +++ b/tests/test_readme_examples.py @@ -0,0 +1,40 @@ +import os +import re +from pathlib import Path + +README_PATH = Path(__file__).resolve().parents[1] / "README.md" + +def _extract_python_blocks(markdown_text: str) -> list[str]: + pattern = re.compiler(r"```python\s*(.*?)```", re.DOTALL) + return [block.strip() for block in pattern.findall(markdown_text)] + + +def test_readme_python_examples_run(tmp_path): + readme_text=README_PATH.read_text(encoding="utf-8") + assert python_blocks, "No python code blocks found in README.md" + + repo_root = README_PATH.parent + + for idx, block in enumerate(python_blocks, start=1): + # Run each block in isolation + globals_dict = {"__name__":"__main__"} + locals_dict = {} + + # Execute from a temp working directory so any writes are isolated + old_cwd = os.getcwd() + try: + os.chdir(tmp_path) + # Ensure relative paths in README still resolve from repo root + globals_dict["__file__"] = str(README_PATH) + globals_dict["REPO_ROOT"] = str(repo_root) + + exec(block, globals_dict, locals_dict) + + except Exception as e: + raise AssertionError( + f"README python block #{idx} failed:\n{block}\n" + ) from e + finally: + os.chdir(old_cwd) + + From a7a19fe55757c79335b94a69c85700119a3df143 Mon Sep 17 00:00:00 2001 From: PredictiveManish Date: Fri, 27 Feb 2026 21:33:37 +0530 Subject: [PATCH 2/3] Updated breaking points --- tests/test_readme_examples.py | 57 ++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/tests/test_readme_examples.py b/tests/test_readme_examples.py index 6d5db962..06c6a5b3 100644 --- a/tests/test_readme_examples.py +++ b/tests/test_readme_examples.py @@ -1,40 +1,41 @@ import os import re -from pathlib import Path +import sys +from pathlib import Path + +README_PATH = Path(__file__).resolve().parent.parent / "README.md" -README_PATH = Path(__file__).resolve().parents[1] / "README.md" def _extract_python_blocks(markdown_text: str) -> list[str]: - pattern = re.compiler(r"```python\s*(.*?)```", re.DOTALL) + pattern = re.compile(r"```python[^\n]*\n(.*?)```", re.DOTALL) return [block.strip() for block in pattern.findall(markdown_text)] -def test_readme_python_examples_run(tmp_path): - readme_text=README_PATH.read_text(encoding="utf-8") +def test_readme_python_examples_run(): + readme_text = README_PATH.read_text(encoding="utf-8") + python_blocks = _extract_python_blocks(readme_text) + assert python_blocks, "No python code blocks found in README.md" repo_root = README_PATH.parent - for idx, block in enumerate(python_blocks, start=1): - # Run each block in isolation - globals_dict = {"__name__":"__main__"} - locals_dict = {} - - # Execute from a temp working directory so any writes are isolated - old_cwd = os.getcwd() - try: - os.chdir(tmp_path) - # Ensure relative paths in README still resolve from repo root - globals_dict["__file__"] = str(README_PATH) - globals_dict["REPO_ROOT"] = str(repo_root) - - exec(block, globals_dict, locals_dict) - - except Exception as e: - raise AssertionError( - f"README python block #{idx} failed:\n{block}\n" - ) from e - finally: - os.chdir(old_cwd) - - + # Make package importable + sys.path.insert(0, str(repo_root)) + + # Run from repo root so relative paths work + old_cwd = os.getcwd() + os.chdir(repo_root) + + globals_dict = {"__name__": "__main__"} + + try: + for idx, block in enumerate(python_blocks, start=1): + exec(block, globals_dict) + + except Exception as e: + raise AssertionError( + f"README python block #{idx} failed:\n{block}" + ) from e + + finally: + os.chdir(old_cwd) \ No newline at end of file From 766ab5f2a4cfaa86b6143d62cc9ff6205e7928c6 Mon Sep 17 00:00:00 2001 From: PredictiveManish Date: Fri, 27 Feb 2026 23:56:42 +0530 Subject: [PATCH 3/3] style: apply ruff formatting --- tests/test_discrete_allocation.py | 2 +- tests/test_efficient_frontier.py | 4 ++-- tests/test_readme_examples.py | 8 +++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tests/test_discrete_allocation.py b/tests/test_discrete_allocation.py index 3feca96d..f0953186 100644 --- a/tests/test_discrete_allocation.py +++ b/tests/test_discrete_allocation.py @@ -1,7 +1,7 @@ +from cvxpy.error import SolverError import numpy as np import pandas as pd import pytest -from cvxpy.error import SolverError from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices from tests.utilities_for_tests import get_data, setup_efficient_frontier diff --git a/tests/test_efficient_frontier.py b/tests/test_efficient_frontier.py index 4028e1a7..038788e0 100644 --- a/tests/test_efficient_frontier.py +++ b/tests/test_efficient_frontier.py @@ -608,7 +608,7 @@ def test_min_vol_pair_constraint(): ef.min_volatility() old_sum = ef.weights[:2].sum() ef = setup_efficient_frontier() - ef.add_constraint(lambda w: (w[1] + w[0] <= old_sum / 2)) + ef.add_constraint(lambda w: w[1] + w[0] <= old_sum / 2) ef.min_volatility() new_sum = ef.weights[:2].sum() assert new_sum <= old_sum / 2 + 1e-4 @@ -620,7 +620,7 @@ def test_max_sharpe_pair_constraint(): old_sum = ef.weights[:2].sum() ef = setup_efficient_frontier() - ef.add_constraint(lambda w: (w[1] + w[0] <= old_sum / 2)) + ef.add_constraint(lambda w: w[1] + w[0] <= old_sum / 2) ef.max_sharpe(risk_free_rate=0.02) new_sum = ef.weights[:2].sum() assert new_sum <= old_sum / 2 + 1e-4 diff --git a/tests/test_readme_examples.py b/tests/test_readme_examples.py index 06c6a5b3..12b77cbb 100644 --- a/tests/test_readme_examples.py +++ b/tests/test_readme_examples.py @@ -1,7 +1,7 @@ import os +from pathlib import Path import re import sys -from pathlib import Path README_PATH = Path(__file__).resolve().parent.parent / "README.md" @@ -33,9 +33,7 @@ def test_readme_python_examples_run(): exec(block, globals_dict) except Exception as e: - raise AssertionError( - f"README python block #{idx} failed:\n{block}" - ) from e + raise AssertionError(f"README python block #{idx} failed:\n{block}") from e finally: - os.chdir(old_cwd) \ No newline at end of file + os.chdir(old_cwd)