2026-04-22
Session 1: Phase 0 (Groundwork) + most of Phase 1 (Amputation)
Engineering log for session 1.
Baseline: PyCaret 3.4.0 @ main.
Environment: Python 3.13.13, uv 0.11.7, scikit-learn 1.7.2, NumPy 2.3.5, pandas 2.x on Windows.
BUILD#
BUILD, BREAKING— Version bumped3.4.0→4.0.0.dev0.pycaret/__init__.pyandpyproject.tomlnow declare 4.0.0.dev0; this is a pre-release marker for the in-flight revamp.BUILD, BREAKING— Migrated build backend fromsetuptoolstohatchling.[build-system]inpyproject.tomlnow useshatchling>=1.25. Wheel packaging handled by[tool.hatch.build.targets.wheel].BUILD, BREAKING— Migrated environment management touv(Astral).uv.lockbecomes the lockfile;uv sync --all-extrasis the supported one-command install. Dev dependencies live in[dependency-groups.dev].BUILD, BREAKING— Deletedsetup.cfg. pytest, flake8, and isort configs moved. Pytest config now lives in[tool.pytest.ini_options]inpyproject.toml. Flake8 / isort replaced by ruff (see below).BUILD, BREAKING— DeletedMANIFEST.in. Hatchling's built-in include/exclude rules replace it.BUILD— Deletedmypy.ini. mypy config now lives in pyproject.toml's tool sections (reinstate there if/when mypy is run).BUILD, BREAKING— Python floor raised from>=3.9,<3.13to>=3.11. Classifiers now list 3.11 / 3.12 / 3.13 / 3.14. Primary dev target is Python 3.13 for session 1; 3.14 is aspirational (PEP 649 currently breaks joblib+cloudpickle pickling — seethinking/2026-04-22_python314_pep649_blocker.md).BUILD— Ruff added as the single linter. Replaces the 3.x stack of black + isort + flake8. Config in[tool.ruff]/[tool.ruff.lint]. Target versionpy313.BUILD— Hard-coded Python version guard rewritten.pycaret/__init__.pynow raisesRuntimeErrorif run under<3.11instead of<3.9or>=3.13.
DEPS — removed from runtime (kill list)#
All removals are pre-approved in KILL_LIST.md. Each is a BREAKING change against any user who relied on the affected feature.
REMOVED, BREAKING— mlflow. No longer a dependency;loggers/mlflow_logger.pymodule deleted.REMOVED, BREAKING— comet-ml.loggers/comet_logger.pydeleted.REMOVED, BREAKING— wandb.loggers/wandb_logger.pydeleted.REMOVED, BREAKING— dagshub.loggers/dagshub_logger.pydeleted.REMOVED, BREAKING—DashboardLoggerfan-out logger.loggers/dashboard_logger.pydeleted.REMOVED, BREAKING— fugue, fugue[dask].pycaret/parallel/fugue_backend.pydeleted.REMOVED, BREAKING— dask, distributed. No replacement.REMOVED, BREAKING— ray[tune], tune-sklearn. Ray Tune integration dropped from thetunersextra.optuna,scikit-optimize, andhyperoptremain.REMOVED, BREAKING— yellowbrick. Plot layer deleted wholesale.pycaret/internal/plots/yellowbrick.pydeleted;pycaret/internal/patches/yellowbrick.pydeleted. 16 inlinefrom yellowbrick.* import ...call sites ininternal/pycaret_experiment/tabular_experiment.pystubbed behind ashow_yellowbrick_plotNotImplementedErrorplaceholder (seetabular_experiment.pytransitional stubs). Replacements land in Phase 3 as native Plotly plots.REMOVED, BREAKING— mljar-scikit-plot.scikitplotimport removed frominternal/plots/helper.py. The only functional dependency was a matplotlib re-export, which is now direct.REMOVED, BREAKING— schemdraw. Pipeline diagram drawing (one code path) no longer supported; Phase 3 will decide whether to re-render it as Plotly.REMOVED, BREAKING— plotly-resampler.display_format='plotly-widget'anddisplay_format='plotly-dash'paths intime_series/forecasting/oop.pyraiseNotImplementedError. Plain Plotly rendering still works.REMOVED, BREAKING— evidently.check_driftmethod (and its test) removed from all experiment classes.REMOVED, BREAKING— fairlearn.check_fairnessmethod (and its test) removed.REMOVED, BREAKING— ydata-profiling.edamethod scheduled for removal; extras entry deleted.REMOVED, BREAKING— explainerdashboard.dashboardmethod scheduled for removal; extras entry deleted.REMOVED, BREAKING— gradio.create_appmethod scheduled for removal; extras entry deleted.REMOVED, BREAKING— fastapi, uvicorn.create_apimethod scheduled for removal; extras entry deleted. If a web server layer comes back it will be a separatepycaret-serverpackage.REMOVED, BREAKING— boto3.deploy_model's S3 path no longer supported.test_persistence.pyS3 fixtures/tests removed.REMOVED, BREAKING— m2cgen.convert_modelmethod scheduled for removal; extras entry deleted.REMOVED, BREAKING— moto. Test-only dep for boto3 S3 mocking; removed.REMOVED, BREAKING— flask, Werkzeug.parallelextras artifacts; removed with dask removal.REMOVED, BREAKING— dash[testing].explainerdashboardtest dep; removed.REMOVED, BREAKING— scikit-learn-intelex. Intel oneAPI sklearn-plus-daal4py extension dropped.engine="sklearnex"paths in the model containers will fail to match; corresponding tests were deleted.REMOVED, BREAKING— trio<0.25. Legacy httpcore workaround removed.REMOVED, BREAKING— statsforecast. Demoted from thetimeseriesextra. (Needed a C toolchain on Python 3.14 with no wheel; no PyCaret code imports it directly. Users can install manually.)REMOVED, BREAKING— tbats. Demoted from thetimeseriesextra. (Declaresnumpy<2, incompatible with NumPy 2.x modernization.BATSContainer/TBATSContainernow try-import and silently mark themselves inactive if the package is missing; users can stillpip install tbatsmanually.)
DEPS — upper-bound pins removed (modernization)#
All of these caps blocked PyCaret from running on modern Python or modern scientific-stack versions.
CHANGED, BREAKING—scikit-learncap lifted from<1.5to>=1.7,<1.8. The<1.8upper bound is transitional:sktime(thetimeseriesextra) caps sklearn at<1.8. When sktime releases with sklearn 1.8 support, we bump.CHANGED, BREAKING—numpycap lifted from<1.27to no upper bound. Floor is>=1.26(for NumPy 2.x API). Codebase updated to NumPy 2 compatibility; see fixes below.CHANGED, BREAKING—pandascap lifted from<2.2to no upper bound. Floor is>=2.2.CHANGED, BREAKING—scipycap lifted from<=1.11.4to no upper bound. Floor is>=1.11.CHANGED—joblibcap lifted from<1.5to no upper bound. Floor is>=1.4.REMOVED—matplotlibupper bound<3.8.0removed. matplotlib now declared>=3.9as a transitional core dep (only used by residual non-Plotly plot paths — Phase 3 will remove it entirely).REMOVED—sktimepinned release>=0.31.0,<0.31.1unpinned to>=0.36.REMOVED—shapupper bound<0.47.0removed. Now>=0.46.REMOVED—fairlearn==0.7.0pin removed (fairlearn itself dropped).REMOVED—evidently<0.4.30pin removed (evidently dropped).REMOVED—pmdarimaexact version constraints relaxed. Floor>=2.0.4.REMOVED—dask<2024.6.3,distributed<2024.6.3,fugue==0.9.1pins removed (packages dropped).REMOVED—Werkzeug>=2.2,<3.0pin removed (dropped).REMOVED—moto<5.0.0pin removed (dropped).
DEPS — optional-extras restructuring#
Extras reorganized from the 3.x layout (full, analysis, models, tuners, mlops, parallel, prophet, dev, test) to a cleaner 4.0 layout:
CHANGED, BREAKING—mlopsextra deleted. Its contents (mlflow, gradio, fastapi, uvicorn, m2cgen, boto3, evidently) are on the kill list.CHANGED, BREAKING—parallelextra deleted (dask/distributed/fugue gone).ADDED—anomalyextra. Isolates pyod + numba so classification/regression users don't pay the install cost.ADDED—timeseriesextra. Contains statsmodels, sktime, pmdarima; isolated from core because sktime's dep closure is heavy.CHANGED—fullextra now meanspycaret[models,tuners,analysis,anomaly,timeseries](plain alias — no duplicated list).CHANGED—testextra gainspytest-xdist,pytest-cov,nbval; losesfugue[dask],dash[testing],moto.CHANGED—devdependency group replacesdevextra. Contents:ruff,mypy,pre-commit. (black/isort/flake8 dropped in favour of ruff.)BUILD— kaleido pinned to>=0.2(core dep for Plotly static image export).BUILD— Core deps trimmed from 30 to 19. Removed from core:deprecation,markupsafe(Colab workaround),wurlitzer,importlib_metadata(stdlib now),setuptools(runtime),mljar-scikit-plot,schemdraw,plotly-resampler,yellowbrick,trio, plus the timeseries packages which moved to their extra.
REMOVED — modules and tests#
REMOVED, BREAKING—pycaret/parallel/directory deleted.REMOVED, BREAKING—pycaret/internal/parallel/directory deleted.REMOVED, BREAKING—pycaret/loggers/{mlflow,comet,wandb,dagshub,dashboard}_logger.py— five logger modules deleted.REMOVED, BREAKING—pycaret/internal/patches/yellowbrick.pydeleted.REMOVED, BREAKING—pycaret/internal/plots/yellowbrick.pydeleted.TESTS— 14 test files deleted:test_classification_parallel.py,test_regression_parallel.py,test_time_series_parallel.py(parallel gone)test_mlflow_artifacts.py(was empty)test_time_series_mlflow.pytest_create_api.py,test_create_app.py,test_create_docker.pytest_dashboard.pytest_check_drift.py,test_check_fairness.pytest_clustering_engines.py(daal4py-only)test_classification_engines.py,test_regression_engines.py,test_time_series_engines.py(sklearnex-only)
TESTS—test_persistence.pyreduced to a single-line stub comment (all its tests were boto3/moto/S3 specific).
CHANGED — API / signature changes#
CHANGED, BREAKING—compare_models(parallel=...)argument removed from 7 files:classification/{functional,oop}.py,regression/{functional,oop}.py,time_series/forecasting/{functional,oop}.py,internal/pycaret_experiment/supervised_experiment.py. Passingparallel=tocompare_modelswill now raiseTypeError: unexpected keyword argument.REMOVED, BREAKING—_parallel_compare_modelsmethod deleted frominternal/pycaret_experiment/supervised_experiment.py.CHANGED, BREAKING—setup(log_experiment=...)no longer accepts string shortcuts ("mlflow","comet_ml","wandb","dagshub"). OnlyboolorBaseLoggerinstances are valid now._validate_log_experiment/_convert_log_experimentrewritten ininternal/pycaret_experiment/tabular_experiment.py. Thelist[...]form is preserved but validates each element to the new rule.CHANGED—_convert_log_experimentnow always returns aBaseLoggerinstance, never a bool. Downstream hooks (log_experiment,log_model,log_model_comparison,log_plot,.loggers) can be called unconditionally — the defaultBaseLogger()is a silent no-op for every method. This eliminates theif self.logging_param:truthiness checks that permeated the experiment classes.CHANGED—BaseLogger(inpycaret/loggers/base_logger.py) rewritten to be the null/identity logger. Was anABC; is now a concrete class with every hook method implemented as a silent no-op. Adds.loggersproperty returning[self]to replace the removedDashboardLoggerfan-out. Addslog_experiment,log_model,log_model_comparison,log_plot,log_hpram_grid,log_artifact,log_sklearn_pipelineas no-op overridable hooks. Users who had aBaseLoggersubclass should still work if they only override hooks (they will inherit no-op defaults for the new methods).CHANGED—pycaret/loggers/__init__.pynow exports onlyBaseLogger. Previously exportedMlflowLogger,CometLogger,WandbLogger,DagshubLogger,DashboardLogger— all deleted.
CHANGED — transitional stubs (Phase 3 will replace)#
These raise a clear NotImplementedError at call time rather than at import time, so the package remains importable while killed features are progressively re-implemented.
CHANGED, BREAKING—show_yellowbrick_plotstubbed ininternal/pycaret_experiment/tabular_experiment.py. Allplot_modelcalls that historically routed through yellowbrick now raiseNotImplementedErrorwith a pointer to the kill-list doc and Phase 3.CHANGED, BREAKING—MlflowLogger/CometLogger/WandbLogger/DagshubLoggerstubs installed intabular_experiment.py. Any code constructing one raisesNotImplementedErrormentioning "pass a customBaseLoggersubclass orlog_experiment=False".CHANGED, BREAKING—scikitplot.metrics.plot_lift_curve / plot_cumulative_gain / plot_ks_statisticstubbed intabular_experiment.py.plot_model('lift' | 'gain' | 'ks')will raiseNotImplementedErroruntil Phase 3 ships the Plotly replacements.CHANGED, BREAKING—plotly_resampler.FigureResampler / FigureWidgetResamplerstubbed intime_series/forecasting/oop.py.display_format='plotly-widget'and'plotly-dash'raiseNotImplementedError.CHANGED—with patch(...)yellowbrick mock-patches replaced withcontextlib.nullcontext()intabular_experiment.py. Preserves body indentation until Phase 3 removes the wrapper blocks entirely.
FIXED — modernization bugs#
FIXED—distutils.version.LooseVersionimport removed. Python 3.12 removed thedistutilsmodule.pycaret/utils/_dependencies.pyrewritten to usepackaging.version.Version+ stdlibimportlib.metadata(replaces theimportlib_metadatabackport).FIXED—joblib.Memorybytes_limitkwarg handling updated.joblib>=1.4movedbytes_limitoff the constructor and ontoreduce_size(bytes_limit=...).FastMemory.__init__inpycaret/internal/memory.pynow strips the old kwarg and forwards it intoreduce_sizeon each reduction.FIXED—np.NaN→np.nan.pycaret/internal/preprocess/preprocessor.pyline 682. NumPy 2.0 removed the capitalised alias.FIXED—sklearn.metrics._regression._check_reg_targetsnew signature. sklearn 1.7 insertedsample_weightas a positional parameter and expanded the return from 4 to 5 values. Custom MAPE metric inpycaret/containers/metrics/regression.pyupdated to pass the new arg and unpack the new return.FIXED— BATS / TBATS containers guard against missingtbats.pycaret/containers/models/time_series.py:BATSContainer.__init__andTBATSContainer.__init__now try-import the sktime wrapper inside atry/exceptand setself.active = Falseon failure, rather than crashing the entire container registry.FIXED—MatplotlibDefaultDPIrewritten inpycaret/internal/plots/helper.py. Previously went throughscikitplot.metrics.plt; now talks to matplotlib directly. Fixes anImportErrorat module load.
DOCS#
DOCS— Createddocs/revamp/directory — the authoritative narrative of the revamp. Index inREADME.md.DOCS— Createddocs/revamp/AUDIT.md— baseline inventory of 3.4.0: 62,164 LOC, monster-file hotspots, dep upper-bound audit, kill-list evidence with file paths, test landscape, headline risks.DOCS— Createddocs/revamp/KILL_LIST.md— every dep and subsystem being removed, with replacements and rationale. Pre-approved removals.DOCS— Createddocs/revamp/ROADMAP.md— phased plan (Phase 0 groundwork / Phase 1 amputation / Phase 2 modernization / Phase 3 Plotly plot rewrite / Phase 4 agent+UI API / Phase 5 docs+release). Exit criteria per phase.DOCS— Createddocs/revamp/DECISIONS.md— ADR-style decision log.DOCS— Createddocs/revamp/STATUS.md— current session status, headline metrics, next steps.DOCS— Createddocs/revamp/thinking/2026-04-22_session1_framing.md— scoping conversation and rejected approaches.DOCS— Createddocs/revamp/thinking/2026-04-22_python314_pep649_blocker.md— why Python 3.13 not 3.14 for primary dev (upstream joblib+cloudpickle blocked on PEP 649).DOCS— Createddocs/revamp/thinking/2026-04-22_session1_outcomes.md— quantitative/qualitative session notes intended to feed the research paper.DOCS— Createddocs/revamp/thinking/phase0_failure_landscape.md— 158 test failures clustered into 5 root causes with ROI-ordered fix list.DOCS— Createddocs/revamp/release_notes_pycaret4.md(this file) — engineering change log; user-facing notes will be generated from it.DOCS— Created user-memory files under.claude/memory/— workspace layout, kill list, version targets, revamp style, user profile, research-paper framing. Persist across sessions.
TESTS#
TESTS— Strippedfrom mlflow.tracking import MlflowClientimports fromtest_classification.py,test_regression.py,test_clustering.py,test_anomaly.py.TESTS— DeletedTestClassificationExperimentCustomTagsclass (3 mlflow-custom-tag tests) fromtest_classification.py.TESTS— DeletedTestRegressionExperimentCustomTagsclass (3 mlflow-custom-tag tests) fromtest_regression.py.TESTS— Deleted mlflow-specifictest_clusteringfunction fromtest_clustering.py. File now has adatafixture but no tests — will be populated in a later session.TESTS— Deleted mlflow-specifictest_anomalyfunction fromtest_anomaly.py. Same state astest_clustering.py.TESTS— First post-amputation full run captured indocs/revamp/thinking/phase0_pytest_run1.log: 568 passed / 158 failed / 8 skipped in 34:26 (77.4% pass rate). Three further engine-only test files deleted after the run.
INTERNAL#
INTERNAL—_show_versionsreference totbatsleft in place. Even though tbats is no longer a declared extra,pycaret/utils/_show_versions.pystill lists it in its introspection table; the BATS/TBATS containers gracefully no-op when the package is missing.INTERNAL— uv dev-dependencies migrated from[tool.uv.dev-dependencies]to[dependency-groups.dev]. The former is deprecated in current uv versions.