Repository navigation
build(deps): move to pgserviceparser 3, keep the GUI binding choice safe - #513
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #513 +/- ##
==========================================
+ Coverage 78.11% 78.17% +0.05%
==========================================
Files 55 55
Lines 3473 3482 +9
Branches 424 425 +1
==========================================
+ Hits 2713 2722 +9
Misses 639 639
Partials 121 121
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
7 of 11 tasks
Guts
force-pushed
the
improve/pgserviceparser-3
branch
from
October 18, 2026 08:09
3973b67 to
8ec6a86
Compare
Guts
added a commit
that referenced
this pull request
Oct 18, 2026
## Description Drops Python 3.10 support. 3.10 reaches its end of life this month (October 2026), and dependencies already move on: pgserviceparser 3 requires Python >= 3.11 (see #513, which needs environment markers only because of 3.10). | Where | Change | | --- | --- | | `pyproject.toml` | `requires-python = ">=3.11, <4"`, 3.10 classifier removed, ruff `target-version = "py311"` | | `.pre-commit-config.yaml` | pyupgrade `--py311-plus` | | `tester.yml` | 3.10 removed from the Ubuntu matrix (the Windows one already started at 3.11, for lack of a cp310 GDAL wheel in the pinned geospatial-wheels release) | | `builder_releaser.yml` | Linux executables built with Python 3.11 instead of 3.10 — the Windows ones already used 3.11 | | `docs_builder.yml` | docs built with 3.11 | | `sonar-project.properties` | analyzed versions | | `docs/development/` | Ubuntu and Windows setup pages | No code change was needed: ruff with the py311 target and `pyupgrade --py311-plus` find nothing to rewrite, and there was no 3.10-specific code path. The `ExtendedEnum.has_value()` helper stays: membership testing an `Enum` with a plain value still raises `TypeError` on 3.11 (it only works from 3.12). ### Verification - `pre-commit run` passes on the branch's changes. - Installing on Python 3.10 is now refused by the resolver (`requires-python`). ### Breaking change DicoGIS no longer installs on Python 3.10. The executables are unaffected for end users (they embed their own Python), but the Linux ones are now built with 3.11: worth a quick smoke test of the next release build. ## Related issue(s) Unblocks a simpler #513 (no more environment markers for pgserviceparser). ## Type of change - [ ] Bug fix (`fix/…` branch) - [ ] New feature or enhancement (`feature/…` branch) - [x] Documentation (`docs/…` branch or `*.md`/`docs/**` changes) - [x] Packaging / build (`packaging/…` branch or `builder/**` changes) - [x] Tooling / CI-CD (`tooling/…` branch or `.github/**` changes) - [ ] Tests only (`tests/**` changes) ## Checklist - [x] I have read the [Contributing Guidelines](/CONTRIBUTING.md) - [x] `pre-commit run --all-files` passes locally (on the branch's changes) - [ ] I have added or updated tests covering my changes (CI matrix change only) - [x] I have updated the documentation where relevant - [x] `pytest` passes locally (no code change) ## AI/LLM disclosure - **Level**: 7 — human specced, bots coded. - **Model**: claude-opus-5-5 - **Session**: https://claude.ai/code/session_01Dwmm8jY9WWvgUJt9WQ7QWZ --- _Generated by [Claude Code](https://claude.ai/code/session_01Dwmm8jY9WWvgUJt9WQ7QWZ)_
In auto mode, the Qt binding was qgis.PyQt as soon as a "qgis" package was imported. But some libraries import qgis.PyQt on their own when QGIS is installed: pgserviceparser >= 3 does, at import time, through its new gui subpackage. And QGIS's own qgis/__init__.py imports qgis.gui, hence qgis.core: a standalone dicogis-gui on a machine with QGIS installed (python3-qgis on Linux) would then load QGIS and could switch to its binding, possibly Qt 5 with QGIS 3. Today only the import order of dicogis-gui avoided it, by resolving the binding before pgserviceparser is imported. auto now checks that the running Qt application is a QgsApplication, looking only at an already loaded qgis.core, never importing QGIS itself. Inside QGIS (desktop, plugin, qgis_process) one is running; in a standalone process it isn't, whatever got imported. Tests cover QGIS absent, imported without application (the pgserviceparser case, failing on the previous detection), a plain Qt application, running, and a failing check, both in-process and in subprocesses with a fake qgis package. AI-Level: 7 (human specced, bots coded) AI-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dwmm8jY9WWvgUJt9WQ7QWZ
pgserviceparser 3.0 (2026-02) requires Python >= 3.11, now DicoGIS's floor. Require >= 3.0.3, the latest fix release. The API DicoGIS uses (conf_path, service_names, write_service, remove_service, ServiceFileNotFound) has the same signatures in 2.5.0 and 3.0.3: 3.x only adds functions, an optional sorted_alphabetically argument to service_names(), and retries writes on read-only service files. Side effect of 3.x, out of DicoGIS's hands: "import pgserviceparser" now tries to import its new Qt GUI, through qgis.PyQt when QGIS is installed, else PyQt6 when installed, whatever extras were requested. dicogis-cli thus loads PyQt6 when the gui extra is installed (listing import: 16 -> 48 ms here); the previous commit keeps the GUI's binding choice safe from it. AI-Level: 7 (human specced, bots coded) AI-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dwmm8jY9WWvgUJt9WQ7QWZ
The image runs Python 3.11+, so it resolves the new pgserviceparser range; update the exact pin accordingly. The Docker workflow builds and smoke-tests the image on this change. AI-Level: 7 (human specced, bots coded) AI-Model: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dwmm8jY9WWvgUJt9WQ7QWZ
Guts
force-pushed
the
improve/pgserviceparser-3
branch
from
October 18, 2026 11:34
8ec6a86 to
d55ce15
Compare
|
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.



