Repository: numpy/numpy

Issue:
Building Numpy package fails with TypeError: __init__() takes from 3 to 4 positional arguments but 13 were given
I'm trying in build Numpy on Ubuntu Server Xenial (Armbian 5.14). I have installed `libexpat1-dev`, `libpython3-dev`, `libpython3.5-dev`, `python3-dev`, `python3.5-dev`, `build-essential`, `gcc`, `gfortran`, `gfortran-5`, `libgfortran-5-dev`, `libgfortran3`, `libblas-common`, `libblas-dev`, `libblas3`, `libopenblas-base`, `libopenblas-dev`, `cython`, `libpng-dev`. Cloned git repo to a dir and ran `python3 setup.py build`. Here's the log:

`$ python3 setup.py build`

`Running from numpy source directory.`
`Cythonizing sources`
`numpy/random/mtrand/mtrand.pyx has not changed`
`Traceback (most recent call last):`
`File "setup.py", line 390, in <module>`
`setup_package()`
`File "setup.py", line 382, in setup_package`
`setup(**metadata)`
`File "/home/odroid/downloads/numpy/numpy/distutils/core.py", line 135, in setup
    config = configuration()`
`File "setup.py", line 165, in configuration`
`config.add_subpackage('numpy')`
`File "/home/odroid/downloads/numpy/numpy/distutils/misc_util.py", line 1001, in add_subpackage`
`caller_level = 2)`
`File "/home/odroid/downloads/numpy/numpy/distutils/misc_util.py", line 970, in get_subpackage`
`caller_level = caller_level + 1)`
`File "/home/odroid/downloads/numpy/numpy/distutils/misc_util.py", line 907, in _get_configuration_from_setup_py`
`config = setup_module.configuration(*args)`
`File "numpy/setup.py", line 10, in configuration`
`config.add_subpackage('core')`
`File "/home/odroid/downloads/numpy/numpy/distutils/misc_util.py", line 1001, in add_subpackage`
`caller_level = 2)`
`File "/home/odroid/downloads/numpy/numpy/distutils/misc_util.py", line 970, in get_subpackage`
`caller_level = caller_level + 1)`
`File "/home/odroid/downloads/numpy/numpy/distutils/misc_util.py", line 907, in _get_configuration_from_setup_py`
`config = setup_module.configuration(*args)`
`File "numpy/core/setup.py", line 638, in configuration
    generate_numpy_api]`
`File "/home/odroid/downloads/numpy/numpy/distutils/misc_util.py", line 1483, in add_extension`
`ext = Extension(**ext_args)`
`File "/home/odroid/downloads/numpy/numpy/distutils/extension.py", line 52, in __init__
    export_symbols)`
`TypeError: __init__() takes from 3 to 4 positional arguments but 13 were given`

How can it be fixed?



Discussion:
I'm getting the same error in a self-written package, but with python 2.7.12 (and numpy 1.11.1), on OS X (with python installed via homebrew).

Hmm, I don't see that here with Fedora 24 and python 3.5.1 or python 2.7.12. @cmarquardt What is a "self-written" package?

Anyway, looks like `distutils.extension.Extension` is the problem. Not sure why positional arguments should be a problem here, but it sounds like the arguments in the call

```
        old_Extension.__init__(self, name, [],
                               include_dirs,
                               define_macros,
                               undef_macros,
                               library_dirs,
                               libraries,
                               runtime_library_dirs,
                               extra_objects,
                               extra_compile_args,
                               extra_link_args,
                               export_symbols)
```

at line 42 in `numpy/distutils/extension.py` need fixing. Could you try making the arguments `include_dirs=include_dirs`, etc. That said, I'm not sure why you are seeing this problem and I am not, perhaps something further up in the call chain.

@maximtrp @cmarquardt Hmm, the python `distutils.extension.Extension` class seems remarkably undocumented. That said, I wonder if you are using a different `distutils.extension` module than the official one? Could you do a search and see if there are several such files floating around in your systems? 

Looking at the Python 3.5 source, there is this comment in `class Extension`

```
    # When adding arguments to this constructor, be sure to update
    # setup_keywords in core.py.
    def __init__(self, name, sources,
                  include_dirs=None,
                  define_macros=None,
                  undef_macros=None,
                  library_dirs=None,
                  libraries=None,
                  runtime_library_dirs=None,
                  extra_objects=None,
                  extra_compile_args=None,
                  extra_link_args=None,
                  export_symbols=None,
                  swig_opts = None,
                  depends=None,
                  language=None,
                  optional=None,
                  **kw                      # To catch unknown keywords
                 ):extension_keywords
```

Which makes me wonder a bit what keywords are in `distutils/core.py` `extension_keywords`. Here I get

