Commit dfb81ed
authored
Migrate QGIS plugin to Qt5/Qt6 dual compatibility (QGIS 4.0) (#249)
* Migrate QGIS plugin to Qt5/Qt6 dual compatibility (QGIS 4.0)
Single codebase that loads on QGIS 3.28+ (PyQt5) and QGIS 4.0 (PyQt6).
Plugin now appears on the QGIS 4 Ready list via qgisMaximumVersion=4.99.
- Run upstream scripts/pyqt5_to_pyqt6 migrator to fully-qualify Qt enums
(Qt.AlignmentFlag.AlignCenter, QMessageBox.StandardButton.Yes, etc.).
Fully-qualified form works on both PyQt5 (>=5.15) and PyQt6.
- Hand-qualify QGIS core enums the script cannot introspect:
Qgis.Info -> Qgis.MessageLevel.Info, QgsWkbTypes.PointGeometry ->
QgsWkbTypes.GeometryType.PointGeometry, etc.
- metadata.txt: bump version 0.6.0 -> 0.7.0, add qgisMaximumVersion=4.99,
changelog entry. (No supportsQt6 flag; that field was removed in QGIS 4.)
- update_checker.py: add _require_https() guard before urlopen/urlretrieve;
annotate the two call sites with # nosec B310 (defense-in-depth for
hardcoded https GitHub constants).
- qgis_plugin/tests/: add PyQt6 import-smoke tests (auto-discovers plugin
package via metadata.txt) with a qgis.PyQt -> PyQt6 stub conftest.
- .github/workflows/qgis-plugin.yml: new CI with Bandit (matches the
plugins.qgis.org medium-severity gate) and PyQt6 import smoke matrix
(Python 3.10-3.13 with the libEGL/libGL runtime libs PyQt6.QtGui dlopens).
- .pre-commit-config.yaml: add Bandit hook scoped to qgis_plugin/.
References:
- https://github.com/qgis/QGIS/wiki/Plugin-migration-to-be-compatible-with-Qt5-and-Qt6
- https://plugins.qgis.org/docs/migrate-qgis4
* Address Copilot review feedback
- conftest.py: gate PyQt6 imports behind pytest.importorskip so other
pytest invocations (e.g. `pytest .` from the repo root) don't fail
collection when PyQt6 is absent.
- test_pyqt6_imports.py: explicitly insert PLUGIN_ROOT.parent on
sys.path before importlib.import_module so the test does not depend
on pytest's rootdir detection. Mirrors how QGIS adds plugin parent
dirs to sys.path.
- update_checker.py: move the two `# nosec B310` annotations from the
closing-paren line onto the line containing `urlopen(` /
`urlretrieve(`, where Bandit attaches the finding. Same suppression
count (2) but more robust across Bandit versions.
- qgis-plugin.yml: pin `pip install bandit==1.9.4` to match the
pre-commit revision so local and CI runs use the same Bandit ruleset.
* Rename qgis_plugin/tests -> qgis_plugin/qt6_tests to avoid pytest package collision
The repo already has a top-level tests/ package (with __init__.py).
Adding qgis_plugin/tests/__init__.py registered a second `tests` package
with the same dotted name, so pytest's default prepend importmode
collapsed both into one entry in sys.modules. The first one to be
collected won, and every test in the other directory then failed with
`ModuleNotFoundError: No module named 'tests.test_<x>'` -- breaking the
existing ubuntu/macos/windows CI workflows that run `pytest .` from the
repo root.
Renaming to qt6_tests gives the smoke tests a unique top-level package
name. The auto-discovery in test_pyqt6_imports.py is name-agnostic
(it globs `*/metadata.txt`), so no test logic changes are needed; only
the CI workflow path is updated.1 parent 61ea3db commit dfb81ed
19 files changed
Lines changed: 396 additions & 148 deletions
File tree
- .github/workflows
- qgis_plugin
- hypercoast_qgis
- core
- dialogs
- qt6_tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
44 | | - | |
| 44 | + | |
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
49 | | - | |
| 49 | + | |
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| |||
217 | 217 | | |
218 | 218 | | |
219 | 219 | | |
220 | | - | |
| 220 | + | |
221 | 221 | | |
222 | 222 | | |
223 | 223 | | |
| |||
258 | 258 | | |
259 | 259 | | |
260 | 260 | | |
261 | | - | |
| 261 | + | |
262 | 262 | | |
263 | 263 | | |
264 | 264 | | |
| |||
267 | 267 | | |
268 | 268 | | |
269 | 269 | | |
270 | | - | |
| 270 | + | |
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
| |||
339 | 339 | | |
340 | 340 | | |
341 | 341 | | |
342 | | - | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
343 | 346 | | |
344 | 347 | | |
345 | | - | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
346 | 352 | | |
347 | 353 | | |
348 | 354 | | |
349 | | - | |
| 355 | + | |
350 | 356 | | |
351 | 357 | | |
352 | 358 | | |
| |||
366 | 372 | | |
367 | 373 | | |
368 | 374 | | |
369 | | - | |
| 375 | + | |
370 | 376 | | |
371 | 377 | | |
372 | 378 | | |
373 | | - | |
| 379 | + | |
374 | 380 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | | - | |
| 35 | + | |
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| |||
142 | 142 | | |
143 | 143 | | |
144 | 144 | | |
145 | | - | |
| 145 | + | |
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
| |||
213 | 213 | | |
214 | 214 | | |
215 | 215 | | |
216 | | - | |
| 216 | + | |
217 | 217 | | |
218 | 218 | | |
219 | 219 | | |
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
225 | | - | |
| 225 | + | |
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
| |||
279 | 279 | | |
280 | 280 | | |
281 | 281 | | |
282 | | - | |
| 282 | + | |
283 | 283 | | |
284 | 284 | | |
285 | 285 | | |
286 | | - | |
| 286 | + | |
287 | 287 | | |
288 | 288 | | |
289 | 289 | | |
| |||
303 | 303 | | |
304 | 304 | | |
305 | 305 | | |
306 | | - | |
| 306 | + | |
307 | 307 | | |
308 | 308 | | |
309 | 309 | | |
310 | | - | |
| 310 | + | |
311 | 311 | | |
0 commit comments