pyfcstm.entry.base

Click command utilities and exception helpers for the pyfcstm.entry package.

This module provides standardized exception classes and a command wrapper that integrates with click to ensure consistent error reporting in CLI commands. It also includes a utility to print detailed exception information with tracebacks for unexpected errors.

The main public components are:

Example:

>>> import click
>>> from pyfcstm.entry.base import command_wrap
>>>
>>> @click.command()
... @command_wrap()
... def main():
...     raise ValueError("Boom")
...
>>> # Running the command prints a formatted error and exits.

CONTEXT_SETTINGS

pyfcstm.entry.base.CONTEXT_SETTINGS = {'help_option_names': ['-h', '--help']}

dict() -> new empty dictionary dict(mapping) -> new dictionary initialized from a mapping object’s

(key, value) pairs

dict(iterable) -> new dictionary initialized as if via:

d = {} for k, v in iterable:

d[k] = v

dict(**kwargs) -> new dictionary initialized with the name=value pairs

in the keyword argument list. For example: dict(one=1, two=2)

P

pyfcstm.entry.base.P = ~P

Parameter specification variable.

Usage:

P = ParamSpec('P')

Parameter specification variables exist primarily for the benefit of static type checkers. They are used to forward the parameter types of one callable to another callable, a pattern commonly found in higher order functions and decorators. They are only valid when used in Concatenate, or as the first argument to Callable, or as parameters for user-defined Generics. See class Generic for more information on generic types. An example for annotating a decorator:

T = TypeVar('T')
P = ParamSpec('P')

def add_logging(f: Callable[P, T]) -> Callable[P, T]:
    '''A type-safe decorator to add logging to a function.'''
    def inner(*args: P.args, **kwargs: P.kwargs) -> T:
        logging.info(f'{f.__name__} was called')
        return f(*args, **kwargs)
    return inner

@add_logging
def add_two(x: float, y: float) -> float:
    '''Add two numbers together.'''
    return x + y

Parameter specification variables defined with covariant=True or contravariant=True can be used to declare covariant or contravariant generic types. These keyword arguments are valid, but their actual semantics are yet to be decided. See PEP 612 for details.

Parameter specification variables can be introspected. e.g.:

P.__name__ == ‘P’ P.__bound__ == None P.__covariant__ == False P.__contravariant__ == False

Note that only parameter specification variables defined in global scope can be pickled.

R

pyfcstm.entry.base.R = ~R

Type variable.

Usage:

T = TypeVar('T')  # Can be anything
A = TypeVar('A', str, bytes)  # Must be str or bytes

Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function definitions. See class Generic for more information on generic types. Generic functions work as follows:

def repeat(x: T, n: int) -> List[T]:

‘’’Return a list containing n references to x.’’’ return [x]*n

def longest(x: A, y: A) -> A:

‘’’Return the longest of two strings.’’’ return x if len(x) >= len(y) else y

The latter example’s signature is essentially the overloading of (str, str) -> str and (bytes, bytes) -> bytes. Also note that if the arguments are instances of some subclass of str, the return type is still plain str.

At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError.

Type variables defined with covariant=True or contravariant=True can be used to declare covariant or contravariant generic types. See PEP 484 for more details. By default generic types are invariant in all type variables.

Type variables can be introspected. e.g.:

T.__name__ == ‘T’ T.__constraints__ == () T.__covariant__ == False T.__contravariant__ = False A.__constraints__ == (str, bytes)

Note that only type variables defined in global scope can be pickled.

ClickWarningException

class pyfcstm.entry.base.ClickWarningException(message: str)[source]

Custom exception class for displaying warnings in yellow color.

Parameters:

message (str) – The error message.

show(file: IO | None = None) None[source]

Display the warning message in yellow.

Parameters:

file (Optional[IO]) – File to write the output to. This parameter is ignored and output is always written to sys.stderr.

ClickErrorException

class pyfcstm.entry.base.ClickErrorException(message: str)[source]

Custom exception class for displaying errors in red color.

Parameters:

message (str) – The error message.

show(file: IO | None = None) None[source]

Display the error message in red.

Parameters:

file (Optional[IO]) – File to write the output to. This parameter is ignored and output is always written to sys.stderr.

KeyboardInterrupted

class pyfcstm.entry.base.KeyboardInterrupted(msg: str | None = None)[source]

Exception class for handling keyboard interruptions.

This exception is raised when the wrapped Click command receives a KeyboardInterrupt. It is a warning-level exception with a specific exit code.

Parameters:

msg (Optional[str]) – Custom message to display. Defaults to "Interrupted.".

__init__(msg: str | None = None) None[source]

Initialize the exception.

Parameters:

msg (Optional[str]) – Custom message to display. Defaults to "Interrupted.".

exit_code = 7

The exit code for this exception.

command_wrap

pyfcstm.entry.base.command_wrap() Callable[[Callable[[P], R]], Callable[[P], R]][source]

Decorator factory for wrapping Click commands with consistent error handling.

The wrapper provides the following behavior:

  • Re-raises click.ClickException without modification.

  • Converts KeyboardInterrupt into KeyboardInterrupted.

  • For any other exception, prints a red error header, outputs a traceback using print_exception(), and exits the current Click context with exit code 1.

Returns:

A decorator that wraps Click command functions.

Return type:

Callable[[Callable[…, R]], Callable[…, R]]

Example:

>>> import click
>>> from pyfcstm.entry.base import command_wrap
>>>
>>> @click.command()
... @command_wrap()
... def main():
...     raise RuntimeError("Unexpected")
...
>>> # Running the command emits a formatted error and exits with code 1.