Skip to content

v3.6.4: documentation accuracy pass - #718

Merged
yzhao062 merged 2 commits into
masterfrom
development
Aug 2, 2026
Merged

v3.6.4: documentation accuracy pass#718
yzhao062 merged 2 commits into
masterfrom
development

Conversation

@yzhao062

@yzhao062 yzhao062 commented Aug 2, 2026

Copy link
Copy Markdown
Owner

PyOD 3.6.4

A documentation-accuracy release. No runtime behavior changes: an executable-AST comparison confirms the 43 touched model modules differ only in docstrings.

An audit compared every constructor signature against its numpydoc block, attempted all 72 example scripts, and built the Sphinx site. What it found was mostly not wrong prose but documentation that had quietly drifted away from the code.

Documented parameters that did not exist

Seven documented constructor parameters raise TypeError when passed. A user following the docs got an error, and the error looked like their mistake:

GMM(verbose=0)                    # TypeError
LUNAR(n_neighbors=5)              # TypeError - the real keyword is n_neighbours
RGraph(random_state=42)           # TypeError
SUOD(cost_forecast_loc_fit=...)   # TypeError

These entries are removed, or renamed to the real keyword where one exists. LUNAR's entry keeps a note about the British spelling so a search for n_neighbors still lands somewhere useful.

Documented defaults that disagreed with the signature

Roughly fourteen, including ABOD.n_neighbors (documented 10, actually 5), ALAD.epochs (500 / 200), ALAD.preprocessing (True / False), AnoGAN.learning_rate_query (0.001 / 0.01), RGraph.transition_steps (20 / 10), and DIF.hidden_neurons, documented as [64, 32] while the constructor substitutes [500, 100] for the None default.

Also corrected: labels_ was typed as int in BaseDetector and in every detector that copied the wording, when it is a numpy array of shape (n_samples,); and XGBOD.labels_ claimed threshold_ is applied to decision_scores_ when fit() never sets threshold_.

Sphinx: 310 warnings to 41

sphinx.ext.napoleon had never been enabled, so every numpydoc Parameters and Attributes heading was parsed as an RST section title rather than a field list. A full build went from 310 warnings and 242 class="problematic" spans to 41 and 5, and the :attr: links for decision_scores_ and labels_ — the two attributes every user touches after fit() — resolve for the first time.

Enabling the parser also exposed five docstrings it could not read, which had been inert text until now: AnoGAN emitted 1 of its 16 parameters, RGraph 5 of 16, DIF produced 30 fields for an 11-parameter constructor, XGBOD turned a commented-out block into four bogus parameter names, and the SO_GAAL in so_gaal_new.py had an entirely empty Parameters section. All five are repaired, and a sweep over all 62 detectors now parses every documented parameter with no bogus or missing entries.

Removed a dead pyod.models.auto_encoder_torch section (the module was deleted in 2024; a duplicated :exclude-members: made the directive raise DuplicateOptionError, which Sphinx stripped from the output, so the page silently rendered a heading with no body) and de-duplicated the pyod.models.base automodule.

Entry points

  • The README quick start called clf.fit(X_train) without ever defining X_train, and used visualize without importing it. Pasting it raised NameError. This block is the GitHub landing page and the PyPI description.
  • docs/install.rst documented a pytorch extra that does not exist. pip treats an unknown extra as a warning, so pip install pyod[pytorch] succeeded while installing none of the PyTorch stack, and the mistake surfaced later as an ImportError. The table now keys on the extras actually defined in pyproject.toml, adds the nine that were missing plus pip install pyod[all], corrects the MCP tool count from seven to ten, and drops the claim that pyod install skill supports Claude Desktop, which no code path targets.

Examples

mad_example.py generated two features for a univariate-only detector, and qmcd_example.py appended ground-truth labels to the feature matrix before calling predict — which raised, and would have leaked test labels if it had not. Both run now. examples/data/mat_file_conversion.py byte-compiles after removal of mid-file Python 2 __future__ imports; end-to-end conversion still needs its optional dependencies and external source datasets.

Deferred to issues

Three findings need a runtime decision and are tracked separately: #713 (CBLOF.n_jobs accepted but unused — now disclosed in its docstring), #714 (DevNet has no class docstring and five parameters, including random_state, are never read, so runs are not reproducible), and #715 (pyod info infers "Claude Code detected" from a directory pyod install skill creates itself).

Full suite: 1532 passed. Reviewed via /implement-review with Codex.

…able examples

An audit compared every constructor signature against its numpydoc block,
attempted all 72 example scripts, and built the Sphinx site. No runtime
behavior changes: an executable-AST comparison confirms the 43 touched model
modules differ only in docstrings.

