Skip to content

fix: define plt before use in heatmap export; annotate pyarrow for type checkers - #80

Open
turbomam wants to merge 2 commits into
mainfrom
bugfix/issue-72-undefined-names
Open

turbomam wants to merge 2 commits into
mainfrom
bugfix/issue-72-undefined-names

Conversation

@turbomam

@turbomam turbomam commented Sep 9, 2026

Copy link
Copy Markdown
Member

Fixes #72.

One of these is a real crash

plotting/cli.py:133 uses plt inside the --export-data branch of the heatmap command:

if isinstance(child, plt.matplotlib.collections.QuadMesh):

plt is never bound there. Every other function in that file does import matplotlib.pyplot as plt locally, but heatmap() does not, and there is no module-level import. Checked the enclosing scope directly: heatmap() spans lines 52 to 172 with no plt import, and no module-level binding exists. So any invocation with --export-data raises NameError: name 'plt' is not defined before it can export anything.

It survived because no test goes through the CLI command. The existing plotting tests call create_heatmap and export_heatmap_data directly.

This PR adds tests/test_plotting/test_heatmap_cli_export.py, which invokes the command through CliRunner with --export-data. Removing the one-line fix and rerunning gives exactly NameError("name 'plt' is not defined"), so the test does catch the regression rather than merely passing.

The fix adds the missing import in that block, matching the lazy-import convention the rest of the file already uses.

The other three are annotations, not crashes

dremio_database.py returns "pyarrow.Table" from three methods. pyarrow is an optional dependency, imported lazily inside the methods that need it, so the name never resolves for a type checker even though nothing fails at runtime.

Fixed with a TYPE_CHECKING import, which resolves the annotations without adding a runtime import or making pyarrow a hard dependency. The comment in the file says so, since a bare import pyarrow under TYPE_CHECKING looks removable otherwise.

Checks

Ruff F821 is now clean across the repository.

Violations in the two touched files go down, not up: plotting/cli.py from 26 to 25, dremio_database.py from 8 to 5. The new test file is ruff-clean.

uv.lock is deliberately untouched. My local test run rewrote it and I reverted that; it is not part of this change.

Scope

Two source lines of real change plus a TYPE_CHECKING block, and one new test.

The other lint issues in these files are left alone. The auto-fixable set from #74 and the CI check from #71 are a separate, mechanical change, and I did not want 96 formatting edits sitting on top of a real bug fix in the same review.

🤖 Generated with Claude Code

…pe checkers

Fixes #72.

The heatmap CLI's --export-data branch used `plt` at plotting/cli.py:133 without
importing it. Every other function in that file imports matplotlib.pyplot
locally, but heatmap() does not, and there is no module-level import, so the
export path raised NameError: name 'plt' is not defined. No test went through
the CLI command, which is why it survived; the existing plotting tests call
create_heatmap and export_heatmap_data directly.

Adds a regression test that invokes the command with --export-data. Confirmed it
fails with that exact NameError without the one-line fix.

The three remaining F821 errors are the "pyarrow.Table" return annotations in the
Dremio adapter. pyarrow is optional and imported lazily inside the methods that
need it, so the names never resolve for a type checker. Adding a TYPE_CHECKING
import fixes that without introducing a runtime import or a hard dependency.

Ruff violations in the two touched files go from 26 to 25 and from 8 to 5. The
lockfile is deliberately untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGdbAo1cW9QBR2u8JBWDdK
Copilot AI lite review requested due to automatic review settings September 9, 2026 19:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The new test’s backend configuration can become collection-order dependent, and there is also an unused import introduced in the touched hunk that should be removed to avoid persistent lint noise.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR addresses the ruff F821 undefined-name crash in the plot heatmap --export-data CLI path (issue #72) by ensuring matplotlib.pyplot is imported before use, and improves static typing for optional pyarrow return annotations in the Dremio store without adding a runtime dependency. It also adds a regression test that exercises the CLI export path via CliRunner.

Changes:

  • Fix heatmap CLI --export-data path to define plt before it’s referenced.
  • Add a TYPE_CHECKING-only pyarrow import so "pyarrow.Table" annotations resolve for type checkers.
  • Add a new pytest regression test that invokes the plot heatmap command with --export-data.
File summaries
File Description
tests/test_plotting/test_heatmap_cli_export.py New regression test covering the CLI --export-data path.
src/linkml_store/plotting/cli.py Imports matplotlib.pyplot as plt in the export branch to avoid NameError.
src/linkml_store/api/stores/dremio/dremio_database.py Adds TYPE_CHECKING import for pyarrow to satisfy type checkers for "pyarrow.Table".
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +11 to +20
import csv
from pathlib import Path

import matplotlib
import pytest
from click.testing import CliRunner

matplotlib.use("Agg") # no display in CI

from linkml_store.plotting.cli import plot_cli # noqa: E402

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Checked this rather than assuming, and the stated failure does not reproduce. On matplotlib 3.11.1, importing matplotlib.pyplot first and then calling matplotlib.use("Agg") switches the backend and raises nothing:

pyplot imported first, backend: macosx
matplotlib.use(Agg) AFTER pyplot: OK, backend now Agg

The concern underneath it is fair though. Setting a backend at module import is a session-wide side effect, and whether it fires depends on which test module loads first. 6a1d444 passes force=False, so if another module has already loaded a backend this leaves it alone instead of switching it out from under other tests. That costs nothing and removes the order dependence regardless of matplotlib version.

Whole plotting suite passes: 7 passed.

Comment thread src/linkml_store/plotting/cli.py Outdated
…backend

Removes `from matplotlib.axes import Axes`, which is imported in the export
branch and used nowhere in the module. Pre-existing rather than introduced here,
but it sits on the line next to the fix, so it belongs in this hunk.

Backend selection now passes force=False. The reviewer's stated failure, that
matplotlib.use can raise when pyplot is already imported, does not reproduce on
matplotlib 3.11.1, where the switch succeeds. The underlying concern about a
session-wide side effect is fair though, and force=False removes it at no cost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGdbAo1cW9QBR2u8JBWDdK
@turbomam turbomam changed the title fix: define plt before use in heatmap export; annotate pyarrow for type checkers fix: define plt before use in heatmap export; annotate pyarrow for type checkers Sep 9, 2026
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.

Fix 4 undefined-name (F821) errors caught by ruff

2 participants