Fix 1.1 release audit findings and complete documentation follow-ups - #286
Fix 1.1 release audit findings and complete documentation follow-ups#286jeremymanning wants to merge 49 commits into
Conversation
…coring loops The ultrareview of PR #286 flagged both 'from .common import ...' lines as loop-body imports with no circular-import reason (common.py does not import backtest.py). Module-scope imports match every sibling module. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e, attribute the unscored warning, score ragged return_score input Release-review findings on the 1.1 draft: - resolve_metrics() now raises ValueError naming a metric listed twice (case-insensitively) instead of a TypeError deep in build_scores(), for both predict(holdout=) and impute(truth=). - holdout=True with t=0 reports t=0 as the problem. - the 'left N scored value(s) missing' warning uses external_stacklevel() like every other user-facing warning in these modules. - align(return_score=True) works on ragged input that align() trims; the 'before' score is computed on the row-trimmed input (documented). Seven regression tests, each failing on the unfixed library. Also: RELEASE_CHECKLIST.md rewritten for the 1.1.0 re-cut (tag exists as a draft and must be moved; gallery namespace is republished wholesale; the example smoke gate is a manual step), and the session note for this review. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…al observables; export HypertoolsOfflineError - tests/predict/test_common.py: the all-identical-timestamps case is proven to come from the live _infer_step via the exception's own traceback and message, not a monkeypatched spy. - tests/predict/test_predict_multiindex.py: grouping helpers are checked through their real outputs and the returned per-group models, not by wrapping them with observers. - tests/test_names_display.py: notebook display timing is observed on a real in-process IPython.InteractiveShell with the json renderer captured through IPython's own capture_output; go.Figure.show is no longer patched. - HypertoolsOfflineError is importable from hypertools and hypertools.io like the other three exceptions (public-API pin test updated). - scripts/generate_baseline_screenshots.py points at the roadmap note that exists; trailing whitespace stripped from six tracked files so 'git diff --check v1.0.0..HEAD' is clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…defect markers, allowlist the deliberate ax= demos, gate the rebuilt tutorials' output cells Issue #284 claimed the DEFECT_MARKERS scan was tightened with a per-file allowlist for deliberate ax= demos and that every tutorial's measured output cells were recorded; the release review found the scan covered only the six launch scripts and six launch notebooks. - scan_for_defects(root) walks all 51 examples and every non-install code cell of all 25 tutorials (install cells hold the legitimate find_spec('hypertools') guard); a planted-marker test proves it. - new ax= marker (hand-built axes, raw ax.plot/scatter, plt.subplots) with a counted DEFECT_ALLOWLIST so a new use in an allowlisted file still fails and a stale entry is reported. - EXPECTED_VISIBLE_OUTPUTS gains the eight rebuilt tutorials; the ran-every-cell / right-cells / no-error-output tests cover all 14. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…le, colour, loader and text paths
Plot (22 findings, 53 regression tests):
- palette= lists shorter than the dataset count cycle again with no hue
(1.0 behaviour); empty palettes raise ValueError, not StopIteration;
per-dataset {category: color} dict entries merge by name; NaN in a
continuous hue no longer poisons the colour range; legend_kwargs
fontsize is honoured with font=; blend categories are RGB.
- dataset_fade= and on_frame artist mutations reach the LineCollections
drawn under a continuous hue; loop=True accepts the documented
2(n+1)-1 rotations list; companion= panels and {index} titles advance
monotonically under order='serial'; window_bounds.start reflects the
comet-head window; bad companion=/dataset_fade= values name the kwarg;
a raising on_frame during .save() surfaces its own exception; a raising
title= leaves no orphaned animation.
- title_wrap= applies to dynamic titles and keeps explicit newlines;
plotly draws newline titles as line breaks and reserves top margin per
title line and size; nested tuple labels= annotate; bare-string labels,
bad label_anchor=, non-string title entries/callables, title_color vs
title_kwargs colour conflicts and bad {index} formats raise clearly.
IO / tools (10 findings):
- load(offline=True) opens no connection: URLs skip the seaborn listing,
the listing fetch has a timeout and a remembered failure, uncacheable
sources raise HypertoolsOfflineError.
- yahoo: bars carry the exchange-local trading day (gmtoffset applied).
- synthetic datasets accept RandomState, Generator, SeedSequence and
np.integer seeds everywhere; a reused SeedSequence is reproducible;
n_datasets rejects non-integral values; streaming=True on a
non-Hugging-Face source raises instead of returning everything.
- text2mat: a flat list of strings is one dataset (was [(N,d),(0,d),...]
since 1.0), ragged nested lists work, mixed inputs raise; a dict
semantic= spec with a gensim vectorizer warns and skips.
- text_windows accepts numpy integers.
- format_data warnings are attributed to the caller's line
(external_stacklevel), so notebooks stop printing the library path.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Manipulator.fit() and Aligner.fit() returned None, so Smooth().fit(x).transform(y) and HyperAlign().fit(xs).transform(ys) raised AttributeError; Imputer.fit() already returned self. Both now return the fitted instance on every path (documented), with a chaining test over Normalize/ZScore/Smooth/Resample/Delay, HyperAlign/Procrustes/ NullAlign and PPCA on real data. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- CHANGELOG: 'Fixed during the release review' subsection (every fix
since the draft), predict(metrics=/per_column=/return_forecasts=),
impute(return_imputed=), load(**source_kwargs) documented; the
unsupported '138 examples executed' claim reworded to what the tests do.
- readme: dependency floors match pyproject exactly (pillow added);
'1.0 API' wording updated for 1.x.
- api.rst: HypertoolsOfflineError and HypertoolsTrustError listed with
their autosummary stubs.
- conf.py: gallery pages' furo view/edit links point at the source
example under examples/ (auto_examples/ is gitignored, so they 404'd);
stale chemtrails/precog comment fixed.
- tutorials.rst + market_sectors prose use model='HyperAlign' like the code.
- notebooks (sources only; re-executed separately): 'hyper' marked as a
deprecated alias (analyze, plot); Normalize(mode='isotropic') section
(manip); alignment illustration restored (align); legend= form for the
hue demo (text); hyp.load('wikipedia:...') replaces the wikipedia-api
cells (wikipedia_embeddings).
- scripts/execute_tutorial.py scrubs the executing user's home directory
from stored outputs so notebooks stop leaking developer paths.
- tests/AGENTS.md no longer claims the hierarchy guide's doctests run in
the suite; hypertools/io/lsl.py numpydoc underline fixed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… into the summary so numpydoc stops warning Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…gs from the 1.1 release review - forecasters carry min_history (ARIMA from its order); fit raises a clear ValueError on a shorter history; the animated forecast schedule waits for enough revealed rows, so predict='ARIMA' (and model lists) no longer crash under animate= with a statsmodels IndexError. - a datetime-like t= works inside hyp.plot; predict= collections work on MultiIndex frames; dated column-MultiIndex frames draw dates for every leaf under ndims=1; forecast_hue= is one value per dataset with a model collection; series-mode bundles match hyp.predict's shape. - panels=: predict+truth in both panel_fit modes; shared mode keeps DataFrame index/column names and accepts 3-column frames; nested hue=/ labels= narrow per panel; ndims>3 draws 3-D panels; save_path is normalised and validated up front; plotly panels use the one-shot display wrapper. - ndims=1: per-column fmt lists; date-aware xlim on both backends; no 'dataset 1' y label; a 3-D ax= with ndims<=2 raises; TimedeltaIndex is drawn in a readable unit. - a trailing Smooth(center=False) that introduces NaN rows is reported as such with the min_periods=1 hint. - docstrings: font= weights, HyperAnimation.drawn_extent/.save. - CHANGELOG entries for all of the above. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d library; gate and test updates analyze, plot, manip, align, text, wikipedia_embeddings, projectile_kalman and conversation_trajectories re-executed with scripts/execute_tutorial.py (home directory scrubbed from stored outputs; no /Users/ path remains in any tutorial). manip's output-cell gate entry gains the new isotropic Normalize cell; the nested-hue length test asserts the new message that names the offending sub-list; tests/test_load_offline.py loses a trailing blank line. Full suite before these two test updates: 5171 passed, 2 failed (these two), 19 skipped. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…xecuted notebook Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ation) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ates Windows' transient access-denied Every Windows job on PR #286 (run 34014888620) failed on the same ten tests: the widened native-usage scanner compared 'docs\tutorials\x' against its forward-slash allowlist and roster, and the URL cache's os.replace raised PermissionError (WinError 5) when twelve threads replaced one entry at once. The scanner now reports POSIX-separated relative paths on every host; the cache retries the rename briefly and accepts a concurrent writer's identical file. macOS and Linux jobs were green on the same commit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… (Windows paths, Windows os.replace, detached verification pipeline) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Second review pass on this branch (2026-09-06): the cloud ultrareview of the PR diff, then nine local reviewers over the full
Local verification on the final library: full suite 5171 passed / 0 failed (after the two stale expectations were updated), ruff clean, After merge the release is re-cut from the merge commit; RELEASE_CHECKLIST.md now describes moving the draft tag, republishing the gallery namespace and replacing the draft release assets. |
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The matplotlib backend draws 's--' as a smoothed line artist (which carries the legend label) plus a markers-only artist at the raw sample points labelled _nolegend_, so the legend handle showed only the dashes (reported from the 1.1 feature tour, section 9.2). The line artist now carries the marker with markevery=[]: its legend handle shows marker and line while it still draws no markers along the interpolated vertices. Pixel-level regression test in tests/test_plot_fmt_split_legend.py. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…data) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…it under return_model, quiet third-party reducer warnings Reported from the 1.1 feature tour (section 9.8): a three-panel grid came out 2x2 with a hole and, in a 9x3.2 in figure, each square 3-D axes shrank to the short cell height; the cell also printed fifteen warnings. - panels=True picks the grid from the figure's aspect ratio and prefers a grid with no spare cell (three panels form a row; four 2x2; six 2x3; five still 2x3 with one hidden cell). Explicit grids are unchanged. - return_model=True reuses the pipeline analyze() fitted for the figure (the cluster stage, which runs on the reduced scores, is appended as a fitted step) instead of refitting every stage, so a UMAP/Isomap plot, and every panel grid built with it, fits and warns once. - a seeded UMAP passes the n_jobs=1 umap forces anyway, so umap stops warning about a seed hypertools injected; a caller's own n_jobs= still reaches umap (and its warning). - Isomap fits silence scipy's SparseEfficiencyWarning burst from sklearn's internal graph completion; sklearn's own connected-components data warning still reaches the user. Seventeen new tests; two older panel tests updated to the new grid rule (the hidden-spare property now covered with five panels). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…pan the whole scene - The truth curve keeps marker='o' with markevery=[] so its 'truth' legend entry is line + marker, no longer identical to the observed trace's entry (feature tour 9.11). - New density.scene_bounds_2d: every 2-D KDE grid covers all datasets' padded bounds plus the unit frame square, on both backends, so a wide flat cloud's glow fades out instead of stopping in a hard band inside the frame (feature tour 9.14). - Tests for both; projectile_kalman and stock_forecasting tutorials re-executed (truth= legends), which also refreshed the stock snapshot CSVs by one trading day as the notebook is designed to. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…+ ax=<cell>, per-panel colorbars on matplotlib - plotly_backend.transplant_panel moves a drawn single-axes figure into a make_subplots cell whole: traces, the 2-D axis layout (unit frame, hidden ticks, DataFrame-column labels, or axis_scale='data' axes), the frame square and labels= annotations re-referenced to the cell, its own legend (plotly multiple legends) and its own colorbar beside the cell; 3-D cells back the camera off so the cube stays inside a narrow cell. - make_panel_grid reserves a gutter beside every cell for those legends and colorbars (default-sized grids widen by it; explicit size= verbatim). - hyp.subplots(backend='plotly') returns the grid figure plus PlotlyCell handles that hyp.plot(..., ax=cell) draws into (title= becomes the cell title); several cell calls display the grid once per notebook cell. - matplotlib: a colorbar drawn into a caller-supplied ax= (every panels= cell, every hyp.subplots axes) uses fig.colorbar(ax=...) instead of the figure-widening placement, so panels no longer stack their colorbars over the last panel or trip tight_layout warnings. - Tests: tests/test_subplots_plotly.py (new), 11 more in tests/test_plot_panels.py. CHANGELOG entries; RELEASE_CHECKLIST.md brought up to date (suite size, Colab tour smoke, announce step). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…id resolution, sparse ARIMA orders, plotly panel titles/fonts/left colorbars - panels= on matplotlib under an active plotly preference built its grid with subplots()' new backend='auto' default; the grid is now explicitly matplotlib. - 2-D density grids pad by four kernel widths past the data instead of spanning the whole scene: the glow still fades out inside the grid, and a small cloud beside a 10,000x larger one keeps its resolution (the scene-wide grid sampled it to all zeros). - ARIMA.min_history_for accepts statsmodels' sparse lag orders (order=([1, 3], 0, 0)), counting the highest lag, as the fitter does. - plotly panels: titles go through the single-axes title path (newlines, title_wrap=, title_kwargs=) and become cell annotations; the panel's font= travels with its legend and becomes the grid default; a location='left' colorbar stays on the cell's left; drawing into a 3-D cell twice keeps the earlier labels= annotations. - Tests for each; a rendered-grid test now checks ink in both cells. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ly cell title placement/replacement, per-cell fonts - predict_new only holds the refit path to the fit-time minimum history; a model with an applier (ARIMA) reuses its learned parameters on any context the new data offers. - plotly cells: the title annotation follows the title's own x/y/anchors mapped into the cell, is replaced (not stacked) when the cell is drawn into again, and reserves the multi-line top margin the single-axes path computed; the panel's font= is materialized on the cell's legend, title, axis titles/ticks and colorbar under explicit overrides. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nd 3-row fits The slow-schedule notice extrapolated a per-row slope from the first two timed fits, one row apart at 2 and 3 rows (tens of milliseconds each); on a slow macOS CI runner that projected 10 s for a 30-row schedule and tripped the 'small schedule stays silent' test. project_schedule_cost now fits every timed length by least squares, and the schedule waits for a timed fit of at least PROJECTION_MIN_ROWS (10) rows before projecting. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, and the figure-review gaps Jeremy's three findings from the 1.1 feature tour: - A collection of models (predict=[...]) keeps each dataset's colour and takes a linestyle per model (forecast.FORECAST_MODEL_LINESTYLES); forecast_palette= on a collection colours by model instead. The old per-model 'husl' default reused the first dataset's colour, so two datasets under two models were indistinguishable pairs. - Every predict= form lists its forecast once in the legend under the model's name, static and animated, on both backends, in the order data / forecasts / truth: proxy glyphs (matplotlib Line2D handles, plotly data-free traces tagged meta['hyp_legend_entry']), neutral gray when one model's forecasts span several colours. Plotly truth= traces mark every observation instead of every antialiased vertex. - The plotly panels= / hyp.subplots grid is laid out like tight_layout: square centred 3-D cells, PANEL_GAP_PX gaps, title room per row, and a camera back-off only for cells narrower than tall (SCENE_CUBE_WIDTH_PER_HEIGHT 1.4 -> 0.92: plotly sizes a scene by its domain height; the old constant was measured against the cube). Cube widths now match the matplotlib grid's within a few pixels. Three-role review of the tour's 51 figures (expected / observed / adjudicated by separate agents) then found eleven more gaps, all fixed with tests: ax= axes and matplotlib panels= cells draw in the palette (they kept their figure's default cycle) and a second call into the same axes or plotly figure continues it; default-size panels= figures widen for their legends/colorbars; 3-D axis labels are inside the tight bbox (_AxisLabelExtent); recoloured forecasts keep their trace's alpha and the legend glyph never drops below 0.8; the 2-D frame square has a 12.5 % margin (UNIT_FRAME_SCALE) on both backends; legend_kwargs loc= drops the outside-right anchor; plotly legend keys use a constant item size; hyp.subplots(backend='plotly') grows its legend gutters only when a cell brings a legend or colorbar (ensure_panel_gutter). Tests: test_plot_forecast_legend_style, test_plot_panels_geometry (real renders, cube fill within 6 %), test_figure_review_gaps; existing suites retargeted to the new rules. Tutorials projectile_kalman and stock_forecasting re-executed (their legend names no longer fold the forecast in). CHANGELOG, docstrings and the session note updated. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…uping, fitted multi-dataset animation, plotly forecast_fmt, legend_colors contract, panel layout Two majors: a collection of models under hue=/cluster= regrouping only resolved forecast ownership when the forecast and run counts differed, so one dataset split into two runs under two models drew Kalman on the earlier run and ARIMA on the final one, and the animated modes indexed the reveal schedule by forecast (model-major) index instead of source dataset, raising IndexError with forecast_trail=; a forecaster fitted on several datasets could not animate because the schedule forecasts one history at a time (Forecaster.for_dataset binds the view it needs). Minors: plotly honours a colour letter and markers in forecast_fmt (traces and legend keys); plotly animations keep a recoloured forecast's alpha; a second call into the same plotly cell continues the palette; plotly legend keys compare RGB, not RGBA; legend_colors pairs define the legend outright on both backends and a plain colour list recolours the final legend after the forecast/truth entries; an attached right colorbar is padded past the panel legend's overhang; plotly grid gutter rebuilds keep multi-line title room and explicit legend_kwargs positions are translated into the cell; the animation guide's forecast sections describe the 1.1 rules; the tight-bbox test asserts four-sided containment. Tests: tests/test_plot_review_round3.py (19), every scenario from the review's own reproduction scripts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ture-hue overlay legends, composed calls, plotly cell furniture - A forecast_fmt colour letter pins the forecast colour in regrouped animations on both backends (only forecast_hue/cluster/palette counted before), and plotly's per-frame colours keep a recoloured forecast's alpha. - Mixture-hue legends list forecasts and truth: a matrix hue clears legend= and builds swatch entries, which the overlay gating did not count as a legend; plotly_draw(legend_explicit=) separates explicit legend_colors pairs (which suppress the entries) from swatches. - Repeated calls into one axes, figure or grid cell compose: the overlays style themselves from this call's lines, truth artists are unlabelled and tagged, and the legend is rebuilt by role (data entries, one key per model over every call's forecasts, one truth) on both backends. - Plotly cells track their furniture per cell, so a legend and a colorbar from separate calls sit side by side and the gutter fits the busiest cell; ensure_panel_layout rebuilds the rows for a taller title immediately. - A marker-only forecast_fmt draws markers on plotly; animated plotly collection traces tag their source dataset. Tests: tests/test_plot_review_round4.py (15), from the review's own reproduction script. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…; index-confusion note
…n; weed out stale install instructions - set_autoinstall (class in _shared.lazy_import, exported at the top level) turns the on-demand installation of optional extras on or off, called directly for the session or as a context manager for one block, like set_interactive_backend; HYPERTOOLS_AUTO_INSTALL only sets the starting value. - New static gate: every library module that imports a package an extra provides calls lazy_import for it in the same file (three stated exemptions). - Stale 'install it first' prose removed from the plot() reducer docstring, the autoencoder/gensim gallery examples and the LSL tutorial; the reduce() torch error says the on-demand install was tried. - Docs: API reference 'Set autoinstall' section + stub, optional_dependencies 'Turning it off' rewritten around the call, index/readme/CHANGELOG updated. - scripts/execute_tutorial.py clears a skipped install cell's outputs; the two tutorials that shipped a pip notice with a local path are cleared, and a gate forbids published install cells from carrying output. - tests/test_lsl_streaming.py: the by-type test uses a unique stream type (other processes on the host advertised idle EEG outlets). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t install policy, panel bundles/partitioning, doctest gate)
Findings 1-6 and the observations in notes/release_audit_2026-09-07_paused.md
(original text kept; an 'Updates by the Claude session' section records each fix):
- load(<built-in>, offline=True) serves only a hash-valid cached copy and raises
HypertoolsOfflineError for a missing/corrupt one without downloading or deleting
(real socket.connect audit-hook tests).
- set_autoinstall(False) reaches the plotly animation-export worker: the parent
passes its effective setting through lazy_import.subprocess_env (tested in a
real interpreter without kaleido); the _pip_install spy test is replaced by a
real-observable one.
- panels=: shared-fit bundles expose the fitted pipeline (top level and per
panel); every per-dataset / per-forecast argument is sliced per panel and a
multi-dataset forecaster is bound with Forecaster.for_dataset (33 tests).
- A list of {category: color} dicts works once hue= regroups the datasets.
- alignment_score rejects 1-D / non-numeric / NaN / all-constant input clearly.
- hypertools.load docstring example is self-contained; docs/conf.py takes
HYPERTOOLS_DOCS_PLOT_GALLERY=0 as a real boolean and the docs-clean CI job
runs the sphinx doctest builder; docs/doc_requirements.txt floors match
pyproject; HypertoolsOfflineError docstring covers built-ins.
Local: pytest 5363 passed, ruff/packaging clean, sphinx -W 0 warnings,
doctest 316/0, smoke gate 344.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rt exception type, panel palette slots) + plotly fmt colour and 2-D panel cells - set_autoinstall: a lock-guarded scope stack replaces the saved global; a with-block removes only its own setting, the newest in force decides (process-global, documented); deterministic and two-thread tests. - Plotly animation export re-raises the worker's ImportError (missing extra with installation off) / HypertoolsIOError (no Chrome) as that type via a .worker-error.json marker instead of a RuntimeError wrapper. - panels=: one forecast_palette slot per LABEL (labels sharing a colour kept); every per-dataset roster entry has a behavioural partitioning test. - Plotly honours the colour letter of a data fmt= string like matplotlib; panels= on 2-/1-column data without ndims= draws 2-D cells on both backends. - tests/test_lsl_streaming.py: the under-load child budget is 900 s (the CI ubuntu 3.13 job hit 300 s where the same run's 3.10 job took 38 s). - Audit notes carry Codex's round-6 section and the matching UPDATE entries. Local: pytest 5460 passed, ruff/packaging clean, sphinx -W 0 warnings, doctest 316/0, smoke gate 344. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nch at 05:44 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…sumed, bounded set_autoinstall scopes) + nits; HypertoolsTrustError exported - panels=: every mode fits through one probe and draws each panel from the analyzed rows, so cell dimensionality follows manip/pipeline/reduce output (Delay -> PCA ndims=3 on 2-column data draws 3-D cells again); requested ndims and per-panel pipelines kept, no second fit. - Composition palette offsets count only cycle-coloured datasets (fmt colour letters, explicit color=, hue= consume none), same on both backends. - set_autoinstall: a new setting replaces a superseded one no block holds open (bounded records, no retained handles); block semantics unchanged. - HypertoolsTrustError importable from hypertools; api.rst documents it and io.synthetic_outlet under their public names (viewcode backlinks resolve). - Tests: tests/test_plot_review_round7.py (32), lazy_import retention + hand-off asserts, export ON-branch exception type. Local (this tree): pytest 5493 passed, ruff/packaging clean; sphinx/doctest/ smoke to be re-run on resume (build interrupted for a machine suspend). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…play, plotly offset, mixed-width panels) + transient TLS-drop classifier - set_autoinstall: live handles as weakref records plus a baseline folded in by the callback of a handle that dies unentered; newest call by order decides; a block only removes its own record; nothing retained. - panels=: cells replay the probe's fitted clustering (seeded memberships equal the individual call's; no extra clusterer fits); bundles carry models['cluster_labels']; plotly composition keeps the palette offset across a color=/categorical-hue call; 1-/3-column independent panels draw the series on the 3-D cell's floor. - tests/_netskip: an SSLError with a TLS-drop cause is transient; a certificate failure is not (CI ubuntu 3.11 Dropbox drop). - HypertoolsTrustError exported; tests/test_plot_review_round8.py (52). Local: pytest 5547 passed, ruff/packaging clean, sphinx -W 0, doctest 316/0, smoke 344. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, datawrangler-based input coercion (wave 0), Codex round 9 fixes - Palettes: image colours sorted by value when used as a plot palette (palette_sort= / ?sort=; lead colour stays salient); a t x k matrix is a palette via hyp.reduce (palette_reduce/manip/normalize/align) -> scaled, sorted, MatrixColormap (exact interpolation); most-saturated anchor leads a per-dataset entry. Docs (api.rst, tutorials.rst, plot.ipynb section), tests. - Datatype wave 0: format_data / get_type / as_dataframe / predict+impute normalisation / is_stream on dw.zoo predicates and dw.wrangle; polars DataFrame/LazyFrame/Series accepted; 46 real-polars tests (4 strict xfails name the wave-1 sites). - Codex round 9: shared cluster colours kept per panel, narrow panels forecast in their own space, marker-only hue consumes no palette slot, live certificate failures never skipped (tests/test_plot_review_round9.py, 57). Checkpoint commit: per-suite runs green; the full pipeline runs before the push. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… aligns unnamed+named lists by position, palette lead colour fix
- plot: index/column capture, hue=/labels=/truth=/matrix palette=/panels= and
axis/legend labels through the shared predicates (polars DataFrame/
LazyFrame/Series accepted; a 1-column label DataFrame hue no longer raises).
- manip (+ Manipulator classes, Pipeline steps), align, stack, damage,
apply_model, Normalizer, save/load, text2mat, impute backtest truth=/mask=:
funnels with backend='pandas', post-funnel re-checks removed, predicates
instead of pandas/numpy isinstance ladders; tests/test_datatype_gate.py keeps
hand-rolled type checks out (allowlisted option/model checks).
- manip([array, named frame]) aligns by position like plot/reduce/align
(failed inside datawrangler before, pandas included); named frames with
different labels raise a clear ValueError.
- palette_lead_color: a bare colour ('red') resolves again (the matrix-lead
branch had swallowed it); most-saturated anchor leads a matrix palette.
- tests: test_polars_inputs.py (xfails lifted), test_polars_inputs_wave1.py (51).
Local: pytest 5754 passed, ruff/packaging clean, sphinx -W 0, doctest 316/0,
smoke 344.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…I-only test fixes (readme.md case, live-source-gate mode) - MatrixColormap builds the parent's channel segment data (as from_list), so integer sampling, resampled(), reversed(), bad/masked input and alpha arrays work; contract test added. - tests/test_format_data.py opens the repo's lowercase readme.md (macOS resolved README.md, the Linux CI jobs did not); the classifier test pins both guard modes (the live-source-gate job sets HYPERTOOLS_REQUIRE_LIVE_SOURCES=1 and re-raises by design). Local: pytest 5755 passed, ruff/packaging clean, sphinx -W 0, doctest 316/0, smoke 344. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…Colormap under/over/bad per element, exact image interpolation - manip: a list mixing unnamed arrays with named DataFrames now aligns on positional COLUMN labels only (frames keep their index; named-frame lists are left untouched; unequal widths untouched) -- R11-2 - MatrixColormap: under/over/bad applied per element, so masked/NaN and out-of-range values render like any LinearSegmentedColormap -- R11-1 - image palettes above 256 colours interpolate exactly instead of through the 256-entry LUT -- R11-3 - polars forecast_hue under panels= matches the pandas result -- R11-4 - prose fixes and stronger assertions in the palette/polars tests; datatype gate allowlist narrowed for the forecast_hue exemption - notes: UPDATE sections after Codex round 11; CHANGELOG bullet Local verification (full_verify19): pytest 5761 passed / 19 skipped, ruff + diff --check clean, packaging 13, sphinx -W 0 warnings, doctest 316/0, example smoke gate 344 passed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This PR fixes scoring errors, cache-write races, lost Delay features, inconsistent font selection, NumPy 2-incompatible optional minimums, and documentation gaps found during the 1.1 review. The full report follows.
Closes #284.
Closes #285.
HyperTools 1.1 release review — 2026-09-05
Reviewed draft source:
96ac8b7f43c132f6f455ad1be3ffc98e84adead5(master and v1.1.0 at review start). Changes are submitted onfix/1.1-release-review; master and the release tag are not modified.Findings fixed in the PR
AutoRegressor()produced negative quadratic forecasts and MAE 2551.68, versus 0.00246 when passing the class.Delaysilently lost features when distinct pandas column labels had identical string representations (1and'1'); a 2-column, 2-lag input produced only 2 output columns.FileNotFoundError.hyp.load(ARCHIVE, cache=True), regenerate and execute the tutorial. Its committed video remains byte-identical.docs-notebooks/master, searched highlighted HTML for contiguouspip install, and demanded an autoplay call in deliberately paused Plotly animations.Source and regression-test map
hypertools/predict/backtest.py,hypertools/impute/backtest.py;tests/test_predict_backtest.py,tests/test_impute_backtest.py.hypertools/io/sources.py;tests/test_load_url_cache.py.hypertools/manip/delay.py;tests/test_manip_delay.py.hypertools/plot/fonts.py;tests/test_fonts_bold.py.pyproject.toml,docs/doc_requirements.txt; real minimum-version runs oftests/test_gensim_text.pyandtests/test_density.py, plus packaging/optional-import checks.docs/optional_dependencies.rst,readme.md,CHANGELOG.md,examples/animate_forecast.py, and its executed tutorial notebook.scripts/verify_docs_playwright.py.Review coverage and validation
Smooth(center=False)(instead of the proposed conflictingalign=),alignment_score, and matplotlib-onlycompanion=; broader animated panels and launch-example visual rewrites remain the explicitly deferred scope.LSLAPICFGwith a private SessionID,KnownPeers = {127.0.0.1}, and machine-scoped discovery. These are the upstream-supported LSL configuration settings; no user/global network settings were changed.-W --keep-goingexecuted 51/51 gallery examples and passed. Rebuilt again after updating the forecast example/tutorial. Post-build processing injected versioned Colab links and updated all 51 thumbnails.git diff --checkpassed. Existing matrix CI and tag CI on96ac8b7fwere green when inspected. PR CI validates the new branch separately.Issues and public-release disposition
The PR resolves the remaining implementation/documentation defects discovered while checking #284 and #285. Both issues are linked for closure on merge, rather than closed before fixes reach master.
Before public release, merge the PR and perform the normal release re-cut from the resulting commit: rebuild and republish the gallery/notebook manifest, rebuild wheel/sdist, update the draft assets/tag, and confirm the release/tag gates. The manifest intentionally pins an exact source commit. The already-green draft at
96ac8b7fcannot stand in for these checks after the fixes merge.Large-download tests remain excluded by the project's default
not bigdatamarker. A passing test suite is not a guarantee that every third-party service, model, or platform combination is defect-free.Detailed local logs and browser evidence are under
/tmp/hypertools-review/(not shipped in the package).