Import heavy third-party modules lazily (matplotlib, numpy, cv2)#110
Merged
Conversation
Problem: Importing anything from hardwarelibrary.spectrometers eagerly loaded matplotlib and numpy. base.py did `from .viewer import *` (viewer is a pure matplotlib GUI module) purely to reach SpectraViewer, and imported numpy at module scope. oceaninsight.py imported matplotlib (backends/pyplot/animation/Button/TextBox) that it never actually used, plus numpy at module scope. __init__.py imported SpectraViewer at the top. As a result `import hardwarelibrary` paid the full matplotlib + numpy cost even when no plot was ever drawn. Solution: Move the heavy imports to their point of use. SpectraViewer is now imported inside Spectrometer.display(), OISpectrometer.display() and displayAny(). numpy is imported inside the __init__/getSpectrum methods that use it; base.py gains `from __future__ import annotations` so the `-> np.array` hint no longer forces numpy at class-definition time. The dead matplotlib import block in oceaninsight.py (never referenced) is removed. viewer.py is unchanged: it legitimately needs matplotlib, and is now only imported when a viewer is actually shown. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem: oscilloscopedevice.py imported matplotlib.pyplot at module scope, so `import hardwarelibrary` (which imports the oscilloscope package) loaded matplotlib even though plt is only ever used by the optional displayWaveforms() method. Solution: Move `import matplotlib.pyplot as plt` into displayWaveforms(), its only caller. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem: camera.py imported cv2 at module scope behind a try/except. Importing the cameras package therefore loaded OpenCV eagerly, and a missing OpenCV only surfaced as a printed warning at import time while leaving cv2 undefined for later calls. Solution: Remove the top-level guarded import and import cv2 inside the three methods that use it (captureLoopSynchronous, openCVProperties, doInitializeDevice). The module now imports without OpenCV present, and a missing dependency surfaces as a clear ModuleNotFoundError only when a camera operation is actually invoked. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem: sutterdevice.py and echodevice.py both did `from pyftdi.ftdi import Ftdi`, each already flagged with a `#FIXME: should not be here.` comment. Neither file references Ftdi anywhere, so the imports were dead code that pulled pyftdi in eagerly. Solution: Delete the unused imports. SutterDevice reaches FTDI hardware through SerialPort, which owns the pyftdi dependency. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
import hardwarelibraryeagerly loadedmatplotlibandnumpythrough the spectrometer and oscilloscope packages, even when nothing was ever plotted or acquired. Several imports were also dead:oceaninsight.pyimported matplotlib it never used, andSutterDevice/EchoDeviceimportedpyftdi.Ftdithey never referenced (both already flagged#FIXME: should not be here).Solution
Defer each non-standard module to its point of use, and delete the dead imports:
010ab73):SpectraViewernow imported insidedisplay()/displayAny();numpyinside the__init__/getSpectrummethods that use it;base.pygainsfrom __future__ import annotationsso the-> np.arrayhint no longer forces numpy at class-definition time. Removed the unused matplotlib import block inoceaninsight.py.viewer.pyis unchanged — it legitimately needs matplotlib and is now only imported when a viewer is shown.ffb1457):matplotlib.pyplotmoved intodisplayWaveforms(), its only caller.ba2a102): removed the top-level guardedimport cv2; deferred into the three methods that use it. A missing OpenCV now surfaces as a clearModuleNotFoundErroronly when a camera op is invoked, instead of a print at import time.6013246): removed unusedfrom pyftdi.ftdi import FtdifromSutterDeviceandEchoDevice.Result
import hardwarelibrary: 336 ms -> 59 ms, withmatplotlibandnumpyno longer loaded until you actually plot or acquire.Reviewed and left as-is
pyftdiincommunication/serialport.py— genuinely used across several methods, ~10 ms to import, core serial dependency.pyserial/pyusb— lightweight core comms deps, used pervasively.u3(LabJack) indaq/labjackdevice.py— not on the default import path.pylablibinmotion/thorlabs.py— already lazily imported.Testing
Full suite: 398 passed, 235 skipped (hardware-absent), unchanged from baseline.
Deferred paths exercised directly:
DebugSpectro.getSpectrum()(numpy), oscilloscope + cameras imports without matplotlib/cv2 loaded.🤖 Generated with Claude Code