def test_strip_number_suffix(self): self.assertEquals(fut.strip_number_suffix('abc123'), 'abc') self.assertEquals(fut.strip_number_suffix('12345'), '') self.assertEquals(fut.strip_number_suffix('9'), '') self.assertEquals(fut.strip_number_suffix('hello'), 'hello') self.assertEquals(fut.strip_number_suffix('12AB34'), '12AB') self.assertEquals(fut.strip_number_suffix(''), '') self.assertEquals(fut.strip_number_suffix('hello_'), 'hello') self.assertEquals(fut.strip_number_suffix('abc_123'), 'abc') self.assertEquals(fut.strip_number_suffix('12AB_34'), '12AB') self.assertEquals(fut.strip_number_suffix('_'), '')
def create_filter(self, param_dict_or_ftype, pipeline=None): # TO-DO Break this up <<<<<<<<<<<< """Extract the right filter dictionary from the factory_dict. Store a reference in the object to the factory that made it. Pass in the filter_attrs so the new object has right attributes. Alternative parameter is just the ftype. Dictionary validation is enforced before the first use. TO-DO: pipeline is (a str? an object? required??) """ if not self._filter_dict_validated: self._validate_filter_dict() # TO-DO: update these comments # If the filter isn't typed explicitly by the param dict, give # it an ftype that is the name, with any trailing digits # removed (necessary because there are more than one of that type.) # Simple use of make_filter() is by passing in the ftype try: param_dict_or_ftype + '' ftype = param_dict_or_ftype param_dict = dict(ftype=ftype) except TypeError: param_dict = param_dict_or_ftype # Search for filter in pypes directory first. This overrides any # programmatically defined filters/pipelines. ## if param_dict.get('_name') in pypes: ftype_or_name = param_dict.get('ftype', param_dict.get('_name', '')) if ftype_or_name.startswith('pype_'): ## ftype = param_dict['_name'][5:] ftype = ftype_or_name[5:] param_dict['ftype'] = ftype try: filter_attrs = dict(_class=ppln.PipelineForPypes, config=self.pypes[ftype]) except KeyError: msg = 'Filter type "%s" not found in the pypes directory' raise dfb.FilterNameError, msg % ftype else: # Use explicit ftype setting in config if available. # Otherwise, try to read the filter type from the name. try: ftype = param_dict['ftype'] except KeyError: # Break up the name into parts separated by '_'. Strip off # parts from the right-hand side, until we find a valid # ftype. short_name = fut.strip_number_suffix(param_dict['_name']) name_parts = short_name.split('_') for j in xrange(len(name_parts), 0, -1): ftype = '_'.join(name_parts[:j]) if ftype in self.factory_dict: break else: ### Last chance before giving up -- is it in pypes? ##if param_dict['name'] in pypes: ##ftype = param_dict['name'] ##else: # We can't get the type from the name msg = 'Can\'t get filter type from "%s"' raise dfb.FilterError, msg % param_dict['_name'] param_dict['ftype'] = ftype try: filter_attrs = copy.copy(self.factory_dict[ftype]) except KeyError: # Make a pipeline with this config. try: filter_attrs = dict(_class=ppln.PipelineForPypes, config=self.pypes[ftype]) except KeyError: msg = 'Filter type "%s" not found in the filter ' + \ 'factory class map dictionary' raise dfb.FilterNameError, msg % ftype # !! If create_filter receives a string, the except clause isn't # executed so filter_attrs isn't defined. filter_attrs['factory'] = self filter_attrs['pipeline'] = pipeline # Update the dictionary so far with the parameters passed in. filter_attrs.update(param_dict) # Everything is now in place for the actual creation of the filter class_to_create = filter_attrs['_class'] # If the config for this filter has dynamic == True, use metaclass ## if filter_attrs.get('dynamic', False) == 'meta': if filter_attrs.get('dynamic', False): class_to_create2 = dfb.DynamicMetaClass( 'DynMeta' + class_to_create.__name__, (class_to_create, ), {}) else: class_to_create2 = class_to_create new_filter = class_to_create2(**filter_attrs) # Filter has now been made # Reversible dynamic approach doesn't work. ### If config file for filter has set 'dynamic', use reversible method ### to make it dynamic. Note the need to test equality with True, because ### of the option for the value to be 'meta'. ##if filter_attrs.get('dynamic', False) == True: ##new_filter.make_dynamic(True) if new_filter.name != new_filter.name.lower(): raise dfb.FilterError, 'Filter name "%s" is not lower case' % ( new_filter.name) # Check the ftype made matches the request try: type_made = new_filter.__class__.ftype # OK for filter except AttributeError: type_made = new_filter.ftype # For pipeline # TO-DO Replace ftype check, which fails when making external pype: # e.g. 'align_supf' != 'p0001_align_supf' # Bad overloading of ftype. #if type_made != ftype: #msg = 'Filter type requested was "%s", but "%s" was made' #raise dfb.FilterAttributeError, msg % (ftype, #new_filter.__class__.ftype) return new_filter
def create_filter(self, param_dict_or_ftype, pipeline=None): # TO-DO Break this up <<<<<<<<<<<< """Extract the right filter dictionary from the factory_dict. Store a reference in the object to the factory that made it. Pass in the filter_attrs so the new object has right attributes. Alternative parameter is just the ftype. Dictionary validation is enforced before the first use. TO-DO: pipeline is (a str? an object? required??) """ if not self._filter_dict_validated: self._validate_filter_dict() # TO-DO: update these comments # If the filter isn't typed explicitly by the param dict, give # it an ftype that is the name, with any trailing digits # removed (necessary because there are more than one of that type.) # Simple use of make_filter() is by passing in the ftype try: param_dict_or_ftype + '' ftype = param_dict_or_ftype param_dict = dict(ftype=ftype) except TypeError: param_dict = param_dict_or_ftype # Search for filter in pypes directory first. This overrides any # programmatically defined filters/pipelines. ## if param_dict.get('_name') in pypes: ftype_or_name = param_dict.get('ftype', param_dict.get('_name', '')) if ftype_or_name.startswith('pype_'): ## ftype = param_dict['_name'][5:] ftype = ftype_or_name[5:] param_dict['ftype'] = ftype try: filter_attrs = dict(_class=ppln.PipelineForPypes, config=self.pypes[ftype]) except KeyError: msg = 'Filter type "%s" not found in the pypes directory' raise dfb.FilterNameError, msg % ftype else: # Use explicit ftype setting in config if available. # Otherwise, try to read the filter type from the name. try: ftype = param_dict['ftype'] except KeyError: # Break up the name into parts separated by '_'. Strip off # parts from the right-hand side, until we find a valid # ftype. short_name = fut.strip_number_suffix(param_dict['_name']) name_parts = short_name.split('_') for j in xrange(len(name_parts), 0, -1): ftype = '_'.join(name_parts[:j]) if ftype in self.factory_dict: break else: ### Last chance before giving up -- is it in pypes? ##if param_dict['name'] in pypes: ##ftype = param_dict['name'] ##else: # We can't get the type from the name msg = 'Can\'t get filter type from "%s"' raise dfb.FilterError, msg % param_dict['_name'] param_dict['ftype'] = ftype try: filter_attrs = copy.copy(self.factory_dict[ftype]) except KeyError: # Make a pipeline with this config. try: filter_attrs = dict(_class=ppln.PipelineForPypes, config=self.pypes[ftype]) except KeyError: msg = 'Filter type "%s" not found in the filter ' + \ 'factory class map dictionary' raise dfb.FilterNameError, msg % ftype # !! If create_filter receives a string, the except clause isn't # executed so filter_attrs isn't defined. filter_attrs['factory'] = self filter_attrs['pipeline'] = pipeline # Update the dictionary so far with the parameters passed in. filter_attrs.update(param_dict) # Everything is now in place for the actual creation of the filter class_to_create = filter_attrs['_class'] # If the config for this filter has dynamic == True, use metaclass ## if filter_attrs.get('dynamic', False) == 'meta': if filter_attrs.get('dynamic', False): class_to_create2 = dfb.DynamicMetaClass( 'DynMeta' + class_to_create.__name__, (class_to_create,), {}) else: class_to_create2 = class_to_create new_filter = class_to_create2(**filter_attrs) # Filter has now been made # Reversible dynamic approach doesn't work. ### If config file for filter has set 'dynamic', use reversible method ### to make it dynamic. Note the need to test equality with True, because ### of the option for the value to be 'meta'. ##if filter_attrs.get('dynamic', False) == True: ##new_filter.make_dynamic(True) if new_filter.name != new_filter.name.lower(): raise dfb.FilterError, 'Filter name "%s" is not lower case' % ( new_filter.name) # Check the ftype made matches the request try: type_made = new_filter.__class__.ftype # OK for filter except AttributeError: type_made = new_filter.ftype # For pipeline # TO-DO Replace ftype check, which fails when making external pype: # e.g. 'align_supf' != 'p0001_align_supf' # Bad overloading of ftype. #if type_made != ftype: #msg = 'Filter type requested was "%s", but "%s" was made' #raise dfb.FilterAttributeError, msg % (ftype, #new_filter.__class__.ftype) return new_filter