config.py (2712:aa0891b4a110) config.py (2714:baa3445b7b9e)
1# Copyright (c) 2004-2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

--- 129 unchanged lines hidden (view full) ---

138
139def isSimObjectClass(value):
140 try:
141 return issubclass(value, SimObject)
142 except TypeError:
143 # happens if value is not a class at all
144 return False
145
1# Copyright (c) 2004-2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright

--- 129 unchanged lines hidden (view full) ---

138
139def isSimObjectClass(value):
140 try:
141 return issubclass(value, SimObject)
142 except TypeError:
143 # happens if value is not a class at all
144 return False
145
146def isSimObjSequence(value):
147 if not isinstance(value, (list, tuple)):
146def isSimObjectSequence(value):
147 if not isinstance(value, (list, tuple)) or len(value) == 0:
148 return False
149
150 for val in value:
151 if not isNullPointer(val) and not isSimObject(val):
152 return False
153
154 return True
155
148 return False
149
150 for val in value:
151 if not isNullPointer(val) and not isSimObject(val):
152 return False
153
154 return True
155
156def isSimObjClassSequence(value):
157 if not isinstance(value, (list, tuple)):
156def isSimObjectClassSequence(value):
157 if not isinstance(value, (list, tuple)) or len(value) == 0:
158 return False
159
160 for val in value:
161 if not isNullPointer(val) and not isSimObjectClass(val):
162 return False
163
164 return True
165
158 return False
159
160 for val in value:
161 if not isNullPointer(val) and not isSimObjectClass(val):
162 return False
163
164 return True
165
166def isSimObjectOrSequence(value):
167 return isSimObject(value) or isSimObjectSequence(value)
168
169def isSimObjectClassOrSequence(value):
170 return isSimObjectClass(value) or isSimObjectClassSequence(value)
171
166def isNullPointer(value):
167 return isinstance(value, NullSimObject)
168
172def isNullPointer(value):
173 return isinstance(value, NullSimObject)
174
175# Apply method to object.
176# applyMethod(obj, 'meth', <args>) is equivalent to obj.meth(<args>)
177def applyMethod(obj, meth, *args, **kwargs):
178 return getattr(obj, meth)(*args, **kwargs)
179
180# If the first argument is an (non-sequence) object, apply the named
181# method with the given arguments. If the first argument is a
182# sequence, apply the method to each element of the sequence (a la
183# 'map').
184def applyOrMap(objOrSeq, meth, *args, **kwargs):
185 if not isinstance(objOrSeq, (list, tuple)):
186 return applyMethod(objOrSeq, meth, *args, **kwargs)
187 else:
188 return [applyMethod(o, meth, *args, **kwargs) for o in objOrSeq]
189
190
169# The metaclass for ConfigNode (and thus for everything that derives
170# from ConfigNode, including SimObject). This class controls how new
171# classes that derive from ConfigNode are instantiated, and provides
172# inherited class behavior (just like a class controls how instances
173# of that class are instantiated, and provides inherited instance
174# behavior).
175class MetaSimObject(type):
176 # Attributes that can be set only at initialization time

--- 73 unchanged lines hidden (view full) ---

250 memo = cls.__dict__.get('_memo', {})
251
252 # Handle SimObject values
253 for key,val in cls._values.iteritems():
254 # SimObject instances need to be promoted to classes.
255 # Existing classes should not have any instance values, so
256 # these can only occur at the lowest level dict (the
257 # parameters just being set in this class definition).
191# The metaclass for ConfigNode (and thus for everything that derives
192# from ConfigNode, including SimObject). This class controls how new
193# classes that derive from ConfigNode are instantiated, and provides
194# inherited class behavior (just like a class controls how instances
195# of that class are instantiated, and provides inherited instance
196# behavior).
197class MetaSimObject(type):
198 # Attributes that can be set only at initialization time

--- 73 unchanged lines hidden (view full) ---

