title: Why TypeError when too many / too few args in Python function call
body: <p>I'm having trouble understanding why Python raises a <code>TypeError</code> when you provide arguments that aren't part of a method signature.</p>
  <p>Example:</p>
  <pre><code>&gt;&gt;&gt; def funky():
  ...    pass
  ... 
  &gt;&gt;&gt; funky(500)
  Traceback (most recent call last):
    File &quot;&lt;stdin&gt;&quot;, line 1, in &lt;module&gt;
  TypeError: funky() takes no arguments (1 given)
  </code></pre>
  <p>I thought, if this is because <code>*args</code> is expected to be <code>None</code> or <code>[]</code> within the scope of a no-arg function, that's a <a href="http://www.python.org/dev/peps/pep-3102/" rel="nofollow noreferrer">leaky abstraction</a>, so I looked it up.</p>
  <h3>What I found</h3>
  <p>A page search for <code>TypeError</code> on <a href="http://www.python.org/dev/peps/pep-3102/" rel="nofollow noreferrer">PEP-3102</a> found what appeared to be justification for one context in which <code>TypeError</code> is raised, but I don't understand the justification. The PEP's example is essentially stating that the functionality is basically a shortcut for <code>if args: raise TypeError()</code>. <code>args</code> is a non-empty list in that case as opposed to an empty list... which are both of the same type. If I'm not mistaken and that <em>is</em> indeed the justification, perhaps a <code>ValueError</code> would be more appropriate. However, that would still be sort-of a leaky abstraction since the example is written in Python, making it more of an implementation detail of a certain use case than a language feature. Something like <code>ArgumentError</code> sounds much more appropriate here to me, which leads me to believe there is some obvious explanation that I missed as to why <code>TypeError</code> makes sense.</p>