-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preparation for future Python exceptions enabled by default #7475
Conversation
688ba19
to
1ef2258
Compare
CC @rcoup This PR will change a bit how the gdal.ConfigurePythonLogging() function you added some time ago behaves when GDAL exceptions are enabled (which will be the default). Previously gdal.UseExceptions() and gdal.ConfigurePythonLogging() would compete against each other as both used gdal.SetErrorHandler() to install their GDAL error handler. Now, gdal.UseExceptions() no longer install a permanent error handler, but just pushes / pops one around each GDAL call. The effect of this is that CPLE_Failure will be caught by the PythonBindingErrorHandler(), and not by the one of gdal.ConfigurePythonLogging(). Warnings, debug and info messages will still be forwarded by PythonBindingErrorHandler() to the previously active error handler, that is the one installed by gdal.ConfigurePythonLogging() |
4abbcdb
to
23b62dc
Compare
Now that the PR is "green," it's time to share my thoughts. I expected this PR First, this PR actually starts at commit "python_exceptions.i: revise logic to Exception handling changesRegarding exception handling, the need to disable it in some places in autotest Before this PR, when UseExceptions() was called, it installed a global error This PR changes the way exceptions are handled by installing the PythonBindingsErrorHandler The gdal/ogr/osr.ExceptionMgr() context manager (introduced earlier in the 3.7-dev cycle) Those changes affect the working of the gdal.ConfigurePythonLogging() function To sum up, these are non-trivial changes, but I believe they result in a saner Separate boolean flag for exception enabled state?One interesting question is if the 15-year tradition of having the exception-enabled Consistency of exception throwing?Is our code base ready for turning on exceptions by default? This is really hard Is the gdal-utils library code added by @idanmiara in Are the Python bindings consistent regarding exception throwing? I discovered that the (deprecated) ogr.Open() didn't throw exceptions (now What should be the criteria to throw exceptions rather than returning None? gdal.Open/gdal.OpenEx/ogr.Open("not_valid") throw an exception when exceptions enabled, return None when disabled Situations where no exception is thrown when exceptions are enabled (same behaviour
Dataset.ExecuteSQL("invalid SQL") throws an exception when exceptions enabled, return None when disabled Multidimensional API (explicit code was added couple months ago for that. cf 173ad00):
It seems to me that Dataset.GetFieldDomain("not_a_field_domain"), GetLayerByName("not_existing") Methods that returns OGRErr (mostly in OGR and OSR API) throw an exception Final thoughts and questionsEnabling exceptions by default will break external code. I see it for example To summarize, here are the questions to answer:
|
Given the feedback given on the mailing list about turning on exceptions by default not being appropriate before GDAL 4.0, I've added 2 extra commits:
|
ad10cfd
to
e4b7530
Compare
This is probably an oversight on my part, my boilerplate has always been Overall +1 on the change; as per gdal-dev@ thread the open question for me is just the timing/rollout path. |
2c9912a
to
e9b0ae1
Compare
I only use the bindings for debugging and in GDAL tests presently, so take my opinion as such. I didn't know that you had to enable/disable separately, and that could be a gotcha. I like the idea of having only one place to set it. This will likely simply the process of disabling the exceptions where necessary and help transition to the new default when it is changed. |
…ptions are enabled
…AllModules() helper
…nd scripts. And emit a FutureWarning if exceptions have not been explicitly enabled or disabled This commit can be just reverted for GDAL 4.0
…) and make existing [Dont]UseExceptions() affect all modules
e9b0ae1
to
a1df6dc
Compare
I've added an extra commit "Python bindings: remove recently added [Dont]UseExceptionsAllModules() and make existing [Dont]UseExceptions() affect all modules" that does that. Demo:
and conversely
The deprecation warning is emitted just once, from the first call to the module that triggers it |
refs #7452
While doing this, I had to change how we interacted with the CPL error handler code. Previously we pushed a global error handler with CPLSetErrorHandlerEx(). It turns out that doing that from the gdal, ogr and osr modules, and enabling to temporarily disable exceptions with gdal.ExceptionMgr(useExceptions=False) is impossible. So I switched to pushing the python error handler before running a GDAL function and restoring it afterwards. This should help making the GDAL Python bindings work more nicely with other Python code using GDAL such as rasterio.
PR not ready as a number of changes have to be done in autotest