Why does round raise on ndigits=None for integers but not for floats?
<p>Why does <code>round()</code> behave different for int and float when <code>ndigits</code> is explicitly set to <code>None</code>?</p>

<p>Console test in Python 3.5.1:</p>

<pre><code>&gt;&gt;&gt; round(1, None)
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
TypeError: 'NoneType' object cannot be interpreted as an integer
&gt;&gt;&gt; round(1.0, None)
1
</code></pre>

<p><strong>Update:</strong></p>

<p>I reported this as a bug (<a href="https://bugs.python.org/issue27936" rel="nofollow">Issue #27936</a>) which has been fixed and closed. I'll report here when the fix is released.</p>

<p>@PadraicCunningham and @CraigBurgler were correct. </p>

<p>From the source code for <code>float_round</code> in <code>floatobjects.c</code> in <code>3.5</code>:</p>

<pre><code>float_round(PyObject *v, PyObject *args)
    ... 
    if (!PyArg_ParseTuple(args, "|O", &amp;o_ndigits))
        return NULL;
    ...
    if (o_ndigits == NULL || o_ndigits == Py_None) {
        /* single-argument round or with None ndigits:
         * round to nearest integer */
        ...
</code></pre>

<p>The <code>|| o_ndigits == Py_None</code> bit catches an <code>ndigits=None</code> argument explicitly and discards it, treating the call to <code>round</code> as a single-argument call.</p>

<p>In <code>3.4</code>, this code looks like:</p>

<pre><code>float_round(PyObject *v, PyObject *args)
    ... 
    if (!PyArg_ParseTuple(args, "|O", &amp;o_ndigits))
        return NULL;
    ...
    if (o_ndigits == NULL) {
            /* single-argument round: round to nearest integer */
    ...
</code></pre>

<p>there is no <code>|| o_ndigits == Py_None</code> test and hence an <code>ndgits=None</code> argument falls through and is treated like an <code>int</code>, thus causing a <code>TypeError</code> for <code>round(1.0, None)</code> in <code>3.4</code>.</p>

<p>There is no check for <code>o_ndigits == Py_None</code> in <code>long_round</code> in <code>longobject.c</code> in both <code>3.4</code> and <code>3.5</code>, thus raising a <code>TypeError</code> for <code>round(1, None)</code> in both <code>3.4</code> and <code>3.5</code> </p>

<pre><code>                treat ndigits=None as      resolve
Version/Type    single-argument call    round(n, None) 
 ----------       ---------------        -----------
  3.4/float              No               TypeError
  3.4/long               No               TypeError
  3.5/float              Yes               round(n)
  3.5/long               No               TypeError
</code></pre>

python rounding python-3.5