Thursday, November 11, 2010

Python 'not callable' errors

Be careful not to heist the names of methods in wsadminlib.py...

The python language allows you to dynamically redefine a method to a variable, and vice-versa. This can be a nice feature if you do it intentionally. But it can be a nuisance to debug if unintentional. Here is a quick example:

First, define a method which returns the sum of two numbers:

ding@dingp:~$ python
Python 2.5.2 (r252:60911, Jan 20 2010, 21:48:48)
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> def myMethod(i,j):
... return i+j
...
>>>

Pass in two numbers, set the return value to another variable, and it works as expected.

>>> k = myMethod(1,2)
>>> print k
3
>>>


But watch what happens next...


Now set the return value to the same name as the method. The return variable has the expected value, but the variable has unknowingly converted the name from a callable method to an integer.

>>> myMethod = myMethod(3,4)
>>> print myMethod
7
>>>


When we repeat the previously-successful call, it fails. The error message says the variable type, an int, is 'not callable' as a method.

>>> k = myMethod(1,2)
Traceback (most recent call last):
File "", line 1, in
TypeError: 'int' object is not callable
>>>



A wsadminlib user recently reported a problem where this behavior was the culprit. The calling script inadvertently defined a variable with the same name as a method in wsadminlib.py. For example, the script had something like this:

isND = isND()

Everything worked fine until much later, when subsequent code tried to query isND() once again. Poof, the 'not callable' error appeared.

Lesson: if ever you see a 'not callable' error, search and examine every location where the method name is used.