Repository: conda/conda

Issue:
Unable to conda update --all
An unexpected error has occurred.
Please consider posting the following information to the
conda GitHub issue tracker at:

```
https://github.com/conda/conda/issues
```

Current conda install:

```
           platform : win-64
      conda version : 4.2.6
   conda is private : False
  conda-env version : 4.2.6
conda-build version : 2.0.1
     python version : 3.5.2.final.0
   requests version : 2.11.1
   root environment : C:\Anaconda3  (writable)
default environment : C:\Anaconda3
   envs directories : C:\Anaconda3\envs
      package cache : C:\Anaconda3\pkgs
       channel URLs : https://repo.continuum.io/pkgs/free/win-64/
                      https://repo.continuum.io/pkgs/free/noarch/
                      https://repo.continuum.io/pkgs/pro/win-64/
                      https://repo.continuum.io/pkgs/pro/noarch/
                      https://repo.continuum.io/pkgs/msys2/win-64/
                      https://repo.continuum.io/pkgs/msys2/noarch/
        config file : c:\users\gvdeynde\.condarc
       offline mode : False
```

`$ C:\Anaconda3\Scripts\conda-script.py update --all`

```
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\conda\exceptions.py", line 472, in conda_exception_handler
    return_value = func(*args, **kwargs)
  File "C:\Anaconda3\lib\site-packages\conda\cli\main.py", line 144, in _main
    exit_code = args.func(args, p)
  File "C:\Anaconda3\lib\site-packages\conda\cli\main_update.py", line 65, in execute
    install(args, parser, 'update')
  File "C:\Anaconda3\lib\site-packages\conda\cli\install.py", line 139, in install
    context.validate_all()
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 752, in validate_all
    for source in self.raw_data))
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 752, in <genexpr>
    for source in self.raw_data))
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 739, in check_source
    collected_errors = parameter.collect_errors(self, typed_value, match.source)
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 642, in collect_errors
    for key, val in iteritems(value) if not isinstance(val, element_type))
  File "C:\Anaconda3\lib\site-packages\conda\compat.py", line 148, in iteritems
    return iter(getattr(d, _iteritems)())
AttributeError: 'str' object has no attribute 'items'
```

Unable to conda update --all
An unexpected error has occurred.
Please consider posting the following information to the
conda GitHub issue tracker at:

```
https://github.com/conda/conda/issues
```

Current conda install:

```
           platform : win-64
      conda version : 4.2.6
   conda is private : False
  conda-env version : 4.2.6
conda-build version : 2.0.1
     python version : 3.5.2.final.0
   requests version : 2.11.1
   root environment : C:\Anaconda3  (writable)
default environment : C:\Anaconda3
   envs directories : C:\Anaconda3\envs
      package cache : C:\Anaconda3\pkgs
       channel URLs : https://repo.continuum.io/pkgs/free/win-64/
                      https://repo.continuum.io/pkgs/free/noarch/
                      https://repo.continuum.io/pkgs/pro/win-64/
                      https://repo.continuum.io/pkgs/pro/noarch/
                      https://repo.continuum.io/pkgs/msys2/win-64/
                      https://repo.continuum.io/pkgs/msys2/noarch/
        config file : c:\users\gvdeynde\.condarc
       offline mode : False
```

`$ C:\Anaconda3\Scripts\conda-script.py update --all`

```
Traceback (most recent call last):
  File "C:\Anaconda3\lib\site-packages\conda\exceptions.py", line 472, in conda_exception_handler
    return_value = func(*args, **kwargs)
  File "C:\Anaconda3\lib\site-packages\conda\cli\main.py", line 144, in _main
    exit_code = args.func(args, p)
  File "C:\Anaconda3\lib\site-packages\conda\cli\main_update.py", line 65, in execute
    install(args, parser, 'update')
  File "C:\Anaconda3\lib\site-packages\conda\cli\install.py", line 139, in install
    context.validate_all()
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 752, in validate_all
    for source in self.raw_data))
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 752, in <genexpr>
    for source in self.raw_data))
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 739, in check_source
    collected_errors = parameter.collect_errors(self, typed_value, match.source)
  File "C:\Anaconda3\lib\site-packages\conda\common\configuration.py", line 642, in collect_errors
    for key, val in iteritems(value) if not isinstance(val, element_type))
  File "C:\Anaconda3\lib\site-packages\conda\compat.py", line 148, in iteritems
    return iter(getattr(d, _iteritems)())
AttributeError: 'str' object has no attribute 'items'
```



Discussion:

Resolving patch:
diff --git a/conda/common/configuration.py b/conda/common/configuration.py
--- a/conda/common/configuration.py
+++ b/conda/common/configuration.py
@@ -637,9 +637,11 @@ def __init__(self, element_type, default=None, aliases=(), validation=None):
 
     def collect_errors(self, instance, value, source="<<merged>>"):
         errors = super(MapParameter, self).collect_errors(instance, value)
-        element_type = self._element_type
-        errors.extend(InvalidElementTypeError(self.name, val, source, type(val), element_type, key)
-                      for key, val in iteritems(value) if not isinstance(val, element_type))
+        if isinstance(value, Mapping):
+            element_type = self._element_type
+            errors.extend(InvalidElementTypeError(self.name, val, source, type(val),
+                                                  element_type, key)
+                          for key, val in iteritems(value) if not isinstance(val, element_type))
         return errors
 
     def _merge(self, matches):


Test patch:
diff --git a/tests/common/test_configuration.py b/tests/common/test_configuration.py
--- a/tests/common/test_configuration.py
+++ b/tests/common/test_configuration.py
@@ -5,7 +5,7 @@
 from conda.common.compat import odict, string_types
 from conda.common.configuration import (Configuration, MapParameter, ParameterFlag,
                                         PrimitiveParameter, SequenceParameter, YamlRawParameter,
-                                        load_file_configs, MultiValidationError)
+                                        load_file_configs, MultiValidationError, InvalidTypeError)
 from conda.common.yaml import yaml_load
 from conda.common.configuration import ValidationError
 from os import environ, mkdir
@@ -388,3 +388,12 @@ def test_validate_all(self):
     def test_cross_parameter_validation(self):
         pass
         # test primitive can't be list; list can't be map, etc
+
+    def test_map_parameter_must_be_map(self):
+        # regression test for conda/conda#3467
+        string = dals("""
+        proxy_servers: bad values
+        """)
+        data = odict(s1=YamlRawParameter.make_raw_parameters('s1', yaml_load(string)))
+        config = SampleConfiguration()._add_raw_data(data)
+        raises(InvalidTypeError, config.validate_all)