Skip to content

Fix CI failures: TOML syntax error, asm_spread typo, missing plotting module#11

Merged
zachessesjohnson merged 3 commits intomainfrom
copilot/fix-toml-syntax-error
Mar 10, 2026
Merged

Fix CI failures: TOML syntax error, asm_spread typo, missing plotting module#11
zachessesjohnson merged 3 commits intomainfrom
copilot/fix-toml-syntax-error

Conversation

Copy link
Contributor

Copilot AI commented Mar 10, 2026

pytest CI was failing before any tests ran due to a TOML syntax error in pyproject.toml, and two additional issues prevented test_plotting.py and test_yield_curve.py from collecting.

Changes

  • pyproject.toml: Removed duplicate include key (TOML disallows duplicate keys in the same table). Also removed the broken sovereign_debt_py* namespace entry — where = ["."] was resolving sovereign_debt_py to the sub-project root directory rather than the inner Python package, making all sovereign_debt_py.* imports fail silently.

  • sovereign_debt_xl/yield_curve.py: Renamed asm_spreadasw_spread (typo; tests and docstring both referenced asw_spread).

  • sovereign_debt_py/sovereign_debt_py/plotting/: Created new subpackage required by test_plotting.py:

    • core.pyto_1d_array, validate_same_length, coerce_dates
    • __init__.pyplot_yield_curve, plot_timeseries, plot_rolling_average, plot_spread, plot_fan_chart, fig_to_png_bytes; all return (fig, ax) tuples
  • .github/workflows/pytest.yml: Added pip install -e sovereign_debt_py/ — the sub-project was never installed by the root pip install -e ., so sovereign_debt_py was only accessible as a broken namespace package.


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copilot AI and others added 2 commits March 10, 2026 22:56
Co-authored-by: zachessesjohnson <168567202+zachessesjohnson@users.noreply.github.com>
…tall step

Co-authored-by: zachessesjohnson <168567202+zachessesjohnson@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix TOML syntax error in pyproject.toml Fix CI failures: TOML syntax error, asm_spread typo, missing plotting module Mar 10, 2026
@zachessesjohnson zachessesjohnson marked this pull request as ready for review March 10, 2026 23:04
Copilot AI review requested due to automatic review settings March 10, 2026 23:04
@zachessesjohnson zachessesjohnson merged commit ff02d10 into main Mar 10, 2026
6 checks passed
@zachessesjohnson zachessesjohnson deleted the copilot/fix-toml-syntax-error branch March 10, 2026 23:06
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses CI/test collection failures by fixing packaging configuration, correcting a yield-curve function typo, and adding the missing sovereign_debt_py.plotting module required by the plotting tests.

Changes:

  • Fix root pyproject.toml TOML packaging config by removing a duplicate/incorrect include entry.
  • Rename asm_spreadasw_spread in sovereign_debt_xl.yield_curve.
  • Add new sovereign_debt_py.plotting subpackage and install the subproject in CI.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
pyproject.toml Removes invalid duplicate include entry so packaging/CI can parse TOML.
sovereign_debt_xl/yield_curve.py Fixes ASW spread function typo to match intended naming/tests.
sovereign_debt_py/sovereign_debt_py/plotting/core.py Adds shared validation/coercion helpers for plotting APIs.
sovereign_debt_py/sovereign_debt_py/plotting/__init__.py Implements plotting helpers expected by test_plotting.py.
.github/workflows/pytest.yml Installs the sovereign_debt_py subproject so its tests/modules import correctly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

