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 --- |