473,715 Members | 6,096 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Checking function calls

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
Mar 7 '06 #1
10 1995
You can match if the list contains the legal number of arguments with.
func_variable.f unc_code.co_arg count

Type checking arguments has to be done manually since Python is a
dynamic language. Perhaps, you could try some typechecking decorators.
http://www.ilowe.net/software/typecheck/
From the docs, this one raises TypeCheckError (not TypeError), so you

should do fine.

Mar 7 '06 #2
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. TypeErrors relating to the type
of argemtns you pass will be raised inside the function only and not
when it is called. I.e. there is no type checking when a function is
called, only in its body.

Types erros can be raised when calling a function like this:

func(*avar)

or

func(**avar)

In the former case, if avar is not a sequence, you will get a TypeError.
In the latter case, if avar is not a dictionary, you will get a TypeError.

In this latter case, if your dictionary has keys that are not in the
parameter list, you will get a TypeError.

This would be similar to explicitly specifying a keyword argument that
is not in the parameter list (e.g. func(aparam=som eval)).

TypeError will be raised also if you give an improper number of
arguments to the 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

To check the parameter names, use

py> func.func_code. co_names
('a', 'b', 'c')
James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Mar 7 '06 #3
James Stroud wrote:
(snip)
Since python is "weakly typed",


s/weakly/dynamically/

(snip)

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'o****@xiludom. gro'.split('@')])"
Mar 7 '06 #4
Fredrik Tolf <py*********@py thon.org> 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?


The only way is to read the documentation for the function (or, the
source code).

Can you be a little more specific about what you're trying to do? Can
you post your code?
Mar 7 '06 #5

Roy Smith wrote:
Fredrik Tolf <py*********@py thon.org> 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?


The only way is to read the documentation for the function (or, the
source code).

Can you be a little more specific about what you're trying to do? Can
you post your code?


