How can I write a C function that takes either an int or a float?
<p>I want to create a function in C that extends Python that can take inputs of either float or int type. So basically, I want <code>f(5)</code> and <code>f(5.5)</code> to be acceptable inputs.</p>

<p>I don't think I can use <code>if (!PyArg_ParseTuple(args, "i", $value))</code> because it only takes only int or only float.</p>

<p>How can I make my function allow inputs that are either ints or floats?</p>

<p>I'm wondering if I should just take the input and put it into a PyObject and somehow take the type of the PyObject - is that the right approach?</p>

<p>If you declare a C function to accept floats, the compiler won't complain if you hand it an int. For instance, this program produces the answer 2.000000:</p>

<pre><code>#include &lt;stdio.h&gt;

float f(float x) {
  return x+1;
}

int main() {
  int i=1;
  printf ("%f", f(i));
}
</code></pre>

<p>A python module version, iorf.c:</p>

<pre><code>#include &lt;Python.h&gt;

static PyObject *IorFError;

float f(float x) {
  return x+1;
}


static PyObject *
fwrap(PyObject *self, PyObject *args) {
  float in=0.0;
  if (!PyArg_ParseTuple(args, "f", &amp;in))
    return NULL;
  return Py_BuildValue("f", f(in));
}

static PyMethodDef IorFMethods[] = {
    {"fup",  fwrap, METH_VARARGS,
     "Arg + 1"},
    {NULL, NULL, 0, NULL}        /* Sentinel */
};


PyMODINIT_FUNC
initiorf(void)
{
  PyObject *m;

  m = Py_InitModule("iorf", IorFMethods);
  if (m == NULL)
    return;

  IorFError = PyErr_NewException("iorf.error", NULL, NULL);
  Py_INCREF(IorFError);
  PyModule_AddObject(m, "error", IorFError);
}
</code></pre>

<p>The setup.py:</p>

<pre><code>from distutils.core import setup, Extension

module1 = Extension('iorf',
                    sources = ['iorf.c'])

setup (name = 'iorf',
       version = '0.1',
       description = 'This is a test package',
       ext_modules = [module1])
</code></pre>

<p>An example:</p>

<pre><code>03:21 $ python
Python 2.7.10 (default, Jul 30 2016, 18:31:42)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; import iorf
&gt;&gt;&gt; print iorf.fup(2)
3.0
&gt;&gt;&gt; print iorf.fup(2.5)
3.5
</code></pre>

python c python-extensions