Package topo :: Package misc :: Module legacy
[hide private]
[frames] | no frames]

Source Code for Module topo.misc.legacy

   1  """ 
   2  Code used to support old snapshots, and update scripts. 
   3   
   4  $Id: legacy.py 11323 2010-07-28 17:10:13Z ceball $ 
   5  """ 
   6  __version__='$Revision: 8021 $' 
   7   
   8  import imp 
   9  import sys 
10 11 # CB: If we were using pickle rather than cpickle, could subclass the 12 # unpickler to look for module Xs as module X if Xs can't be found, 13 # and probably simplify quite a lot of the legacy code installation. 14 # 15 # Maybe we could do that by trying to use cpickle initially, then 16 # falling back to pickle when we do a 'legacy load' of the snapshot. 17 18 # CEBALERT: should have ONE list for the update script and for this, 19 # rather than having (effectively) a list in each. 20 21 22 23 # CEBALERT: deal with this 24 # Temporary as of 12/2007, for backwards compatibility 25 # Image=FileImage 26 27 28 -def _setstate(inst,state):
29 for k,v in state.items(): 30 setattr(inst,k,v)
31
32 33 -def preprocess_state(class_,state_mod_fn):
34 """ 35 Allow processing of state with state_mod_fn before 36 class_.__setstate__(instance,state) is called. 37 38 state_mod_fn must accept two arguments: instance and state. 39 """ 40 if not hasattr(class_,'__setstate__'): 41 # e.g. class_ used to be Parameterized, but now isn't 42 class_.__setstate__ = _setstate 43 44 old_setstate = class_.__setstate__ 45 def new_setstate(instance,state): 46 # passing instance here allows us to avoid having to list 47 # specific classes in SnapshotSupport, because we can 48 # now test each instance. 49 state_mod_fn(instance,state) 50 old_setstate(instance,state) 51 class_.__setstate__ = new_setstate 52
53 54 # CB: this is complicated, and I'd like to remove it. Only 55 # being used once at the moment. 56 -def select_setstate(class_,selector,pre_super=False,post_super=True):
57 """ 58 Select appropriate function to call as a replacement 59 for class.__setstate__ at runtime. 60 61 selector must return None if the class_'s original method is 62 to be used; otherwise, it should return a function that takes 63 an instance of the class and the state. 64 65 pre_super and post_super determine if super(class_)'s 66 __setstate__ should be invoked before or after (respectively) 67 calling the function returned by selector. If selector returns 68 None, super(class_)'s __setstate__ is never called. 69 """ 70 if pre_super is True and post_super is True: 71 raise ValueError("Cannot call super method before and after.") 72 73 old_setstate = class_.__setstate__ 74 def new_setstate(instance,state): 75 setstate = selector(state) or old_setstate 76 77 if pre_super and setstate is not old_setstate: 78 super(class_,instance).__setstate__ 79 80 setstate(instance,state) 81 82 if post_super and setstate is not old_setstate: 83 super(class_,instance).__setstate__(state)
84 85 86 class_.__setstate__ = new_setstate 87
88 89 # fake_X() vs redirect_X(): redirect simply makes the name point to 90 # another thing, whereas fake actually creates a new thing (e.g. new 91 # module) 92 93 -def fake_a_class(module,old_name,new_class,new_class_args=()):
94 """ 95 Install a class named 'old_name' in 'module'; when created, 96 the class actually returns an instance of 'new_class'. 97 98 new_class_args allow any arguments to be supplied to new_class 99 before other arguments are passed at creation time. 100 101 For use when module.old_name=new_class is not possible. 102 """ 103 class_code = """ 104 class %s(object): 105 def __new__(cls,*args,**kw): 106 all_args = new_class_args+args 107 return new_class(*all_args,**kw)""" 108 exec class_code%old_name in locals() 109 fake_old_class = eval(old_name,locals()) 110 111 setattr(module,old_name,fake_old_class)
112
113 114 -def _import(x,y):
115 """return module y from: 'from x import y'""" 116 return __import__(x+'.'+y,fromlist=[y])
117
118 -def module_redirect(name,parent,actual_module,parent_name=None):
119 """ 120 For use when module parent.name is now actual_module. 121 122 Use parent_name to override parent.name if necessary (e.g. when 123 parent is already redirected). 124 """ 125 if parent_name is None: 126 parent_name=parent.__name__ 127 128 sys.modules[parent_name+'.'+name]=actual_module 129 setattr(sys.modules[parent_name],name,actual_module) 130 131 return getattr(parent,name)
132
133 134 -def package_redirect(name,parent,actual_package):
135 """ 136 For use when package parent.name is now actual_package. 137 138 All .py files found in actual_package's path are added to newly 139 created parent.name package. 140 """ 141 new_package = module_redirect(name,parent,actual_package) 142 143 import os,fnmatch 144 mod_names = [f.split('.py')[0] for f in os.listdir(actual_package.__path__[0]) if fnmatch.fnmatch(f,'[!._]*.py')] 145 146 for mod_name in mod_names: 147 m=_import(actual_package.__name__,mod_name) 148 module_redirect(mod_name,new_package,m,parent_name=parent.__name__+'.'+name)
149
150 151 152 -def fake_a_module(name,source_code,parent=None,parent_name=None):
153 """ 154 Create the module parent.name using source_code. 155 156 Installs to sys.modules[name] unless parent is not None, 157 in which case see module_redirect(). 158 """ 159 # create the module 160 module = imp.new_module(name) 161 exec source_code in module.__dict__ 162 163 if parent is None: 164 sys.modules[name]=module 165 else: 166 module_redirect(name,parent,module,parent_name)
167
168 169 -class DuplicateCheckingList(list):
170 - def append(self,item):
171 assert item not in self, "%s already added"%item 172 list.append(self,item)
173 174 175 # put this somewhere... 176 import param 177 param.parameterized.PicklableClassAttributes.do_not_restore+=[ 178 'topo.base.boundingregion.BoundingRegion', 179 'topo.base.boundingregion.BoundingBox', 180 'topo.base.boundingregion.BoundingCircle', 181 'topo.base.boundingregion.BoundingEllipse', 182 'topo.base.cf.ConnectionField', 183 'topo.projection.basic.SharedWeightCF']
184 185 186 -class SnapshotSupport(object):
187 188 @staticmethod
189 - def install(svn=None):
190 191 # CEBALERT: should add svn version test to see which hacks 192 # actually need to be installed. I.e. organize these in 193 # suitable way e.g. dictionary. 194 # Haven't yet thought about whether or not it's actually possible 195 # to get the version number before unpickling... 196 import param 197 global supporters 198 for f in supporters: 199 param.Parameterized(name='SnapshotSupport').debug("calling %s"%f.__name__) 200 f()
201
202 203 204 #### 205 # CEB: this is only to show how we could support running old scripts 206 # without modifying them. Currently we haven't implemented enough for 207 # it to be useful. 208 # E.g. we changed output_fn to output_fns for several classes. To 209 # support that in a snapshot requires intercepting the saved data and 210 # detecting 'output_fn=x' and replacing it with 'output_fns=[x]', 211 # etc. To support it in a script requires installing something in the 212 # class that will take .output_fn=x and actually do .output_fns=[x]. A 213 # concrete example is given below: CFProjection's weights_shape was 214 # changed to cf_shape. 215 -def LegacySupport():
216 """ 217 Support for running old scripts. Use in conjunction with 218 SnapshotSupport.install() to avoid duplication. 219 """ 220 # rXXXX renamed CFProjection.weights_shape to CFProjection.cf_shape 221 import topo.base.cf 222 cfp = topo.base.cf.CFProjection 223 type.__setattr__(cfp,'weights_shape',cfp.__dict__['cf_shape'])
224 ####
225 226 227 -def install_legacy_support():
228 SnapshotSupport.install() 229 LegacySupport()
230 231 232 233 ###################################################################### 234 ###################################################################### 235 236 # note there's no legacy support for people using CFSOM. We could 237 # add that if necessary. 238 239 240 S=supporters=DuplicateCheckingList() 241 # in general, newest changes should go at the start of the list. 242 243 244 # do not restore search_paths,prefix for resolve_path,normalize_path 245 # hack 246 import param.parameterized 247 param.parameterized.PicklableClassAttributes.do_not_restore+=[ 248 'param.normalize_path', 249 'param.resolve_path'] 250 251 252 # fixedpoint available as topo.misc.fixedpoint, not fixedpoint 253 import topo.misc.fixedpoint as fixedpoint 254 from topo.misc.util import ModuleImporter,ModuleFaker
255 256 -class FixedPointImporter(ModuleImporter):
257
258 - def find_module(self, fullname, path=None):
259 if fullname == 'fixedpoint' or fullname.startswith('fixedpoint.'): 260 f = FixedPointFaker() 261 f.path = path 262 return f 263 return None
264
265 -class FixedPointFaker(ModuleFaker):
266 - def create_module(self,name):
267 return fixedpoint
268 269 import sys 270 sys.meta_path.append(FixedPointImporter())
271 272 273 274 -def removed_Enumeration():
275 276 import param 277 278 class Enumeration(object): 279 """ 280 Provide support for existing code that uses Enumeration. 281 """ 282 @staticmethod 283 def _transform(kw): 284 if 'available' in kw: 285 kw['objects']=kw['available'] 286 del kw['available'] 287 kw['check_on_set']=True
288 289 def __new__(cls,*args,**kw): 290 print "no way!" 291 Enumeration._transform(kw) 292 n = param.ObjectSelector(*args,**kw) 293 return n 294 295 def __init__(self,*args,**kw): 296 Enumeration._transform(kw) 297 super(param.ObjectSelector,self).__init__(self,*args,**kw) 298 299 param.Enumeration = Enumeration 300 301 S.append(removed_Enumeration)
302 303 304 -def bye_bye_param():
305 import param 306 import topo 307 package_redirect('param',topo,param)
308 309 S.append(bye_bye_param)
310 311 312 -def renamed_output_fn_to_output_fns():
313 ## rXXXX output_fn=X changed to output_fns=[x] in multiple classes 314 315 def _changed_output_fn(instance,state): 316 for x in 'output_fn','weights_output_fn': 317 if x in state: 318 fn = state[x] 319 state['%ss'%x] = [fn] 320 # CEBALERT: ideally, would also delete old 'output_fn' parameter, 321 # but we don't currently support parameter deletion. 322 del state[x] # probably does nothing 323 324 if 'apply_%s'%x in state: 325 state['apply_%ss'%x]=state['apply_%s'%x] 326 del state['apply_%s'%x] 327 328 if 'apply_%s_init'%x in state: 329 state['apply_%ss_init'%x]=state['apply_%s_init'%x] 330 del state['apply_%s_init'%x]
331 332 # because I can't be bothered narrowing it down; does this 333 # slow down legacy support installation? 334 from topo.param.parameterized import Parameterized 335 preprocess_state(Parameterized,_changed_output_fn) 336 337 338 def _post_initialization_weights_output_fn(instance,state): 339 if 'post_initialization_weights_output_fn' in state: 340 state['post_initialization_weights_output_fns']=[state['post_initialization_weights_output_fn']] 341 del state['post_initialization_weights_output_fn'] 342 from topo.sheet.lissom import LISSOM 343 # CEBALERT: problem with multiple preprocess_state functions? 344 #preprocess_state(LISSOM,_post_initialization_weights_output_fn) 345 346 347 # CEBALERT: need to handle the class parameters 348 # (see ALERT in topo.param.parameterized saying that it's 349 # currently not possible) 350 351 352 353 354 S.append(renamed_output_fn_to_output_fns)
355 356 357 -def removed_pipeline():
358 import topo.transferfn.basic,topo.base.functionfamily 359 from topo import param 360 class PipelineTF(topo.base.functionfamily.TransferFn): 361 def __new__(self,*args,**kw): 362 param.Parameterized().warning("PipelineTF is deprecated; returning output_fns list.") 363 364 if 'output_fns' in kw: 365 return kw['output_fns'] 366 else: 367 return []
368 369 topo.base.functionfamily.PipelineOF = PipelineTF 370 topo.base.functionfamily.PipelineTF = PipelineTF 371 372 topo.transferfn.basic.PipelineTF = PipelineTF 373 topo.transferfn.basic.Pipeline = PipelineTF 374 topo.transferfn.basic.PipelineOF = PipelineTF 375 376 S.append(removed_pipeline)
377 378 379 380 -def rename_outputfn_to_transferfn():
381 ### rXXXX moved topo.outputfn to topo.transferfn 382 import topo,topo.transferfn 383 package_redirect('outputfn',topo,topo.transferfn) 384 385 ### rXXXX renamed OutputFn to TransferFn + xxxOF->xxxTF 386 import topo.base.functionfamily 387 import topo.transferfn.basic 388 389 def _rename(mod): 390 for name,obj in mod.__dict__.items(): 391 if isinstance(obj,type) and issubclass(obj,mod.TransferFn): 392 if name.endswith('TF'): 393 old_name = name[0:-2]+'OF' 394 new_class = obj 395 setattr(mod,old_name,obj) 396 elif 'TransferFn' in name: 397 old_name=name.replace('Transfer','Output') 398 setattr(mod,old_name,obj)
399 400 _rename(topo.base.functionfamily) 401 _rename(topo.transferfn.basic) 402 403 S.append(rename_outputfn_to_transferfn)
404 405 406 -def removed_InstanceMethodWrapper():
407 # removed this class in rXXXX 408 class InstanceMethodWrapper(object): 409 """ 410 Wrapper for pickling instance methods. 411 412 The constructor takes an instance method (e.g. for an object 413 'sim', method sim.time) as its only argument. The wrapper 414 instance is callable, picklable, etc. 415 """ 416 def __repr__(self): 417 return repr(self.im.im_func)
418 419 # Hope __name__ doesn't get set... 420 def _fname(self): 421 return self.im.im_func.func_name 422 __name__ = property(_fname) 423 424 def __init__(self,im): 425 self.im = im 426 427 def __getstate__(self): 428 return (self.im.im_self, 429 self.im.im_func.func_name) 430 431 def __setstate__(self,state): 432 obj,func_name = state 433 self.im = getattr(obj,func_name) 434 435 def __call__(self,*args,**kw): 436 return self.im(*args,**kw) 437 438 import topo.param 439 topo.param.InstanceMethodWrapper = InstanceMethodWrapper 440 441 S.append(removed_InstanceMethodWrapper)
442 443 444 -def param_remove_hidden():
445 # Hidden attribute removed from Parameter in r7861 446 from topo import param 447 def _param_remove_hidden(instance,state): 448 if 'hidden' in state: 449 if state['hidden'] is True: 450 state['precedence']=-1 451 del state['hidden']
452 preprocess_state(param.Parameter,_param_remove_hidden) 453 454 S.append(param_remove_hidden)
455 456 -def param_add_readonly():
457 # Hidden attribute added to Parameter in r7975 458 from topo import param 459 def _param_add_readonly(instance,state): 460 if 'readonly' not in state: 461 state['readonly']=False
462 preprocess_state(param.Parameter,_param_add_readonly) 463 464 S.append(param_add_readonly)
465 466 467 -def class_selector_remove_suffixtolose():
468 # suffix_to_lose removed from ClassSelectorParameter in r8031 469 from topo import param 470 def _class_selector_remove_suffixtolose(instance,state): 471 if 'suffix_to_lose' in state: 472 del state['suffix_to_lose']
473 preprocess_state(param.ClassSelector,_class_selector_remove_suffixtolose) 474 475 S.append(class_selector_remove_suffixtolose)
476 477 478 -def cf_rename_slice_array():
479 ## slice_array was renamed to input_sheet_slice in r7548 480 def _cf_rename_slice_array(instance,state): 481 if 'slice_array' in state: 482 input_sheet_slice = state['slice_array'] 483 state['input_sheet_slice'] = input_sheet_slice 484 del state['slice_array'] # probably doesn't work
485 486 from topo.base.cf import ConnectionField 487 preprocess_state(ConnectionField,_cf_rename_slice_array) 488 489 S.append(cf_rename_slice_array)
490 491 -def sim_remove_time_type_attr():
492 # _time_type attribute added to simulation in r7581 493 # and replaced by time_type param in r8215 494 def _sim_remove_time_type_attr(instance,state): 495 if '_time_type' in state: 496 # CB: untested code (unless someone has such a snapshot; 497 # if nobody has such a snapshot, can remove this code). 498 state['_time_type_param_value']=state['_time_type'] 499 del state['_time_type']
500 501 from topo.base.simulation import Simulation 502 preprocess_state(Simulation,_sim_remove_time_type_attr) 503 S.append(sim_remove_time_type_attr)
504 505 506 507 -def slice_setstate_selector():
508 # Allow loading of pickles created before Pickle support was added to Slice. 509 # 510 # In snapshots created between 7547 (Slice becomes array) and 7762 511 # (inclusive; Slice got pickle support in 7763), Slice instances 512 # will be missing some information. 513 # 514 # CB: info could be recovered if required. 515 def _slice_setstate_selector(state): 516 517 if isinstance(state,dict): 518 return None 519 else: 520 import numpy 521 return numpy.ndarray.__setstate__
522 523 from topo.base.sheetcoords import Slice 524 select_setstate(Slice,_slice_setstate_selector,post_super=False) 525 526 S.append(slice_setstate_selector)
527 528 529 -def sheet_set_shape():
530 # CB: this is to work round change in SCS, but __setstate__ is never 531 # called on that (method resolution order means __setstate__ comes 532 # from EventProcessor instead) 533 from topo.base.sheetcoords import Slice 534 def _sheet_set_shape(instance,state): 535 # since 7958, SCS has stored shape on creation 536 if '_SheetCoordinateSystem__shape' not in state: 537 m = '_SheetCoordinateSystem__' 538 # all these are necessary for the calculation now, 539 # but would not otherwise be restored until later 540 setattr(instance,'bounds',state['bounds']) 541 setattr(instance,'lbrt',state['lbrt']) 542 setattr(instance,m+'xdensity',state[m+'xdensity']) 543 setattr(instance,m+'xstep',state[m+'xstep']) 544 setattr(instance,m+'ydensity',state[m+'ydensity']) 545 setattr(instance,m+'ystep',state[m+'ystep']) 546 shape = Slice(instance.bounds,instance).shape_on_sheet() 547 setattr(instance,m+'shape',shape) 548 state[m+'shape']=shape
549 550 from topo.base.sheet import Sheet 551 preprocess_state(Sheet,_sheet_set_shape) 552 S.append(sheet_set_shape)
553 554 555 -def removed_function_family_parameters():
556 # r8001 Removed OutputFnParameter and CFPOutputFnParameter 557 # r8014 Removed LearningFnParameter and ResponseFnParameter (+CFP equivalents) 558 # r8028 Removed CoordinateMapperFnParameter 559 # r8029 Removed PatternGeneratorParameter 560 from topo import param 561 from topo.base.functionfamily import OutputFn,ResponseFn,LearningFn,\ 562 CoordinateMapperFn 563 d = {"OutputFnParameter":OutputFn, 564 "ResponseFnParameter":ResponseFn, 565 "LearningFnParameter":LearningFn, 566 "CoordinateMapperFnParameter":CoordinateMapperFn} 567 568 import topo.base.functionfamily 569 for name,arg in d.items(): 570 fake_a_class(topo.base.functionfamily,name, 571 param.ClassSelector,(arg,)) 572 573 from topo.base.cf import CFPOutputFn,CFPResponseFn,CFPLearningFn 574 d = {"CFPOutputFnParameter":CFPOutputFn, 575 "CFPResponseFnParameter":CFPResponseFn, 576 "CFPLearningFnParameter":CFPLearningFn} 577 578 import topo.base.cf 579 for name,arg in d.items(): 580 fake_a_class(topo.base.cf,name, 581 param.ClassSelector,(arg,)) 582 583 import topo.base.patterngenerator 584 from topo.base.patterngenerator import PatternGenerator 585 fake_a_class(topo.base.patterngenerator,"PatternGeneratorParameter", 586 param.ClassSelector,(PatternGenerator,))
587 588 S.append(removed_function_family_parameters)
589 590 591 592 -def added_dynamic_time_fn():
593 # for snapshots saved before r7901 594 from topo import param 595 class SimSingleton(object): 596 """Support for old snapshots.""" 597 def __setstate__(self,state): 598 sim = state['actual_sim'] 599 param.Dynamic.time_fn = sim.time
600 601 import topo.base.simulation 602 topo.base.simulation.SimSingleton=SimSingleton 603 604 S.append(added_dynamic_time_fn)
605 606 -def moved_parameterized():
607 # rXXXX 608 # support topo.base.parameterized 609 import topo.base 610 module_redirect('parameterized',topo.base,topo.param.parameterized)
611 612 S.append(moved_parameterized)
613 614 -def renamed_parameterizedobject():
615 # rXXXX 616 # support topo.base.parameterizedobject 617 import topo.param 618 module_redirect('parameterizedobject',topo.base,topo.param.parameterized) 619 topo.base.parameterizedobject.ParameterizedObject=topo.param.parameterized.Parameterized
620 S.append(renamed_parameterizedobject)
621 622 -def removed_parameterclasses():
623 # rXXXX 624 # support topo.base.parameterclasses 625 import topo.param 626 module_redirect('parameterclasses',topo.base,topo.param) 627 628 new_names = ['Boolean','String','Callable','Composite','Selector', 629 'ObjectSelector','ClassSelector','List','Dict'] 630 631 for name in new_names: 632 setattr(topo.base.parameterclasses,name+'Parameter', 633 getattr(topo.base.parameterclasses,name))
634 S.append(removed_parameterclasses)
635 636 -def removed_DynamicNumber():
637 # DynamicNumber was removed in rXXXX 638 class DynamicNumber(object): 639 """ 640 Provide support for existing code that uses DynamicNumber: 641 see __new__(). 642 """ 643 warnedA = False # suppress warnings for the moment. 644 warnedB = False 645 646 def __new__(cls,default=None,**params): 647 """ 648 If bounds or softbounds or any params are supplied, assume 649 we're dealing with DynamicNumber declared as a parameter 650 of a ParameterizedObject class. In this case, return a 651 new *Number* parameter instead. 652 653 Otherwise, assume we're dealing with DynamicNumber 654 supplied as the value of a Number Parameter. In this case, 655 return a DynamicNumber (but one which is not a Parameter, 656 just a simple wrapper). 657 658 * Of course, this is not 100% reliable: if someone defines 659 * a class with a DynamicNumber but doesn't pass any doc or 660 * bounds or whatever. But in such cases, they'll get the 661 * ParameterizedObject warning about being unable to set a 662 * class attribute. 663 664 Most of the code is to generate warning messages. 665 666 """ 667 if len(params)>0: 668 #################### 669 m = "\n------------------------------------------------------------\nPlease update your code - instead of using the 'DynamicNumber' Parameter in the code for your class, please use the 'Number' Parameter; the Number Parameter now supports dynamic values automatically.\n\nE.g. change\n\nclass X(Parameterized):\n y=DynamicNumber(NumberGenerator())\n\nto\n\n\nclass X(Parameterized):\n y=Number(NumberGenerator())\n------------------------------------------------------------\n" 670 if not cls.warnedA: 671 param.Parameterized().warning(m) 672 cls.warnedA=True 673 #################### 674 675 n = Number(default,**params) 676 return n 677 else: 678 #################### 679 m = "\n------------------------------------------------------------\nPlease update your code - instead of using DynamicNumber to contain a number generator, pass the number generator straight to the Number parameter:\n\nE.g. in code using the class below...\n\nclass X(Parameterized):\n y=Number(0.0)\n\n\nchange\n\nx = X(y=DynamicNumber(NumberGenerator()))\n\nto\n\nx = X(y=NumberGenerator())\n------------------------------------------------------------\n" 680 if not cls.warnedB: 681 param.Parameterized().warning(m) 682 cls.warnedB=True 683 #################### 684 return object.__new__(cls,default)
685 686 687 def __init__(self,default=0.0,bounds=None,softbounds=None,**params): 688 self.val = default 689 def __call__(self): 690 return self.val() 691 692 import topo.base.parameterclasses 693 topo.base.parameterclasses.DynamicNumber = DynamicNumber 694 import topo.param 695 topo.param.DynamicNumber = DynamicNumber 696 697 S.append(removed_DynamicNumber)
698 699 700 -def cfproj_add_cfs():
701 # cfs attribute added in r8227 702 from topo.base.cf import CFProjection 703 from numpy import array 704 def _cfproj_add_cfs(instance,state): 705 if 'cfs' not in state: 706 cflist = state['_cfs'] 707 state['cfs'] = array(cflist)
708 preprocess_state(CFProjection,_cfproj_add_cfs) 709 710 S.append(cfproj_add_cfs)
711 712 -def renamed_component_libraries():
713 # rXXXX renaming of component libraries 714 import topo.outputfn,topo.responsefn,\ 715 topo.learningfn,topo.coordmapper 716 package_redirect('outputfns',topo,topo.outputfn) 717 package_redirect('responsefns',topo,topo.responsefn) 718 package_redirect('learningfns',topo,topo.learningfn) 719 package_redirect('coordmapperfns',topo,topo.coordmapper)
720 721 S.append(renamed_component_libraries)
722 723 -def removed_generator():
724 ### rXXXX removed topo/sheet/generator.py 725 import topo.sheet 726 module_redirect('generator',topo.sheet,topo.sheet)
727 728 S.append(removed_generator)
729 730 -def renamed_sheets():
731 import topo,topo.sheet 732 package_redirect('sheets',topo,topo.sheet)
733 734 S.append(renamed_sheets)
735 736 -def renamed_eps():
737 import topo,topo.ep 738 package_redirect('eps',topo,topo.ep)
739 740 S.append(renamed_eps)
741 742 743 -def renamed_patterns():
744 import topo.pattern 745 package_redirect('patterns',topo,topo.pattern)
746 747 S.append(renamed_patterns)
748 749 -def renamed_commands():
750 import topo.command 751 package_redirect('commands',topo,topo.command)
752 753 S.append(renamed_commands)
754 755 -def renamed_projections():
756 import topo.projection 757 package_redirect('projections',topo,topo.projection) 758 759 # CEBALERT: check this is necessary 760 # the isn't-in-__all__ shimmy 761 import sys 762 import topo.projections.basic as ps,topo.projection.basic as p 763 ps.CFPOF_SharedWeight = p.CFPOF_SharedWeight 764 ps.SharedWeightCF = p.SharedWeightCF
765 766 S.append(renamed_projections)
767 768 769 -def renamed_generatorsheet():
770 # CEBALERT: below gives errors with snapshot-compatiblity-tests 771 import topo.sheets 772 module_redirect('generatorsheet',topo.sheets,topo.sheet.generator,parent_name='topo.sheets')
773 774 S.append(renamed_generatorsheet)
775 776 -def renamed_functionfamilies():
777 # rXXXX renamed functionfamilies 778 import topo.base,topo.base.functionfamily 779 module_redirect('functionfamilies',topo.base,topo.base.functionfamily)
780 781 S.append(renamed_functionfamilies)
782 783 -def renamed_projfns():
784 # rXXXX renamed topo.x.projfns 785 import topo.outputfn.projfn,topo.responsefn.projfn,topo.learningfn.projfn 786 for mod in ['outputfn','responsefn','learningfn']: 787 existing_mod = _import('topo.%s'%mod,'projfn') 788 module_redirect('projfns',_import('topo',mod),existing_mod,parent_name='topo.%s'%mod) 789 module_redirect('projfns',_import('topo',mod+'s'),existing_mod,parent_name='topo.%ss'%mod)
790 791 S.append(renamed_projfns)
792 793 # CEBALERT: what's going on with the order in this file? Should have 794 # maintained a consistent order, processing most recent changes first. 795 -def removed_numbergenerator():
796 import topo.numbergen 797 module_redirect('numbergenerator',topo.misc,topo.numbergen)
798 799 S.append(removed_numbergenerator)
800 801 802 -def renamed_numbergenerators():
803 # rXXXX renamed topo.misc.numbergenerators 804 import topo.misc.numbergenerator 805 module_redirect('numbergenerators',topo.misc,topo.misc.numbergenerator)
806 807 S.append(renamed_numbergenerators)
808 809 -def renamed_patternfns():
810 # rXXXX renamed topo.misc.patternfns 811 import topo.misc.patternfn 812 module_redirect('patternfns',topo.misc,topo.misc.patternfn)
813 814 S.append(renamed_patternfns)
815 816 -def removed_ExtraPickler():
817 import topo.misc.util 818 # r9617 removed ExtraPickler 819 class ExtraPicklerSkipper(object): 820 def __setstate__(self,state): 821 # print warning of what's being skipped? 822 pass
823 topo.misc.util.ExtraPickler=ExtraPicklerSkipper 824 825 S.append(removed_ExtraPickler)
826 827 -def renamed_utils():
828 # rXXXX renamed topo.misc.utils 829 import topo.misc.util 830 module_redirect('utils',topo.misc,topo.misc.util)
831 832 S.append(renamed_utils)
833 834 -def renamed_traces():
835 # rXXXX renamed topo.misc.traces 836 import topo.misc.trace 837 module_redirect('traces',topo.misc,topo.misc.trace)
838 839 S.append(renamed_traces)
840 841 842 -def duplicate_SineGratingDisk():
843 # rXXXX duplicate SineGratingDisk removed 844 import topo.pattern.basic 845 from topo.pattern import SineGrating,Disk 846 # rXXXX removed these classes 847 from topo import param 848 class SineGratingDisk(SineGrating): 849 """2D sine grating pattern generator with a circular mask.""" 850 mask_shape = param.Parameter(default=Disk(smoothing=0,size=1.0))
851 topo.pattern.basic.SineGratingDisk = SineGratingDisk 852 S.append(duplicate_SineGratingDisk)
853 854 855 # CEB: possibly this should be higher up (above topo.patterns?) 856 # And were there other classes e.g. OrientationContrastPattern? 857 -def teststimuli_removed():
858 # rXXXX 859 import topo.pattern 860 code = \ 861 """ 862 from topo.pattern.basic import SineGrating,Disk,Rectangle,Ring 863 from topo import param 864 class SineGratingDisk(SineGrating): 865 mask_shape = param.Parameter(default=Disk(smoothing=0,size=1.0)) 866 867 class SineGratingRectangle(SineGrating): 868 mask_shape = param.Parameter(default=Rectangle(smoothing=0,size=1.0)) 869 870 class SineGratingRing(SineGrating): 871 mask_shape = param.Parameter(default=Ring(smoothing=0,size=1.0)) 872 """ 873 fake_a_module('teststimuli',code,parent=topo.pattern)
874 875 S.append(teststimuli_removed)
876 877 878 -def moved_homeostatic():
879 # rXXXX homeostatic of moved into basic 880 import topo.outputfns 881 # CEBALERT: surely a typo here? 882 module_redirect('homeostatic',topo.outputfns,topo.outputfns)
883 884 S.append(moved_homeostatic)
885 886 -def renamed_cfproj_weights_shape():
887 # rXXXX renamed CFProjection.weights_shape to CFProjection.cf_shape 888 from topo import param 889 param.parameterized.PicklableClassAttributes.param_name_changes['topo.base.cf.CFProjection']={'weights_shape':'cf_shape'}
890 891 S.append(renamed_cfproj_weights_shape)
892 893 -def cf_bounds_readonly():
894 # rXXXX CF's bounds made into read-only attribute (since the value 895 # actually comes from the slice). 896 # (Problem exposed when Parameterized's __setstate__ changed to 897 # set all state attributes, rather than just those in __dict__?) 898 def cf_bounds_property(instance,state): 899 try: 900 del state['bounds'] 901 except KeyError: 902 pass
903 904 from topo.base.cf import ConnectionField 905 preprocess_state(ConnectionField,cf_bounds_property) 906 907 S.append(cf_bounds_readonly)
908 909 910 # (Currently, the code below is already run in topo.__init__ if gmpy 911 # isn't available.) 912 ## If gmpy.mpq is not available, use fixedpoint.FixedPoint. 913 #from topo.misc.util import gmpyImporter 914 #sys.meta_path.append(gmpyImporter()) 915 916 917 -def param_add_allow_None():
918 # allow_None added in r9380 919 from topo import param 920 def _param_add_allow_None(instance,state): 921 if 'allow_None' not in state and hasattr(instance.__class__,'allow_None'): 922 # have to add to state or else slot won't exist on instance, but will 923 # exist on class (consequence of using __slots__) 924 state['allow_None']=False
925 preprocess_state(param.Parameter,_param_add_allow_None) 926 927 S.append(param_add_allow_None)
928 929 -def number_add_inclusive_bounds():
930 # inclusive_bounds added to Number in r9789 931 from topo import param 932 def _number_add_inclusive_bounds(instance,state): 933 if 'inclusive_bounds' not in state: 934 state['inclusive_bounds']=(True,True)
935 preprocess_state(param.Number,_number_add_inclusive_bounds) 936 937 S.append(number_add_inclusive_bounds)
938 939 940 -def onedpowerspectrum_was_in_basic():
941 # rXXXX-rXXXX OneDPowerSpectrum moved back to pattern/audio 942 import topo.pattern.audio 943 import topo.pattern.basic 944 topo.pattern.audio.OneDPowerSpectrum=topo.pattern.basic.Spectrogram 945 topo.pattern.basic.OneDPowerSpectrum=topo.pattern.audio.OneDPowerSpectrum
946 S.append(onedpowerspectrum_was_in_basic)
947 948 949 -def boundingregion_not_parameterized():
950 import topo.base.boundingregion 951 952 def _boundingregion_not_parameterized(instance,state): 953 for a in ['initialized', '_name_param_value', 'nopickle']: 954 if a in state: 955 del state[a]
956 957 preprocess_state(topo.base.boundingregion.BoundingRegion, 958 _boundingregion_not_parameterized) 959 960 S.append(boundingregion_not_parameterized) 961 962 963 cf_xy_warned=False
964 -def cf_not_parameterized():
965 from topo.base.cf import ConnectionField 966 967 def _cf_not_parameterized(instance,state): 968 969 for p in [('_y_param_value','y'),('_x_param_value','x')]: 970 if p[0] in state: 971 state[p[1]]=state[p[0]] 972 del state[p[0]] 973 974 for p in ['_name_param_value','initialized','nopickle','bounds_template']: 975 if p in state: 976 del state[p] 977 978 # rXXXX weights_slice no longer stored 979 if 'weights_slice' in state: 980 del state['weights_slice'] 981 982 # rXXXX input_sheet no longer stored 983 if 'input_sheet' in state: 984 del state['input_sheet'] 985 986 # rXXXX x,y no longer stored 987 if 'x' in state: # assume 'y' also in state 988 global cf_xy_warned 989 if not cf_xy_warned: 990 from topo import param 991 param.Parameterized().warning("Not restoring ConnectionField's (x,y) location. Bounds resizing will not work -- please file a support request via the website.") # could add support by loading ResizableCFProjection for any CFProjection with CFs that have x and y, and moving x and y to the ResizableProjection. 992 cf_xy_warned=True 993 del state['x'] 994 del state['y']
995 996 997 preprocess_state(ConnectionField,_cf_not_parameterized) 998 999 S.append(cf_not_parameterized)
1000 1001 1002 -def cfproj_add_flatcfs():
1003 # flatcfs attribute added 1004 from topo.base.cf import CFProjection 1005 def _cfproj_add_flatcfs(instance,state): 1006 if 'flatcfs' not in state: 1007 try: 1008 state['flatcfs'] = list(state['cfs'].flat) 1009 except KeyError: 1010 from topo.misc.util import flatten 1011 state['flatcfs'] = flatten(state['_cfs'])
1012 1013 preprocess_state(CFProjection,_cfproj_add_flatcfs) 1014 1015 S.append(cfproj_add_flatcfs)
1016 1017 1018 -def cfproj_add_n_units():
1019 # n_units() -> n_units 1020 1021 from topo.base.cf import CFProjection 1022 1023 def get_n_units(self): 1024 try: 1025 return self.__dict__['n_units'] 1026 except KeyError: 1027 n = self._calc_n_units() 1028 self.__dict__['n_units'] = n
1029 1030 def set_n_units(self,n): 1031 self.__dict__['n_units'] = n 1032 1033 type.__setattr__(CFProjection,'n_units',property(get_n_units,set_n_units)) 1034 1035 1036 S.append(cfproj_add_n_units)
1037 1038 -def transferfn_misc():
1039 import topo.transferfn.misc as ttm 1040 import topo.transferfn.basic as ttb 1041 ttb.HalfRectify=ttm.HalfRectify 1042 ttb.PatternCombine=ttm.PatternCombine 1043 ttb.AttributeTrackingTF=ttm.AttributeTrackingTF 1044 ttb.HomeostaticResponse=ttm.HomeostaticResponse 1045 ttb.KernelMax=ttm.KernelMax
1046 1047 S.append(transferfn_misc)
1048 1049 1050 -def renamed_pylabplots():
1051 import topo.command.pylabplot 1052 module_redirect('pylabplots',topo.command,topo.command.pylabplot)
1053 1054 S.append(renamed_pylabplots) 1055