Repository: google/yapf
Pull request #407 (2017-05-10 17:10:07)

Add ability to specify style via dict with string values
This actually is a better solution than just documenting how to write a string properly in the docs for in memory use, since you can just use the dict directly (see #405).

Becuase I wanted to keep it the same as before using the config parser, that means that all values need to be passed in as a string, which seems reasonable enough.


Patch:
diff --git a/yapf/yapflib/style.py b/yapf/yapflib/style.py
index 14be59e..a3d59ed 100644
--- a/yapf/yapflib/style.py
+++ b/yapf/yapflib/style.py
@@ -375,18 +375,29 @@ def CreateStyleFromConfig(style_config):
     if not def_style:
       return _style
     return _GLOBAL_STYLE_FACTORY()
-  style_factory = _STYLE_NAME_TO_FACTORY.get(style_config.lower())
-  if style_factory is not None:
-    return style_factory()
-  if style_config.startswith('{'):
-    # Most likely a style specification from the command line.
-    config = _CreateConfigParserFromConfigString(style_config)
-  else:
-    # Unknown config name: assume it's a file name then.
-    config = _CreateConfigParserFromConfigFile(style_config)
+  if isinstance(style_config, dict):
+    config = _CreateConfigParserFromConfigDict(style_config)
+  elif isinstance(style_config, str):
+    style_factory = _STYLE_NAME_TO_FACTORY.get(style_config.lower())
+    if style_factory is not None:
+      return style_factory()
+    if style_config.startswith('{'):
+      # Most likely a style specification from the command line.
+      config = _CreateConfigParserFromConfigString(style_config)
+    else:
+      # Unknown config name: assume it's a file name then.
+      config = _CreateConfigParserFromConfigFile(style_config)
   return _CreateStyleFromConfigParser(config)
 
 
+def _CreateConfigParserFromConfigDict(config_dict):
+  config = py3compat.ConfigParser()
+  config.add_section('style')
+  for key, value in config_dict.items():
+    config.set('style', key, str(value))
+  return config
+
+
 def _CreateConfigParserFromConfigString(config_string):
   """Given a config string from the command line, return a config parser."""
   if config_string[0] != '{' or config_string[-1] != '}':


Test patch:
diff --git a/yapftests/style_test.py b/yapftests/style_test.py
index 2bbbd50..02ecbae 100644
--- a/yapftests/style_test.py
+++ b/yapftests/style_test.py
@@ -207,6 +207,31 @@ class StyleFromFileTest(unittest.TestCase):
         style.CreateStyleFromConfig(filepath)
 
 
+class StyleFromDict(unittest.TestCase):
+
+  @classmethod
+  def setUpClass(cls):
+    style.SetGlobalStyle(style.CreatePEP8Style())
+
+  def testDefaultBasedOnStyle(self):
+    config_dict = {
+        'based_on_style': 'pep8',
+        'indent_width': 2,
+        'blank_line_before_nested_class_or_def': True
+    }
+    cfg = style.CreateStyleFromConfig(config_dict)
+    self.assertTrue(_LooksLikeChromiumStyle(cfg))
+    self.assertEqual(cfg['INDENT_WIDTH'], 2)
+
+  def testDefaultBasedOnStyleBadDict(self):
+    self.assertRaisesRegexp(style.StyleConfigError, 'Unknown style option',
+                            style.CreateStyleFromConfig,
+                            {'based_on_styl': 'pep8'})
+    self.assertRaisesRegexp(style.StyleConfigError, 'not a valid',
+                            style.CreateStyleFromConfig,
+                            {'INDENT_WIDTH': 'FOUR'})
+
+
 class StyleFromCommandLine(unittest.TestCase):
 
   @classmethod