-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathModelUser.py
More file actions
126 lines (94 loc) · 4.1 KB
/
ModelUser.py
File metadata and controls
126 lines (94 loc) · 4.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import sys
from types import ModuleType
from MiscUtils.MixIn import MixIn
from MiscUtils import NoDefault
class ModelUser(object):
## Init ##
def __init__(self):
self._model = None
## Settings ##
def setting(self, name, default=NoDefault):
"""Return the given setting which is actually just taken from the model."""
return self._model.setting(name, default)
## Models ##
def model(self):
return self._model
def setModel(self, model):
assert model
assert self._model is None, 'Can only set model once.'
self._model = model
self.modelWasSet()
def readModelFileNamed(self, filename, modelClass=None, **keywords):
assert self._model is None, 'Cannot re-read a model.'
if modelClass is None:
from MiddleKit.Core.Model import Model as modelClass
self._model = modelClass(**keywords)
self._model.read(filename)
self.modelWasSet()
def modelWasSet(self):
"""Perform additional set up of the store after the model is set.
Invoked by setModel() or readModelFileNamed() as a hook for taking
action on this event. Invokes installMixIns().
"""
self.installMixIns()
## Mix-ins ##
def installMixIns(self, verbose=False):
if verbose:
print '>> installMixIns()'
print 'class =', self.__class__
modules = self.modulesForClass(self.__class__)
if verbose:
print 'modules =', ', '.join(modules)
# reverse order so that mix-ins in subclasses override super
for module in reversed(modules):
module = sys.modules[module]
assert type(module) is ModuleType
self.installMixInsForModule(module, verbose)
if verbose:
print
def installMixInsForModule(self, module, verbose=False):
# @@ 2000-10-18 ce: perhaps MixIns should be applied to the actual
# MiddleKit.Core class and not the custom one that possibly was
# passed into model. This would help with "invoking super" which
# may be a non-trivial operation in a mix-in of a generator module.
coreClassNames = self._model.coreClassNames()
if verbose:
print '>>', module
for name in dir(module):
generatorThing = getattr(module, name)
if isinstance(generatorThing, type):
# See if a class with the same name exists in MiddleKit.Core
import MiddleKit.Core as Core
if name in coreClassNames:
baseClass = self._model.coreClass(name)
if baseClass is not generatorThing:
if verbose:
print '>> mixing %s into %s' % (generatorThing, baseClass)
assert isinstance(baseClass, type)
assert isinstance(generatorThing, type)
MixIn(baseClass, generatorThing, mixInSuperMethods=True)
## Warning ##
def warning(self, msg):
"""Output a warning.
Invoked by self for any kind of appropriate warning that doesn't
warrant an exception being thrown. Preferably, this should be invoked
from a method that is invoked when the "bad event" occurs. This allows
subclasses to override that method and potentially customize the
behavior, including providing more debugging information.
This implementation writes the msg to stdout.
"""
print 'WARNING:', msg
## Self utility ##
def modulesForClass(self, pyClass, modules=None):
"""Return the modules for the class.
Returns a list of modules for pyClass, going up the chain of ancestor
classes, stopping short before ModelUser. Utility method for installMixIns.
"""
if modules is None:
modules = []
className = pyClass.__name__
if className != 'ModelUser':
modules.append(pyClass.__module__)
for baseClass in pyClass.__bases__:
self.modulesForClass(baseClass, modules)
return modules