1# Copyright 2013 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import re
6
7
8def ToUnderscore(obj):
9  """Converts a string, list, or dict from camelCase to lower_with_underscores.
10
11  Descends recursively into lists and dicts, converting all dict keys.
12  Returns a newly allocated object of the same structure as the input.
13  """
14  if isinstance(obj, basestring):
15    return re.sub('(?!^)([A-Z]+)', r'_\1', obj).lower()
16
17  elif isinstance(obj, list):
18    return [ToUnderscore(item) for item in obj]
19
20  elif isinstance(obj, dict):
21    output = {}
22    for k, v in obj.iteritems():
23      if isinstance(v, list) or isinstance(v, dict):
24        output[ToUnderscore(k)] = ToUnderscore(v)
25      else:
26        output[ToUnderscore(k)] = v
27    return output
28
29  else:
30    return obj
31