grass.temporal should behave like other parts of the grass package and allow passing env to allow not using os.environ.
Details and scope (generated with Claude Code)
Current state
tgis.init() resolves the session with gs.gisenv() and no env, then caches it in module-level globals in core.py (current_mapset, current_location, current_gisdbase, tgis_backend, tgis_database*, message_interface, c_library_interface, ...). None of the 64 grass.script calls in python/grass/temporal/ (50 run_command, 7 parse_command, 5 gisenv, 2 read_command) pass env=.
Elsewhere in the package the environment can be explicit: gs.run_command(env=...), Tools(session=session), gs.setup.init(..., env=...).
Describe the solution you'd like
tgis.init(env=session.env)
dbif = tgis.SQLDatabaseInterfaceConnection(env=session.env)
with env threaded through to the grass.script calls underneath. env=None would keep reading os.environ as it does now, so existing code and the global session stay valid.
It would also make it possible to use more than one session in a process, which the rest of the API allows.
Scope
This is not a small change. At minimum it needs:
init() to accept env and not rely on gs.gisenv() against the global environment,
- the session carried on the objects which currently rely on the globals (
SQLDatabaseInterfaceConnection, the AbstractDataset hierarchy, ...) rather than module-level state in core.py,
env passed at the 64 grass.script call sites,
- the RPC-backed interfaces (
CLibrariesInterface, the messenger), which spawn subprocesses that need the environment too.
So it probably wants to be staged.
Describe alternatives you've considered
A test which needs a session outside the global environment can mirror it into os.environ with monkeypatch, which is what #7732 does. It works, but every caller has to repeat it.
Additional context
This came up while debugging r.coin on the OSGeo4W CI (#7732).
grass.temporal should behave like other parts of the grass package and allow passing env to allow not using os.environ.
Details and scope (generated with Claude Code)
Current state
tgis.init()resolves the session withgs.gisenv()and noenv, then caches it in module-level globals incore.py(current_mapset,current_location,current_gisdbase,tgis_backend,tgis_database*,message_interface,c_library_interface, ...). None of the 64grass.scriptcalls inpython/grass/temporal/(50run_command, 7parse_command, 5gisenv, 2read_command) passenv=.Elsewhere in the package the environment can be explicit:
gs.run_command(env=...),Tools(session=session),gs.setup.init(..., env=...).Describe the solution you'd like
with
envthreaded through to thegrass.scriptcalls underneath.env=Nonewould keep readingos.environas it does now, so existing code and the global session stay valid.It would also make it possible to use more than one session in a process, which the rest of the API allows.
Scope
This is not a small change. At minimum it needs:
init()to acceptenvand not rely ongs.gisenv()against the global environment,SQLDatabaseInterfaceConnection, theAbstractDatasethierarchy, ...) rather than module-level state incore.py,envpassed at the 64grass.scriptcall sites,CLibrariesInterface, the messenger), which spawn subprocesses that need the environment too.So it probably wants to be staged.
Describe alternatives you've considered
A test which needs a session outside the global environment can mirror it into
os.environwithmonkeypatch, which is what #7732 does. It works, but every caller has to repeat it.Additional context
This came up while debugging r.coin on the OSGeo4W CI (#7732).