Repository: spack/spack

Issue:
spack uninstall fails for libxml2
spack uninstall fails for libxml2, when without python bindings.

cab687@lee218:spack uninstall libxml2  
Traceback (most recent call last):  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/bin/spack", line 163, in <module>
    main()  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/bin/spack", line 144, in main  
    return_val = command(parser, args)  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/lib/spack/spack/cmd/uninstall.py", line 96, in uninstall  
    pkg.do_uninstall(force=args.force)  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/lib/spack/spack/package.py", line 932, in do_uninstall  
    spack.hooks.pre_uninstall(self)  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/lib/spack/spack/hooks/**init**.py", line 69, in **call**  
    hook(pkg)  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/lib/spack/spack/hooks/extensions.py", line 35, in pre_uninstall  
    if pkg.activated:  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/lib/spack/spack/package.py", line 518, in activated  
    exts = spack.install_layout.extension_map(self.extendee_spec)  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/lib/spack/spack/directory_layout.py", line 345, in extension_map  
    _check_concrete(spec)  
  File "/nfs/tmp2/lee218/pkg/spack3/spack/lib/spack/spack/directory_layout.py", line 44, in _check_concrete  
    raise ValueError('Specs passed to a DirectoryLayout must be concrete!')  
ValueError: Specs passed to a DirectoryLayout must be concrete!  



Discussion:

Resolving patch:
diff --git a/lib/spack/spack/database.py b/lib/spack/spack/database.py
--- a/lib/spack/spack/database.py
+++ b/lib/spack/spack/database.py
@@ -211,6 +211,10 @@ def _read_spec_from_yaml(self, hash_key, installs, parent_key=None):
             child = self._read_spec_from_yaml(dep_hash, installs, hash_key)
             spec._add_dependency(child)
 
+        # Specs from the database need to be marked concrete because
+        # they represent actual installations.
+        spec._mark_concrete()
+
         return spec
 
 
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -212,9 +212,7 @@ def read_spec(self, path):
             spec = Spec.from_yaml(f)
 
         # Specs read from actual installations are always concrete
-        for s in spec.traverse():
-            s._normal = True
-            s._concrete = True
+        spec._mark_concrete()
 
         return spec
 
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -833,7 +833,18 @@ def concretize(self):
             changed = any(changes)
             force=True
 
-        self._concrete = True
+        self._mark_concrete()
+
+
+    def _mark_concrete(self):
+        """Mark this spec and its dependencies as concrete.
+
+        Only for internal use -- client code should use "concretize"
+        unless there is a need to force a spec to be concrete.
+        """
+        for s in self.traverse():
+            s._normal = True
+            s._concrete = True
 
 
     def concretized(self):


Test patch: