comparison python/simpleini.py @ 113:44534594f402

add variable interpolation
author Jeff Hammel <jhammel@mozilla.com>
date Thu, 02 Dec 2010 13:04:54 -0800
parents e85298a35998
children 9b193312ceba
comparison
equal deleted inserted replaced
112:e85298a35998 113:44534594f402
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 2
3 import os 3 import os
4 4
5 def read(fp, comments=';#', separators=('=', ':')): 5 def read(fp, variables=None, default='DEFAULT',
6 comments=';#', separators=('=', ':'), strict=True):
7 """
8 read an .ini file and return a list of [(section, values)]
9 - fp : file pointer or name to read
10 - variables : default set of variables
11 - default : name of the section for the default section
12 - comments : characters that if they start a line denote a comment
13 - separators : strings that denote key, value separation in order
14 - strict : whether to be strict about parsing
15 """
16
17 if variables is None:
18 variables = {}
19 variables = variables.copy() # no reason to overwrite the originals
6 20
7 if isinstance(fp, basestring): 21 if isinstance(fp, basestring):
8 fp = file(fp) 22 fp = file(fp)
9 23
10 sections = [] 24 sections = []
11 key = value = None 25 key = value = None
12 26 section_names = set([])
27
28 # read the lines
13 for line in fp.readlines(): 29 for line in fp.readlines():
14 30
15 stripped = line.strip() 31 stripped = line.strip()
16 32
17 # ignore blank lines 33 # ignore blank lines
18 if not stripped: 34 if not stripped:
35 # XXX should probably reset key and value to avoid continuation lines
36 key = value = None
19 continue 37 continue
20 38
21 # ignore comment lines 39 # ignore comment lines
22 if stripped[0] in comments: 40 if stripped[0] in comments:
23 continue 41 continue
24 42
25 # check for a new section 43 # check for a new section
26 if len(stripped) > 2 and stripped[0] == '[' and stripped[-1] == ']': 44 if len(stripped) > 2 and stripped[0] == '[' and stripped[-1] == ']':
27 section = stripped[1:-1].strip() 45 section = stripped[1:-1].strip()
28 sections.append((section, {}))
29 key = value = None 46 key = value = None
30 # TODO: should probably make sure this section doesn't already exist 47
48 # deal with DEFAULT section
49 if section.lower() == default.lower():
50 if strict:
51 assert default not in section_names
52 section_names.add(default)
53 current_section = variables
54 continue
55
56 if strict:
57 # make sure this section doesn't already exist
58 assert section not in section_names
59
60 section_names.add(section)
61
62 current_section = {}
63 sections.append((section, current_section))
31 continue 64 continue
32 65
33 # if there aren't any sections yet, something bad happen 66 # if there aren't any sections yet, something bad happen
34 if not sections: 67 if not section_names:
35 raise Exception('No sections yet :(') 68 raise Exception('No sections yet :(')
36 69
37 # (key, value) pair 70 # (key, value) pair
38 for separator in separators: 71 for separator in separators:
39 if separator in stripped: 72 if separator in stripped:
40 key, value = stripped.split(separator, 1) 73 key, value = stripped.split(separator, 1)
41 key = key.strip() 74 key = key.strip()
42 value = value.strip() 75 value = value.strip()
43 sections[-1][1][key] = value 76
44 # TODO: should probably make sure this key isn't already in the section 77 if strict:
78 # make sure this key isn't already in the section or empty
79 assert key
80 if current_section is not variables:
81 assert key not in current_section
82
83 current_section[key] = value
45 break 84 break
46 else: 85 else:
47 # continuation line ? 86 # continuation line ?
48 if line[0].isspace() and key: 87 if line[0].isspace() and key:
49 value = '%s%s%s' % (value, os.linesep, stripped) 88 value = '%s%s%s' % (value, os.linesep, stripped)
50 sections[-1][1][key] = value 89 current_section[key] = value
51 else: 90 else:
52 # something bad happen! 91 # something bad happen!
53 raise Exception("Not sure what you're trying to do") 92 raise Exception("Not sure what you're trying to do")
54 93
94 # interpret the variables
95 def interpret_variables(global_dict, local_dict):
96 variables = global_dict.copy()
97 variables.update(local_dict)
98 # TODO: string intepolation
99 return variables
100
101 sections = [(i, interpret_variables(variables, j)) for i, j in sections]
55 return sections 102 return sections
56 103
57 if __name__ == '__main__': 104 if __name__ == '__main__':
58 import sys 105 import sys
59 for i in sys.argv[1:]: 106 for i in sys.argv[1:]: