Skip to content

Commit cf9dc1a

Browse files
authored
Merge pull request OSGeo#11919 from dbaston/cpl-quiet-warnings
Add CPLQuietWarningsErrorHandler
2 parents 6d3dd57 + 1c404c6 commit cf9dc1a

File tree

6 files changed

+77
-1
lines changed

6 files changed

+77
-1
lines changed

autotest/gcore/misc.py

+34
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import gdaltest
2020
import pytest
21+
from test_py_scripts import run_py_script_as_external_script
2122

2223
from osgeo import gdal, osr
2324

@@ -1126,6 +1127,39 @@ def test_misc_gdal_driver_has_open_option(driver_name, open_option, expected):
11261127
assert driver.HasOpenOption(open_option) == expected
11271128

11281129

1130+
###############################################################################
1131+
# Test gdal.quiet_errors() and gdal.quiet_warnings()
1132+
1133+
1134+
@pytest.mark.parametrize("context", ("quiet_errors", "quiet_warnings"))
1135+
def test_misc_quiet_errors(tmp_path, context):
1136+
1137+
script = f"""
1138+
from osgeo import gdal
1139+
1140+
with gdal.{context}():
1141+
gdal.Error(gdal.CE_Debug, gdal.CPLE_AppDefined, "Debug")
1142+
gdal.Error(gdal.CE_Warning, gdal.CPLE_AppDefined, "Warning")
1143+
gdal.Error(gdal.CE_Failure, gdal.CPLE_AppDefined, "Failure")
1144+
"""
1145+
1146+
with open(tmp_path / "script.py", "w") as f:
1147+
f.write(script)
1148+
1149+
out, err = run_py_script_as_external_script(
1150+
tmp_path, "script", "", return_stderr=True
1151+
)
1152+
if context == "quiet_errors":
1153+
assert "Debug" in err
1154+
assert "Warning" not in err
1155+
assert "Failure" not in err
1156+
1157+
if context == "quiet_warnings":
1158+
assert "Debug" in err
1159+
assert "Warning" not in err
1160+
assert "Failure" in err
1161+
1162+
11291163
###############################################################################
11301164

11311165

port/cpl_error.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,20 @@ void CPL_STDCALL CPLQuietErrorHandler(CPLErr eErrClass, CPLErrorNum nError,
11111111
CPLDefaultErrorHandler(eErrClass, nError, pszErrorMsg);
11121112
}
11131113

1114+
/************************************************************************/
1115+
/* CPLQuietWarningsErrorHandler() */
1116+
/************************************************************************/
1117+
1118+
/** Error handler that ignores CE_Warning messages. */
1119+
void CPL_STDCALL CPLQuietWarningsErrorHandler(CPLErr eErrClass,
1120+
CPLErrorNum nError,
1121+
const char *pszErrorMsg)
1122+
1123+
{
1124+
if (eErrClass != CE_Warning)
1125+
CPLDefaultErrorHandler(eErrClass, nError, pszErrorMsg);
1126+
}
1127+
11141128
/************************************************************************/
11151129
/* CPLLoggingErrorHandler() */
11161130
/************************************************************************/

port/cpl_error.h

+2
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ void CPL_DLL CPL_STDCALL CPLDefaultErrorHandler(CPLErr, CPLErrorNum,
183183
const char *);
184184
void CPL_DLL CPL_STDCALL CPLQuietErrorHandler(CPLErr, CPLErrorNum,
185185
const char *);
186+
void CPL_DLL CPL_STDCALL CPLQuietWarningsErrorHandler(CPLErr, CPLErrorNum,
187+
const char *);
186188
void CPL_DLL CPLTurnFailureIntoWarning(int bOn);
187189

188190
CPLErrorHandler CPL_DLL CPLGetErrorHandler(void **ppUserData);

swig/include/cpl.i

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ void CPL_STDCALL PyCPLErrorHandler(CPLErr eErrClass, CPLErrorNum err_no, const c
127127
CPLErrorHandler pfnHandler = NULL;
128128
if( pszCallbackName == NULL || EQUAL(pszCallbackName,"CPLQuietErrorHandler") )
129129
pfnHandler = CPLQuietErrorHandler;
130+
else if( EQUAL(pszCallbackName,"CPLQuietWarningsErrorHandler") )
131+
pfnHandler = CPLQuietWarningsErrorHandler;
130132
else if( EQUAL(pszCallbackName,"CPLDefaultErrorHandler") )
131133
pfnHandler = CPLDefaultErrorHandler;
132134
else if( EQUAL(pszCallbackName,"CPLLoggingErrorHandler") )

swig/include/python/gdal_python.i

+23-1
Original file line numberDiff line numberDiff line change
@@ -4957,7 +4957,7 @@ def config_option(key, value, thread_local=True):
49574957

49584958
@contextlib.contextmanager
49594959
def quiet_errors():
4960-
"""Temporarily install an error handler that silents all warnings and errors.
4960+
"""Temporarily install an error handler that silences all warnings and errors.
49614961
49624962
Returns
49634963
-------
@@ -4975,6 +4975,28 @@ def quiet_errors():
49754975
finally:
49764976
PopErrorHandler()
49774977

4978+
@contextlib.contextmanager
4979+
def quiet_warnings():
4980+
"""Temporarily install an error handler that silences all warnings.
4981+
4982+
.. versionadded: 3.11
4983+
4984+
Returns
4985+
-------
4986+
A context manager
4987+
4988+
Example
4989+
-------
4990+
4991+
>>> with gdal.ExceptionMgr(useExceptions=False), gdal.quiet_warnings():
4992+
... gdal.Error(gdal.CE_Warning, gdal.CPLE_AppDefined, "you will never see me")
4993+
"""
4994+
PushErrorHandler("CPLQuietWarningsErrorHandler")
4995+
try:
4996+
yield
4997+
finally:
4998+
PopErrorHandler()
4999+
49785000
%}
49795001

49805002

swig/include/python/typemaps_python.i

+2
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,8 @@ static PyObject *XMLTreeToPyList( CPLXMLNode *psTree )
18201820
{
18211821
if( pszCallbackName == NULL || EQUAL(pszCallbackName,"CPLQuietErrorHandler") )
18221822
$1 = CPLQuietErrorHandler;
1823+
else if( EQUAL(pszCallbackName,"CPLQuietWarningsErrorHandler") )
1824+
$1 = CPLQuietWarningsErrorHandler;
18231825
else if( EQUAL(pszCallbackName,"CPLDefaultErrorHandler") )
18241826
$1 = CPLDefaultErrorHandler;
18251827
else if( EQUAL(pszCallbackName,"CPLLoggingErrorHandler") )

0 commit comments

Comments
 (0)