Package: exception-escaping
exception_escapingIf you've just confessed and you can't wait to sin again, try this package. It will help youhide your mistakesand make your life more carefree.Table of contentsQuick startDecorator modeContext manager modeWhich exceptions are escaped?LoggingQuick startInstall it:pipinstallexception_escapingAnd use:importescape@escapedeffunction():raiseValueErrorfunction()# The exception is suppressed.Read about other library features below.Decorator modeYou can hang theescapedecorator on any function, including a coroutine one. Exceptions that occur internally will be suppressed.An example with a regular function:@escapedeffunction():raiseValueErrorAnd with coroutine one:@escapeasyncdefcoroutine_function():raiseValueErrorThe decorator will work both with and without brackets:@escape()# This will work too.deffunction():...If an exception occurred inside the function wrapped by the decorator, it will return the default value -None. You can specify your own default value:@escape(default='some value')deffunction():raiseValueErrorassertfunction()=='some value'# It's going to work.Context manager modeYou can useescapeas a context manager. It works almost the same way ascontextlib.suppressfrom the standard library. However, in this case, you can choose whether to use the context manager with or without brackets:# Both options work the same way.withescape:raiseValueErrorwithescape():raiseValueErrorHowever, as you should understand, the default value cannot be specified in this case. If you try to specify a default value for the context manager, get ready to face an exception:withescape(default='some value'):...# escape.errors.SetDefaultReturnValueForDecoratorError: You cannot set a default value for the context manager. This is only possible for the decorator.Which exceptions are escaped?By default, not all exceptions from thehierarchyare escaped. This only applies toExceptionand all its descendants. Starting with Python 3.11,groups of exceptionsappear - and they are also escaped by default. However, exceptionsGeneratorExit,KeyboardInterruptandSystemExitare not escaped by default. This is due to the fact that in most programs none of them is part of the semantics of the program, but is used exclusively for system needs. For example, ifKeyboardInterruptwas blocked, you would not be able to stop your program using theControl-Ckeyboard shortcut.If you want to expand or narrow the range of escaped exceptions, use theexceptionsargument. You must pass a list or tuple of exception types.It works for thedecorator mode:@escape(exceptions=[ValueError]):deffunction():raiseValueError# It will be suppressed.@escape(exceptions=[ValueError]):deffunction():raiseKeyError# And this is not.... and for thecontext manager mode:withescape(exceptions=[ValueError]):raiseValueError# It will be suppressed.withescape(exceptions=[ValueError]):raiseKeyError# And this is not.LoggingYou can pass a logger object to theescape. In such case, if an exception is raised inside the context or the function wrapped by the decorator, it will be logged:importloggingimportescapelogging.basicConfig(level=logging.INFO,format="%(asctime)s[%(levelname)s]%(message)s",handlers=[logging.StreamHandler(),])logger=logging.getLogger('logger_name')withescape(logger=logger):1/0# You will see a description of the error in the console.It works in any mode: both in the case of the context manager and the decorator.Only exceptions are logged. If the code block or function was executed without errors, the log will not be recorded. Also the log is recorded regardless of whether the exception was suppressed or not. However, depending on this, you will see different log messages to distinguish one situation from another.