Commit 69b6172a authored by Frédéric Escudié's avatar Frédéric Escudié
Browse files

Change Parameter to IntParameter, FloatParameter, BoolParameter and...

Change Parameter to IntParameter, FloatParameter, BoolParameter and StrParameter (fix bug with None and with number parameter operators).
parent 3013ebde
......@@ -45,7 +45,7 @@ def localfile(file):
return os.path.abspath(file)
else:
raise argparse.ArgumentTypeError("Local file '" + file + "' does not exists! Please provide a valid file path!")
def urlfile(file):
uri_object = urlparse(file)
try:
......@@ -61,7 +61,7 @@ def urlfile(file):
return file
else:
raise argparse.ArgumentTypeError("URL '" + file + "' does not contain any file name!")
def inputfile(file):
# test the format
uri_object = urlparse(file)
......@@ -70,8 +70,8 @@ def inputfile(file):
return localfile(file)
else:
return urlfile(file)
class Formats(object):
ANY = "any"
BAM = "bam"
......@@ -93,13 +93,13 @@ class MultipleParameters(object):
self.index = None
self.required = required
self.__name__ = "MultipleParameters"
def get_help(self):
help = " ("
for flag in self.types.keys():
help += flag + "=<" + self.types[flag].__name__.upper() + ">, "
return help[:-2] + ")"
def __call__(self, arg):
parts = arg.split("=")
if not self.types.has_key(parts[0]):
......@@ -107,7 +107,7 @@ class MultipleParameters(object):
if self.choices[parts[0]] != None:
if parts[1] not in self.choices[parts[0]]:
raise argparse.ArgumentTypeError("argument " + parts[0] + ": invalid choice: '" + parts[1] + "' (choose from " + ", ".join(self.choices[parts[0]]) + "))")
if self.types[parts[0]] == types.BooleanType:
return (parts[0], not self.default[parts[0]], self.required, self.excludes)
else:
......@@ -115,7 +115,7 @@ class MultipleParameters(object):
value = self.types[parts[0]](parts[1])
except:
raise argparse.ArgumentTypeError("invalid " + self.types[parts[0]].__name__ + " value: '" + parts[1] + "' for sub parameter '" + parts[0] + "'")
self.index = parts[0]
return (parts[0], value, self.required, self.excludes, self.actions)
......@@ -153,7 +153,7 @@ class MiltipleAction(argparse.Action):
parser.error("argument '" + found + "': not allowed with argument '" + param + "'")
break
elif param in given_params: found = param
# check for required exclusive if one of them is in
if len(exclusif_required.keys()) > 0:
for group in exclusif_required:
......@@ -162,7 +162,7 @@ class MiltipleAction(argparse.Action):
for param in values[0][3][group]:
if param in given_params: rfound = True
if not rfound: parser.error("one of the arguments: " + ", ".join(values[0][3][group]) + " is required")
# if ok add the value
final_hash, final_values = {}, []
for value in values:
......@@ -176,6 +176,7 @@ class MiltipleAction(argparse.Action):
final_values.append((param, final_hash[param]))
setattr(namespace, self.dest, final_values)
class MiltipleAppendAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
# what is commun within required and excludes
......@@ -210,7 +211,7 @@ class MiltipleAppendAction(argparse.Action):
parser.error("argument '" + found + "': not allowed with argument '" + param + "'")
break
elif param in given_params: found = param
# check for required exclusive if one of them is in
if len(exclusif_required.keys()) > 0:
for group in exclusif_required:
......@@ -232,11 +233,11 @@ class MiltipleAppendAction(argparse.Action):
for param in final_hash:
final_values.append((param, final_hash[param]))
items.append(final_values)
setattr(namespace, self.dest, items)
setattr(namespace, self.dest, items)
class AbstractParameter(object):
def __init__(self, name, help, default=None, type=types.StringType, choices=None, required=False,
flag=None, action="store", sub_parameters=None, group="default", display_name=None):
......@@ -251,35 +252,28 @@ class AbstractParameter(object):
if flag == None:
self.flag = "--"+name.replace("_", "-")
else: self.flag = flag
if display_name == None:
if display_name == None:
self.display_name = name.replace("_", " ").title()
else: self.display_name = display_name
self.required = required
self.choices = choices
# Set parameter type
if type == "date":
self.type = date
self.type = types.MemberDescriptorType
elif type == "multiple":
self.type = "multiple"
elif isinstance(type, types.FunctionType):
self.type = type
elif type.__class__.__name__ == "type":
elif type in [types.StringType, types.IntType, types.FloatType, types.BooleanType]:
self.type = type
else:
try: self.type = eval(type)
except: self.type = types.StringType
# Set parameter value
self.default = default
if self.type == "date" and not self.default:
today = datetime.date.today()
self.default = today.strftime('%d/%m/%Y')
elif self.type == types.BooleanType :
if self.default.__class__.__name__ == "str":
if self.default: self.default = str(self.default).lower() in (True, "true", "t", "1")
else: self.default = True
elif self.action == "append":
self.default = []
def export_to_argparse(self):
if self.type == types.BooleanType and str(self.default).lower() in (False, "false", "f", "0"):
return {"help": self.help, "required": self.required, "dest": self.name,
......@@ -295,13 +289,13 @@ class AbstractParameter(object):
return {"type": self.type, "help": self.help, "required": self.required,
"dest": self.name, "default": self.default,
"action": self.action, "choices": self.choices}
def get_type(self):
return self.type.__name__
class AbstractIOFile(object):
def __init__(self, file_format="any"):
self.file_format = file_format
self.component_nameid = None
......@@ -334,14 +328,14 @@ class MultiParameter(dict, AbstractParameter):
elif self.type.__class__ == MultipleParameters:
self.type.types[param_flag] = param.type
self.type.choices[param_flag] = param.choices
self.type.default[param_flag] = param.default
self.type.default[param_flag] = param.default if param != None else None
self.type.actions[param_flag] = param.action
if param.required:
self.type.required.append(param_flag)
self.help = self.global_help + self.type.get_help()
param.flag = param_flag
self.sub_parameters.append(param)
class MultiParameterList(list, AbstractParameter):
......@@ -369,7 +363,7 @@ class MultiParameterList(list, AbstractParameter):
elif self.type.__class__ == MultipleParameters:
self.type.types[param_flag] = param.type
self.type.choices[param_flag] = param.choices
self.type.default[param_flag] = param.default
self.type.default[param_flag] = param.default if param != None else None
self.type.actions[param_flag] = param.action
if param.required:
self.type.required.append(param_flag)
......@@ -378,37 +372,197 @@ class MultiParameterList(list, AbstractParameter):
self.sub_parameters.append(param)
class Parameter(str, AbstractParameter):
def __new__(self, name, help, default="", type=types.StringType, choices=None, required=False,
def noneException(*args, **kwargs):
raise Exception( "The parameter value is None." )
class BoolParameter(int, AbstractParameter):
def __new__(self, name, help, default=None, type=types.BooleanType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
return str.__new__(self, default)
bool_default = False if default == None else bool(default)
val = int.__new__(self, bool_default)
val.is_None = False
if default == None:
val.is_None = True
for attr in val.__dict__:
value = getattr(val, attr)
if callable(value) and attr not in ["__new__", "__init__", "__int__", "__getattribute__", "__eq__", "__ne__", "__nonzero__"]:
setattr(val, attr, noneException)
return val
def __init__(self, name, help, default=None, type=types.BooleanType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
AbstractParameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, required=required,
action="store", sub_parameters=sub_parameters, group=group, display_name=display_name)
def __eq__(self, other):
if other.__class__.__name__ == "NoneType":
return self == 'None'
else: return str.__eq__(self, other)
return self.is_None
elif self.is_None:
return False
else:
return int(self) == int(other)
def __ne__(self, other):
if other.__class__.__name__ == "NoneType":
return self != 'None'
else: return str.__ne__(self, other)
return not self.is_None
elif self.is_None:
return True
else:
return int(self) != int(other)
def __nonzero__(self):
if self == None or self == 'None':
if self.is_None:
return False
else: return True
else:
return self != 0
def __init__(self, name, help, default="", type=types.StringType, choices=None, required=False,
class IntParameter(int, AbstractParameter):
def __new__(self, name, help, default=None, type=types.IntType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
int_default = 0 if default == None else int(default)
val = int.__new__(self, int_default)
val.is_None = False
if default == None:
val.is_None = True
for attr in val.__dict__:
value = getattr(val, attr)
if callable(value) and attr not in ["__new__", "__init__", "__int__", "__getattribute__", "__eq__", "__ne__", "__nonzero__"]:
setattr(val, attr, noneException)
return val
def __init__(self, name, help, default=None, type=types.IntType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
AbstractParameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, required=required,
action="store", sub_parameters=sub_parameters, group=group, display_name=display_name)
class AbstractInputFile(AbstractIOFile):
"""
@summary : Parent of all InputFile(s) parameters.
"""
pass
def __eq__(self, other):
if other.__class__.__name__ == "NoneType":
return self.is_None
elif self.is_None:
return False
else:
return int(self) == int(other)
def __ne__(self, other):
if other.__class__.__name__ == "NoneType":
return not self.is_None
elif self.is_None:
return True
else:
return int(self) != int(other)
def __nonzero__(self):
if self.is_None:
return False
else:
return self != 0
class FloatParameter(int, AbstractParameter):
def __new__(self, name, help, default=None, type=types.FloatType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
float_default = 0.0 if default == None else float(default)
val = int.__new__(self, float_default)
val.is_None = False
if default == None:
val.is_None = True
for attr in val.__dict__:
value = getattr(val, attr)
if callable(value) and attr not in ["__new__", "__init__", "__float__", "__getattribute__", "__eq__", "__ne__", "__nonzero__"]:
setattr(val, attr, noneException)
return val
def __init__(self, name, help, default=None, type=types.FloatType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
AbstractParameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, required=required,
action="store", sub_parameters=sub_parameters, group=group, display_name=display_name)
def __eq__(self, other):
if other.__class__.__name__ == "NoneType":
return self.is_None
elif self.is_None:
return False
else:
return float(self) == float(other)
def __ne__(self, other):
if other.__class__.__name__ == "NoneType":
return not self.is_None
elif self.is_None:
return True
else:
return float(self) != float(other)
def __nonzero__(self):
if self.is_None:
return False
else:
return self != 0.0
class StrParameter(str, AbstractParameter):
def __new__(self, name, help, default=None, type=types.StringType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
str_default = "" if default == None else str(default)
val = str.__new__(self, str_default)
val.is_None = False
if default == None:
val.is_None = True
for attr in val.__dict__:
value = getattr(val, attr)
if callable(value) and attr not in ["__new__", "__init__", "__str__", "__getattribute__", "__eq__", "__ne__", "__nonzero__"]:
setattr(val, attr, noneException)
return val
def __init__(self, name, help, default=None, type=types.StringType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
AbstractParameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, required=required,
action="store", sub_parameters=sub_parameters, group=group, display_name=display_name)
def __eq__(self, other):
if other.__class__.__name__ == "NoneType":
return self.is_None
elif self.is_None:
return False
else:
return str(self) == str(other)
def __ne__(self, other):
if other.__class__.__name__ == "NoneType":
return not self.is_None
elif self.is_None:
return True
else:
return str(self) != str(other)
def __nonzero__(self):
if self.is_None:
return False
else:
return (True if str(self) else False)
class ParameterFactory(object):
@staticmethod
def factory(*args, **kwargs):
if not kwargs.has_key( "type" ):
return StrParameter( *args, **kwargs )
if kwargs["type"] == "int" or kwargs["type"] is types.IntType:
return IntParameter( *args, **kwargs )
elif kwargs["type"] == "bool" or kwargs["type"] is types.BooleanType :
return BoolParameter( *args, **kwargs )
elif kwargs["type"] == "float" or kwargs["type"] is types.FloatType :
return FloatParameter( *args, **kwargs )
else:
return StrParameter( *args, **kwargs )
class AbstractOutputFile(AbstractIOFile):
"""
......@@ -416,42 +570,45 @@ class AbstractOutputFile(AbstractIOFile):
"""
pass
class InputFile(Parameter, AbstractInputFile):
class InputFile(StrParameter, AbstractInputFile):
def __new__(self, name, help, file_format="any", default="", type="localfile", choices=None,
required=False, flag=None, group="default", display_name=None):
if hasattr(type, '__call__'):
type2test = type.__name__
else: type2test = type
if type2test not in INPUTFILE_TYPES:
raise ValueError("InputFile.__new__: wrong type provided: '"+type2test+"', this should be choosen between '"
+ "', '".join(INPUTFILE_TYPES)+"'")
return str.__new__(self, default)
return StrParameter.__new__(self, name, help, flag=flag, default=default, type=type, choices=choices,
required=required, group=group, display_name=display_name)
def __init__(self, name, help, file_format="any", default="", type="localfile", choices=None,
required=False, flag=None, group="default", display_name=None):
AbstractIOFile.__init__(self, file_format)
Parameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices,
StrParameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices,
required=required, group=group, display_name=display_name)
class OutputFile(Parameter, AbstractOutputFile):
class OutputFile(StrParameter, AbstractOutputFile):
def __new__(self, name, help, file_format="any", default="", choices=None,
required=False, flag=None, group="default", display_name=None):
return str.__new__(self, default)
return StrParameter.__new__(self, name, help, flag=flag, default=default, type="localfile", choices=choices,
required=required, group=group, display_name=display_name)
def __init__(self, name, help, file_format="any", default="", choices=None,
required=False, flag=None, group="default", display_name=None):
AbstractIOFile.__init__(self, file_format)
Parameter.__init__(self, name, help, flag=flag, default=default, type="localfile", choices=choices,
StrParameter.__init__(self, name, help, flag=flag, default=default, type="localfile", choices=choices,
required=required, group=group, display_name=display_name)
class ParameterList(list, AbstractParameter):
def __init__(self, name, help, default=None, type=types.StringType, choices=None, required=False,
flag=None, sub_parameters=None, group="default", display_name=None):
if default == None: default = []
......@@ -461,26 +618,26 @@ class ParameterList(list, AbstractParameter):
return list.__init__(self, [default])
elif default.__class__.__name__ == "list":
return list.__init__(self, default)
class InputFileList(ParameterList, AbstractInputFile):
def __init__(self, name, help, file_format="any", default=None, type="localfile", choices=None,
required=False, flag=None, group="default", display_name=None):
if default == None: default = []
if hasattr(type, '__call__'):
type2test = type.__name__
else: type2test = type
if type2test not in INPUTFILE_TYPES:
raise ValueError("InputFile.__new__: wrong type provided: '"+type2test+"', this should be choosen between '"
+ "', '".join(INPUTFILE_TYPES)+"'")
AbstractIOFile.__init__(self, file_format)
ParameterList.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices,
required=required, group=group, display_name=display_name)
if default.__class__.__name__ == "str":
return list.__init__(self, [default])
elif default.__class__.__name__ == "list":
......@@ -490,6 +647,7 @@ class InputFileList(ParameterList, AbstractInputFile):
elif issubclass( default.__class__, AbstractOutputFile ):
return list.__init__(self, default)
class OutputFileList(ParameterList, AbstractOutputFile):
def __init__(self, name, help, file_format="any", default=None, choices=None,
......@@ -503,6 +661,7 @@ class OutputFileList(ParameterList, AbstractOutputFile):
elif default.__class__.__name__ == "list":
return list.__init__(self, default)
class DynamicOutput(ParameterList, AbstractOutputFile):
"""
@warning : with this class of output, the component become dynamic.
......@@ -513,6 +672,7 @@ class DynamicOutput(ParameterList, AbstractOutputFile):
"""
raise NotImplementedError
class OutputFilesEndsWith(DynamicOutput):
def __init__(self, name, help, output_directory, end_str, include=True, file_format="any", choices=None,
......@@ -542,6 +702,7 @@ class OutputFilesEndsWith(DynamicOutput):
output_files.append( os.path.join(self.output_directory, file) )
list.__init__(self, output_files)
class OutputFilesPattern(DynamicOutput):
def __init__(self, name, help, output_directory, pattern, include=True, file_format="any", choices=None,
......
......@@ -157,7 +157,7 @@ class Workflow(threading.Thread):
def add_parameter(self, name, help, default=None, type=types.StringType, choices=None,
required=False, flag=None, group="default", display_name=None, add_to=None):
new_param = Parameter(name, help, flag=flag, default=default, type=type, choices=choices,
new_param = ParameterFactory.factory(name, help, flag=flag, default=default, type=type, choices=choices,
required=required, group=group, display_name=display_name)
# if this input should be added to a particular parameter
if add_to:
......@@ -244,10 +244,10 @@ class Workflow(threading.Thread):
for param in parameters:
try: args[param.name] = args[param.name].encode('ascii','ignore')
except: pass
if param.__class__ == Parameter:
if param.__class__ == StrParameter or param.__class__ == IntParameter or param.__class__ == FloatParameter or param.__class__ == BoolParameter:
if args[param.name]: default = args[param.name]
else: default = param.default
new_param = Parameter(param.name, param.help, default=default, type=param.type, choices=param.choices,
new_param = ParameterFactory.factory(param.name, param.help, default=default, type=param.type, choices=param.choices,
required=param.required, flag=param.flag, group=param.group, display_name=param.display_name)
self.__setattr__(param.name, new_param)
elif param.__class__ == InputFile:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment