Skip to content

maint: close search.log handler + four CLI-noise warning fixes #1495

Description

@Jammy2211

Overview

A /cli_noise_clean audit of the full PyAutoFit suite (1667 tests, -W all) surfaced five mechanical warning sources, all in PyAutoFit. The largest is an unclosed search.log FileHandler leaking a file descriptor per decorated search call (44 warnings/run); the rest are one deprecation each from SQLAlchemy, nautilus, scipy, and CPython's fork-in-threads check. All five are noise-only fixes with no behaviour change.

Plan

  • Close the search.log FileHandler in configure_handler's finally block, beside the existing removeHandler.
  • Annotate the overlapping Fit.arrays/Fit.hdus vs HDU.fit SQLAlchemy relationships with the overlaps= parameters SQLAlchemy suggests, silencing the SAWarning from configure_mappers().
  • Swap the deprecated nautilus search_internal.evidence() call for the .log_z property.
  • Stop forwarding the scipy-deprecated disp/iprint options to the L-BFGS-B solver (constructor keeps accepting them for API stability).
  • Add a module-local filterwarnings mark to test_fork_context.py for CPython's fork-in-a-multi-threaded-process DeprecationWarning, which pytest's background thread makes unavoidable there.
Detailed implementation plan

Affected Repositories

  • PyAutoFit (primary, only)

Work Classification

Library

Branch Survey

Repository Current Branch Dirty?
PyAutoFit main (fresh clone @ 401e666) clean

Branch: claude/pyautofit-cli-noise-fixes-vqs7mg (session-designated; remote web session, no local worktree — the ~/Code/PyAutoLabs-wt/ flow is not used)

Note: active.md claims PyAutoFit for stored-sample-reconstruction-guard (autofit/non_linear/samples/) and version-stamp-sync-guards (autofit/__init__.py, files/release.sh). This task is file-disjoint from both.

Implementation Steps

  1. autofit/non_linear/search/abstract_search.py (configure_handler, finally block): add handler.close() after root_logger.removeHandler(handler) — the handler holds search.log open otherwise (44 ResourceWarnings per suite run).
  2. autofit/database/model/array.py: Array.fit, HDU.fit, Fit.arrays and Fit.hdus all write the same array.fit_id column (HDU inherits it via joined-table inheritance), which fires SAWarning: relationship ... will copy column fit.id to column array.fit_id, which conflicts with relationship(s) ... at configure_mappers(). Add the overlaps="..." parameter with exactly the relationship names SQLAlchemy's warning lists (reproduced locally before committing).
  3. autofit/non_linear/search/nest/nautilus/search.py (samples_info_from, line 535): search_internal.evidence()search_internal.log_z (nautilus deprecated the method for the property).
  4. autofit/non_linear/search/mle/bfgs/search.py: scipy 1.15 deprecated the L-BFGS-B disp/iprint options (removal slated for 1.18). Override options in LBFGS to drop both keys before the dict reaches optimize.minimize; constructor keeps accepting them (API stability; disp remains live for plain BFGS). Update test_autofit/non_linear/search/optimize/test_lbfgs.py accordingly (assert the attributes survive and the options keys are absent).
  5. test_autofit/non_linear/test_fork_context.py: add pytestmark = pytest.mark.filterwarnings("ignore:This process:DeprecationWarning") — CPython 3.12+ warns on os.fork() in a multi-threaded process, and pytest's machinery keeps a thread alive; the tests exercise the fork-pinned pool deliberately.

Out of scope (noted lowest-priority in the prompt): edge-case LinAlgWarning/RuntimeWarning from tests that deliberately exercise degenerate inputs (interpolator/covariance.py, messages/normal.py, fitness.py).

Key Files

  • autofit/non_linear/search/abstract_search.py — handler close
  • autofit/database/model/array.py — SQLAlchemy overlaps=
  • autofit/non_linear/search/nest/nautilus/search.py.log_z
  • autofit/non_linear/search/mle/bfgs/search.py + test_autofit/non_linear/search/optimize/test_lbfgs.py — L-BFGS-B options
  • test_autofit/non_linear/test_fork_context.py — fork warning mark

Testing

  • Reproduce each warning on main first (SAWarning via sa.orm.configure_mappers(); scipy deprecation via an af.LBFGS fit; handler leak via -W error::ResourceWarning on a search-log test), then show it gone after the fix.
  • Run the affected test files: test_autofit/non_linear/search/optimize/test_lbfgs.py, test_autofit/non_linear/test_fork_context.py, test_autofit/database/, nautilus search tests, plus the non_linear/search tree.

Original Prompt

Click to expand starting prompt

PyAutoFit CLI-noise batch: unclosed search.log handler + four small warning fixes

Type: maintenance
Target: PyAutoFit
Repos:

  • PyAutoFit
    Difficulty: small
    Autonomy: safe
    Priority: normal
    Status: formalised

Filed 2026-08-06 from a full /cli_noise_clean audit (full PyAutoFit suite,
1667 tests, -W all). Five mechanical fixes, all in PyAutoFit:

  1. Unclosed search.log FileHandler (44 warnings/run)
    autofit/non_linear/search/abstract_search.py:123-131 (configure_handler)
    removes the handler in finally but never calls handler.close(). Add
    handler.close() beside removeHandler at line 131.
  2. SQLAlchemy SAWarning relationship overlapFit.arrays/Fit.hdus
    vs HDU.fit ("will copy column fit.id ... conflicts"). Add the
    overlaps="..." parameters SQLAlchemy suggests, in the DB model
    definitions (fires from configure_mappers(), not the test).
  3. Nautilus deprecationnon_linear/search/nest/nautilus/search.py:535
    uses search_internal.evidence(); swap to the .log_z property.
  4. scipy L-BFGS-B deprecationnon_linear/search/mle/bfgs/search.py:194
    passes deprecated disp/iprint options; drop them per scipy's migration
    note (or gate on scipy version).
  5. fork() DeprecationWarning in test_fork_context.py — pytest's thread
    pool + os.fork(); add a module-local filterwarnings mark or use the
    spawn context in that test where feasible.

Edge-case numerical warnings from tests that deliberately exercise degenerate
inputs (LinAlgWarning/RuntimeWarning in interpolator/covariance.py,
messages/normal.py, fitness.py) are lowest priority — silence locally in
the triggering tests with warnings.catch_warnings(), never globally.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions