cdxcore.err#

Basic error handling and reporting functions with minimal runtime performance overhead for string formatting.

Overview#

The main use of this module are the functions cdxcore.err.verify() and cdxcore.err.warn_if(). Both test some runtime condition and will either raise an Exception or issue a Warning if triggered. In both cases, required string formatting is only performed if the event is actually triggered.

This way we are able to write neat code which produces robust, informative errors and warnings without impeding runtime performance.

Example:

from cdxcore.err import verify, warn_if
import numpy as np

def f( x : np.ndarray ):
    std = np.std(x,axis=0,keepdims=True)
    verify( np.all( std>1E-8 ), "Cannot normalize 'x' by standard deviation: standard deviations are {std}", std=std )
    x /= std        

f( np.zeros((10,10)) )

raises a RuntimeError

Cannot normalize 'x' by standard deviation: standard deviations are [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]

For warnings, we can use warn_if:

from cdxcore.err import verify, warn_if
import numpy as np

def f( x : np.ndarray ):
    std = np.std(x,axis=0,keepdims=True)
    warn_if( not np.all( std>1E-8 ), lambda : f"Normalizing 'x' by standard deviation: standard deviations are {std}" )
    x   = np.where( std<1E-8, 0., x/np.where( std<1E-8, 1., std ) )

f( np.zeros((10,10)) )

issues a warning:

RuntimeWarning: Normalizing 'x' by standard deviation: standard deviations are [[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
  warn_if( not np.all( std>1E-8 ), "Normalizing 'x' by standard deviation: standard deviations are {std}", std=std )    

Note that though we used two different approaches for message formatting, the the error messages in both cases are only formatted if the condition in verify is not met.

Import#

from cdxcore.err import verify, warn_if, error, warn

Documentation#

Functions

error(text, *args[, exception])

Raise an exception with string formatting.

fmt(text, *args, **kwargs)

Basic tool for delayed string formatting.

verify(cond, text, *args[, exception])

Raise an exception using delayed error string formatting if a condition is not met.

warn(text, *args[, warning, stack_level])

Issue a warning.

warn_if(cond, text, *args[, warning, ...])

Issue a warning with delayed string formatting if a condition is met.

cdxcore.err.error(text, *args, exception=<class 'RuntimeError'>, **kwargs)[source]#

Raise an exception with string formatting.

See also cdxcore.err.fmt() for formatting comments. The point of this function is to have an interface which is consistent with cdxcore.err.verify().

Examples:

from cdxcore.err import error
one = 1
error(lambda : f"one {one:d}")  # wrapped f-string
error("one {one:d}", one=one)   # using python 3 string.format()
error("one %(one)ld", one=one)  # using python 2 style
error("one %ld", one)           # using c-style

As shown, do not use f-strings directly as they are immediately executed in the scope they are typed in but wrap them with a lambda function.

Parameters:
textstr | Callable

Error text which may contain one of the following string formatting patterns:

  • Python 3 `{parameter:d}`, in which case message.fmt(kwargs) for str.format() is used to obtain the output message.

  • Python 2 `%(parameter)d` in which case message % kwargs is used to obtain the output message.

  • Classic C-stype `%d, %s, %f` in which case message % args is used to obtain the output message.

  • If message is a Callable such as a lambda function, then message( * args, ** kwargs ) is called to obtain the output message.

    A common use case is using an f-string wrapped in a lambda function; see example above.

exceptionException, optional

Which type of exception to raise. Defaults to RuntimeError.

* args, ** kwargs:

See above

Raises:
exceptionexception
cdxcore.err.fmt(text, *args, **kwargs)[source]#

Basic tool for delayed string formatting.

The main use case is that formatting is not executed until this function is called, hence potential error messages are not generated until an error actually occurs. See, for example, cdxcore.err.verify().

The follwing example illustrates all four supported modi operandi:

from cdxcore.err import fmt
one = 1
fmt(lambda : f"one {one:d})   # using a lambda function
fmt("one {one:d}", one=one)   # using python 3 string.format()
fmt("one %(one)ld", one=one)  # using python 2 style
fmt("one %ld", one)           # using c-style

As shown, do not use f-strings directly as they are immediately executed in the scope they are typed in but wrap them with a lambda function.

Parameters:
textstr | Callable

Error text which may contain one of the following string formatting patterns:

  • Python 3 `{parameter:d}`, in which case message.fmt(kwargs) for str.format() is used to obtain the output message.

  • Python 2 `%(parameter)d` in which case message % kwargs is used to obtain the output message.

  • Classic C-stype `%d, %s, %f` in which case message % args is used to obtain the output message.

  • If message is a Callable such as a lambda function, then message( * args, ** kwargs ) is called to obtain the output message.

    A common use case is using an f-string wrapped in a lambda function; see example above.

* args, ** kwargs:

See above

Returns:
Textstr

The formatted message.

cdxcore.err.verify(cond, text, *args, exception=<class 'RuntimeError'>, **kwargs)[source]#

Raise an exception using delayed error string formatting if a condition is not met.

The point of this function is to only format an error message if a condition cond is not met and an error is to be raised.

Examples:

from cdxcore.err import verify
one = 1
good = False                           # some condition
verify(good, lambda : f"one {one:d}")  # wrapped f-string
verify(good, "one {one:d}", one=one)   # using python 3 string.format()
verify(good, "one %(one)ld", one=one)  # using python 2 style
verify(good, "one %ld", one)           # using c-style

As shown, do not use f-strings directly as they are immediately executed in the scope they are typed in but wrap them with a lambda function.

Parameters:
condbool

Condition to test.

textstr | Callable

Error text which may contain one of the following string formatting patterns:

  • Python 3 `{parameter:d}`, in which case message.fmt(kwargs) for str.format() is used to obtain the output message.

  • Python 2 `%(parameter)d` in which case message % kwargs is used to obtain the output message.

  • Classic C-stype `%d, %s, %f` in which case message % args is used to obtain the output message.

  • If message is a Callable such as a lambda function, then message( * args, ** kwargs ) is called to obtain the output message.

    A common use case is using an f-string wrapped in a lambda function; see example above.

exceptionException, optiona

Which type of exception to raise. Defaults to RuntimeError.

* args, ** kwargs:

See above

Raises:
exceptionexception
cdxcore.err.warn(text, *args, warning=<class 'RuntimeWarning'>, stack_level=1, **kwargs)[source]#

Issue a warning.

The point of this function is to have an interface consistent with cdxcore.err.warn_if().

Examples:

from cdxcore.err import warn
one = 1        
warn(lambda : f"one {one:d}")  # wrapped f-string
warn("one {one:d}", one=one)   # using python 3 string.format()
warn("one %(one)ld", one=one)  # using python 2 style
warn("one %ld", one)           # using c-style

As shown, do not use f-strings directly as they are immediately executed in the scope they are typed in but wrap them with a lambda function.

Parameters:
textstr | Callable

Error text which may contain one of the following string formatting patterns:

  • Python 3 `{parameter:d}`, in which case message.fmt(kwargs) for str.format() is used to obtain the output message.

  • Python 2 `%(parameter)d` in which case message % kwargs is used to obtain the output message.

  • Classic C-stype `%d, %s, %f` in which case message % args is used to obtain the output message.

  • If message is a Callable such as a lambda function, then message( * args, ** kwargs ) is called to obtain the output message.

    A common use case is using an f-string wrapped in a lambda function; see example above.

warningoptional

Which type of warning to issue. This corresponds to the category parameter for warnings.warn(). Default is RuntimeWarning.

stack_levelint, optional

What stack to report; see warnings.warn(). Default is 1, which means warn itself is not reported as part of the stack trace.

* args, ** kwargs:

See above

cdxcore.err.warn_if(cond, text, *args, warning=<class 'RuntimeWarning'>, stack_level=1, **kwargs)[source]#

Issue a warning with delayed string formatting if a condition is met.

The point of this function is to only format an error message if a condition cond is met and a warning is to be issued.

Examples:

from cdxcore.err import warn_if
one = 1       
bad = True                            # some conditon
warn_if(bad,lambda : f"one {one:d}")  # wrapped f-string
warn_if(bad,"one {one:d}", one=one)   # using python 3 string.format()
warn_if(bad,"one %(one)ld", one=one)  # using python 2 style
warn_if(bad,"one %ld", one)           # using c-style

As shown, do not use f-strings directly as they are immediately executed in the scope they are typed in but wrap them with a lambda function.

Parameters:
condbool

Condition to test.

textstr | Callable

Error text which may contain one of the following string formatting patterns:

  • Python 3 `{parameter:d}`, in which case message.fmt(kwargs) for str.format() is used to obtain the output message.

  • Python 2 `%(parameter)d` in which case message % kwargs is used to obtain the output message.

  • Classic C-stype `%d, %s, %f` in which case message % args is used to obtain the output message.

  • If message is a Callable such as a lambda function, then message( * args, ** kwargs ) is called to obtain the output message.

    A common use case is using an f-string wrapped in a lambda function; see example above.

warningoptional

Which type of warning to issue. This corresponds to the category parameter for warnings.warn(). Default is RuntimeWarning.

stack_levelint, optional

What stack to report; see warnings.warn(). Default is 1, which means warn itself is not reported as part of the stack trace.

* args, ** kwargs:

See above