On 15Nov2017 09:12, Chris Angelico <ros...@gmail.com> wrote:
On Wed, Nov 15, 2017 at 8:05 AM, Cameron Simpson <c...@cskk.id.au> wrote:
I know that this isn't generally solvable, but I'm wondering if it is
partially solvable.

I have a task manager which accepts callables, usually functions or
generators, and calls them on data items as needed. For reasons which,
frankly, suggest user interface ergonomics failure to me it happens that
inappropriate functions get submtted to this system. For example, functions
accepting no arguments but which are handed one by the system.

I would like to inspect submitted functions' signatures for suitability at
submission time, without calling the function. For example to see if this
function accepts exactly one argument, or to see if it is a generator, etc.

Is this possible, even in a limited way?

Yes, it is. Sometimes in a very limited way, other times fairly well.
(NOTE: I'm using CPython for this. Other interpreters may differ
wildly.)

I'm using CPython too.

First off, you can look at the function's attributes to see
some of the info you want:

def wants_one_arg(x): pass
...
wants_one_arg.__code__.co_argcount
1
wants_one_arg.__code__.co_varnames
('x',)

co_varnames has the names of all local variables, and the first N of
those are the arguments. You aren't matching on the argument names,
but they might help you make more readable error messages.

As to recognizing generators, every function has a set of flags which
will tell you whether it yields or just returns:

def fun(): pass
...
def gen(): yield 1
...
fun.__code__.co_flags
67
gen.__code__.co_flags
99

That's the raw info. For human-friendly functions that look at this
info, check out the inspect module:

inspect.isgeneratorfunction(fun)
False
inspect.isgeneratorfunction(gen)
True
inspect.signature(wants_one_arg)
<Signature (x)>

Poke around with its functions and you should be able to find most of
what you want, I think.

Thank you, looks like just what I need.

Cheers,
Cameron Simpson <c...@cskk.id.au> (formerly c...@zip.com.au)
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to