ConfigIter.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import ConfigParser
  2. import numpy as np
  3. from math import pi
  4. ###
  5. # Utility object for reading config files
  6. ###
  7. class ConfigIter (object):
  8. '''
  9. ConfigIter is a utility class that extends the Python ConfigParser in
  10. several ways:
  11. 1.) Sections are grouped into category types by specifying the section
  12. names like 'Type: name'. The ConfigIter object iterates through all
  13. sections having the type specified in 'Category'.
  14. 2.) Sections can inherit from other sections using a 'Template' key.
  15. 3.) Key values can be Python expressions, evaluated using 'eval'.
  16. '''
  17. def __iter__(self):
  18. return self
  19. def __init__(self, config, category, defaultname):
  20. '''
  21. Create the iterator. `config' should be a ConfigParser object.
  22. `category' should be the section prefix; sections not beginning with
  23. 'category:' should be ignored. `category' is case-insensitive.
  24. '''
  25. self.Config = config
  26. self.Category = category
  27. self.DefaultName = defaultname
  28. self.Sections = []
  29. self.Names = []
  30. self.Index = 0
  31. # Find all matching sections
  32. for sec in self.Config.sections():
  33. sp = sec.split(':')
  34. if len(sp) < 2 or sp[0].upper() != category.upper():
  35. continue
  36. self.Sections.append(sec)
  37. self.Names.append(sp[1].strip())
  38. def readSection(self, secName, tgt=None):
  39. '''
  40. Read the section specified by `secName', with fancy interpolation and
  41. recursive templating. If `tgt' is specified, update that dict.
  42. otherwise, create a new dict including the interpolated key-value pairs.
  43. '''
  44. # If unspecified, create a new output dict.
  45. if tgt is None:
  46. tgt = {}
  47. # Read in template, or default if unspecified.
  48. if secName != self.DefaultName:
  49. try:
  50. tpl = self.Config.get(secName, "Template")
  51. except ConfigParser.NoOptionError:
  52. tpl = self.DefaultName
  53. self.readSection(tpl, tgt)
  54. # Read in the specified section
  55. for key, value in self.Config.items(secName):
  56. try:
  57. tgt[key] = eval(value)
  58. except (NameError, SyntaxError):
  59. tgt[key] = value
  60. return tgt
  61. def next(self):
  62. '''
  63. Return the next section in the sequence.
  64. '''
  65. if self.Index >= len(self.Sections):
  66. raise StopIteration()
  67. sec = self.Sections[self.Index]
  68. name = self.Names[self.Index]
  69. conf = self.readSection(sec)
  70. self.Index += 1
  71. return (conf, name)