```
>>> import distutils.core as dc
>>> dc.extension_keywords
('name', 'sources', 'include_dirs', 'define_macros', 'undef_macros', 'library_dirs', 'libraries', 'runtime_library_dirs', 'extra_objects', 'extra_compile_args', 'extra_link_args', 'swig_opts', 'export_symbols', 'depends', 'language')
```

I'm guessing that both these problems stem from the installed python, in the OS X case from homebrew, and in the Armbian 5.14 case because Armbian. So we can maybe help make things more compatible on the Numpy end but problems may still remain that need to be reported upstream.

I've just had the same problem and noticed that `setuptools` was updated to version `25.4.0` yesterday. Using `setuptools==25.3.0` is working for me.

Fedora 24 on my end here.  Works just fine if I build numpy as normal.  But if I try and build numpy with in a virtual environment created with virtualenv-3.5 I get the same error.  Passing arguments to old_Extension.**init**() as charris suggested fixes the problem though.

@charris 
Armbian `python3.5` package comes from ports.ubuntu.com. Though, it doesn't imply that some other packages cannot interfere.

```
$ apt-cache policy python3.5
python3.5:
  Installed: 3.5.2-2~16.01
  Candidate: 3.5.2-2~16.01
  Version table:
 *** 3.5.2-2~16.01 500
        500 http://ports.ubuntu.com xenial-updates/main arm64 Packages
        100 /var/lib/dpkg/status
     3.5.1-10 500
        500 http://ports.ubuntu.com xenial/main arm64 Packages
```

Python2.7 is installed from ports too.
Keywords in `distutils/core.py` `extension_keywords` are just the same.

> Could you do a search and see if there are several such files floating around in your systems?

I've found `distutils` here:

```
/usr/lib/python3.5/distutils
/usr/lib/python2.7/distutils
/usr/lib/python2.7/dist-packages/Cython/Distutils
/usr/share/dh-python/dhpython/build/__pycache__/plugin_distutils.cpython-35.pyc
/usr/share/dh-python/dhpython/build/plugin_distutils.py
```

> Could you try making the arguments include_dirs=include_dirs, etc. 

@charris, @AssumeACanOpener
It **helped**! I've just installed Numpy and it's working as expected. Thank you!

@sisp Aha, looking at newest setuptools definition of `class Extensions` there is a new `__init__` function with arguments

```
    def __init__(self, name, sources, py_limited_api=False, **kw):
        self.py_limited_api = py_limited_api
        _Extension.__init__(self, name, sources, **kw)
```

So that definitely looks like a problem, one that should be fixed by using the proper call with keywords in Numpy.


Resolving patch:
diff --git a/numpy/distutils/extension.py b/numpy/distutils/extension.py
--- a/numpy/distutils/extension.py
+++ b/numpy/distutils/extension.py
@@ -20,36 +20,39 @@
 fortran_pyf_ext_re = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
 
 class Extension(old_Extension):
-    def __init__ (self, name, sources,
-                  include_dirs=None,
-                  define_macros=None,
-                  undef_macros=None,
-                  library_dirs=None,
-                  libraries=None,
-                  runtime_library_dirs=None,
-                  extra_objects=None,
-                  extra_compile_args=None,
-                  extra_link_args=None,
-                  export_symbols=None,
-                  swig_opts=None,
-                  depends=None,
-                  language=None,
-                  f2py_options=None,
-                  module_dirs=None,
-                  extra_f77_compile_args=None,
-                  extra_f90_compile_args=None,
-                 ):
-        old_Extension.__init__(self, name, [],
-                               include_dirs,
-                               define_macros,
-                               undef_macros,
-                               library_dirs,
-                               libraries,
-                               runtime_library_dirs,
-                               extra_objects,
-                               extra_compile_args,
-                               extra_link_args,
-                               export_symbols)
+    def __init__ (
+            self, name, sources,
+            include_dirs=None,
+            define_macros=None,
+            undef_macros=None,
+            library_dirs=None,
+            libraries=None,
+            runtime_library_dirs=None,
+            extra_objects=None,
+            extra_compile_args=None,
+            extra_link_args=None,
+            export_symbols=None,
+            swig_opts=None,
+            depends=None,
+            language=None,
+            f2py_options=None,
+            module_dirs=None,
+            extra_f77_compile_args=None,
+            extra_f90_compile_args=None,):
+
+        old_Extension.__init__(
+                self, name, [],
+                include_dirs=include_dirs,
+                define_macros=define_macros,
+                undef_macros=undef_macros,
+                library_dirs=library_dirs,
+                libraries=libraries,
+                runtime_library_dirs=runtime_library_dirs,
+                extra_objects=extra_objects,
+                extra_compile_args=extra_compile_args,
+                extra_link_args=extra_link_args,
+                export_symbols=export_symbols)
+
         # Avoid assert statements checking that sources contains strings:
         self.sources = sources
 


Test patch: