release: cut v1.0.0

Prepare the first public 1.0.0 release and finish the remaining CI hardening work.

Highlights:
- align Python, Rust, WASM, Conda, API, MCP, and docs version metadata to 1.0.0
- promote package metadata to Production/Stable and update stability/versioning docs for the stable series
- move the accumulated Unreleased notes into a dated 1.0.0 changelog section and keep a fresh top-level Unreleased block
- strengthen the changelog checker so it validates a single top-level Unreleased section
- fix the CI/package support mismatch by declaring Python >=3.10 consistently and gating pandas-ta extras to Python 3.12+
- restore Sphinx autodoc compatibility for documented ferro_ta.<module> imports by registering module aliases
- make the TA-Lib benchmark guardrail less flaky by checking median and tail-percentile speedups instead of failing on a single mild outlier
- switch PyPI publishing to OIDC-only trusted publishing and wire the changelog check into the required CI gate
- apply the Ruff-driven cleanup across the Python and test tree and refresh uv/cargo lockfiles

Validated locally:
- python3 scripts/check_changelog.py
- uv run --with ruff ruff check python tests
- uv run --with ruff ruff format --check python tests
- uv lock --check
- sphinx-build -b html docs docs/_build -W --keep-going
- build/install the ferro_ta 1.0.0 wheel successfully
This commit is contained in:
Pratik Bhadane
2026-03-23 23:57:30 +05:30
parent 7a5a220dfe
commit 307beeca02
47 changed files with 1822 additions and 573 deletions
+39 -6
View File
@@ -1,10 +1,32 @@
"""Unit tests for ferro_ta.indicators.math_ops"""
import numpy as np
import pytest
from ferro_ta.indicators.math_ops import (
ADD, SUB, MULT, DIV, SUM, MAX, MIN, MAXINDEX, MININDEX,
ACOS, ASIN, ATAN, CEIL, COS, COSH, EXP, FLOOR,
LN, LOG10, SIN, SINH, SQRT, TAN, TANH,
ACOS,
ADD,
ASIN,
ATAN,
CEIL,
COS,
COSH,
DIV,
EXP,
FLOOR,
LN,
LOG10,
MAX,
MAXINDEX,
MIN,
MININDEX,
MULT,
SIN,
SINH,
SQRT,
SUB,
SUM,
TAN,
TANH,
)
# ---------------------------------------------------------------------------
@@ -14,17 +36,18 @@ from ferro_ta.indicators.math_ops import (
A3 = np.array([1.0, 2.0, 3.0])
B3 = np.array([4.0, 5.0, 6.0])
TRIG = np.array([0.0, np.pi / 6, np.pi / 4, np.pi / 3, np.pi / 2])
UNIT = np.array([0.0, 0.25, 0.5, 0.75, 1.0]) # values in [0,1] for ASIN/ACOS
UNIT = np.array([0.0, 0.25, 0.5, 0.75, 1.0]) # values in [0,1] for ASIN/ACOS
RNG = np.random.default_rng(17)
N = 100
_ARR = 1.0 + RNG.random(N) * 9.0 # positive values in (1, 10]
_ARR = 1.0 + RNG.random(N) * 9.0 # positive values in (1, 10]
# ---------------------------------------------------------------------------
# ADD
# ---------------------------------------------------------------------------
class TestADD:
def test_known_values(self):
result = ADD(A3, B3)
@@ -41,6 +64,7 @@ class TestADD:
# SUB
# ---------------------------------------------------------------------------
class TestSUB:
def test_known_values(self):
result = SUB(B3, A3)
@@ -54,6 +78,7 @@ class TestSUB:
# MULT
# ---------------------------------------------------------------------------
class TestMULT:
def test_known_values(self):
result = MULT(A3, B3)
@@ -70,6 +95,7 @@ class TestMULT:
# DIV
# ---------------------------------------------------------------------------
class TestDIV:
def test_known_values(self):
result = DIV(B3, A3)
@@ -86,6 +112,7 @@ class TestDIV:
# SUM
# ---------------------------------------------------------------------------
class TestSUM:
def test_known_values(self):
arr = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
@@ -106,6 +133,7 @@ class TestSUM:
# MAX
# ---------------------------------------------------------------------------
class TestMAX:
def test_known_values(self):
arr = np.array([1.0, 3.0, 2.0, 5.0, 4.0])
@@ -127,6 +155,7 @@ class TestMAX:
# MIN
# ---------------------------------------------------------------------------
class TestMIN:
def test_known_values(self):
arr = np.array([5.0, 3.0, 4.0, 1.0, 2.0])
@@ -143,6 +172,7 @@ class TestMIN:
# MAXINDEX
# ---------------------------------------------------------------------------
class TestMAXINDEX:
def test_known_values(self):
arr = np.array([1.0, 5.0, 3.0, 2.0, 4.0])
@@ -162,6 +192,7 @@ class TestMAXINDEX:
# MININDEX
# ---------------------------------------------------------------------------
class TestMININDEX:
def test_known_values(self):
arr = np.array([5.0, 1.0, 3.0, 2.0, 4.0])
@@ -181,6 +212,7 @@ class TestMININDEX:
# Trig functions
# ---------------------------------------------------------------------------
class TestSIN:
def test_known_values(self):
angles = np.array([0.0, np.pi / 2, np.pi])
@@ -236,6 +268,7 @@ class TestTANH:
# Rounding/exponential
# ---------------------------------------------------------------------------
class TestCEIL:
def test_known_values(self):
arr = np.array([1.1, 2.5, 3.9, -0.5])