Skip to content
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

Checks: Fix E722 do not use bare except #3748

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

mshukuno
Copy link
Contributor

The entire fix involves converting except: into except Exception:. Please let me know if specific exceptions are needed in certain conditions.

@github-actions github-actions bot added GUI wxGUI related vector Related to vector data processing raster Related to raster data processing Python Related code is in Python translation Message translation related libraries module docs display imagery labels May 28, 2024
Copy link
Member

@wenzeslaus wenzeslaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great. except Exception is far better than bare except which catches even syntax errors, but later we will aim at Pylint and that asks for something more specific than Exception.

It seems easier to see the exceptions here in this PR than going to Pylint later on, so fixing as much as possible now would be good.

Nevertheless, I would aim at the clear cases in this PR. I tried to mark couple of cases which are clear and will be repeated over several files. Ultimately, you need to look at every case. If you need to read more than 10 lines of code to understand the context, leaving Exception is probably the right choice.

Comment on lines 18 to 20
try:
from osgeo import gdal
except:
except Exception:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cases like this are import error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except ImportError:

utils/gitlog2changelog.py Show resolved Hide resolved
Comment on lines 80 to 82
try:
self.code = int(values[-1])
except:
except Exception:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a case where code context helps: values clearly has at least one value, so the indexing will succeed here. What can fail is the conversion to an integer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except ValueError:

Comment on lines 278 to 280
try:
grass.run_command("r.in.gdal", input=bilfile, out=tileout)
except:
except Exception:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provided error message is trivial. This will be better handled by removing try-except and simply asking run_command to issue the fatal error with errors="fatal":

run_command(..., errors="fatal")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about grass.read_command? It appears that it works with the "errors" parameter. A question would be the status of the errors. For example, gui/wxpython/core/utils.py

def _getGDALFormats():
    """Get dictionary of available GDAL drivers"""
    try:
        ret = grass.read_command("r.in.gdal", quiet=True, flags="f")
    except Exception:
        ret = None

    return _parseFormats(ret), _parseFormats(ret, writableOnly=True)


def _getOGRFormats():
    """Get dictionary of available OGR drivers"""
    try:
        ret = grass.read_command("v.in.ogr", quiet=True, flags="f")
    except Exception:
        ret = None

    return _parseFormats(ret), _parseFormats(ret, writableOnly=True)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: The difference here is gui/wxpython/ versus a scripts/.

Copy link
Contributor Author

@mshukuno mshukuno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm reading the code between try and except and finding possible errors, so you may want to disregard some of the errors I listed in except. As a side note, I used code assistant to find out some of the most common exceptions, and then evaluated whether they might occur in the given code.

Third-party library exceptions (e.g. wxPython) and nested internal function calls related exceptions are difficult to figure out. In such a situation, broad exceptions are useful, so I kept them as they are, but please let me know if you have any suggestions for specific exceptions.

@@ -676,7 +676,7 @@ def RunCmd(
if len(command) == 1 and not skipInterface:
try:
task = gtask.parse_interface(command[0])
except:
except Exception:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to note any changes I made along the way.
parse_interface

from grass.exceptions import ScriptError
except ScriptError:

@@ -1242,7 +1242,7 @@ def SetRegion(self, windres=False, windres3=False):

return grass_region

except:
except Exception:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except (KeyError, TypeError):

@@ -110,7 +110,7 @@ def _generateLocale(self):
self.locs.sort()
# Add a default choice to not override system locale
self.locs.insert(0, "system")
except:
except Exception:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except (KeyError, FileNotFoundError, PermissionError, NotADirectoryError, OSError):
  1. KeyError: This would occur if the environment variable "GISBASE" is not set.
  2. FileNotFoundError: This would be raised by os.listdir() if the directory specified does not exist. In this case, if the "locale" directory does not exist within the directory specified by "GISBASE".
  3. PermissionError: This would be raised by os.listdir() if the user does not have the necessary permissions to read the contents of the directory.
  4. NotADirectoryError: This would be raised by os.listdir() if the path exists but is not a directory.
  5. OSError: This would be raised by os.listdir() for reasons like insufficient system resources or other OS-related issues.

@@ -992,7 +992,7 @@ def SaveToFile(self, settings=None):
if not os.path.exists(dirPath):
try:
os.mkdir(dirPath)
except:
except Exception:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except OSError:

gui/wxpython/core/toolboxes.py Outdated Show resolved Hide resolved
@@ -77,7 +77,7 @@ def main():
tar = tarfile.TarFile.open(name=input_base, mode="r")
try:
data_name = tar.getnames()[0]
except:
except Exception:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except (AttributeError, IndexError, tarfile.ReadError):
  1. AttributeError: This exception is raised if the tar object does not have a getnames method. This could occur if tar is not a TarFile object.
  2. IndexError: This exception is raised during the tar.getnames()[0] call if the result of tar.getnames() does not have at least one element. This could occur if the tar file is empty.
  3. tarfile.ReadError: This exception is raised if the tar file cannot be read, which might happen if the file is not a tar file or is corrupted.

scripts/v.what.strds/v.what.strds.py Outdated Show resolved Hide resolved
utils/gitlog2changelog.py Show resolved Hide resolved
@@ -66,7 +66,7 @@
author = authorList[1]
author = author[0 : len(author) - 1]
authorFound = True
except:
except Exception:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except IndexError:

@@ -76,7 +76,7 @@
date = dateList[1]
date = date[0 : len(date) - 1]
dateFound = True
except:
except Exception:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except (IndexError, TypeError):

@@ -118,31 +118,31 @@ def get_number_of_spatial_relations(self):
relations = {}
try:
relations["equivalent"] = len(self._spatial_topology["EQUIVALENT"])
except:
except (KeyError, TypeError):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class, e.g., def append_equivalent(self, map):, always creates the dict item with an empty list, so the len call should always succeed, so there should be no TypeError, or if there is, it is programmer's fault and traceback is the desired behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping except Exception for now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant the opposite. If you analyze the code, it should reveal that of the dict item is there, it will be an empty list. So, no TypeError. The attribute seems to be present. (Please check.) This would leave KeyError as what the original author intended to catch here.

Comment on lines 80 to 81
except (AttributeError, IndexError, tarfile.ReadError):
grass.fatal(_("Pack file unreadable"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the other extract code: Report the error to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am guessing you are refering to scripts/r.in.srtm/r.in.srtm.py and changed to as following.

    except (AttributeError, IndexError, tarfile.ReadError) as error:
        grass.fatal(_("Pack file unreadable: {error}").format(error=error))

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you push the change?

@@ -76,7 +76,7 @@
date = dateList[1]
date = date[0 : len(date) - 1]
dateFound = True
except:
except (IndexError, TypeError):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why TypeError?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeError: This will occur if dateList is not a list or if dateList[1] is not a string. This can happen if the input to this code snippet is not as expected.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dateList and dateList[1] are a result of the re.split function call on line 74 which returns a list of strings according to the documentation.

Copy link
Member

@wenzeslaus wenzeslaus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left comments for several changes. Some of them hopefully apply generally, too.

@@ -230,8 +230,8 @@ def main():
try:
zf = zfile.ZipFile(zipfile)
zf.extractall()
except:
grass.fatal(_("Unable to unzip file."))
except (FileNotFoundError, PermissionError, OSError, zipfile.BadZipFile) as error:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[black] reported by reviewdog 🐶

Suggested change
except (FileNotFoundError, PermissionError, OSError, zipfile.BadZipFile) as error:
except (
FileNotFoundError,
PermissionError,
OSError,
zipfile.BadZipFile,
) as error:

@@ -2213,7 +2213,7 @@ def print_params(params):
try:
revision = linerev.split(" ")[1]
sys.stdout.write("%s\n" % revision[1:])
except:
except (IndexError, TypeError, AttributeError):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AttributeError - Generally, attribute error should not be caught unless there is a specific reason to do so (like dealing with different types of objects and reacting to the differences in their attributes).

TypeError - Where this would happen and is that something we want to hide or cause traceback?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeError happens as following.

TypeError: This exception could be raised by revision[1:] if revision is not a string or bytes-like object. The slicing operation is not supported by all data types, so if revision is not of a type that supports slicing, a TypeError would be raised.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under which conditions revision would not be a string? The revision value is a result of the line 2214 which splits a string using str.split which returns list of the words in the string.

@echoix echoix removed GUI wxGUI related vector Related to vector data processing raster Related to raster data processing Python Related code is in Python translation Message translation related libraries module docs display imagery labels Oct 17, 2024
@echoix
Copy link
Member

echoix commented Oct 17, 2024

Fixed conflicts, maybe some changes wouldn't still be needed since some work has already been done (and those lines would revert back if I didn't do my job correctly)

@github-actions github-actions bot added GUI wxGUI related vector Related to vector data processing raster Related to raster data processing Python Related code is in Python translation Message translation related libraries module docs display imagery labels Oct 17, 2024
@echoix echoix added the needs rebase Rebase to or merge with the latest base branch is needed label Dec 11, 2024
@echoix
Copy link
Member

echoix commented Dec 12, 2024

Solved conflicts. The diff is now smaller, as multiple issues where already fixed

@echoix echoix removed the needs rebase Rebase to or merge with the latest base branch is needed label Dec 12, 2024
@echoix
Copy link
Member

echoix commented Dec 13, 2024

@arohanajit Before you finish the year, can you take a look at what's left here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display docs GUI wxGUI related imagery libraries module Python Related code is in Python raster Related to raster data processing translation Message translation related vector Related to vector data processing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants