2 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/a4113cc1cb5e/ changeset: a4113cc1cb5e user: dan date: 2013-01-10 20:57:37 summary: Fixes for Tool.check_and_update_param_values_helper() to check that the type of value provided is valid for the input parameter currently declared. Fixes an issue where rurun would select the wrong input dataset. affected #: 6 files diff -r ce62bf5a91f86d0c53764bda3df4975486d7512e -r a4113cc1cb5eaa68091c9a73375f00555b66dd11 lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -2128,16 +2128,16 @@ return params_to_strings( self.inputs, params, app ) def params_from_strings( self, params, app, ignore_errors=False ): return params_from_strings( self.inputs, params, app, ignore_errors ) - def check_and_update_param_values( self, values, trans ): + def check_and_update_param_values( self, values, trans, update_values=True ): """ Check that all parameters have values, and fill in with default values where necessary. This could be called after loading values from a database in case new parameters have been added. """ messages = {} - self.check_and_update_param_values_helper( self.inputs, values, trans, messages ) + self.check_and_update_param_values_helper( self.inputs, values, trans, messages, update_values=update_values ) return messages - def check_and_update_param_values_helper( self, inputs, values, trans, messages, context=None, prefix="" ): + def check_and_update_param_values_helper( self, inputs, values, trans, messages, context=None, prefix="", update_values=True ): """ Recursive helper for `check_and_update_param_values_helper` """ @@ -2183,10 +2183,11 @@ # Regular tool parameter, no recursion needed try: #this will fail when a parameter's type has changed to a non-compatible one: e.g. conditional group changed to dataset input - input.value_from_basic( values[ input.name ], trans.app, ignore_errors=False ) + input.value_from_basic( input.value_to_basic( values[ input.name ], trans.app ), trans.app, ignore_errors=False ) except: messages[ input.name ] = "Value no longer valid for '%s%s', replaced with default" % ( prefix, input.label ) - values[ input.name ] = input.get_initial_value( trans, context ) + if update_values: + values[ input.name ] = input.get_initial_value( trans, context ) def handle_unvalidated_param_values( self, input_values, app ): """ Find any instances of `UnvalidatedValue` within input_values and diff -r ce62bf5a91f86d0c53764bda3df4975486d7512e -r a4113cc1cb5eaa68091c9a73375f00555b66dd11 lib/galaxy/tools/parameters/basic.py --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -747,9 +747,9 @@ return { "__class__": "RuntimeValue" } return value def value_from_basic( self, value, app, ignore_errors=False ): - if isinstance( value, dict ) and value["__class__"] == "UnvalidatedValue": + if isinstance( value, dict ) and value.get( "__class__", None ) == "UnvalidatedValue": return UnvalidatedValue( value["value"] ) - return super( SelectToolParameter, self ).value_from_basic( value, app ) + return super( SelectToolParameter, self ).value_from_basic( value, app, ignore_errors=ignore_errors ) def need_late_validation( self, trans, context ): """ Determine whether we need to wait to validate this parameters value @@ -943,7 +943,7 @@ if not isinstance( value, list ): value = value.split( '\n' ) for column in value: - for column2 in column.split( ',' ): + for column2 in str( column ).split( ',' ): column2 = column2.strip() if column2: column_list.append( column2 ) @@ -1586,8 +1586,11 @@ elif isinstance( value, list) and len(value) > 0 and isinstance( value[0], DummyDataset): return None elif isinstance( value, list ): - return ",".join( [ val if isinstance( val, basestring ) else str(val.id) for val in value] ) - return value.id + return ",".join( [ str( self.to_string( val, app ) ) for val in value ] ) + try: + return value.id + except: + return str( value ) def to_python( self, value, app ): # Both of these values indicate that no dataset is selected. However, 'None' diff -r ce62bf5a91f86d0c53764bda3df4975486d7512e -r a4113cc1cb5eaa68091c9a73375f00555b66dd11 lib/galaxy/tools/parameters/grouping.py --- a/lib/galaxy/tools/parameters/grouping.py +++ b/lib/galaxy/tools/parameters/grouping.py @@ -68,21 +68,25 @@ return rval def value_from_basic( self, value, app, ignore_errors=False ): rval = [] - for i, d in enumerate( value ): - rval_dict = {} - # If the special __index__ key is not set, create it (for backward - # compatibility) - rval_dict['__index__'] = d.get( '__index__', i ) - # Restore child inputs - for input in self.inputs.itervalues(): - if ignore_errors and input.name not in d: - # If we do not have a value, and are ignoring errors, we simply - # do nothing. There will be no value for the parameter in the - # conditional's values dictionary. - pass - else: - rval_dict[ input.name ] = input.value_from_basic( d[input.name], app, ignore_errors ) - rval.append( rval_dict ) + try: + for i, d in enumerate( value ): + rval_dict = {} + # If the special __index__ key is not set, create it (for backward + # compatibility) + rval_dict['__index__'] = d.get( '__index__', i ) + # Restore child inputs + for input in self.inputs.itervalues(): + if ignore_errors and input.name not in d: + # If we do not have a value, and are ignoring errors, we simply + # do nothing. There will be no value for the parameter in the + # conditional's values dictionary. + pass + else: + rval_dict[ input.name ] = input.value_from_basic( d[input.name], app, ignore_errors ) + rval.append( rval_dict ) + except Exception, e: + if not ignore_errors: + raise e return rval def visit_inputs( self, prefix, value, callback ): for i, d in enumerate( value ): @@ -441,24 +445,28 @@ return rval def value_from_basic( self, value, app, ignore_errors=False ): rval = dict() - current_case = rval['__current_case__'] = value['__current_case__'] - # Test param - if ignore_errors and self.test_param.name not in value: - # If ignoring errors, do nothing. However this is potentially very - # problematic since if we are missing the value of test param, - # the entire conditional is wrong. - pass - else: - rval[ self.test_param.name ] = self.test_param.value_from_basic( value[ self.test_param.name ], app, ignore_errors ) - # Inputs associated with current case - for input in self.cases[current_case].inputs.itervalues(): - if ignore_errors and input.name not in value: - # If we do not have a value, and are ignoring errors, we simply - # do nothing. There will be no value for the parameter in the - # conditional's values dictionary. + try: + current_case = rval['__current_case__'] = value['__current_case__'] + # Test param + if ignore_errors and self.test_param.name not in value: + # If ignoring errors, do nothing. However this is potentially very + # problematic since if we are missing the value of test param, + # the entire conditional is wrong. pass else: - rval[ input.name ] = input.value_from_basic( value[ input.name ], app, ignore_errors ) + rval[ self.test_param.name ] = self.test_param.value_from_basic( value[ self.test_param.name ], app, ignore_errors ) + # Inputs associated with current case + for input in self.cases[current_case].inputs.itervalues(): + if ignore_errors and input.name not in value: + # If we do not have a value, and are ignoring errors, we simply + # do nothing. There will be no value for the parameter in the + # conditional's values dictionary. + pass + else: + rval[ input.name ] = input.value_from_basic( value[ input.name ], app, ignore_errors ) + except Exception, e: + if not ignore_errors: + raise e return rval def visit_inputs( self, prefix, value, callback ): current_case = value['__current_case__'] diff -r ce62bf5a91f86d0c53764bda3df4975486d7512e -r a4113cc1cb5eaa68091c9a73375f00555b66dd11 lib/galaxy/tools/parameters/validation.py --- a/lib/galaxy/tools/parameters/validation.py +++ b/lib/galaxy/tools/parameters/validation.py @@ -182,10 +182,13 @@ def from_element( cls, param, elem ): return cls( message=elem.get( 'message', None ), check=elem.get( 'check', "" ), skip=elem.get( 'skip', "" ) ) def validate( self, value, history=None ): - if value and value.missing_meta( check = self.check, skip = self.skip ): - if self.message is None: - self.message = "Metadata missing, click the pencil icon in the history item to edit / save the metadata attributes" - raise ValueError( self.message ) + if value: + if not isinstance( value, model.DatasetInstance ): + raise ValueError( 'A non-dataset value was provided.' ) + if value.missing_meta( check = self.check, skip = self.skip ): + if self.message is None: + self.message = "Metadata missing, click the pencil icon in the history item to edit / save the metadata attributes" + raise ValueError( self.message ) class UnspecifiedBuildValidator( Validator ): """ diff -r ce62bf5a91f86d0c53764bda3df4975486d7512e -r a4113cc1cb5eaa68091c9a73375f00555b66dd11 lib/galaxy/util/hash_util.py --- a/lib/galaxy/util/hash_util.py +++ b/lib/galaxy/util/hash_util.py @@ -32,3 +32,10 @@ def hmac_new( key, value ): return hmac.new( key, value, sha ).hexdigest() + +def is_hashable( value ): + try: + hash( value ) + except: + return False + return True diff -r ce62bf5a91f86d0c53764bda3df4975486d7512e -r a4113cc1cb5eaa68091c9a73375f00555b66dd11 lib/galaxy/webapps/galaxy/controllers/tool_runner.py --- a/lib/galaxy/webapps/galaxy/controllers/tool_runner.py +++ b/lib/galaxy/webapps/galaxy/controllers/tool_runner.py @@ -4,6 +4,7 @@ from galaxy.web.base.controller import * from galaxy.util.bunch import Bunch +from galaxy.util.hash_util import is_hashable from galaxy.tools import DefaultToolState from galaxy.tools.parameters.basic import UnvalidatedValue from galaxy.tools.parameters import params_to_incoming @@ -174,7 +175,7 @@ params_objects = job.get_param_values( trans.app, ignore_errors = True ) except: raise Exception( "Failed to get parameters for dataset id %d " % data.id ) - upgrade_messages = tool.check_and_update_param_values( params_objects, trans ) + upgrade_messages = tool.check_and_update_param_values( params_objects, trans, update_values=False ) # Need to remap dataset parameters. Job parameters point to original # dataset used; parameter should be the analygous dataset in the # current history. @@ -199,12 +200,13 @@ if isinstance(value,list): values = [] for val in value: - if val in history.datasets: - values.append( val ) - elif val in hda_source_dict: - values.append( hda_source_dict[ val ]) + if is_hashable( val ): + if val in history.datasets: + values.append( val ) + elif val in hda_source_dict: + values.append( hda_source_dict[ val ]) return values - if value not in history.datasets and value in hda_source_dict: + if is_hashable( value ) and value not in history.datasets and value in hda_source_dict: return hda_source_dict[ value ] visit_input_values( tool.inputs, params_objects, rerun_callback ) # Create a fake tool_state for the tool, with the parameters values https://bitbucket.org/galaxy/galaxy-central/commits/58851b490112/ changeset: 58851b490112 user: dan date: 2013-01-10 22:15:30 summary: Merging heads affected #: 5 files diff -r ca12edce5f10d1411599dcb687d7d51706af99cb -r 58851b49011218dbb11370392bbc03f9b1e69a9f lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -2128,16 +2128,16 @@ return params_to_strings( self.inputs, params, app ) def params_from_strings( self, params, app, ignore_errors=False ): return params_from_strings( self.inputs, params, app, ignore_errors ) - def check_and_update_param_values( self, values, trans ): + def check_and_update_param_values( self, values, trans, update_values=True ): """ Check that all parameters have values, and fill in with default values where necessary. This could be called after loading values from a database in case new parameters have been added. """ messages = {} - self.check_and_update_param_values_helper( self.inputs, values, trans, messages ) + self.check_and_update_param_values_helper( self.inputs, values, trans, messages, update_values=update_values ) return messages - def check_and_update_param_values_helper( self, inputs, values, trans, messages, context=None, prefix="" ): + def check_and_update_param_values_helper( self, inputs, values, trans, messages, context=None, prefix="", update_values=True ): """ Recursive helper for `check_and_update_param_values_helper` """ @@ -2183,10 +2183,11 @@ # Regular tool parameter, no recursion needed try: #this will fail when a parameter's type has changed to a non-compatible one: e.g. conditional group changed to dataset input - input.value_from_basic( values[ input.name ], trans.app, ignore_errors=False ) + input.value_from_basic( input.value_to_basic( values[ input.name ], trans.app ), trans.app, ignore_errors=False ) except: messages[ input.name ] = "Value no longer valid for '%s%s', replaced with default" % ( prefix, input.label ) - values[ input.name ] = input.get_initial_value( trans, context ) + if update_values: + values[ input.name ] = input.get_initial_value( trans, context ) def handle_unvalidated_param_values( self, input_values, app ): """ Find any instances of `UnvalidatedValue` within input_values and diff -r ca12edce5f10d1411599dcb687d7d51706af99cb -r 58851b49011218dbb11370392bbc03f9b1e69a9f lib/galaxy/tools/parameters/basic.py --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -747,9 +747,9 @@ return { "__class__": "RuntimeValue" } return value def value_from_basic( self, value, app, ignore_errors=False ): - if isinstance( value, dict ) and value["__class__"] == "UnvalidatedValue": + if isinstance( value, dict ) and value.get( "__class__", None ) == "UnvalidatedValue": return UnvalidatedValue( value["value"] ) - return super( SelectToolParameter, self ).value_from_basic( value, app ) + return super( SelectToolParameter, self ).value_from_basic( value, app, ignore_errors=ignore_errors ) def need_late_validation( self, trans, context ): """ Determine whether we need to wait to validate this parameters value @@ -943,7 +943,7 @@ if not isinstance( value, list ): value = value.split( '\n' ) for column in value: - for column2 in column.split( ',' ): + for column2 in str( column ).split( ',' ): column2 = column2.strip() if column2: column_list.append( column2 ) @@ -1586,8 +1586,11 @@ elif isinstance( value, list) and len(value) > 0 and isinstance( value[0], DummyDataset): return None elif isinstance( value, list ): - return ",".join( [ val if isinstance( val, basestring ) else str(val.id) for val in value] ) - return value.id + return ",".join( [ str( self.to_string( val, app ) ) for val in value ] ) + try: + return value.id + except: + return str( value ) def to_python( self, value, app ): # Both of these values indicate that no dataset is selected. However, 'None' diff -r ca12edce5f10d1411599dcb687d7d51706af99cb -r 58851b49011218dbb11370392bbc03f9b1e69a9f lib/galaxy/tools/parameters/validation.py --- a/lib/galaxy/tools/parameters/validation.py +++ b/lib/galaxy/tools/parameters/validation.py @@ -182,10 +182,13 @@ def from_element( cls, param, elem ): return cls( message=elem.get( 'message', None ), check=elem.get( 'check', "" ), skip=elem.get( 'skip', "" ) ) def validate( self, value, history=None ): - if value and value.missing_meta( check = self.check, skip = self.skip ): - if self.message is None: - self.message = "Metadata missing, click the pencil icon in the history item to edit / save the metadata attributes" - raise ValueError( self.message ) + if value: + if not isinstance( value, model.DatasetInstance ): + raise ValueError( 'A non-dataset value was provided.' ) + if value.missing_meta( check = self.check, skip = self.skip ): + if self.message is None: + self.message = "Metadata missing, click the pencil icon in the history item to edit / save the metadata attributes" + raise ValueError( self.message ) class UnspecifiedBuildValidator( Validator ): """ diff -r ca12edce5f10d1411599dcb687d7d51706af99cb -r 58851b49011218dbb11370392bbc03f9b1e69a9f lib/galaxy/util/hash_util.py --- a/lib/galaxy/util/hash_util.py +++ b/lib/galaxy/util/hash_util.py @@ -32,3 +32,10 @@ def hmac_new( key, value ): return hmac.new( key, value, sha ).hexdigest() + +def is_hashable( value ): + try: + hash( value ) + except: + return False + return True diff -r ca12edce5f10d1411599dcb687d7d51706af99cb -r 58851b49011218dbb11370392bbc03f9b1e69a9f lib/galaxy/webapps/galaxy/controllers/tool_runner.py --- a/lib/galaxy/webapps/galaxy/controllers/tool_runner.py +++ b/lib/galaxy/webapps/galaxy/controllers/tool_runner.py @@ -4,6 +4,7 @@ from galaxy.web.base.controller import * from galaxy.util.bunch import Bunch +from galaxy.util.hash_util import is_hashable from galaxy.tools import DefaultToolState from galaxy.tools.parameters.basic import UnvalidatedValue from galaxy.tools.parameters import params_to_incoming @@ -174,7 +175,7 @@ params_objects = job.get_param_values( trans.app, ignore_errors = True ) except: raise Exception( "Failed to get parameters for dataset id %d " % data.id ) - upgrade_messages = tool.check_and_update_param_values( params_objects, trans ) + upgrade_messages = tool.check_and_update_param_values( params_objects, trans, update_values=False ) # Need to remap dataset parameters. Job parameters point to original # dataset used; parameter should be the analygous dataset in the # current history. @@ -199,12 +200,13 @@ if isinstance(value,list): values = [] for val in value: - if val in history.datasets: - values.append( val ) - elif val in hda_source_dict: - values.append( hda_source_dict[ val ]) + if is_hashable( val ): + if val in history.datasets: + values.append( val ) + elif val in hda_source_dict: + values.append( hda_source_dict[ val ]) return values - if value not in history.datasets and value in hda_source_dict: + if is_hashable( value ) and value not in history.datasets and value in hda_source_dict: return hda_source_dict[ value ] visit_input_values( tool.inputs, params_objects, rerun_callback ) # Create a fake tool_state for the tool, with the parameters values Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.