On Mon, 2006-03-06 at 20:25 -0800, James Stroud wrote: > Fredrik Tolf wrote: > > If I have a variable which points to a function, can I check if certain > > argument list matches what the function wants before or when calling it? > > > > Currently, I'm trying to catch a TypeError when calling the function > > (since that is what is raised when trying to call it with an illegal > > list), but that has the rather undesirable side effect of also catching > > any TypeErrors raised inside the function. Is there a way to avoid that? > > > > Fredrik Tolf > > > > > > Since python is "weakly typed", you will not be able to check what > "type" of arguments a function expects. [...]
Sorry, it seems I made myself misunderstood. I don't intend to check the type of the values that I pass to a function (I'm well aware that Python is dynamically typed). The reason I refer to TypeError is because that seems to be the exception raised by Python when I attempt to call a function with an argument list that wouldn't be valid for it (for example due to the number of parameters being wrong). I just want to check in advance whether a certain arglist would be valid to call a certain function. > So, if you want to know the number of > arguments expected, I've found this works: > > py> def func(a,b,c): > ... print a,b,c > ... > py> func.func_code.co_argcount > 3 Not very well, though: >>> def a(b, c, *d): pass ... >>> print a.func_code.co_argcount 2 Here, that would indicate that I could only call `a' with two arguments, while in fact I could call it with two or more arguments. More exactly, what I'm trying to do is this; I writing a small protocol server class as part of a program, and I thought it would be convenient to be able to define new commands in the protocol by just adding a function for them, like this: class client: # ... # Read is called from the event driver when data is available on the # socket. def read(self): self.buf += self.sk.recv(65536) for c in self.buf.split("\n")[:-1]: cv = tokenize(c) if len(cv) > 0: f = getattr(self, "cmd_" + cv[0], None) if callable(f): f(*cv[1:]) else: self.reply("err", "unk") # Example: def cmd_echo(self, arg1): self.reply("ok", arg1) So basically, I want to be able to handle to client giving the wrong number of arguments and reply with an error rather than the server process crashing and dying. Therefore, I'm currently catching TypeErrors when calling the function: # ... if callable(f): try: f(*cv[1:]) except TypeError: self.reply("err", "argno") # ... However, this results in bugs in the server code that would cause TypeError to reply to the client that it had the wrong number of args, and I can't see what the real cause is without turning off that check while debugging. Therefore, I'd like to check in advance whether cv[1:] would raise a TypeError upon calling f with it or not. And of course, I'd like to be able to use cmd_* functions with variable arglists as well. Surely, there ought to be some way in python to see whether a certain argument list would be valid for a function call, without checking magic values of f.func_code? Fredrik Tolf -- http://mail.python.org/mailman/listinfo/python-list