Skip to content

V1: fix beta correctness bugs, packaging, and documentation#39

Open
ngg1995 wants to merge 2 commits into
masterfrom
v1-fixes
Open

V1: fix beta correctness bugs, packaging, and documentation#39
ngg1995 wants to merge 2 commits into
masterfrom
v1-fixes

Conversation

@ngg1995

@ngg1995 ngg1995 commented Jun 29, 2026

Copy link
Copy Markdown
Member

Overview

Takes the library from beta toward a trustworthy V1: fixes a large set of correctness bugs, cleans up packaging/CI, and makes the documentation accurate and self-verifying. Two commits:

  1. Fix beta-stage correctness bugs and packaging for V1
  2. Make documentation correct and enforce docstring examples in CI

A full read of every module surfaced many bugs that the previous test suite never caught (it only exercised Pbox + Pbox). All fixes were verified by running the code; new tests pin each one. No public API was removed — only fixed/added.

Why

Basic operations were broken in ways the tests didn't cover, e.g. pba.N(0,1) + 1 raised TypeError and pba.what_I_know(minimum=0, maximum=10, mean=5) raised. The docs also drifted from the code (22 of 86 docstring examples were wrong, and the Sphinx build had broken references).

Correctness fixes (verified)

Critical

  • Pbox arithmetic with scalars/Intervals was completely broken — _arithmetic referenced an undefined variable (other vs b). pbox + 5, N(0,1) + 1, pbox + Interval now work.
  • pba.sum / pba.mean raised TypeError (isinstance(x, [list, ...]) → tuple).
  • Interval.add/sub with method='p'/'o' returned None (missing return).
  • Interval.__ge__ was a copy-paste of __le__ (wrong results).
  • Interval.env([...]) raised on list input; Pbox.exp/sqrt used the wrong kwarg.
  • beta() (and KN/KM) raised; what_I_know built its imposition list wrong; imposition() discarded its result; min_mean had a length mismatch; min_max_median built bounds from probabilities instead of values.

High

  • always/never returned None for mid-range values; Pbox.min/max called the NotImplemented singleton; logicaland/logicalor applied builtin min/max to p-boxes; core.sqrt had a "PBox" typo; Interval.__pow__ raised on numpy exponents.

Other

  • Interval.intersection used a containment test instead of overlap, so Interval(0,1).intersection(Interval(0.5,1.5)) returned None instead of [0.5,1].
  • Fixed a backwards division-by-zero guard, __rsub__, removed a dead Pbox.mean method, uniform ignoring steps, a mean-formula typo, a broken t() constructor, stray debug prints, dead pseudo-dunders, operand-mutating _check_steps, mixture returning a string, an invalid interpolation method, and narrowed all bare except: clauses.

Packaging / CI

  • Removed the distutils setup.py (breaks on Python ≥3.12) and the stale MANIFEST; pyproject.toml is now authoritative (requires-python, classifiers, dev/docs extras).
  • CI coverage was --cov=com (nonexistent) → --cov=pba; added a Python 3.10–3.13 matrix and install the package itself.
  • Comprehensive .gitignore; updated the release workflow.

API additions

  • pba.__version__; exported Cbox, singh, min_mean, max_mean, change_default_arithmetic_method; closed an np/warnings namespace leak.
  • Added Interval.__hash__ (Intervals were unhashable because __eq__ returns a Logical). Comparisons still return Logical by design.

Documentation

  • Fixed all wrong docstring examples (pba.pmPM, incorrect never/xtimes outputs, [0,1][0, 1] whitespace) and converted implementation/side-effecting pseudo-code into illustrative code blocks.
  • Sphinx build is now warning-free (fixed broken cross-references, an invalid .. example:: directive, a remote-image :scale: warning; conf.py version now read from package metadata).
  • Doctests are now enforced: a conftest.py injects the common names, pyproject enables --doctest-modules, and CI runs them so examples can't silently drift again.

Reviewer notes

  • Deferred (not in this PR): broader unit-test coverage and docs prose/content expansion.
  • A couple of distribution-free constructors (trapz, weibull) have questionable SciPy parameterizations that were left unchanged — they need domain validation rather than an obvious fix.
  • tests/test_regression_v1.py adds targeted regression coverage for each Tier-1/Tier-2 fix.

Verification

pytest → 64 passed (50 unit + 14 doctest items); Sphinx build succeeds with 0 warnings; python -m build produces a valid sdist/wheel.