Description
Moves to pgserviceparser 3 (3.0.3, latest), and fixes a GUI binding issue its upgrade exposed.
Dependency
pgserviceparser>=3.0.3,<4. pgserviceparser 3.0 requires Python >= 3.11: Python 3.10 support was dropped in #514 (it previously kept 2.x on 3.10 through environment markers, no longer needed).The API DicoGIS uses (
conf_path,service_names,write_service,remove_service,ServiceFileNotFound) has the same signatures in 2.5.0 and 3.0.3 (compared on both sources): 3.x only adds functions, an optionalsorted_alphabeticallyargument toservice_names(), and a retry on read-only service files. The Docker image pin moves to 3.0.3.The issue it exposed (first commit)
import pgserviceparser3.x tries to import its new Qt GUI, throughqgis.PyQtwhen QGIS is installed, PyQt6 otherwise. And QGIS's ownqgis/__init__.pyimportsqgis.gui, henceqgis.core. Measured, with a fakeqgis.PyQton the path standing in for an installed QGIS:dicogis.ui.qt_compat'sautomode pickedqgis.PyQtas soon as aqgispackage was imported: importing pgserviceparser before the GUI made a standalone run believe it was inside QGIS. Only the current import order ofdicogis-gui(binding resolved before pgserviceparser is imported) avoided it.qgis.PyQt, a standalonedicogis-guiends up loading PyQt5 next to PyQt6 in the same process. No crash observed offscreen here, but that's fragile — and out of DicoGIS's hands, it's pgserviceparser importing QGIS.autonow selectsqgis.PyQtonly when the running Qt application is aQgsApplication, looking at an already loadedqgis.corewithout ever importing QGIS. Inside QGIS (desktop, plugin,qgis_process) one runs; standalone it doesn't, whatever got imported. Tests cover QGIS absent / imported without application (the pgserviceparser case — fails on the previous detection) / a plain Qt application / running / a failing check, in-process and in subprocesses.Remaining side effect, not fixable here
pgserviceparser only has a
guiextra (adding PyQt6), no GUI-free variant: its__init__tries to import the GUI in any case, and it succeeds whenever PyQt6 orqgis.PyQtis importable. Sodicogis-clinow loads PyQt6 at import when DicoGIS'sguiextra is installed (listing import: 16 → 48 ms here), and QGIS's libraries when QGIS is installed, both through pgserviceparser. Worth raising with pgserviceparser upstream: importing the core package shouldn't import a GUI toolkit.Verification
pg_service.conf(missing file →ServiceFileNotFound,store_in_pgservice_file(),service_names(), connection string/URI,check_usable_pg_services(),remove_service()): identical results with 2.5.0 and 3.0.3.masterwith 2.5.0 in the same environment (no PostGIS instance, missing fixtures).Related issue(s)
None.
Type of change
fix/…branch)feature/…branch)docs/…branch or*.md/docs/**changes)packaging/…branch orbuilder/**changes)tooling/…branch or.github/**changes)tests/**changes)Checklist
pre-commit run --all-filespasses locally (on the branch's changes)qt_compatdocstring,CLAUDE.md)pytestpasses locally, apart from the environment failures listed above, identical onmasterAI/LLM disclosure
https://claude.ai/code/session_01Dwmm8jY9WWvgUJt9WQ7QWZ
Generated by Claude Code