Repository: spack/spack

Issue:
Metis is broken
```
$ spack install metis@5.0.2
==> Installing metis
==> cmake is already installed in /Users/davydden/spack/opt/spack/darwin-sierra-x86_64/clang-8.0.0-apple/cmake-3.6.1-knsjcg5wlbnsy27ja5ngp5xdftflnv4a
==> Trying to fetch from file:///Users/davydden/spack/var/spack/cache/metis/metis-5.0.2.tar.gz
curl: (37) Couldn't open file /Users/davydden/spack/var/spack/cache/metis/metis-5.0.2.tar.gz
==> Fetching from file:///Users/davydden/spack/var/spack/cache/metis/metis-5.0.2.tar.gz failed.
==> Trying to fetch from http://glaros.dtc.umn.edu/gkhome/fetch/sw/metis/metis-5.0.2.tar.gz
######################################################################## 100.0%
==> Staging archive: /Users/davydden/spack/var/spack/stage/metis-5.0.2-36gz5ygfj3o7ptkltsuh3t2cezy56g3y/metis-5.0.2.tar.gz
==> Created stage in /Users/davydden/spack/var/spack/stage/metis-5.0.2-36gz5ygfj3o7ptkltsuh3t2cezy56g3y
==> Applied patch install_gklib_defs_rename.patch
==> Ran patch() for metis
==> Building metis [Package]
==> Executing phase : 'install'
Traceback (most recent call last):
  File "/Users/davydden/spack/bin/spack", line 202, in <module>
    main()
  File "/Users/davydden/spack/bin/spack", line 179, in main
    return_val = command(parser, args)
  File "/Users/davydden/spack/lib/spack/spack/cmd/install.py", line 117, in install
    package.do_install(**kwargs)
  File "/Users/davydden/spack/lib/spack/spack/package.py", line 1268, in do_install
    spack.build_environment.fork(self, build_process, dirty=dirty)
  File "/Users/davydden/spack/lib/spack/spack/build_environment.py", line 542, in fork
    raise exception
AttributeError: 'functools.partial' object has no attribute '__module__'
```

@alalazo any guesses here? Maybe related to https://github.com/LLNL/spack/pull/1186. But I don't see any clues in `package.py` of `metis`.



Discussion:
I'll have a look.

It's trying to raise the exception from the child process but it looks like whatever was sent back from the child is missing an attribute somewhere...

I think it comes from `install` decorated with `@when`, I am looking at it right now.

Maybe `@when` needs to add some more metadata... that is pretty old and I'm not sure I did all the required things you're supposed to do when wrapping functions in Python.  The function object created by `@when` is in `multimethod.py`

Thanks @tgamblin 

EDIT : running `spack test` on a fix


Resolving patch:
diff --git a/lib/spack/spack/multimethod.py b/lib/spack/spack/multimethod.py
--- a/lib/spack/spack/multimethod.py
+++ b/lib/spack/spack/multimethod.py
@@ -105,7 +105,17 @@ def register(self, spec, method):
 
     def __get__(self, obj, objtype):
         """This makes __call__ support instance methods."""
-        return functools.partial(self.__call__, obj)
+        # Method_list is a list of tuples (constraint, method)
+        # Here we are going to assume that we have at least one
+        # element in the list. The first registered function
+        # will be the one 'wrapped'.
+        wrapped_method = self.method_list[0][1]
+        # Call functools.wraps manually to get all the attributes
+        # we need to be disguised as the wrapped_method
+        func = functools.wraps(wrapped_method)(
+            functools.partial(self.__call__, obj)
+        )
+        return func
 
     def __call__(self, package_self, *args, **kwargs):
         """Find the first method with a spec that matches the


Test patch: