Package: lazy-runtime-typechecker
Runtime typechecker for Python methodsThis package provides a simple wrapper for methods to enforce type checking at runtimeLimitationsInstallationBasic UsageDocumentationinit_check: boolcheck_input_args: bool = Truecheck_return_value: bool = Truecheck_generic_types: bool = Truedefined_by_class: bool = FalseExceptionLimitationsLet's talk about the limitations of this package firstThe type checking only works with the new python 3.10 syntax. For older versions basic type
checking still works. ButGenericsandUnionsare not working with the old systax. Have a look
atPEP 604for more information.Performance: Of course checking something at runtime comes with a performance penalty. This module
is intended to be used for only a few methods were type checking is absolutely necessary. If you need typechecking for
everything consider using something likemypyNon-callable object: normal function are callable object in python but a function with the@classmethoddecorator
is not callable. This Packageonlysupports callable objects.Installationpipinstalllazy_runtime_typecheckerBasic UsageThis module contains one wrapper. This wrapper can be used to type check a function.fromlazy_runtime_typecheckerimportstatic_typed@static_typed(init_check=True)defmy_function(x:str)->str:returnxif__name__=='__main__':my_function(x="hello world")# okmy_function(12)# will raise an exceptionDocumentationThe@static_typedwrapper takes different arguments to configure how the types are checked.
The default is alwaysTruebecause the assumption is, that if someone adds this wrapper to a
function, they want to be really sure that nearly all cases are checked. Of course every single
parameter that is set to true will add a performance penalty to the type checker (exceptdefined_by_class).init_check: boolIf the parameter is set to true the signature of the arguments and the return type is checked even
before the first call. Also, the default values are checked against the signature of the arguments.Example:fromlazy_runtime_typecheckerimportstatic_typed@static_typed(init_check=False)defmy_function(x:str=12)->str:returnx# this will not raise an exception@static_typed(init_check=True)defmy_function(x:str=12)->str:returnx# this will raise an exception because 12 is not a str@static_typed(init_check=True)defmy_function(x:str="hi"):returnx# this will raise an exception because no return type was specifiedThe exception that is raised for the initial validation is from typeruntime_typechecker.TypeingError.
All other exceptions from this module are inheritance form this exception.check_input_args: bool = TrueIf this parameter is set toTruethen the input values are checked each time the function is
called. The exception that is raised by an input validation is from typeruntime_typechecker.InputTypeingError.fromlazy_runtime_typecheckerimportstatic_typed,InputTypeingError@static_typed(init_check=True,check_input_args=False)defmy_function(x:str="hi"):returnx# this will not raise an exceptionmy_function(12)@static_typed(init_check=True,check_input_args=True)defmy_function(x:str="hi"):returnx# this will raise an exceptionmy_function(12)# or catch the exceptiontry:my_function(12)exceptInputTypeingError:passcheck_return_value: bool = TrueIf this parameter is set toTruethen the return value is checked each time the function is
called. The exception that is raised by an input validation is from typeruntime_typechecker.InputTypeingError.fromlazy_runtime_typecheckerimportstatic_typed,OutputTypeingError@static_typed(init_check=True,check_return_value=False)defmy_function(x:int)->int:returnstr(x)# this will not raise an exceptionmy_function(12)@static_typed(init_check=True,check_return_value=True)defmy_function(x:int)->int:returnstr(x)# this will raise an exceptionmy_function(12)# or catch the exceptiontry:my_function(12)exceptOutputTypeingError:passcheck_generic_types: bool = TrueUntil now all examples only showed some basic types. But python also has a rich selection of types to
represent nearly every possible typing expression. Of course with these more complex and nested types
the performance penalty increases. If this parameter is set toTruegeneric types are also check
in full depth. If set toFalseonly the first level of the generic type is matched. This behavior
is applied for the input and the output stream.fromlazy_runtime_typecheckerimportstatic_typed@static_typed(init_check=True,check_generic_types=False)defmy_function(x:list[str])->list[str]:returnx# this will not raise an exceptionmy_function([12,"hello world"])@static_typed(init_check=True,check_generic_types=True)defmy_function(x:list[str])->list[str]:returnx# this will raise an exceptionmy_function([12,"hello world"])# also multiple level of depth are supported@static_typed(init_check=True,check_generic_types=True)defmy_function(x:tuple[str|list[int|float]])->dict[str,int]:return{"abc":12}defined_by_class: bool = FalseIf a method is defined by a class, then set this parameter to True. This means the first parameter for passing the
instance of the class to the method is not checked.fromlazy_runtime_typecheckerimportstatic_typedclassMyTestClass:@static_typed(init_check=True,defined_by_class=True)defmy_function(self,x:str)->int:returnint(x)@static_typed(init_check=True,defined_by_class=False)@staticmethoddefmy_static_function(x:str)->str:returnx# this does not work because a class method is not callable@static_typed(init_check=True,defined_by_class=False)@classmethoddefmy_class_method(cls,x:str)->str:returncls()ExceptionThree exception are part of this module.TypeingError(TypeError): is the base exceptionInputTypeingError(TypeingError): this exception is raised if an input parameter validation failsOutputTypeingError(TypeingError): this exception is raised if a return value validation fails