272 memo = cls.__dict__.get('_memo', {})
273
274 # Handle SimObject values
275 for key,val in cls._values.iteritems():
276 # SimObject instances need to be promoted to classes.
277 # Existing classes should not have any instance values, so
278 # these can only occur at the lowest level dict (the
279 # parameters just being set in this class definition).
258 if isSimObject(val):
280 if isSimObjectOrSequence(val):
259 assert(val == cls._values.local[key])
281 assert(val == cls._values.local[key])
260 cls._values[key] = val.makeClass(memo)
261 elif isSimObjSequence(val) and len(val):
262 assert(val == cls._values.local[key])
263 cls._values[key] = [ v.makeClass(memo) for v in val ]
282 cls._values[key] = applyOrMap(val, 'makeClass', memo)
264 # SimObject classes need to be subclassed so that
265 # parameters that get set at this level only affect this
266 # level and derivatives.
283 # SimObject classes need to be subclassed so that
284 # parameters that get set at this level only affect this
285 # level and derivatives.
267 elif isSimObjectClass(val):
286 elif isSimObjectClassOrSequence(val):
268 assert(not cls._values.local.has_key(key))
287 assert(not cls._values.local.has_key(key))
269 cls._values[key] = val.makeSubclass({}, memo)
270 elif isSimObjClassSequence(val) and len(val):
271 assert(not cls._values.local.has_key(key))
272 cls._values[key] = [ v.makeSubclass({}, memo) for v in val ]
288 cls._values[key] = applyOrMap(val, 'makeSubclass', {}, memo)
273
274
275 def _set_keyword(cls, keyword, val, kwtype):
276 if not isinstance(val, kwtype):
277 raise TypeError, 'keyword %s has bad type %s (expecting %s)' % \
278 (keyword, type(val), kwtype)
279 if isinstance(val, types.FunctionType):
280 val = classmethod(val)

--- 15 unchanged lines hidden (view full) ---

296 if cls.keywords.has_key(attr):
297 cls._set_keyword(attr, value, cls.keywords[attr])
298 return
299
300 # must be SimObject param
301 param = cls._params.get(attr, None)
302 if param:
303 # It's ok: set attribute by delegating to 'object' class.
289
290
291 def _set_keyword(cls, keyword, val, kwtype):
292 if not isinstance(val, kwtype):
293 raise TypeError, 'keyword %s has bad type %s (expecting %s)' % \
294 (keyword, type(val), kwtype)
295 if isinstance(val, types.FunctionType):
296 val = classmethod(val)

--- 15 unchanged lines hidden (view full) ---

312 if cls.keywords.has_key(attr):
313 cls._set_keyword(attr, value, cls.keywords[attr])
314 return
315
316 # must be SimObject param
317 param = cls._params.get(attr, None)
318 if param:
319 # It's ok: set attribute by delegating to 'object' class.
304 if (isSimObject(value) or isSimObjSequence(value)) \
305 and cls._instantiated:
320 if isSimObjectOrSequence(value) and cls._instantiated:
306 raise AttributeError, \
307 "Cannot set SimObject parameter '%s' after\n" \
308 " class %s has been instantiated or subclassed" \
309 % (attr, cls.__name__)
310 try:
311 cls._values[attr] = param.convert(value)
312 except Exception, e:
313 msg = "%s\nError setting param %s.%s to %s\n" % \
314 (e, cls.__name__, attr, value)
315 e.args = (msg, )
316 raise
317 # I would love to get rid of this
321 raise AttributeError, \
322 "Cannot set SimObject parameter '%s' after\n" \
323 " class %s has been instantiated or subclassed" \
324 % (attr, cls.__name__)
325 try:
326 cls._values[attr] = param.convert(value)
327 except Exception, e:
328 msg = "%s\nError setting param %s.%s to %s\n" % \
329 (e, cls.__name__, attr, value)
330 e.args = (msg, )
331 raise
332 # I would love to get rid of this
318 elif isSimObject(value) or isSimObjSequence(value):
333 elif isSimObjectOrSequence(value):
319 cls._values[attr] = value
320 else:
321 raise AttributeError, \
322 "Class %s has no parameter %s" % (cls.__name__, attr)
323
324 def __getattr__(cls, attr):
325 if cls._values.has_key(attr):
326 return cls._values[attr]

--- 75 unchanged lines hidden (view full) ---

402 self._values = multidict(self.__class__._values)
403 # For SimObject-valued parameters, the class should have
404 # classes (not instances) for the values. We need to
405 # instantiate these classes rather than just inheriting the
406 # class object.
407 for key,val in self.__class__._values.iteritems():
408 if isSimObjectClass(val):
409 setattr(self, key, val(_memo))
334 cls._values[attr] = value
335 else:
336 raise AttributeError, \
337 "Class %s has no parameter %s" % (cls.__name__, attr)
338
339 def __getattr__(cls, attr):
340 if cls._values.has_key(attr):
341 return cls._values[attr]

--- 75 unchanged lines hidden (view full) ---

417 self._values = multidict(self.__class__._values)
418 # For SimObject-valued parameters, the class should have
419 # classes (not instances) for the values. We need to
420 # instantiate these classes rather than just inheriting the
421 # class object.
422 for key,val in self.__class__._values.iteritems():
423 if isSimObjectClass(val):
424 setattr(self, key, val(_memo))
410 elif isSimObjClassSequence(val) and len(val):
425 elif isSimObjectClassSequence(val) and len(val):
411 setattr(self, key, [ v(_memo) for v in val ])
412 # apply attribute assignments from keyword args, if any
413 for key,val in kwargs.iteritems():
414 setattr(self, key, val)
415
416 # Use this instance as a template to create a new class.
417 def makeClass(self, memo = {}):
418 cls = memo.get(self)

--- 30 unchanged lines hidden (view full) ---

449 try:
450 value = param.convert(value)
451 except Exception, e:
452 msg = "%s\nError setting param %s.%s to %s\n" % \
453 (e, self.__class__.__name__, attr, value)
454 e.args = (msg, )
455 raise
456 # I would love to get rid of this
426 setattr(self, key, [ v(_memo) for v in val ])
427 # apply attribute assignments from keyword args, if any
428 for key,val in kwargs.iteritems():
429 setattr(self, key, val)
430
431 # Use this instance as a template to create a new class.
432 def makeClass(self, memo = {}):
433 cls = memo.get(self)

--- 30 unchanged lines hidden (view full) ---

464 try:
465 value = param.convert(value)
466 except Exception, e:
467 msg = "%s\nError setting param %s.%s to %s\n" % \
468 (e, self.__class__.__name__, attr, value)
469 e.args = (msg, )
470 raise
471 # I would love to get rid of this
457 elif isSimObject(value) or isSimObjSequence(value):
472 elif isSimObjectOrSequence(value):
458 pass
459 else:
460 raise AttributeError, "Class %s has no parameter %s" \
461 % (self.__class__.__name__, attr)
462
463 # clear out old child with this name, if any
464 self.clear_child(attr)
465
466 if isSimObject(value):
467 value.set_path(self, attr)
473 pass
474 else:
475 raise AttributeError, "Class %s has no parameter %s" \
476 % (self.__class__.__name__, attr)
477
478 # clear out old child with this name, if any
479 self.clear_child(attr)
480
481 if isSimObject(value):
482 value.set_path(self, attr)
468 elif isSimObjSequence(value):
483 elif isSimObjectSequence(value):
469 value = SimObjVector(value)
470 [v.set_path(self, "%s%d" % (attr, i)) for i,v in enumerate(value)]
471
472 self._values[attr] = value
473
474 # this hack allows tacking a '[0]' onto parameters that may or may
475 # not be vectors, and always getting the first element (e.g. cpus)
476 def __getitem__(self, key):

--- 406 unchanged lines hidden (view full) ---

883
884class VectorParamDesc(ParamDesc):
885 # Convert assigned value to appropriate type. If the RHS is not a
886 # list or tuple, it generates a single-element list.
887 def convert(self, value):
888 if isinstance(value, (list, tuple)):
889 # list: coerce each element into new list
890 tmp_list = [ ParamDesc.convert(self, v) for v in value ]
484 value = SimObjVector(value)
485 [v.set_path(self, "%s%d" % (attr, i)) for i,v in enumerate(value)]
486
487 self._values[attr] = value
488
489 # this hack allows tacking a '[0]' onto parameters that may or may
490 # not be vectors, and always getting the first element (e.g. cpus)
491 def __getitem__(self, key):

--- 406 unchanged lines hidden (view full) ---

898
899class VectorParamDesc(ParamDesc):
900 # Convert assigned value to appropriate type. If the RHS is not a
901 # list or tuple, it generates a single-element list.
902 def convert(self, value):
903 if isinstance(value, (list, tuple)):
904 # list: coerce each element into new list
905 tmp_list = [ ParamDesc.convert(self, v) for v in value ]
891 if isSimObjSequence(tmp_list):
906 if isSimObjectSequence(tmp_list):
892 return SimObjVector(tmp_list)
893 else:
894 return VectorParamValue(tmp_list)
895 else:
896 # singleton: leave it be (could coerce to a single-element
897 # list here, but for some historical reason we don't...
898 return ParamDesc.convert(self, value)
899

--- 526 unchanged lines hidden ---
907 return SimObjVector(tmp_list)
908 else:
909 return VectorParamValue(tmp_list)
910 else:
911 # singleton: leave it be (could coerce to a single-element
912 # list here, but for some historical reason we don't...
913 return ParamDesc.convert(self, value)
914

--- 526 unchanged lines hidden ---