Repository: StackStorm/st2

Issue:
add utf8  supporting  for config file(yaml)
add utf8  supporting  for config file(yaml)


Discussion:

Resolving patch:
diff --git a/st2client/st2client/config_parser.py b/st2client/st2client/config_parser.py
--- a/st2client/st2client/config_parser.py
+++ b/st2client/st2client/config_parser.py
@@ -23,6 +23,8 @@
 
 from collections import defaultdict
 
+import io
+
 import six
 from six.moves.configparser import ConfigParser
 
@@ -137,7 +139,7 @@ def parse(self):
             return CONFIG_DEFAULT_VALUES
 
         config = ConfigParser()
-        with open(self.config_file_path, 'r') as fp:
+        with io.open(self.config_file_path, 'r', encoding='utf8') as fp:
             config.readfp(fp)
 
         for section, keys in six.iteritems(CONFIG_FILE_OPTIONS):
diff --git a/st2common/st2common/util/config_parser.py b/st2common/st2common/util/config_parser.py
--- a/st2common/st2common/util/config_parser.py
+++ b/st2common/st2common/util/config_parser.py
@@ -17,6 +17,7 @@
 import os
 
 import yaml
+import io
 
 from st2common.content import utils
 
@@ -94,7 +95,7 @@ def get_and_parse_config(cls, config_path):
             return None
 
         if os.path.exists(config_path) and os.path.isfile(config_path):
-            with open(config_path, 'r') as fp:
+            with io.open(config_path, 'r', encoding='utf8') as fp:
                 config = yaml.safe_load(fp.read())
 
             return ContentPackConfig(file_path=config_path, config=config)
diff --git a/st2tests/st2tests/fixtures/packs/dummy_pack_18/__init__.py b/st2tests/st2tests/fixtures/packs/dummy_pack_18/__init__.py
new file mode 100644


Test patch:
diff --git a/st2client/tests/fixtures/test_unicode.ini b/st2client/tests/fixtures/test_unicode.ini
new file mode 100644
--- /dev/null
+++ b/st2client/tests/fixtures/test_unicode.ini
@@ -0,0 +1,20 @@
+[general]
+base_url = http://127.0.0.1
+api_version = v1
+cacert = cacartpath
+
+[cli]
+debug = True
+
+[credentials]
+username = test1
+password = 密码
+
+[api]
+url = http://127.0.0.1:9101/v1
+
+[auth]
+url = http://127.0.0.1:9100/
+
+[stream]
+url = http://127.0.0.1:9102/v1/stream
diff --git a/st2client/tests/unit/test_config_parser.py b/st2client/tests/unit/test_config_parser.py
--- a/st2client/tests/unit/test_config_parser.py
+++ b/st2client/tests/unit/test_config_parser.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 # Licensed to the StackStorm, Inc ('StackStorm') under one or more
 # contributor license agreements.  See the NOTICE file distributed with
 # this work for additional information regarding copyright ownership.
@@ -16,6 +17,7 @@
 from __future__ import absolute_import
 import os
 
+import six
 import unittest2
 
 from st2client.config_parser import CLIConfigParser
@@ -24,6 +26,7 @@
 BASE_DIR = os.path.dirname(os.path.abspath(__file__))
 CONFIG_FILE_PATH_FULL = os.path.join(BASE_DIR, '../fixtures/st2rc.full.ini')
 CONFIG_FILE_PATH_PARTIAL = os.path.join(BASE_DIR, '../fixtures/st2rc.partial.ini')
+CONFIG_FILE_PATH_UNICODE = os.path.join(BASE_DIR, '../fixtures/test_unicode.ini')
 
 
 class CLIConfigParserTestCase(unittest2.TestCase):
@@ -79,3 +82,13 @@ def test_parse(self):
                                  validate_config_exists=False)
         result = parser.parse()
         self.assertTrue(result['cli']['cache_token'], True)
+
+    def test_get_config_for_unicode_char(self):
+        parser = CLIConfigParser(config_file_path=CONFIG_FILE_PATH_UNICODE,
+                                 validate_config_exists=False)
+        config = parser.parse()
+
+        if six.PY3:
+            self.assertEqual(config['credentials']['password'], '密码')
+        else:
+            self.assertEqual(config['credentials']['password'], u'\u5bc6\u7801')
diff --git a/st2common/tests/unit/test_config_parser.py b/st2common/tests/unit/test_config_parser.py
--- a/st2common/tests/unit/test_config_parser.py
+++ b/st2common/tests/unit/test_config_parser.py
@@ -1,3 +1,4 @@
+# coding=utf-8
 # Licensed to the StackStorm, Inc ('StackStorm') under one or more
 # contributor license agreements.  See the NOTICE file distributed with
 # this work for additional information regarding copyright ownership.
@@ -44,3 +45,9 @@ def test_get_config_existing_config(self):
         config = parser.get_config()
         self.assertEqual(config.config['section1']['key1'], 'value1')
         self.assertEqual(config.config['section2']['key10'], 'value10')
+
+    def test_get_config_for_unicode_char(self):
+        pack_name = 'dummy_pack_18'
+        parser = ContentPackConfigParser(pack_name=pack_name)
+        config = parser.get_config()
+        self.assertEqual(config.config['section1']['key1'], u'测试')