🤖 Generated with Claude Code


📚 Documentation preview 📚: https://readthedocs-preview--39.org.readthedocs.build/en/39/

Nick and others added 2 commits June 29, 2026 10:03
Audit of the whole library surfaced many bugs that the existing tests
(which only exercised Pbox+Pbox) never caught. All fixes verified by
running the code; adds tests/test_regression_v1.py to pin each one.

Critical correctness:
- pbox._arithmetic referenced undefined `other` -> Pbox+scalar/Interval
  (incl. N(0,1)+1) were broken
- core.sum/mean: isinstance(x, [list,...]) raised TypeError
- Interval.add/sub method 'p'/'o' missing return (returned None)
- Interval.__ge__ was a copy-paste of __le__ (wrong results)
- Interval.env([...]) isinstance list-literal bug
- Pbox.exp/sqrt used wrong kwarg (function= vs func=)
- beta() stray `args = list(args)` + invalid scipy support kwarg
  (also unbroke KN/KM)
- what_I_know used `imp += pbox` (extends with values) and passed a list
  to imposition()
- imposition() discarded p.imp() result; Pbox.imp used undefined `pbox`
- min_mean off-by-one length mismatch
- min_max_median built bounds from probabilities, not values

High-severity logic:
- always/never bare `False` (returned None)
- Pbox.min/max error path called NotImplemented(...) as a function
- logicaland/logicalor used builtin min/max on p-boxes; fixed all
  dependency methods and logicalor's wrong env() arity
- core.sqrt checked "PBox" (typo); Interval.__pow__ UnboundLocalError on
  numpy exponents

Cleanups:
- __rsub__ interval branch, removed dead Pbox.mean method, uniform
  ignored steps, min_max_median_is_mode mean typo, removed broken t(),
  dropped debug prints / print->warn, removed dead pseudo-dunders,
  _check_steps no longer mutates operands, mixture raises instead of
  returning a string, invalid interpolation="outer", narrowed bare
  excepts, fixed backwards _check_div_by_zero guard

Packaging / CI:
- removed distutils setup.py (broke on 3.12) and stale MANIFEST;
  pyproject.toml is now authoritative (requires-python, classifiers,
  dev/docs extras)
- CI: --cov=com -> --cov=pba, Python 3.10-3.13 matrix, install package
- comprehensive .gitignore; updated release workflow

V1 API:
- added pba.__version__; exported Cbox/singh/min_mean/max_mean/
  change_default_arithmetic_method; closed np/warnings namespace leak
- added Interval.__hash__ (kept Logical-returning comparisons)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Sphinx build had broken cross-references and an invalid directive, and
22 of 86 docstring examples were wrong (incorrect outputs, removed/renamed
APIs, or implementation pseudo-code mislabelled as runnable examples).

Code fix surfaced by the docs:
- Interval.intersection used a containment test (straddles) instead of an
  overlap test, so Interval(0,1).intersection(Interval(0.5,1.5)) returned
  None instead of [0.5, 1] (the documented result). Now uses a proper
  overlap test; the list form checks max(lefts) <= min(rights).

Docstring example fixes:
- pba.pm -> pba.PM
- never/xtimes examples had outputs contradicting the (correct) comparison
  logic; replaced with comparisons that demonstrate the documented results
- whitespace: "Interval [0,1]" -> "Interval [0, 1]" to match repr
- converted implementation pseudo-code and side-effecting plotting/repr
  examples (>>> self.*, pm_repr/lr_repr global mutation, Pbox.show) into
  illustrative code-blocks so they aren't run as doctests
- marked the non-deterministic Interval.sample() example +SKIP

Sphinx build (now warning-free):
- fixed broken refs (pba.core.envelope, pba.pbox.Pbox.env, interpolation,
  lr_interval_repr) using :func:/:meth: roles
- replaced invalid ".. example::" directive with ".. admonition:: Example"
- replaced remote-image :scale: with :width: to avoid size warning
- conf.py: release now read from package metadata (was v0.16.2); copyright year

Doctest enforcement:
- conftest.py injects pba/np/Interval/Pbox/Logical into the doctest namespace
- pyproject pytest config: testpaths=[tests, pba], --doctest-modules,
  NORMALIZE_WHITESPACE + ELLIPSIS
- testing.yml runs the full suite so examples can't silently drift again

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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