name="SOV_ASW_SPREAD",
)
def asm_spread(
def asw_spread(
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming this public function fixes the typo, but it is a breaking change for any Python callers importing/using asm_spread directly (sovereign_debt_xl re-exports everything from yield_curve). Consider keeping a backwards-compatible asm_spread alias (optionally with a deprecation warning) to avoid breaking existing users.

Copilot uses AI. Check for mistakes.
Comment on lines +11 to +15
from typing import Any

import matplotlib

matplotlib.use("Agg") # headless – must come before pyplot import
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling matplotlib.use("Agg") at import time in this package can raise an ImportError or otherwise misbehave if matplotlib.pyplot has already been imported by the caller (e.g., tests import pyplot before importing sovereign_debt_py.plotting). Consider removing this global backend switch from the library, or guarding it so it only runs when pyplot is not yet imported / backend not already set.

Suggested change
from typing import Any
import matplotlib
matplotlib.use("Agg") # headless – must come before pyplot import
import sys
from typing import Any
import matplotlib
# Use a non-interactive backend by default in headless environments, but
# avoid changing the backend if matplotlib.pyplot has already been imported
# by the caller, which could otherwise raise an ImportError or misbehave.
if "matplotlib.pyplot" not in sys.modules:
matplotlib.use("Agg") # headless – must come before pyplot import

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +75
if fig is None or ax is None:
fig, ax = plt.subplots()
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fig/ax handling here uses if fig is None or ax is None: which will silently discard a provided fig (or ax) when only one is passed. Consider either requiring both fig and ax together (raise if only one is provided) or deriving the missing one (e.g., if ax is provided use ax.figure).

Suggested change
if fig is None or ax is None:
fig, ax = plt.subplots()
if fig is None and ax is None:
fig, ax = plt.subplots()
elif fig is None and ax is not None:
fig = ax.figure
elif fig is not None and ax is None:
ax = fig.gca()

Copilot uses AI. Check for mistakes.
Comment on lines +186 to +187
for i in range(window - 1, len(v_arr)):
rolling[i] = float(np.mean(v_arr[i - window + 1: i + 1]))
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rolling-average computation is implemented with a Python loop, which will be noticeably slow for larger series. This can be vectorized with NumPy (e.g., via cumulative sums or convolution) to keep runtime O(n) in C rather than Python.

Suggested change
for i in range(window - 1, len(v_arr)):
rolling[i] = float(np.mean(v_arr[i - window + 1: i + 1]))
# Vectorized rolling mean using convolution for performance
kernel = np.ones(window, dtype=float) / window
rolling_valid = np.convolve(v_arr.astype(float), kernel, mode="valid")
rolling[window - 1:] = rolling_valid

Copilot uses AI. Check for mistakes.
Comment on lines +129 to +132
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(
mdates.AutoDateFormatter(mdates.AutoDateLocator())
)
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutoDateLocator() is instantiated twice (once for the locator and again for the formatter). The formatter should usually be constructed with the same locator instance used on the axis; otherwise tick formatting can drift from the actual tick locations.

Suggested change
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(
mdates.AutoDateFormatter(mdates.AutoDateLocator())
)
locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

Copilot uses AI. Check for mistakes.
Comment on lines +193 to +196
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(
mdates.AutoDateFormatter(mdates.AutoDateLocator())
)
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same AutoDateLocator/AutoDateFormatter mismatch as in plot_timeseries: the formatter is created with a new locator instance instead of the one set on the axis. Reusing a single locator instance avoids inconsistent tick formatting.

Suggested change
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(
mdates.AutoDateFormatter(mdates.AutoDateLocator())
)
locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

Copilot uses AI. Check for mistakes.
Comment on lines +252 to +255
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(
mdates.AutoDateFormatter(mdates.AutoDateLocator())
)
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same AutoDateLocator/AutoDateFormatter mismatch as in plot_timeseries: the formatter is created with a new locator instance instead of the one set on the axis. Reusing a single locator instance avoids inconsistent tick formatting.

Suggested change
ax.xaxis.set_major_locator(mdates.AutoDateLocator())
ax.xaxis.set_major_formatter(
mdates.AutoDateFormatter(mdates.AutoDateLocator())
)
locator = mdates.AutoDateLocator()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(locator))

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants