diff --git a/datasette/utils/__init__.py b/datasette/utils/__init__.py index cdb1bbc9..03157072 100644 --- a/datasette/utils/__init__.py +++ b/datasette/utils/__init__.py @@ -3,6 +3,7 @@ from collections import OrderedDict import base64 import click import hashlib +import inspect import json import mergedeep import os @@ -803,3 +804,13 @@ def parse_metadata(content): return yaml.safe_load(content) except yaml.YAMLError: raise BadMetadataError("Metadata is not valid JSON or YAML") + + +def call_with_supported_arguments(fn, **kwargs): + parameters = inspect.signature(fn).parameters.keys() + call_with = [] + for parameter in parameters: + if parameter not in kwargs: + raise TypeError("{} requires parameters {}".format(fn, tuple(parameters))) + call_with.append(kwargs[parameter]) + return fn(*call_with) diff --git a/tests/test_utils.py b/tests/test_utils.py index 7e4f1a8e..59b80a67 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -446,3 +446,14 @@ async def test_request_post_vars(): request = Request(scope, receive) assert {"foo": "bar", "baz": "1"} == await request.post_vars() + + +def test_call_with_supported_arguments(): + def foo(a, b): + return "{}+{}".format(a, b) + + assert "1+2" == utils.call_with_supported_arguments(foo, a=1, b=2) + assert "1+2" == utils.call_with_supported_arguments(foo, a=1, b=2, c=3) + + with pytest.raises(TypeError): + utils.call_with_supported_arguments(foo, a=1)