Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the Pythonic way to report nonfatal errors in a parser?

A parser I created reads recorded chess games from a file. The API is used like this:

import chess.pgn

pgn_file = open("games.pgn")

first_game = chess.pgn.read_game(pgn_file)
second_game = chess.pgn.read_game(pgn_file)
# ...

Sometimes illegal moves (or other problems) are encountered. What is a good Pythonic way to handle them?

  • Raising exceptions as soon as the error is encountered. However, this makes every problem fatal, in that execution stops. Often, there is still useful data that has been parsed and could be returned. Also, you can not simply continue parsing the next data set, because we are still in the middle of some half-read data.

  • Accumulating exceptions and raising them at the end of the game. This makes the error fatal again, but at least you can catch it and continue parsing the next game.

  • Introduce an optional argument like this:

    game = chess.pgn.read_game(pgn_file, parser_info)
    if parser_info.error:
       # This appears to be quite verbose.
       # Now you can at least make the best of the sucessfully parsed parts.
       # ...
    

Are some of these or other methods used in the wild?

like image 816
Niklas Avatar asked Oct 14 '14 09:10

Niklas


People also ask

How does Python handle parse error?

Errors cannot be handled, while Python exceptions can be handled at the run time. An error can be a syntax (parsing) error, while there can be many types of exceptions that could occur during the execution and are not unconditionally inoperable.

How do you show errors in Python?

Build A Paint Program With TKinter and Python If you need to display the error messagebox in your application, you can use showerror("Title", "Error Message") method. This method can be invoked with the messagebox itself.

What are parsing errors in Python?

Syntax errors, also called parsing errors, are errors that occur as a result of incorrect syntax in any part of the code/program. The syntax is a rule that states how words and phrases must be used in Python.

How many types of errors are there in Python?

In python there are three types of errors; syntax errors, logic errors and exceptions.


1 Answers

The most Pythonic way is the logging module. It has been mentioned in comments but unfortunately without stressing this hard enough. There are many reasons it's preferable to warnings:

  1. Warnings module is intended to report warnings about potential code issues, not bad user data.
  2. First reason is actually enough. :-)
  3. Logging module provides adjustable message severity: not only warnings, but anything from debug messages to critical errors can be reported.
  4. You can fully control output of logging module. Messages can be filtered by their source, contents and severity, formatted in any way you wish, sent to different output targets (console, pipes, files, memory etc)...
  5. Logging module separates actual error/warning/message reporting and output: your code can generate messages of appropriate type and doesn't have to bother how they're presented to end user.
  6. Logging module is the de-facto standard for Python code. Everyone everywhere is using it. So if your code is using it, combining it with 3rd party code (which is likely using logging too) will be a breeze. Well, maybe something stronger than breeze, but definitely not a category 5 hurricane. :-)

A basic use case for logging module would look like:

import logging
logger = logging.getLogger(__name__) # module-level logger

# (tons of code)
logger.warning('illegal move: %s in file %s', move, file_name)
# (more tons of code)

This will print messages like:

WARNING:chess_parser:illegal move: a2-b7 in file parties.pgn

(assuming your module is named chess_parser.py)

The most important thing is that you don't need to do anything else in your parser module. You declare that you're using logging system, you're using a logger with a specific name (same as your parser module name in this example) and you're sending warning-level messages to it. Your module doesn't have to know how these messages are processed, formatted and reported to user. Or if they're reported at all. For example, you can configure logging module (usually at the very start of your program) to use a different format and dump it to file:

logging.basicConfig(filename = 'parser.log', format = '%(name)s [%(levelname)s] %(message)s')

And suddenly, without any changes to your module code, your warning messages are saved to a file with a different format instead of being printed to screen:

chess_parser [WARNING] illegal move: a2-b7 in file parties.pgn

Or you can suppress warnings if you wish:

logging.basicConfig(level = logging.ERROR)

And your module's warnings will be ignored completely, while any ERROR or higher-level messages from your module will still be processed.

like image 140
Lav Avatar answered Nov 16 '22 04:11

Lav