Skip to content

feat(api): expose trend_analysis at top level (broken — listed in __all__ but unimportable) #81

Open

Description

@BnJam

Problem

trend_analysis is listed in __all__ at python/eo_processor/__init__.py:151 and documented as a public top-level function in the README, but it is neither imported from ._core nor defined as a wrapper anywhere in __init__.py.

This means:

  • from eo_processor import trend_analysis → ImportError
  • from eo_processor import * → ImportError (star-import resolves every name in __all__, and trend_analysis is unbound)
  • The README itself works around the bug by telling users to import from the private module: from eo_processor._core import trend_analysis

This directly violates the project's own invariant from skills/python-api-surface/SKILL.md: "if it's public, it must be importable, typed, tested, and documented."

The Rust kernel works

The function is fully implemented in src/trends.rs:20 and registered into _core at src/lib.rs:100. Only the Python public surface is broken.

Scope

File Change
python/eo_processor/__init__.py Add trend_analysis as _trend_analysis and TrendSegment as _TrendSegment to the from ._core import (...) block. Add a thin wrapper def trend_analysis(y, threshold): ... following the existing pattern (e.g. linear_regression at ~line 349).
python/eo_processor/__init__.pyi Add stub for trend_analysis(y: Sequence[float], threshold: float) -> list[TrendSegment]: ... and a class TrendSegment matching the Rust struct fields (start_index, end_index, slope, intercept).
tests/test_trends.py Add tests: no-break case (large threshold → single segment), a break case (linspace(0,10,50) + linspace(10,0,50) → ≥2 segments), invalid inputs (negative threshold, NaN in y).
README.md:321 Replace from eo_processor._core import trend_analysis with from eo_processor import trend_analysis.

Acceptance criteria

  • from eo_processor import trend_analysis works
  • from eo_processor import * works (no ImportError)
  • Type stub present in __init__.pyi
  • At least 3 tests covering the function
  • README import example updated to use the public API
  • ruff check python/eo_processor/ passes
  • CI green

Version impact

Per the project's SemVer section: exposing a previously-unexported-but-documented function is a minor bump (new public surface, backward-compatible).


Note: A bump:minor label will be needed on the PR to trigger the automated version bump and release pipeline.

Activity

  1. BnJam commented on Aug 1, 2026

    @BnJam
    OwnerAuthor

    Starting work on this issue. Plan: import trend_analysis/TrendSegment from _core into python/eo_processor/init.py, add a thin wrapper following the linear_regression pattern, add the type stub and TrendSegment class to init.pyi, add tests in tests/test_trends.py, and update the README import example to use the public API.

  2. BnJam commented on Aug 1, 2026

    @BnJam
    OwnerAuthor

    Opened PR: #82

  3. BnJam commented on Aug 1, 2026

    @BnJam
    OwnerAuthor

    technocore completed pipeline issue-handler.

    Now let me look at the Rust implementation, the stub, tests, and README.
    Now let me check the Sphinx docs and skills mentioned in the issue, plus how linear_regression is exposed.
    Now let me check the environment for running tests.
    No Python/Rust toolchain locally, so I'll rely on careful review + CI. Let me check CI and tox for what gates run.
    Now let me implement. First, the import block in __init__.py:
    Now add the wrapper near linear_regression (line 349):
    Now the type stub __init__.pyi:
    Now the tests in tests/test_trends.py:
    Now the README fixes:
    All private imports fixed. Let me verify the final state of the changed files:
    Let me verify CoreError maps to ValueError in Python, since the tests rely on it:
    Let me add a star-import regression test, which directly validates acceptance criterion #2:
    Now let me review final state of all changed files and check for any other references:
    All changes complete. Now create the branch, commit, and push:
    PR created. Now add the bump:minor label and post the PR URL on the issue:
    Done. PR: #82

    Fix summary:

    • python/eo_processor/__init__.py: imported trend_analysis as _trend_analysis and TrendSegment as _TrendSegment from ._core, added the thin trend_analysis(y, threshold) wrapper (mirroring linear_regression at __init__.py:349) and a TrendSegment = _TrendSegment alias. This binds the name in __all__ (line 151), fixing both from eo_processor import trend_analysis and star-imports.
    • __init__.pyi: added class TrendSegment (start_index, end_index, slope, intercept) and the trend_analysis(y: Sequence[float], threshold: float) -> list[TrendSegment] stub.
    • tests/test_trends.py: 5 tests — no-break single segment, break detection (≥2 segments), negative threshold rejection, NaN rejection, and a star-import regression test.
    • README.md + docs/source/README.md: replaced the eo_processor._core workaround with the public import.

    No local Python/Rust toolchain exists in this environment, so I couldn't run ruff/pytest locally; CI (tox lint + py tests) will verify. Added the bump:minor label to the PR to trigger the automated version bump/release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions