Skip to content

Flatten analytics/ subpackage to top-level jquantstats/#439

Merged
tschm merged 4 commits intomainfrom
copilot/flatten-analytics-subpackage
Mar 23, 2026
Merged

Flatten analytics/ subpackage to top-level jquantstats/#439
tschm merged 4 commits intomainfrom
copilot/flatten-analytics-subpackage

Conversation

Copy link
Contributor

Copilot AI commented Mar 23, 2026

Portfolio and its supporting modules were buried in an analytics/ subpackage, making the import hierarchy unnecessarily deep. This flattens everything to src/jquantstats/.

File moves

From To
analytics/portfolio.py portfolio.py
analytics/_portfolio_data.py _portfolio_data.py
analytics/_cost_model.py _cost_model.py
analytics/_plots.py _portfolio_plots.py (renamed — avoids clash with existing top-level _plots.py)
analytics/_report.py _report.py
analytics/exceptions.py exceptions.py
analytics/templates/ templates/

analytics/__init__.py and the analytics/ directory are deleted entirely.

Import changes

  • portfolio.py: from .._data / from .._statsfrom ._data / from ._stats; from ._plots import Plotsfrom ._portfolio_plots import Plots; deferred inline import updated likewise
  • __init__.py: from .analytics import CostModel/Portfoliofrom ._cost_model import CostModel / from .portfolio import Portfolio
  • exceptions.py: doctests updated from jquantstats.analytics.exceptions.*jquantstats.exceptions.*
  • All test files under test_analytics/: from jquantstats.analytics import …from jquantstats import …

Public API — unchanged

from jquantstats import Portfolio   # still works
from jquantstats import CostModel   # still works
Original prompt

Goal

Flatten the analytics/ subpackage so that the two core classes — Portfolio and PortfolioData — live at the top level of the package (src/jquantstats/), alongside the existing _data.py, _stats.py, etc. The supporting helpers (_plots.py, _report.py, _cost_model.py, exceptions.py) should also move up and lose their analytics. prefix.

Current structure

src/jquantstats/
├── __init__.py
├── _data.py
├── _plots.py          ← top-level plots (for Data/Stats)
├── _reports.py
├── _stats.py
├── _stats_basic.py
├── _stats_core.py
├── _stats_performance.py
├── _stats_reporting.py
├── _stats_rolling.py
├── _types.py
├── api.py
├── py.typed
└── analytics/
    ├── __init__.py
    ├── _cost_model.py
    ├── _plots.py      ← portfolio-specific plots (Plots class)
    ├── _portfolio_data.py
    ├── _report.py
    ├── exceptions.py
    ├── portfolio.py
    └── templates/
        ├── _base.html
        └── portfolio_report.html

Target structure

src/jquantstats/
├── __init__.py
├── _cost_model.py         ← moved from analytics/_cost_model.py
├── _data.py
├── _plots.py              ← top-level plots (for Data/Stats) — unchanged
├── _portfolio_plots.py    ← moved from analytics/_plots.py (renamed to avoid clash)
├── _portfolio_data.py     ← moved from analytics/_portfolio_data.py
├── _report.py             ← moved from analytics/_report.py
├── _reports.py
├── _stats.py
├── _stats_basic.py
├── _stats_core.py
├── _stats_performance.py
├── _stats_reporting.py
├── _stats_rolling.py
├── _types.py
├── api.py
├── exceptions.py          ← moved from analytics/exceptions.py
├── portfolio.py           ← moved from analytics/portfolio.py
├── py.typed
└── templates/             ← moved from analytics/templates/
    ├── _base.html
    └── portfolio_report.html

The analytics/ directory should be deleted entirely after the move.

Required import updates

All files must have their from .analytics.X / from ..X / from .X imports updated to reflect the new flat layout. Specifically:

portfolio.py (was analytics/portfolio.py)

  • from ._cost_model import CostModel (was from ._cost_model import CostModel — same relative name, just now at top level)
  • from ._portfolio_plots import Plots (was from ._plots import Plots)
  • from ._portfolio_data import PortfolioData (was from ._portfolio_data import PortfolioData)
  • from ._report import Report (was from ._report import Report)
  • from .exceptions import IntegerIndexBoundError (was from .exceptions import ...)
  • TYPE_CHECKING imports: from ._data import Data, from ._stats import Stats (were from .._data import Data, from .._stats import Stats)

_portfolio_data.py (was analytics/_portfolio_data.py)

  • from .exceptions import (...) (was from .exceptions import ... — same relative name, now top level)

_portfolio_plots.py (was analytics/_plots.py)

  • from .portfolio import Portfolio in the TYPE_CHECKING block (was from .portfolio import Portfolio — same relative name)

_report.py (was analytics/_report.py)

  • from .portfolio import Portfolio in the TYPE_CHECKING block (was from .portfolio import Portfolio)
  • _TEMPLATES_DIR = Path(__file__).parent / "templates" (was the same, now correctly points to src/jquantstats/templates/)

src/jquantstats/__init__.py

  • Replace from .analytics import CostModel as CostModelfrom ._cost_model import CostModel as CostModel
  • Replace from .analytics import Portfolio as Portfoliofrom .portfolio import Portfolio as Portfolio

exceptions.py (was analytics/exceptions.py)

  • The doctest references jquantstats.analytics.exceptions.MissingDateColumnError — update to jquantstats.exceptions.MissingDateColumnError

Notes

  • The existing top-level _plots.py is for Data/Stats plots and is unrelated to analytics/_plots.py (which is the Plots facade for Portfolio). To avoid the name clash, rename analytics/_plots.py_portfolio_plots.py.
  • The templates/ directory must be moved to src/jquantstats/templates/; the _TEMPLATES_DIR path in _report.py already uses Path(__file__).parent / "templates", so it will automatically resolve correctly once the file is at the top level.
  • The analytics/__init__.py should be deleted (it only re-exported CostModel and Portfolio, which are now directly importable).
  • Backward compatibility: from jquantstats import Portfolio and from jquantstats import CostModel must continue to work (they are re-exported from src/jquantstats/__init__.py). The subpackage path from jquantstats.analytics import Portfolio can be dropped.
  • Update any docstrings that reference jquantstats.analytics.* paths to reflect the new flat paths.
  • Check whether there are any test files importing from jquantstats.analytics.* and update them too.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: I think t...

This pull request was created from Copilot chat.


📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

@tschm tschm marked this pull request as ready for review March 23, 2026 14:17
Co-authored-by: tschm <2046079+tschm@users.noreply.github.com>
Agent-Logs-Url: https://github.com/tschm/jquantstats/sessions/fd5ca62f-558f-413c-9270-959a2f65d836
Copilot AI changed the title [WIP] Flatten analytics subpackage to top level Flatten analytics/ subpackage to top-level jquantstats/ Mar 23, 2026
Copilot AI requested a review from tschm March 23, 2026 14:27
tschm and others added 2 commits March 23, 2026 18:28
Fix stale import in analytics_demo.py (jquantstats.analytics no longer
exists after subpackage flattening) and bump marimo pin to 0.20.4 in
both notebooks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tschm tschm merged commit 17551ff into main Mar 23, 2026
22 checks passed
@tschm tschm deleted the copilot/flatten-analytics-subpackage branch March 23, 2026 14:36
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.

2 participants