Repository navigation
temporal: add test for tgis.init() across a session change - #7445
Conversation
|
Another attempt - using pytest with importlib option. Waiting for CI to confirm it helps. Here is AI summary:
The change in core.py may still be needed. |
|
All tests passed, so I am pretty confident this fixes it. @echoix any opinion on the changes in pytest import? |
tgis.init() spawns message and C-library subprocesses that capture GISRC at spawn time. When a process switches to a different project and calls tgis.init() again, those subprocesses stayed bound to the previous session's GISRC (which may have been deleted), causing failures like No active GRASS session. tgis.init() now detects a mapset/location/gisdbase change and stops the stale message and C-library interfaces so they are respawned in the current environment. The test exercises the multiprocessing subprocesses, which use spawn on macOS/Windows. Under pytest's default prepend import mode, the GRASS source python/ dir lands at sys.path[0], ahead of the installed tree. A spawned child then re-imports grass from source, where grass.lib (compiled ctypes bindings) doesn't exist → ModuleNotFoundError: No module named 'grass.lib', killing the RPC server. Setting --import-mode=importlib (which doesn't mutate sys.path) resolves this. Verified with no regressions across the python/grass suite (501 tests identical in both modes).
I noticed in other PRs that pytests don't work with tgis - switching to a different project between two tgis.init() calls in the same Python process must respawn the C-library subprocess. This PR contains a test reproducing the problem, fix in tgis.init() function AND changes the way pytest import tests. The fix in the init function fixes the test for linux and the pytest import change makes it work on other platforms. The change in pytest imports impacts all tests, but seems harmless.
AI summary and explanation below:
Problem
tgis.init() spawns message and C-library subprocesses that capture GISRC at spawn time. When a process
switches to a different project and calls tgis.init() again, those subprocesses stayed bound to the previous
session's GISRC (which may have been deleted), causing failures like No active GRASS session.
Fix
tgis.init() now detects a mapset/location/gisdbase change and stops the stale message and C-library
interfaces so they are respawned in the current environment.
Test
Adds a regression test that runs tgis.init() across two projects and asserts the C-library interface is
replaced and usable in the second session. The test fails on main (all platforms) and passes with the fix.
Why the import-mode change is included
The test exercises the multiprocessing subprocesses, which use spawn on macOS/Windows. Under pytest's default
prepend import mode, the GRASS source python/ dir lands at sys.path[0], ahead of the installed tree. A
spawned child then re-imports grass from source, where grass.lib (compiled ctypes bindings) doesn't exist →
ModuleNotFoundError: No module named 'grass.lib', killing the RPC server. Setting --import-mode=importlib
(which doesn't mutate sys.path) resolves this. Verified with no regressions across the python/grass suite
(501 tests identical in both modes).
This is required for any pytest that drives temporal/pygrass RPC subprocesses on macOS/Windows.