Docstrings (83 fixes across 43 modules):
- Removed seven documented constructor parameters that do not exist and raise
  TypeError if passed: GMM.verbose, GMM.verbose_interval,
  RGraph.active_support_params, RGraph.random_state,
  SUOD.cost_forecast_loc_fit/_pred, and LUNAR.n_neighbors (the real keyword is
  the British spelling n_neighbours; the entry is renamed with a note).
- Corrected documented defaults that disagreed with the signature, among them
  ABOD.n_neighbors 10->5, ALAD.epochs 500->200, ALAD.preprocessing True->False,
  AnoGAN.learning_rate_query 0.001->0.01, RGraph.transition_steps 20->10, and
  DIF.hidden_neurons, documented as [64,32] while the constructor substitutes
  [500,100].
- Documented public parameters that had no entry, and corrected labels_, typed
  as int in BaseDetector and every detector that copied the wording when it is
  a numpy array, plus XGBOD.labels_, which claimed threshold_ is applied to
  decision_scores_ when fit() never sets threshold_.
- Disclosed CBLOF.n_jobs as accepted-but-unused (see #713).

Sphinx:
- Enabled sphinx.ext.napoleon, absent since numpydoc style was adopted, so
  every Parameters/Attributes heading was parsed as an RST section title. A
  full build goes from 310 warnings and 242 class="problematic" spans to 41
  and 5, and the :attr: links for decision_scores_ and labels_ resolve for the
  first time.
- Enabling it also exposed five docstrings the parser could not read, inert
  text until now: AnoGAN emitted 1 of 16 parameters, RGraph 5 of 16, DIF 30
  fields for an 11-parameter constructor, XGBOD turned a commented-out block
  into four bogus parameters, and so_gaal_new.SO_GAAL had an entirely empty
  Parameters section. All five repaired; a sweep over all 62 detectors now
  parses every documented parameter with no bogus or missing entries.
- Removed the dead pyod.models.auto_encoder_torch section (module deleted in
  2024; a duplicated :exclude-members: made the directive raise
  DuplicateOptionError, which Sphinx stripped, so the page rendered a bare
  heading) and de-duplicated the pyod.models.base automodule.

Entry points:
- The README quick start called clf.fit(X_train) without defining X_train and
  used visualize without importing it, so the block on the GitHub landing page
  and the PyPI description raised NameError when pasted.
- docs/install.rst documented a pytorch extra that does not exist (pip treats
  an unknown extra as a warning, so the command succeeded while installing
  none of the PyTorch stack), omitted nine real extras and pyod[all], claimed
  the MCP server registers seven tools when it registers ten, and advertised
  Claude Desktop support for a command no code path targets.

Examples: fixed runtime failures in mad_example.py (two features for a
univariate-only detector) and qmcd_example.py (appended ground-truth labels to
the feature matrix before predict, raising and leaking test labels).
mat_file_conversion.py now byte-compiles after removal of mid-file Python 2
__future__ imports.

Deferred to separate issues, since each needs a runtime decision: #713
(CBLOF.n_jobs), #714 (DevNet unused parameters including random_state), #715
(pyod info infers Claude Code from a directory it creates itself).

Full suite: 1532 passed, 0 failed. Reviewed via /implement-review (Codex round
6), which caught that enabling Napoleon had silently broken four docstrings --
a failure mode that produces no "problematic" markup and so was invisible to
the metric used to validate the change.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: df3dded3f8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +47 to +48
The number of epochs of training. Training stops early, after
``epoch_num // 3`` epochs, once the generator has converged.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Describe the generator's actual stopping behavior

For any epoch_num >= 1, BaseDeepLearningDetector.train() calls epoch_update() after the first epoch, and SO_GAAL.epoch_update() tests the constant expression self.epoch_num >= self.epoch_num // 3, which is immediately true. The generator therefore stops updating after one epoch, with no convergence check, rather than after epoch_num // 3 epochs as newly documented; users cannot rely on this parameter description when choosing a training duration.

Useful? React with 👍 / 👎.

Comment on lines +59 to +61
use_compile : bool, optional (default=False)
If True, compile the model with ``torch.compile`` before training.
Requires PyTorch 2.0 or later; ignored on older versions.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not promise compile is ignored on older PyTorch

When PyOD is installed without the optional torch extra into an environment that already has PyTorch 1.x, setting use_compile=True is not ignored: training_prepare() calls torch.compile(...) unconditionally and raises AttributeError. Either guard this call by the PyTorch version or document that this option requires PyTorch 2.0+, rather than telling users the unsupported setting safely falls back.

Useful? React with 👍 / 👎.

@yzhao062
yzhao062 merged commit 3d0169a into master Aug 2, 2026
26 checks passed
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.

1 participant