Search code examples
pythonmethodsargumentstypeerrortrace

Python method giving TypeError takes exactly 9 arguments (8 given)


I am running into a TypeError about # of parameters when calling a Python method (2.7.2). Most of the similar questions that I have found online occur when people forget that "self" is also a parameter (sample SO question). Or, when someone forgets to concatenate arguments (like here).

I am not sure if this is also a "self" issue, but it seems to be different. I am basically getting an error that I don't have enough arguments, even though I count enough. In my trace:

-> message += XMLProcessor(zf, root, filepath, tag_type, display_name, containers, depth, message, username)
(Pdb) n
TypeError: 'XMLProcessor() takes exactly 9 arguments (8 given)'

Now, I have counted this multiple times, and I swear there are 9 arguments. But I may be mistaken or missing something critical? This method is not part of a class, so I would assume "self" is not an issue...I feel like I am missing a fundamental understanding of something, but not sure what.

########## Function: XMLProcessor #################
# This does the work of examining the XML and traversing it.
####################################################
def XMLProcessor(zf, root, filepath, tag_type, display_name, containers, depth, message, username):

Could anyone please shed some light on why 9 != 9 in this case?

Thanks!


UPDATE #1

So I have no idea what this means, but running the code that Martijn provided in my debugger:

(Pdb) import inspect, dis;
(Pdb) dis.dis(inspect.currentframe().f_code)
  1           0 LOAD_NAME                0 (dis)
              3 LOAD_ATTR                0 (dis)
              6 LOAD_NAME                1 (inspect)
              9 LOAD_ATTR                2 (currentframe)
             12 CALL_FUNCTION            0
             15 LOAD_ATTR                3 (f_code)
             18 CALL_FUNCTION            1
             21 PRINT_EXPR          
             22 LOAD_CONST               0 (None)
             25 RETURN_VALUE        
(Pdb) 

Update #2

Still trying to get up to speed on dis, but I find it kind of ironic that my code tries to ignore exactly 9 arguments. On a side-note, I have cleared out my *.pyc files and rerun my code...no help:

(Pdb) XMLProcessor(zf, root, filepath, tag_type, display_name, containers, depth, message, username)
*** TypeError: XMLProcessor() takes exactly 9 arguments (8 given)
(Pdb) XMLProcessor(zf, root, filepath, tag_type, display_name, containers, depth, message, username, '')
*** TypeError: XMLProcessor() takes exactly 9 arguments (10 given)

Solved!

As I noted in the comments, this wound up being not related to stale bytecodes (though that sounds like something I will definitely have to investigate in the future), but more coder oversight. I am modifying someone else's legacy code, and it turns out that XMLProcessor is a recursive method. And I didn't modify the internal, recursive method call for the new argument. So the "8" argument error was actually fired on the internal call, whereas the "10" argument error in Update #2 was fired on the external call. Since I had set my trace() before the external call, to me both errors looked the same--as if they were coming from my external call...Gah!!! Thanks everyone for your help--I need to work on my debugging techniques, and I learned some useful tricks from this.


Solution

  • As suggested, I'm posting the solution here to make it more obvious.


    TLDR


    The legacy method (XMLProcessor) was recursive, and the TypeError was being triggered on the recursive call in the method definition. I was tracing outside of the method and didn't realize that.


    Original post


    Solved!

    As I noted in the comments, this wound up being not related to stale bytecodes (though that sounds like something I will definitely have to investigate in the future), but more coder oversight. I am modifying someone else's legacy code, and it turns out that XMLProcessor is a recursive method. And I didn't modify the internal, recursive method call for the new argument. So the "8" argument error was actually fired on the internal call, whereas the "10" argument error in Update #2 was fired on the external call. Since I had set my trace() before the external call, to me both errors looked the same--as if they were coming from my external call...Gah!!! Thanks everyone for your help--I need to work on my debugging techniques, and I learned some useful tricks from this.