Source code for pysepal.mapping.gdal_env
"""Sanitize GDAL/PROJ data environment variables.
SEPAL's system GDAL exports GDAL_DATA, PROJ_LIB and PROJ_DATA into every module
venv, pointing at data files for a different GDAL build than the venv's wheels.
That breaks raster reads, so drop them before anything imports rasterio.
Paths inside the interpreter's own prefix are kept: they are this environment's
own GDAL stack, and pyogrio and osgeo break without them. This cannot fix a mixed
conda/wheel install, where a wheel's own libgdal lives in that prefix too.
"""
import os
import sys
from pathlib import Path
GDAL_ENV_VARS = ("GDAL_DATA", "PROJ_LIB", "PROJ_DATA")
"""Data-directory variables to sanitize.
``PROJ_LIB`` is PROJ's pre-9.1 name for ``PROJ_DATA``; both are still exported in
the wild, so a foreign PROJ install can arrive through either one.
"""
def _is_own_path(path: str) -> bool:
"""Whether ``path`` resolves under one of this interpreter's own prefixes.
``sys.base_prefix`` differs from ``sys.prefix`` inside a venv, and a venv
layered on a conda env inherits that env's GDAL stack, so both count as ours.
"""
if not path:
return False
try:
resolved = Path(path).resolve()
prefixes = [Path(prefix).resolve() for prefix in (sys.prefix, sys.base_prefix)]
except OSError:
return False
return any(resolved.is_relative_to(prefix) for prefix in prefixes)
[docs]
def prune_foreign_gdal_env() -> None:
"""Delete the GDAL/PROJ data variables that point outside this environment."""
for var in GDAL_ENV_VARS:
path = os.environ.get(var)
if path is not None and not _is_own_path(path):
del os.environ[var]