The short answer is No.
In the most general case, the only way to know whether a function call will succeed is to call it and see if it actually succeeds.
The slightly longer answer is Not Really, But Maybe Sometimes, Kinda Sort Of.
By using introspection on the function, you may sometimes be able to tell whether the arguments you are intending to call will match the signature of the function, for some definition of “match”.
This is what linters, type-checkers, IDEs and smart editors do.
For instance, a linter should be able to flag function calls with too few or too many arguments. If the function signature is def spam(a, b, c)
then a linter will know that the calls spam(1)
and spam(1, 2, 3, 4)
must be wrong, because they don’t match the number of required arguments.
In practice, they work reasonably well, but they are always subject to two kinds of errors:
- false negatives: the linter doesn’t pick up an actual error;
- and false positives: the linter wrongly reports something as an error when it isn’t.
The signature of a function tells us, as a human reader:
- the number of arguments;
- whether they are positional-only, keyword-only, or positional-or-keyword;
- if they have type annotations, the acceptable types;
- whether they are optional or required;
- and if they are well-named, the meaning of the argument (the semantics).
An introspection function can see the same things, except for the last.
Obviously missing from the list is the acceptable range of values, although that might be hinted at by the name.
For example, if you know that an argument has to be an int, that doesn’t tell you whether negative values or zero are accepted, or whether the number has to be an odd number, or a prime number, or less than 1000, or an even number greater than 4.
If the function has any restrictions on the values, you can’t get that information from the function signature. Only a human reader can determine that, by reading the documentation, or by knowledge of what the function is supposed to do and how it does it.
If the function accepts *args
or **kwargs
, then things become even more uncertain. Can the function really accept an unrestricted set of keyword arguments? What is it going to do with them?
And lastly, if your function depends on any external environment, say it tries to open a file, or fetch data from the network, then there is no way of knowing whether those external resources will be available without actually trying to use them.
Now we come to the most critical question. Why do you want to do this?
In general, when programming, the programmer knows what function they are calling, and what arguments have to be provided. Linters and type-checkers etc exist to help the programmer avoid mistakes. They aren’t an alternative to knowing what arguments the function needs.
But your description suggests that you have a bunch of functions, and you don’t know what they do or what arguments they need, and you almost want to guess a set of arguments and then check whether or not the call will succeed.
Or you have a single function, but you don’t know what arguments it requires, so you want to try a bunch of random things until it works.
If you explain what you are actually trying to do, and why, we might be able to recommend something:
- a static linter or type-checker, to avoid programmer errors;
- a runtime introspection check, to avoid… well I’m not sure what exactly;
- or just “don’t worry about it”.