annotate pyloader/factory.py @ 19:8987867698ee

a bit more stubbing of .ini parsing
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 30 May 2011 10:55:55 -0700
parents d303a5883991
children 057ccfe310b2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
1 """
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
2 abstract factories
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
3 """
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
4
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
5 import loader
15
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
6 import os
19
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
7 from ConfigParser import InterpolationMissingOptionError
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
8 from ConfigParser import InterpolationSyntaxError
16
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
9 from ConfigParser import SafeConfigParser as ConfigParser
15
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
10
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
11 __all__ = ['CircularReferenceError', 'PyFactory', 'IniFactory']
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
12
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
13 class CircularReferenceError(Exception):
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
14 """factory has detected a circular reference"""
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
15
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
16 class PyFactory(object):
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
17
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
18 delimeters = ('%(', ')s')
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
19
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
20 def __init__(self, config=None, main=''):
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
21 self.main = main # main section
10
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
22 self.configure(config or {})
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
23
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
24 def configure(self, config):
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
25 """load a new configuration"""
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
26 # TODO: this should really be a configuration update. If you keep
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
27 # track of all "apps" and their parents (i.e. as a ADG)
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
28 # you should be able to update only relevent apps
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
29 self.config = config
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
30 self.seen = set() # already seen apps to note cyclic dependencies
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
31 self.parsed = {} # instantiated apps
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
32
10
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
33 def load(self, name=None):
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
34 """load an object"""
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
35
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
36 name = name or self.main # load main section by default
10
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
37 assert name in self.config, "'%s' not found in configuration"
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
38 if name in self.parsed:
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
39 return self.parsed[name]
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
40 if name in self.seen:
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
41 raise CircularReferenceError('Circular reference! : %s' % name)
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
42 self.seen.add(name)
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
43
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
44 # get section
11
ff272dcd5cd8 we have a passing test
Jeff Hammel <jhammel@mozilla.com>
parents: 10
diff changeset
45 section = self.config[name]
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
46 assert 'path' in section
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
47
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
48 # load object
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
49 obj = loader.load(section['path'])
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
50
10
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
51 # get the object's arguments (if any)
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
52 args = section.get('args', None)
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
53 kwargs = section.get('kwargs', None)
10
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
54
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
55 # if args and kwargs aren't there, you're done!
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
56 if args is None and kwargs is None:
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
57 self.parsed[name] = obj
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
58 return obj
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
59
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
60 # interpolate arguments
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
61 if args:
11
ff272dcd5cd8 we have a passing test
Jeff Hammel <jhammel@mozilla.com>
parents: 10
diff changeset
62 args = [self.interpolate(arg) for arg in args]
ff272dcd5cd8 we have a passing test
Jeff Hammel <jhammel@mozilla.com>
parents: 10
diff changeset
63 else:
ff272dcd5cd8 we have a passing test
Jeff Hammel <jhammel@mozilla.com>
parents: 10
diff changeset
64 args = []
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
65 if kwargs:
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
66 kwargs = dict([(key, self.interpolate(value))
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
67 for key, value in kwargs.items()])
11
ff272dcd5cd8 we have a passing test
Jeff Hammel <jhammel@mozilla.com>
parents: 10
diff changeset
68 else:
ff272dcd5cd8 we have a passing test
Jeff Hammel <jhammel@mozilla.com>
parents: 10
diff changeset
69 kwargs = {}
10
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
70
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
71 # invoke
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
72 self.parsed[name] = obj(*args, **kwargs)
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
73 return self.parsed[name]
9
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
74
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
75 def interpolate(self, value):
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
76
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
77 # only interpolate strings
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
78 if not isinstance(value, basestring):
ff634cc2e62b unfinished sketch of an abstract factory
Jeff Hammel <jhammel@mozilla.com>
parents:
diff changeset
79 return value
10
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
80
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
81 if value.startswith(self.delimeters[0]) and value.endswith(self.delimeters[1]):
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
82 value = value[len(self.delimeters[0]):-len(self.delimeters[1])]
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
83 if value in self.config:
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
84 return self.load(value)
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
85 return value
ba2355d57998 finish baseline abstract factory implementation
Jeff Hammel <jhammel@mozilla.com>
parents: 9
diff changeset
86
15
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
87 class IniFactory(PyFactory):
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
88
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
89 def __init__(self, inifile, main=''):
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
90 assert os.path.exists(inifile), "File not found: %s" % inifile
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
91
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
92 def read(self):
0bea5297c156 introduce a more betterer test
Jeff Hammel <jhammel@mozilla.com>
parents: 14
diff changeset
93 """reads configuration from an .ini file"""
16
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
94
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
95 here = os.path.dirname(os.path.abspath(self.inifile))
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
96
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
97 # read configuration
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
98 defaults={'here': here,
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
99 'this': os.path.abspath(self.inifile)}
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
100 parser = ConfigParser(defaults=defaults)
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
101 parser.optionxform = str # use whole case
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
102 parser.read(self.inifile)
18
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
103
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
104 # parse configuration
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
105 config = {}
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
106 for section in parser.sections():
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
107
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
108 # sanity check
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
109 assert ':' in section, "No : in section: %s" % section
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
110 name, path = section.split(':', 1)
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
111 sect = config[name] = dict(path=path)
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
112 for option in parser.options(section):
19
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
113
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
114 if option in parser.defaults():
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
115 # don't include the defaults
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
116 continue
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
117 try:
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
118 value = parser.get(section, option)
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
119 except (InterpolationMissingOptionError, InterpolationSyntaxError):
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
120 value = parser.get(section, option, raw=True)
8987867698ee a bit more stubbing of .ini parsing
Jeff Hammel <jhammel@mozilla.com>
parents: 18
diff changeset
121
18
d303a5883991 even more stubbing
Jeff Hammel <jhammel@mozilla.com>
parents: 16
diff changeset
122
16
edecb6fbd5a7 further stubbing of ini factory
Jeff Hammel <jhammel@mozilla.com>
parents: 15
diff changeset
123