0

if I'm building a function call using partial, is there any way to query the partial to see if all the arguments for that function have been supplied? For instance in the code below is there any function I can pass empty_partial, partial_partial, and full_partial into, that will return True only on full_partial, indicating that all the arguments have been supplied?

from functools import partial

def foo(bar, baz):
    return bar + baz

empty_partial = partial(foo)
partial_partial = partial(empty_partial, bar=3)
full_partial = partial(partial_partial, baz=5)

print(full_partial())
# 8

if I tried to call the empty partial I'll get a message like this:

empty_partial = partial(foo)
empty_partial()
TypeError: foo() missing 2 required positional arguments: 'bar' and 'baz'

Where do I go to get this error, that it's missing 2 required arguments if I did call it (without having to try to call it and parse the error)?

MetaStack
  • 3,266
  • 4
  • 30
  • 67
  • 2
    I'm wondering what you could do with that information at runtime. – Klaus D. Nov 08 '18 at 03:18
  • @KlausD. well since you asked... I'm creating a coroutine that builds partials of functions as the arguments become available (they're computed in a distributed fashion and some become available before others). So I want the coroutine to be able to tell when it has successfully finished building a callable function (one that has all the needed arguments) when that occurs, it will call the function instead of yielding. – MetaStack Nov 08 '18 at 03:41
  • 2
    partial objects do have a documented api: https://docs.python.org/3.7/library/functools.html#partial-objects – Mark Harviston Nov 08 '18 at 04:12

1 Answers1

2

get the signature of the partial object, then check to make sure signature.bind does not raise a TypeError

import inspect

def partial_satisfied(partial_fn):
    signature = inspect.signature(partial_fn.func)
    try:
       signature.bind(*partial_fn.args, **partial_fn.keywords)
       return True
    except TypeError:
       return False

should do the trick (requires a python new enough to support function signatures)

Mark Harviston
  • 660
  • 4
  • 18