if you know ahead of runtime which methods are at issue and what method
signatures you want, multimethod decorators, maybe?
http://www.artima.com/weblogs/viewpo...?thread=101605
(read comments: PJE, ian bicking

or you can arg-test inside the method, which isn't much fun
http://www.python.org/doc/faq/progra...hods-in-python

Mar 7 '06 #6
If you have access to the source of the function you want to call (and know what kind of data types it wants in its args) you can raise something else for bad parameters, eg:

----------------------------------------------------------------
class ArgTypeError(Ty peError):
def __init__(self, arg):
self.arg = arg

def __str__(self):
return "bad type for argument %r" % self.arg

def moo(cow):
if not isinstance(cow, str):
raise ArgTypeError('c ow')
print "%s says moo!" % cow
# this error is not caused by wrong arg type:
var = 1 + 's'

function = moo

for arg in [1, 'rose']:
try:
function(arg)
except ArgTypeError, e:
print e
----------------------------------------------------------------

Output:
----------------------------------------------------------------
bad type for argument 'cow'
rose says moo!

Traceback (most recent call last):
File "/merlot1/yohell/eraseme/test.py", line 23, in -toplevel-
make_noise('ros e')
File "/merlot1/yohell/eraseme/test.py", line 13, in moo
raise TypeError
TypeError
----------------------------------------------------------------

Hope it helps
/Joel Hedlund
Mar 8 '06 #7
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(65 536)
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
Mar 8 '06 #8
Fredrik Tolf wrote:
# ...
if callable(f):
****try:
********f(*cv[1:])
****except*Type Error:
********self.re ply("err",*"arg no")
# ...

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.


If you must, just check the error message, not just the type of exception.

I'd just drop the cryptical error codes like 'argno' and 'unk' and pass on
the actual error message:

try:
f(*cv[1:])
except:
tp, exc, traceback = sys.exc_info()
self.reply("err ", str(exc))

Note that the check whether f is callable is also gone.

Peter
Mar 8 '06 #9
Fredrik Tolf wrote:
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(65 536)
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")
# ...

It might be more reasonable to program your cmd_* functions to be more
flexible themselves. This would be more pythonic. E.g.

def cmd_echo(self, *args):
if not len(args):
answer = 'OMITTED' # or raise your own exception
else:
answer = args[0]
self.reply("ok" , answer)

Now, you never have to worry about length of the argument list.
You could, of course factor this behavior. Here's how I might do it:

# first make a custom exception class, called whatever you want
class ServerError(exc eption): pass

#... somewhere in your client class
def preprocess_args (self, args, numexpected):
"""
This is the more flexible way.
A less flexible way would to check for the exact number of
arguments. But that goes against the "lenient in what you accept"
maxim.
"""
if len(args) < numexpected:
raise ServerError, 'Too few args!'
else:
return args[:numexpected]

def cmd_echo(self, *args):
(answer,) = preprocess_args (args, 1) # preprocess returns tuple
self.reply("ok" , answer)

#... elsewhere in your client class
if callable(f):
try:
f(*cv[1:])
except ServerError, e:
self.reply("err ", "argno") # can also make use of exception e
You could factor even further with a dictionary:

minargs = {'echo' : 1, 'etc' : 5000}

#... somewhere in your client class
def preprocess_args (self, cv):
"""
This is the more flexible way.
A less flexible way would to check for the exact number of
arguments. But that goes against the "lenient in what you accept"
maxim.
"""
args = cv[1:]
expected = minargs[cv[0]]
if len(args) < expected:
raise ServerError, 'Too few args!'
else:
return args[:expected]

# ...
def cmd_echo(self, answer):
self.reply("ok" , answer)

# ... elsewhere
if callable(f):
try:
args = preprocess_args (cv)
except ServerError, e:
self.reply("err ", "argno") # can also make use of exception e
f(*args)

Now you shouldn't have to rewrite any cmd_* functions.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/
Mar 8 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
3005
by: Tongu? Yumruk | last post by:
I have a little proposal about type checking in python. I'll be glad if you read and comment on it. Sorry for my bad english (I'm not a native English speaker) A Little Stricter Typing in Python - A Proposal As we all know, one of the best things about python and other scripting languages is dynamic typing (yes I know it has advantages and disadvantages but I will not discuss them now). Dynamic typing allows us to change types of...
67
4263
by: Steven T. Hatton | last post by:
Some people have suggested the desire for code completion and refined edit-time error detection are an indication of incompetence on the part of the programmer who wants such features. Unfortunately these ad hominem rhetorts are frequently introduced into purely technical discussions on the feasibility of supporting such functionality in C++. That usually serves to divert the discussion from the technical subject to a discussion of the...
4
9053
by: Victor | last post by:
Hello, I've got a situation in which the number of (valid) recursive calls I make will cause stack overflow. I can use getrlimit (and setrlimit) to test (and set) my current stack size. However, it is not as straightforward to determine the base address for my stack space. The approach I have taken is to save the address of an automatic variable in main( ), and assume this is a fairly good indicator of my base address. Then, I can...
30
2240
by: Michael B Allen | last post by:
I have a general purpose library that has a lot of checks for bad input parameters like: void * linkedlist_get(struct linkedlist *l, unsigned int idx) { if (l == NULL) { errno = EINVAL; return NULL; }
10
356
by: Mikhail Teterin | last post by:
Hello! Consider the following simple accessor function: šššššššštypedefšstructš{ ššššššššššššššššintššššši; ššššššššššššššššcharššššname; šššššššš}šMY_TYPE; ššššššššconstšcharš*
6
2037
by: Abubakar | last post by:
Hi, lets say I have a connected SOCKET s. At some point in time, I want to know if the "s" is still valid, that it is still connected. Is there any API that I can give me this information? And can I register some callback like thing, that would inform me when "s" disconnection happens? What I usually do is while I call "send" or "recv", I get the socket_error and through that I know whats the status. But in this situation actually I...
4
2382
by: Patient Guy | last post by:
Does anyone have any coding rules they follow when doing argument checking? When arguments fail during check, do you return from the call with an ambiguous return value, or do you throw exceptions?
1
1911
by: halcyon943 | last post by:
have 4 folders that I watch and need to move files from to another location. Three constraints: -Finish time. Make sure the program stops transferring files at a specific time -Number of files transferred. Can only move a certain amount of files per time period. -Folders have a priority. The files have to be moved based on the folder priority.
10
4728
by: David | last post by:
I am trying to get this straight in my head so I can implement. I wrote a small utility some time ago in c# that utilized a handful of threads. That scenario was one main thread manually spawning a handfull of worker threads, then waiting for all of them to complete before moving on. I believe I used array of ManualResetEvents and the WaitAll() method to do this. All the worker threads used a shared object (a common place to collect...
0
8823
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8718
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9343
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9198
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9047
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7973
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5967
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
2
2541
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2119
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.