Repository: spack/spack

Issue:
Documented feature of conditionally autoloading dependencies doesn't work
I followed the documentation on [autoloading direct dependencies for packages dependent on python](https://spack.readthedocs.io/en/latest/module_file_support.html?highlight=autoload#autoload-dependencies) and now every package has it's direct dependencies autoloaded. (This happens for both lmod and tcl modules).

### Steps to reproduce the issue

```console
$ git clone https://github.com/spack/spack.git
$ # follow the documented instructions linked above to add `^python: autoload: 'direct'` to `~/.spack/modules.yaml`
$ spack install emacs
$ module load emacs-26.1-gcc-4.8.5-6idl5st
$ ml

Currently Loaded Modules:
  1) pcre-8.42-gcc-4.8.5-vwvgnbn   2) ncurses-6.1-gcc-4.8.5-wkyck36   3) zlib-1.2.11-gcc-4.8.5-vhzh5cf   4) emacs-26.1-gcc-4.8.5-6idl5st
```

### Error Message

See above for the current, unexpected out (note that emacs and its direct dependencies are loaded).
See below for the expected output (note the lack of emacs' direct dependencies). This is the same output that I get if I don't include the `^python: autoload: 'direct'` that is suggested in the documentation.
```console
$ git clone https://github.com/spack/spack.git
$ # follow the documented instructions linked above to add `^python: autoload: 'direct'` to `~/.spack/modules.yaml`
$ spack install emacs
$ module load emacs-26.1-gcc-4.8.5-6idl5st
$ ml

Currently Loaded Modules:
  1) emacs-26.1-gcc-4.8.5-6idl5st
```

### Information on your system

 1. I'm running RHEL7
 2. 
```
→ spack config blame modules
---                                                                         modules:
~/.spack/modules.yaml:17                                         enable:
~/.spack/modules.yaml:18                                         - lmod
~/.spack/modules.yaml:19                                         - tcl
~/Repositories/spack/etc/spack/defaults/modules.yaml:19          - dotkit
~/Repositories/spack/etc/spack/defaults/linux/modules.yaml:17    prefix_inspections:
~/Repositories/spack/etc/spack/defaults/modules.yaml:21            bin:
~/Repositories/spack/etc/spack/defaults/modules.yaml:22            - PATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:23            man:
~/Repositories/spack/etc/spack/defaults/modules.yaml:24            - MANPATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:25            share/man:
~/Repositories/spack/etc/spack/defaults/modules.yaml:26            - MANPATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:27            share/aclocal:
~/Repositories/spack/etc/spack/defaults/modules.yaml:28            - ACLOCAL_PATH
~/Repositories/spack/etc/spack/defaults/linux/modules.yaml:18      lib:
~/Repositories/spack/etc/spack/defaults/linux/modules.yaml:19      - LD_LIBRARY_PATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:30            - LIBRARY_PATH
~/Repositories/spack/etc/spack/defaults/linux/modules.yaml:20      lib64:
~/Repositories/spack/etc/spack/defaults/linux/modules.yaml:21      - LD_LIBRARY_PATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:32            - LIBRARY_PATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:33            include:
~/Repositories/spack/etc/spack/defaults/modules.yaml:34            - CPATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:35            lib/pkgconfig:
~/Repositories/spack/etc/spack/defaults/modules.yaml:36            - PKG_CONFIG_PATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:37            lib64/pkgconfig:
~/Repositories/spack/etc/spack/defaults/modules.yaml:38            - PKG_CONFIG_PATH
~/Repositories/spack/etc/spack/defaults/modules.yaml:40            ? ''
~/.spack/modules.yaml:23                                           : - CMAKE_PREFIX_PATH
~/.spack/modules.yaml:26                                         lmod:
~/.spack/modules.yaml:27                                           hierarchy:
~/.spack/modules.yaml:27                                           - mpi
~/.spack/modules.yaml:27                                           blacklist_implicits: False
~/.spack/modules.yaml:27                                           verbose: False
~/.spack/modules.yaml:24                                           hash_length: 7
~/.spack/modules.yaml:25                                           core_compilers:
~/.spack/modules.yaml:28                                           - gcc@4.8.5
~/.spack/modules.yaml:29                                           ^python:
~/.spack/modules.yaml:20                                             autoload: direct
~/.spack/modules.yaml:21                                         tcl:
~/.spack/modules.yaml:22                                           ^python:
~/.spack/modules.yaml:22                                             autoload: direct
~/.spack/modules.yaml:22                                           blacklist_implicits: False
~/.spack/modules.yaml:22                                           verbose: False

```


Discussion:
Potentially related: it appears that `blacklist_implicits: true` has no effect (i.e., implicit packages are still created) even after removing the `^python: autoload: 'direct'` lines.
I was able to reproduce this on a local machine (Ubuntu 18.04).

Resolving patch:
diff --git a/lib/spack/spack/modules/common.py b/lib/spack/spack/modules/common.py
--- a/lib/spack/spack/modules/common.py
+++ b/lib/spack/spack/modules/common.py
@@ -173,7 +173,7 @@ def merge_config_rules(configuration, spec):
         if constraint.endswith(':'):
             constraint = constraint.strip(':')
             override = True
-        if spec.satisfies(constraint):
+        if spec.satisfies(constraint, strict=True):
             if override:
                 spec_configuration = {}
             update_dictionary_extending_lists(spec_configuration, action)


Test patch:
diff --git a/lib/spack/spack/test/data/modules/tcl/autoload_with_constraints.yaml b/lib/spack/spack/test/data/modules/tcl/autoload_with_constraints.yaml
new file mode 100644
--- /dev/null
+++ b/lib/spack/spack/test/data/modules/tcl/autoload_with_constraints.yaml
@@ -0,0 +1,8 @@
+enable:
+  - tcl
+tcl:
+  ^mpich2:
+    autoload: 'direct'
+
+  ^python:
+    autoload: 'direct'
diff --git a/lib/spack/spack/test/modules/tcl.py b/lib/spack/spack/test/modules/tcl.py
--- a/lib/spack/spack/test/modules/tcl.py
+++ b/lib/spack/spack/test/modules/tcl.py
@@ -276,3 +276,20 @@ def test_blacklist_implicits(
         for item in callpath_specs:
             writer = writer_cls(item)
             assert writer.conf.blacklisted
+
+    @pytest.mark.regression('9624')
+    @pytest.mark.db
+    def test_autoload_with_constraints(
+            self, modulefile_content, module_configuration, database
+    ):
+        """Tests the automatic loading of direct dependencies."""
+
+        module_configuration('autoload_with_constraints')
+
+        # Test the mpileaks that should have the autoloaded dependencies
+        content = modulefile_content('mpileaks ^mpich2')
+        assert len([x for x in content if 'is-loaded' in x]) == 2
+
+        # Test the mpileaks that should NOT have the autoloaded dependencies
+        content = modulefile_content('mpileaks ^mpich')
+        assert len([x for x in content if 'is-loaded' in x]) == 0