inifile.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. # Written by John Hoffman
  2. # see LICENSE.txt for license information
  3. '''
  4. reads/writes a Windows-style INI file
  5. format:
  6. aa = "bb"
  7. cc = 11
  8. [eee]
  9. ff = "gg"
  10. decodes to:
  11. d = { '': {'aa':'bb','cc':'11'}, 'eee': {'ff':'gg'} }
  12. the encoder can also take this as input:
  13. d = { 'aa': 'bb, 'cc': 11, 'eee': {'ff':'gg'} }
  14. though it will only decode in the above format. Keywords must be strings.
  15. Values that are strings are written surrounded by quotes, and the decoding
  16. routine automatically strips any.
  17. Booleans are written as integers. Anything else aside from string/int/float
  18. may have unpredictable results.
  19. '''
  20. from cStringIO import StringIO
  21. from traceback import print_exc
  22. from types import DictType, StringType
  23. try:
  24. from types import BooleanType
  25. except ImportError:
  26. BooleanType = None
  27. try:
  28. True
  29. except:
  30. True = 1
  31. False = 0
  32. DEBUG = False
  33. def ini_write(f, d, comment=''):
  34. try:
  35. a = {'':{}}
  36. for k,v in d.items():
  37. assert type(k) == StringType
  38. k = k.lower()
  39. if type(v) == DictType:
  40. if DEBUG:
  41. print 'new section:' +k
  42. if k:
  43. assert not a.has_key(k)
  44. a[k] = {}
  45. aa = a[k]
  46. for kk,vv in v:
  47. assert type(kk) == StringType
  48. kk = kk.lower()
  49. assert not aa.has_key(kk)
  50. if type(vv) == BooleanType:
  51. vv = int(vv)
  52. if type(vv) == StringType:
  53. vv = '"'+vv+'"'
  54. aa[kk] = str(vv)
  55. if DEBUG:
  56. print 'a['+k+']['+kk+'] = '+str(vv)
  57. else:
  58. aa = a['']
  59. assert not aa.has_key(k)
  60. if type(v) == BooleanType:
  61. v = int(v)
  62. if type(v) == StringType:
  63. v = '"'+v+'"'
  64. aa[k] = str(v)
  65. if DEBUG:
  66. print 'a[\'\']['+k+'] = '+str(v)
  67. r = open(f,'w')
  68. if comment:
  69. for c in comment.split('\n'):
  70. r.write('# '+c+'\n')
  71. r.write('\n')
  72. l = a.keys()
  73. l.sort()
  74. for k in l:
  75. if k:
  76. r.write('\n['+k+']\n')
  77. aa = a[k]
  78. ll = aa.keys()
  79. ll.sort()
  80. for kk in ll:
  81. r.write(kk+' = '+aa[kk]+'\n')
  82. success = True
  83. except:
  84. if DEBUG:
  85. print_exc()
  86. success = False
  87. try:
  88. r.close()
  89. except:
  90. pass
  91. return success
  92. if DEBUG:
  93. def errfunc(lineno, line, err):
  94. print '('+str(lineno)+') '+err+': '+line
  95. else:
  96. errfunc = lambda lineno, line, err: None
  97. def ini_read(f, errfunc = errfunc):
  98. try:
  99. r = open(f,'r')
  100. ll = r.readlines()
  101. d = {}
  102. dd = {'':d}
  103. for i in xrange(len(ll)):
  104. l = ll[i]
  105. l = l.strip()
  106. if not l:
  107. continue
  108. if l[0] == '#':
  109. continue
  110. if l[0] == '[':
  111. if l[-1] != ']':
  112. errfunc(i,l,'syntax error')
  113. continue
  114. l1 = l[1:-1].strip().lower()
  115. if not l1:
  116. errfunc(i,l,'syntax error')
  117. continue
  118. if dd.has_key(l1):
  119. errfunc(i,l,'duplicate section')
  120. d = dd[l1]
  121. continue
  122. d = {}
  123. dd[l1] = d
  124. continue
  125. try:
  126. k,v = l.split('=',1)
  127. except:
  128. try:
  129. k,v = l.split(':',1)
  130. except:
  131. errfunc(i,l,'syntax error')
  132. continue
  133. k = k.strip().lower()
  134. v = v.strip()
  135. if len(v) > 1 and ( (v[0] == '"' and v[-1] == '"') or
  136. (v[0] == "'" and v[-1] == "'") ):
  137. v = v[1:-1]
  138. if not k:
  139. errfunc(i,l,'syntax error')
  140. continue
  141. if d.has_key(k):
  142. errfunc(i,l,'duplicate entry')
  143. continue
  144. d[k] = v
  145. if DEBUG:
  146. print dd
  147. except:
  148. if DEBUG:
  149. print_exc()
  150. dd = None
  151. try:
  152. r.close()
  153. except:
  154. pass
  155. return dd