Skip to content

Instantly share code, notes, and snippets.

@0rdinal
Created September 17, 2021 09:35
Show Gist options
  • Save 0rdinal/f04cc7c91fa0bc2322e268e46f548dd1 to your computer and use it in GitHub Desktop.
Save 0rdinal/f04cc7c91fa0bc2322e268e46f548dd1 to your computer and use it in GitHub Desktop.
def assert_types(**arguments):
"""Type assertion for function calls. Prepend any function definition with this decorator to define
All defined keywords are considered required.
If you want optional arguments, you can omit it or add `None` to its list of permitted types.
A parameter type can be any type, a tuple of types or a string pointing to an object as shown in the example.
Example
=======
.. highlight:: python
.. code-block:: python
@assert_types(product="storefront.models.Product", name=str, price=(int, float), is_active=bool, quantity=int)
def update_product(*, product, name, price, is_active, quantity, description=None):
...
"""
def decorator(function):
def wrapper(*args, **kwargs):
for argument, argtype in arguments.items():
try:
if isinstance(argtype, str):
path = argtype.split(".")
argtype = __import__(path[0])
for elem in path[1:]:
argtype = getattr(argtype, elem)
if not isinstance(kwargs[argument], argtype):
raise TypeError(
f"{argument} must be of type {argtype}. Given: {type(kwargs[argument])}"
)
except KeyError:
raise LookupError(f"Missing required keyword-only argument: {argument}.")
return function(*args, **kwargs)
return wrapper
return decorator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment