Repository: conda/conda

Issue:
conda config --set show_channel_urls yes doesn't work anymore
This is happening since the latest conda update:

``` bat
λ conda config --set show_channel_urls yes
Error: Key: show_channel_urls; yes is not a YAML boolean.
```

It happens with both conda 4.1.1 (local windows py 3.5) and 4.1.0 (appveyor, https://ci.appveyor.com/project/mdboom/matplotlib/build/1.0.1774) and it worked with 4.0.8 (https://ci.appveyor.com/project/mdboom/matplotlib/build/1.0.1765/job/bkldg98f8p087xmf)



Discussion:
This one is CC @mcg1969 

I didn't mess with the section of code. I don't mind fixing it, don't get me wrong, but I am guessing that this is a difference between our old YAML library and our new one

Try using true/false instead of yes/no... @msarahan?

Ahhhh, interesting.  I thought I had tested for that.  But we can change
the ruamel_yaml version back to using yaml 1.1 (if it isn't already), and
then yes/no should work for yaml booleans.

On Thu, Jun 16, 2016 at 5:33 PM, Michael C. Grant notifications@github.com
wrote:

> Try using true/false instead of yes/no... @msarahan
> https://github.com/msarahan?
> 
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> https://github.com/conda/conda/issues/2732#issuecomment-226633230, or mute
> the thread
> https://github.com/notifications/unsubscribe/ABWks12m0vAh-7R3sO7oVkpihlF1YwIhks5qMc8tgaJpZM4I33Ze
> .

## 

_Kale J. Franz, PhD_
_Conda Tech Lead_
_kfranz@continuum.io kfranz@continuum.io_
_@kalefranz https://twitter.com/kalefranz_

http://continuum.io/ http://continuum.io/
http://continuum.io/
221 W 6th St | Suite 1550 | Austin, TX 78701

I think the ship is sailed on the new library. I think we have to work around it

Looks like YAML 1.2 drops Yes/No and On/Off support: http://yaml.readthedocs.io/en/latest/pyyaml.html

Good news, we can fix

Changing `version="1.2"` to `version="1.1"` on line 298 of `utils.py` restores this behavior. I'm concerned we may be breaking other things though by doing this, so my inclination is to create a `yaml_bool` function to wrap around the output of `yaml.load` in cases like this.

Even better: drop the use of `yaml.load` to parse the boolean strings in `cli/main_config.py` in the first place.


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
@@ -13,7 +13,7 @@
 from ..compat import string_types
 from ..config import (rc_bool_keys, rc_string_keys, rc_list_keys, sys_rc_path,
                       user_rc_path, rc_other)
-from ..utils import yaml_load, yaml_dump
+from ..utils import yaml_load, yaml_dump, yaml_bool
 
 descr = """
 Modify configuration values in .condarc.  This is modeled after the git
@@ -289,14 +289,14 @@ def execute_config(args, parser):
     set_bools, set_strings = set(rc_bool_keys), set(rc_string_keys)
     for key, item in args.set:
         # Check key and value
-        yamlitem = yaml_load(item)
         if key in set_bools:
-            if not isinstance(yamlitem, bool):
+            itemb = yaml_bool(item)
+            if itemb is None:
                 error_and_exit("Key: %s; %s is not a YAML boolean." % (key, item),
                                json=args.json, error_type="TypeError")
-            rc_config[key] = yamlitem
+            rc_config[key] = itemb
         elif key in set_strings:
-            rc_config[key] = yamlitem
+            rc_config[key] = item
         else:
             error_and_exit("Error key must be one of %s, not %s" %
                            (', '.join(set_bools | set_strings), key), json=args.json,
diff --git a/conda/connection.py b/conda/connection.py
--- a/conda/connection.py
+++ b/conda/connection.py
@@ -22,7 +22,7 @@
 from . import __version__ as VERSION
 from .compat import urlparse, StringIO
 from .config import platform as config_platform, ssl_verify, get_proxy_servers
-from .utils import gnu_get_libc_version
+from .utils import gnu_get_libc_version, yaml_bool
 
 RETRIES = 3
 
@@ -110,7 +110,7 @@ def __init__(self, *args, **kwargs):
 
         self.headers['User-Agent'] = user_agent
 
-        self.verify = ssl_verify
+        self.verify = yaml_bool(ssl_verify, ssl_verify)
 
 
 class NullAuth(requests.auth.AuthBase):
diff --git a/conda/utils.py b/conda/utils.py
--- a/conda/utils.py
+++ b/conda/utils.py
@@ -292,6 +292,20 @@ def get_yaml():
     return yaml
 
 
+# Restores YAML 1.1 boolean flexibility.
+yaml_bool_ = {
+    'true': True, 'yes': True, 'on': True,
+    'false': False, 'no': False, 'off': False
+}
+def yaml_bool(s, passthrough=None):
+    if type(s) is bool:
+        return s
+    try:
+        return yaml_bool_.get(s.lower(), passthrough)
+    except AttributeError:
+        return passthrough
+
+
 def yaml_load(filehandle):
     yaml = get_yaml()
     try:


Test patch:
diff --git a/tests/test_config.py b/tests/test_config.py
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -12,7 +12,7 @@
 import pytest
 
 import conda.config as config
-from conda.utils import get_yaml
+from conda.utils import get_yaml, yaml_bool
 
 from tests.helpers import run_conda_command
 
@@ -441,20 +441,17 @@ def test_invalid_rc():
 
 def test_config_set():
     # Test the config set command
-    # Make sure it accepts only boolean values for boolean keys and any value for string keys
+    # Make sure it accepts any YAML 1.1 boolean values
+    assert yaml_bool(True) is True
+    assert yaml_bool(False) is False
+    for str in ('yes', 'Yes', 'YES', 'on', 'On', 'ON',
+                'off', 'Off', 'OFF', 'no', 'No', 'NO'):
+      with make_temp_condarc() as rc:
+          stdout, stderr = run_conda_command('config', '--file', rc,
+                                             '--set', 'always_yes', str)
+          assert stdout == ''
+          assert stderr == ''
 
-    with make_temp_condarc() as rc:
-        stdout, stderr = run_conda_command('config', '--file', rc,
-                                           '--set', 'always_yes', 'yes')
-
-        assert stdout == ''
-        assert stderr == 'Error: Key: always_yes; yes is not a YAML boolean.'
-
-        stdout, stderr = run_conda_command('config', '--file', rc,
-                                           '--set', 'always_yes', 'no')
-
-        assert stdout == ''
-        assert stderr == 'Error: Key: always_yes; no is not a YAML boolean.'
 
 def test_set_rc_string():
     # Test setting string keys in .condarc