# Local modifications to pyqtgraph

This repository vendors a reduced copy of pyqtgraph.

## Removed
The following components have been removed because they are not used by
Insar Explorer and triggered unnecessary security scanner warnings:


- `configfile.py`
- `flowchart`
- `opengl`
- `console`
- `examples`


- Removed `multiprocess` and `widgets/RemoteGraphicsView.py` and removed `from .widgets.RemoteGraphicsView import RemoteGraphicsView` from `__init__.py`


## Modified
The following components have been modified to address security scanner warnings:

- `exporters/SVGExporter.py`
  1. `doc = xml.parseString(xmlStr)  # nosec B318 - parses a hardcoded constant`
  2. `doc = xml.parseString(xmlStr)  # nosec B318 - parses a hardcoded constant`
  3. `doc = xml.parseString(arr.data())  # nosec B318 - parses SVG generated by QSvgGenerator`


- `Qt/__init__.py`
  1. Remove `import subprocess`
  2. Replaced `_loadUiType()` with a guarded implementation that raises a `RuntimeError` when called under PySide.
      ```
      def _loadUiType(uiFile):
        raise RuntimeError(
            "PySide UI compilation is disabled in this QGIS-vendored PyQtGraph. "
        )
      ```
  3. Adapted the active Qt bootstrap for the QGIS-vendored build to use `qgis.PyQt` instead of independently importing or probing system PyQt/PySide bindings. The pyqtgraph-facing `QtCore`, `QtGui`, and `QtWidgets` facade is preserved, while the active binding is controlled by QGIS. Direct `PyQt5` / `PyQt6` imports were removed from the active QGIS runtime path, and PySide is not selected as the active binding in this build.
  4. Added centralized `exec_qt(...)` compatibility that prefers modern `exec()` and dynamically falls back to Qt5 `exec_()`, forwarding arguments and preserving return values. The module-level `exec()` application-event-loop helper now delegates through `exec_qt(...)`.

- `dockarea/Dock.py`
  - Route drag execution through `exec_qt(...)` instead of directly calling Qt5-style `exec_()`. Modern `exec()` is preferred, Qt5 fallback remains supported, and dock drag/drop behavior is otherwise unchanged.

- `exporters/PrintExporter.py`
  - Route print-dialog execution through `exec_qt(...)` instead of directly calling `exec_()`, preserving Qt5/Qt6 dialog compatibility with no other print-export behavior change.

- `debug.py`
  - Obtain SIP through the QGIS-controlled pyqtgraph Qt facade / `qgis.PyQt` path instead of importing it directly from `PyQt5`, avoiding an independent system-PyQt binding.

- QGIS Qt integration architecture
  - These are intentional local QGIS-vendor patches, not generic upstream pyqtgraph changes. The retained runtime follows `QGIS -> qgis.PyQt -> vendored pyqtgraph Qt facade -> retained pyqtgraph runtime` so pyqtgraph stays aligned with the Qt binding already loaded by QGIS while preserving QGIS 3 / Qt5 and QGIS 4 / Qt6 compatibility.

- `metaarray/MetaArray.py`
  1. `import ast`
  2. replace `ret = eval(meta)` with `ret = ast.literal_eval(meta)`
  3. replace `inf = eval(line)` with `inf = ast.literal_eval(line)`
  4. replace `val = eval(val)` with `val = ast.literal_eval(val)`
  5. `subarr = pickle.loads(fd.read())  # nosec B301`
  6. `data = pickle.loads(fd.read(inf["len"]))  # nosec B301` 

### Security / Bandit cleanup

- `SignalProxy.py`
  - Narrow Qt signal disconnect failures to `TypeError`/`RuntimeError`.
  - Replace the slot-connected assertion with an explicit `RuntimeError` guard.
- `debug.py`
  - Narrow expected probing failures in ndarray-size and QObject-report helpers.
- `dockarea/Container.py`
  - Narrow expected signal-disconnect failures.
- `graphicsItems/ScatterPlotItem.py`
  - Narrow symbol-conversion probing failures to expected conversion exceptions.
- `graphicsItems/ViewBox/ViewBox.py`
  - Replace exception-swallowing list removal with an explicit membership check.
- `widgets/ScatterPlotWidget.py`
  - Narrow expected signal-disconnect failures.
- `functions_qimage.py`
  - Replace the internal LUT assertion with an explicit runtime invariant check.
- `graphicsItems/AxisItem.py`
  - Replace `stopAxisAtTick` assertion-based validation with explicit validation.
- `parametertree/SystemSolver.py`
  - Replace range-constraint shape assertion with explicit validation.
- `parametertree/parameterTypes/pen.py`
  - Replace the fallback receiver-count assertion with an explicit runtime invariant check.
- `graphicsItems/GraphicsItem.py`
  - Remove the runtime `xml.etree.ElementTree.Element` import used only for annotations; use `Any` annotations instead.
- `exporters/SVGExporter.py`
  - Mark the reviewed `xml.dom.minidom` import with targeted `# nosec B408`; minidom is only used with hardcoded or internally generated SVG and parse sites remain separately reviewed.
- `metaarray/MetaArray.py`
  - Mark the reviewed `pickle` import with targeted `# nosec B403`; deserialization sites remain separately annotated with `# nosec B301`.
  - Remove the dead remote-HDF5 fallback that depended on the already-removed `multiprocess` package. When `h5py` is unavailable, HDF5 loading now fails immediately with the existing explicit unsupported-dependency error.
  - Replace byte-decoding `try/except/pass` blocks with explicit `bytes` checks.
- `widgets/DiffTreeWidget.py`
  - Removed after dependency audit found no production or retained-runtime users other than its top-level pyqtgraph export; the corresponding export was removed from `external/pyqtgraph/__init__.py`.
