/setupcfg/cfg.py

https://github.com/looking-for-a-job/setupcfg.py
Python | 97 lines | 67 code | 16 blank | 14 comment | 13 complexity | b6dede7bdc508e502008f9766866c8c6 MD5 | raw file
  1. #!/usr/bin/env python
  2. import collections
  3. try:
  4. from ConfigParser import ConfigParser
  5. from StringIO import StringIO
  6. except ImportError:
  7. from configparser import ConfigParser
  8. from io import StringIO
  9. import setupcfg
  10. import orderdict
  11. import write
  12. """
  13. http://setuptools.readthedocs.io/en/latest/setuptools.html#metadata
  14. http://setuptools.readthedocs.io/en/latest/setuptools.html#options
  15. """
  16. SECTIONS = ["metadata", "options"]
  17. def _dict2configparser(*args, **kwargs):
  18. """
  19. python2.X dict ordering not supported (use collections.OrderedDict)
  20. configparser.update(dict) python3 only
  21. """
  22. inputdict = collections.OrderedDict(*args, **kwargs)
  23. configparser = ConfigParser()
  24. for section, value in inputdict.items():
  25. configparser.add_section(section)
  26. for k, v in value.items():
  27. configparser.set(section, k, v)
  28. return configparser
  29. def _strings(data):
  30. result = collections.OrderedDict()
  31. for key, value in data.items():
  32. if value is not None:
  33. value = setupcfg.values.string(value)
  34. if value:
  35. result[key] = value
  36. return result
  37. class Setupcfg(collections.defaultdict):
  38. """`setup.cfg` generator class. dict/attr access"""
  39. __readme__ = ["load", "save", "string"]
  40. def load(self, path="setup.cfg"):
  41. """load from `setup.cfg` file"""
  42. config = ConfigParser()
  43. config.read(path)
  44. for section in config.sections():
  45. if section not in self:
  46. self[section] = dict()
  47. for option, value in config.items(section):
  48. self[section][option] = setupcfg.values.value(value)
  49. return self
  50. def save(self, path="setup.cfg"):
  51. """save to `setup.cfg` file"""
  52. write.write(path, "%s\n" % str(self))
  53. return self
  54. def _configparser(self):
  55. metadata = orderdict.order(setupcfg.metadata.KEYS, self.get("metadata", {}))
  56. options = orderdict.order(setupcfg.options.KEYS, self.get("options", {}))
  57. data = dict(self, metadata=metadata, options=options)
  58. for section_name, section_data in data.items():
  59. data[section_name] = _strings(section_data)
  60. data = orderdict.order(SECTIONS, data)
  61. return _dict2configparser(data)
  62. def render(self):
  63. """return string representation"""
  64. output = StringIO()
  65. self._configparser().write(output)
  66. value = output.getvalue()
  67. output.close()
  68. return value.rstrip()
  69. def __getattr__(self, attr):
  70. """return dictionary with section data"""
  71. if attr in self:
  72. return self[attr]
  73. def __missing__(self, key):
  74. self[key] = dict()
  75. return self[key]
  76. def __setitem__(self, key, value):
  77. if not isinstance(value, dict):
  78. raise ValueError("'%s' is not dict" % key)
  79. super(type(self), self).__setitem__(key, value)
  80. def __str__(self):
  81. return self.render()