Repository: conda/conda

Issue:
Ruamel Yaml CommentedSeq Subclasses MutableSequence not List
## Current Behavior
`conda` checks if something is a list, but since it is loaded by `ruamel_yaml` it is a `CommentedSeq`, which now no longer subclasses from `list` but from `MutableSequence`.

```python
Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/site-packages/conda/cli/main_config.py", line 30, in execute
    execute_config(args, parser)
  File "/opt/conda/lib/python3.6/site-packages/conda/cli/main_config.py", line 263, in execute_config
    raise CouldntParseError("key %r should be a list, not %s." % (key, bad))
conda.exceptions.CouldntParseError: key 'channels' should be a list, not CommentedSeq.
```
I think this is the relevant line in master. https://github.com/conda/conda/blob/master/conda/cli/main_config.py#L286

[Commit in `ruamel.yaml` changing inheritance](https://bitbucket.org/ruamel/yaml/commits/9e4de94ee6a88ed86ab5fdc6d49a23cfc6ab5782)

### Steps to Reproduce
Run a build with `ruamel_yaml>0.15.54`.

## Expected Behavior
Not error with `ruamel_yaml>0.15.54`


## Environment Information
Working on it.
<details open><summary><code>`conda info`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda info' -->

```

```
</p></details>


<details open><summary><code>`conda config --show-sources`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda config --show-sources' -->

```

```
</p></details>


<details><summary><code>`conda list --show-channel-urls`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda list --show-channel-urls' -->

```

```
</p></details>

Ruamel Yaml CommentedSeq Subclasses MutableSequence not List
## Current Behavior
`conda` checks if something is a list, but since it is loaded by `ruamel_yaml` it is a `CommentedSeq`, which now no longer subclasses from `list` but from `MutableSequence`.

```python
Traceback (most recent call last):
  File "/opt/conda/lib/python3.6/site-packages/conda/cli/main_config.py", line 30, in execute
    execute_config(args, parser)
  File "/opt/conda/lib/python3.6/site-packages/conda/cli/main_config.py", line 263, in execute_config
    raise CouldntParseError("key %r should be a list, not %s." % (key, bad))
conda.exceptions.CouldntParseError: key 'channels' should be a list, not CommentedSeq.
```
I think this is the relevant line in master. https://github.com/conda/conda/blob/master/conda/cli/main_config.py#L286

[Commit in `ruamel.yaml` changing inheritance](https://bitbucket.org/ruamel/yaml/commits/9e4de94ee6a88ed86ab5fdc6d49a23cfc6ab5782)

### Steps to Reproduce
Run a build with `ruamel_yaml>0.15.54`.

## Expected Behavior
Not error with `ruamel_yaml>0.15.54`


## Environment Information
Working on it.
<details open><summary><code>`conda info`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda info' -->

```

```
</p></details>


<details open><summary><code>`conda config --show-sources`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda config --show-sources' -->

```

```
</p></details>


<details><summary><code>`conda list --show-channel-urls`</code></summary><p>
<!-- between the ticks below, paste the output of 'conda list --show-channel-urls' -->

```

```
</p></details>



Discussion:

Resolving patch:
diff --git a/conda/cli/main_config.py b/conda/cli/main_config.py
--- a/conda/cli/main_config.py
+++ b/conda/cli/main_config.py
@@ -2,7 +2,6 @@
 # Consult LICENSE.txt or http://opensource.org/licenses/BSD-3-Clause.
 from __future__ import absolute_import, division, print_function, unicode_literals
 
-import collections
 import json
 import os
 from os.path import isfile, join
@@ -13,7 +12,8 @@
 from .._vendor.auxlib.entity import EntityEncoder
 from ..base.constants import PathConflict, SafetyChecks
 from ..base.context import context, sys_rc_path, user_rc_path
-from ..common.compat import isiterable, iteritems, itervalues, string_types, text_type
+from ..common.compat import (Mapping, Sequence, isiterable, iteritems, itervalues, string_types,
+                             text_type)
 from ..common.configuration import pretty_list, pretty_map
 from ..common.io import timeout
 from ..common.serialize import yaml, yaml_dump, yaml_load
@@ -35,7 +35,7 @@ def execute(args, parser):
 def format_dict(d):
     lines = []
     for k, v in iteritems(d):
-        if isinstance(v, collections.Mapping):
+        if isinstance(v, Mapping):
             if v:
                 lines.append("%s:" % k)
                 lines.append(pretty_map(v))
@@ -257,7 +257,8 @@ def execute_config(args, parser):
             if key not in sequence_parameters:
                 from ..exceptions import CondaValueError
                 raise CondaValueError("Key '%s' is not a known sequence parameter." % key)
-            if not isinstance(rc_config.get(key, []), list):
+            if not (isinstance(rc_config.get(key, []), Sequence) and not
+                    isinstance(rc_config.get(key, []), string_types)):
                 from ..exceptions import CouldntParseError
                 bad = rc_config[key].__class__.__name__
                 raise CouldntParseError("key %r should be a list, not %s." % (key, bad))
diff --git a/conda/common/compat.py b/conda/common/compat.py
--- a/conda/common/compat.py
+++ b/conda/common/compat.py
@@ -46,6 +46,7 @@
 # #############################
 
 if PY3:  # pragma: py2 no cover
+    from collections.abc import Mapping, Sequence
     from io import StringIO
     from itertools import zip_longest
     if sys.version_info[1] >= 5:
@@ -54,6 +55,7 @@
     else:
         JSONDecodeError = ValueError
 elif PY2:  # pragma: py3 no cover
+    from collections import Mapping, Sequence
     from cStringIO import StringIO
     from itertools import izip as zip, izip_longest as zip_longest
     JSONDecodeError = ValueError


Test patch: