parameter.py 21.2 KB
Newer Older
Jerome Mariette's avatar
Jerome Mariette committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#
# Copyright (C) 2012 INRA
# 
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import types
Jerome Mariette's avatar
Jerome Mariette committed
19
import datetime
Jerome Mariette's avatar
Jerome Mariette committed
20
import logging
Jerome Mariette's avatar
Jerome Mariette committed
21
import argparse
Jerome Mariette's avatar
Jerome Mariette committed
22
23
import os
import tempfile
24
from argparse import _ensure_value
Jerome Mariette's avatar
Jerome Mariette committed
25
import urllib2
26
import copy as _copy
Jerome Mariette's avatar
Jerome Mariette committed
27
28
29
from urlparse import urlparse
from jflow.config_reader import JFlowConfigReader

Jerome Mariette's avatar
Jerome Mariette committed
30
31
# import custom types
from workflows.types import *
Jerome Mariette's avatar
Jerome Mariette committed
32

Jerome Mariette's avatar
Jerome Mariette committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

# define all input type available
INPUTFILE_TYPES = ["inputfile", "localfile", "urlfile", "browsefile"]

def browsefile(file):
    # browsefile are not available from command line, considere it as a localfile
    # from the gui, this will not been tested this way
    return localfile(file)

def localfile(file):
    if os.path.isfile(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:
        opener = urllib2.urlopen(file)
    except:
        raise argparse.ArgumentTypeError("URL '" + file + "' is invalid!")
    file_name = os.path.basename(uri_object.path)
    if file_name is not None and file_name != "":
        metadata = opener.info()
        file_size = int(metadata.getheaders("Content-Length")[0])
        if file_size == 0:
            raise argparse.ArgumentTypeError("The URL file '" + file + "' is empty!")
        return file
    else:
        raise argparse.ArgumentTypeError("URL '" + file + "' does not contain any file name!")
    
def inputfile(file):
    # test the format
    uri_object = urlparse(file)
    # check the file
    if uri_object.scheme == '':
        return localfile(file)
    else:
        return urlfile(file)
    
Jerome Mariette's avatar
Jerome Mariette committed
73
74
75
76
77
78
79
80
81
82
83
    
class Formats(object):
    ANY = "any"
    BAM = "bam"
    FASTQ = "fastq"
    FASTA = "fasta"
    SFF = "sff"
    QUAL = "qual"
    FLOW = "flow"
    HTML = "html"

Jerome Mariette's avatar
Jerome Mariette committed
84

Jerome Mariette's avatar
Jerome Mariette committed
85
class MultipleParameters(object):
86
    def __init__(self, types, required, choices, excludes, default, actions):
Jerome Mariette's avatar
Jerome Mariette committed
87
        self.types = types
88
        self.choices = choices
Jerome Mariette's avatar
Jerome Mariette committed
89
        self.excludes = excludes
90
        self.default = default
91
        self.actions = actions
Jerome Mariette's avatar
Jerome Mariette committed
92
        self.index = None
93
        self.required = required
Jerome Mariette's avatar
Jerome Mariette committed
94
        self.__name__ = "MultipleParameters"
95
        
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
96
97
98
99
100
101
    def get_help(self):
        help = " ("
        for flag in self.types.keys():
            help += flag + "=<" + self.types[flag].__name__.upper() + ">, "
        return help[:-2] + ")"
        
102
    def __call__(self, arg):
Jerome Mariette's avatar
Jerome Mariette committed
103
104
105
        parts = arg.split("=")
        if not self.types.has_key(parts[0]):
            raise argparse.ArgumentTypeError(parts[0] + " is an invalid flag! Available ones are: "+", ".join(self.types.keys()))
106
107
108
        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]]) + "))")
109
110
111
112
113
114
115
116
117
118
        
        if self.types[parts[0]] == types.BooleanType:
            return (parts[0], not self.default[parts[0]], self.required, self.excludes)
        else:
            try:
                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]
119
            return (parts[0], value, self.required, self.excludes, self.actions)
Jerome Mariette's avatar
Jerome Mariette committed
120

121
122
class MiltipleAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
123
124
125
126
127
128
129
        # what is commun within required and excludes
        exclusif_required = {}
        for exclude_group in values[0][3]:
            exclusif_required[exclude_group] = False
            for param in values[0][3][exclude_group]:
                if param in values[0][2]:
                    exclusif_required[exclude_group] = True
Jerome Mariette's avatar
Jerome Mariette committed
130
131
        given_params = []
        # first check for required parameters
132
133
        try:
            required = _copy.copy(values[0][2])
134
135
136
137
138
139
            # delete required that are exclusive
            for group in exclusif_required:
                if exclusif_required[group]:
                    for val in values[0][3][group]:
                        if val in required:
                            del required[required.index(val)]
140
            for val in values:
Jerome Mariette's avatar
Jerome Mariette committed
141
                given_params.append(val[0])
142
143
144
145
146
                if val[0] in required:
                    del required[required.index(val[0])]
        except: pass
        if len(required) == 1: parser.error(", ".join(required) + " is a required parameter!")
        elif len(required) > 1: parser.error(", ".join(required) + " are required parameters!")
Jerome Mariette's avatar
Jerome Mariette committed
147
148
149
150
151
152
153
154
        # then for exclude ones    
        for exclude_group in values[0][3]:
            found = None
            for param in values[0][3][exclude_group]:
                if param in given_params and found != None:
                    parser.error("argument '" + found + "': not allowed with argument '" + param + "'")
                    break
                elif param in given_params: found = param
155
156
157
158
159
160
161
162
163
        
        # check for required exclusive if one of them is in
        if len(exclusif_required.keys()) > 0:
            for group in exclusif_required:
                if exclusif_required[group]:
                    rfound = False
                    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")
164
        
Jerome Mariette's avatar
Jerome Mariette committed
165
        # if ok add the value
166
167
168
169
170
171
172
173
174
175
176
        final_hash, final_values = {}, []
        for value in values:
            if values[0][4][value[0]] == "append" and final_hash.has_key(value[0]):
                final_hash[value[0]].append(value[1])
            elif values[0][4][value[0]] == "append":
                final_hash[value[0]]= [value[1]]
            else:
                final_hash[value[0]]= value[1]
        for param in final_hash:
            final_values.append((param, final_hash[param]))
        setattr(namespace, self.dest, final_values)
177
178
179

class MiltipleAppendAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
180
181
182
183
184
185
186
        # what is commun within required and excludes
        exclusif_required = {}
        for exclude_group in values[0][3]:
            exclusif_required[exclude_group] = False
            for param in values[0][3][exclude_group]:
                if param in values[0][2]:
                    exclusif_required[exclude_group] = True
Jerome Mariette's avatar
Jerome Mariette committed
187
188
        given_params = []
        # first check for required parameters
189
190
        try:
            required = _copy.copy(values[0][2])
191
192
193
194
195
196
            # delete required that are exclusive
            for group in exclusif_required:
                if exclusif_required[group]:
                    for val in values[0][3][group]:
                        if val in required:
                            del required[required.index(val)]
197
            for val in values:
Jerome Mariette's avatar
Jerome Mariette committed
198
                given_params.append(val[0])
199
200
201
202
203
                if val[0] in required:
                    del required[required.index(val[0])]
        except: pass
        if len(required) == 1: parser.error(", ".join(required) + " is a required parameter!")
        elif len(required) > 1: parser.error(", ".join(required) + " are required parameters!")
Jerome Mariette's avatar
Jerome Mariette committed
204
205
206
207
208
209
210
211
        # then for exclude ones    
        for exclude_group in values[0][3]:
            found = None
            for param in values[0][3][exclude_group]:
                if param in given_params and found != None:
                    parser.error("argument '" + found + "': not allowed with argument '" + param + "'")
                    break
                elif param in given_params: found = param
212
213
214
215
216
217
218
219
220
        
        # check for required exclusive if one of them is in
        if len(exclusif_required.keys()) > 0:
            for group in exclusif_required:
                if exclusif_required[group]:
                    rfound = False
                    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")
Jerome Mariette's avatar
Jerome Mariette committed
221
        # if ok add the value
222
        items = _copy.copy(_ensure_value(namespace, self.dest, []))
223
224
225
226
227
228
229
230
231
232
233
        final_hash, final_values = {}, []
        for value in values:
            if values[0][4][value[0]] == "append" and final_hash.has_key(value[0]):
                final_hash[value[0]].append(value[1])
            elif values[0][4][value[0]] == "append":
                final_hash[value[0]]= [value[1]]
            else:
                final_hash[value[0]]= value[1]
        for param in final_hash:
            final_values.append((param, final_hash[param]))
        items.append(final_values)
234
        setattr(namespace, self.dest, items)        
235
236
237


class AbstractParameter(object):
Jerome Mariette's avatar
Jerome Mariette committed
238
    
239
240
    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):
Jerome Mariette's avatar
Jerome Mariette committed
241

Jerome Mariette's avatar
Jerome Mariette committed
242
243
        self.name = name
        self.help = help
244
        self.action = action
Jerome Mariette's avatar
Jerome Mariette committed
245
        self.nargs = None
246
247
248
        if sub_parameters:
            self.sub_parameters = sub_parameters
        else: self.sub_parameters = []
Jerome Mariette's avatar
Jerome Mariette committed
249
        self.group = group
250
251
252
253
254
        if flag == None:
            self.flag = "--"+name.replace("_", "-")
        else: self.flag = flag
        if display_name == None: 
            self.display_name = name.replace("_", " ").title()
Jerome Mariette's avatar
Jerome Mariette committed
255
        else: self.display_name = display_name
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
256
        self.required = required
257
        self.choices = choices
Jerome Mariette's avatar
Jerome Mariette committed
258
        
Jerome Mariette's avatar
Jerome Mariette committed
259
260
        if type == "date":
            self.type = date
Jerome Mariette's avatar
Jerome Mariette committed
261
        elif type == "multiple":
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
262
            self.type = "multiple"
Jerome Mariette's avatar
Jerome Mariette committed
263
264
        elif isinstance(type, types.FunctionType):
            self.type = type
Jerome Mariette's avatar
Jerome Mariette committed
265
266
267
        else:
            try: self.type = eval(type)
            except: self.type = types.StringType
Jerome Mariette's avatar
Jerome Mariette committed
268
                        
Jerome Mariette's avatar
Jerome Mariette committed
269
        self.default = default
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
270
        if self.type == "date" and not self.default:
Jerome Mariette's avatar
Jerome Mariette committed
271
272
            today = datetime.date.today()
            self.default = today.strftime('%d/%m/%Y')
273
        elif self.type == types.BooleanType :
Jerome Mariette's avatar
Jerome Mariette committed
274
275
            if self.default: self.default = str(self.default).lower() in ("true",  "t", "1")
            else: self.default = True
Jerome Mariette's avatar
Jerome Mariette committed
276
277
        elif self.action == "append":
            self.default = []
278
    
279
    def export_to_argparse(self):
280
281
282
283
        if self.type == types.BooleanType and str(self.default).lower() in ("false",  "f", "0"):
            return {"help": self.help, "required": self.required, "dest": self.name, 
                    "default": False, "action": "store_true"}
        elif self.type == types.BooleanType:
284
            return {"help": self.help, "required": self.required, "dest": self.name, 
285
                    "default": True, "action": "store_false"}
Jerome Mariette's avatar
Jerome Mariette committed
286
287
288
        elif self.nargs > 1:
            return {"type": self.type, "help": self.help, "required": self.required,
                    "dest": self.name, "default": self.default,
Jerome Mariette's avatar
Jerome Mariette committed
289
                    "action": self.action, "choices": self.choices, "nargs": "+"}
290
291
        else:
            return {"type": self.type, "help": self.help, "required": self.required,
Jerome Mariette's avatar
Jerome Mariette committed
292
                    "dest": self.name, "default": self.default,
293
294
                    "action": self.action, "choices": self.choices}
    
Jerome Mariette's avatar
Jerome Mariette committed
295
296
297
    def get_type(self):
        return self.type.__name__
    
Jerome Mariette's avatar
Jerome Mariette committed
298
    
Jerome Mariette's avatar
Jerome Mariette committed
299
300
class AbstractIOFile(object):
    
Jerome Mariette's avatar
Jerome Mariette committed
301
302
    def __init__(self, file_format="any"):
        self.file_format = file_format
Jerome Mariette's avatar
Jerome Mariette committed
303
        self.component_nameid = None
Jerome Mariette's avatar
Jerome Mariette committed
304
305
306
307
308
309
310
311
312
313
        self.parent_component_nameid = None


class MultiParameter(dict, AbstractParameter):
    
    def __init__(self, name, help, required=False, flag=None, group="default", display_name=None):
        AbstractParameter.__init__(self, name, help, required=required, type="multiple", flag=flag, group=group, 
                                   display_name=display_name)
        return dict.__init__(self, {})

Jerome Mariette's avatar
help ok    
Jerome Mariette committed
314
315
316
    def add_sub_parameter(self, param):
        param_flag = param.flag[2:]
        if self.type == "multiple":
Jerome Mariette's avatar
Jerome Mariette committed
317
318
319
            if param.required: req = [param_flag] 
            else: req = []
            self.type = MultipleParameters({param_flag: param.type}, req, 
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
320
321
322
323
324
325
326
327
                                           {param_flag: param.choices}, {}, {param_flag: param.default},
                                           {param_flag: param.action})
            if self.action == "append":
                self.action = MiltipleAppendAction
            else:
                self.action = MiltipleAction
            self.global_help = self.help
            self.help = self.global_help + " (" + param_flag + "=<" + param.type.__name__.upper() + ">)"
Jerome Mariette's avatar
Jerome Mariette committed
328
            self.default = {}
Jerome Mariette's avatar
Jerome Mariette committed
329
            self.nargs = "+"
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
330
331
332
333
334
        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.actions[param_flag] = param.action
Jerome Mariette's avatar
Jerome Mariette committed
335
336
            if param.required:
                self.type.required.append(param_flag)
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
337
            self.help = self.global_help + self.type.get_help()
Jerome Mariette's avatar
Jerome Mariette committed
338
        param.flag = param_flag
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
339
        self.sub_parameters.append(param)
Jerome Mariette's avatar
Jerome Mariette committed
340
        
341
342
343
344

class MultiParameterList(list, AbstractParameter):
    
    def __init__(self, name, help, required=False, flag=None, group="default", display_name=None):
Jerome Mariette's avatar
help ok    
Jerome Mariette committed
345
346
        AbstractParameter.__init__(self, name, help, required=required, type="multiple", flag=flag, 
                                   action="append", group=group, display_name=display_name)
347
        return list.__init__(self, [])
Jerome Mariette's avatar
Jerome Mariette committed
348

Jerome Mariette's avatar
Jerome Mariette committed
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
    def add_sub_parameter(self, param):
        param_flag = param.flag[2:]
        if self.type == "multiple":
            if param.required: req = [param_flag] 
            else: req = []
            self.type = MultipleParameters({param_flag: param.type}, req, 
                                           {param_flag: param.choices}, {}, {param_flag: param.default},
                                           {param_flag: param.action})
            if self.action == "append":
                self.action = MiltipleAppendAction
            else:
                self.action = MiltipleAction
            self.global_help = self.help
            self.help = self.global_help + " (" + param_flag + "=<" + param.type.__name__.upper() + ">)"
            self.default = []
            self.nargs = "+"
        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.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)

376
377
378
379
380
381

class Parameter(str, AbstractParameter):
    
    def __new__(self, name, help, default="", type=types.StringType, choices=None, required=False,
                flag=None, sub_parameters=None, group="default", display_name=None):
        return str.__new__(self, default)
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397

    def __eq__(self, other):
        if other.__class__.__name__ == "NoneType":
            return self == 'None'
        else: return str.__eq__(self, other)
        
    def __ne__(self, other):
        if other.__class__.__name__ == "NoneType":
            return self != 'None'
        else: return str.__ne__(self, other)
        
    def __nonzero__(self):
        if self == None or self == 'None': 
            return False
        else: return True

398
399
    def __init__(self, name, help, default="", type=types.StringType, choices=None, required=False,
                 flag=None, sub_parameters=None, group="default", display_name=None):
Jerome Mariette's avatar
Jerome Mariette committed
400
        AbstractParameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, required=required, 
401
402
403
                                   action="store", sub_parameters=sub_parameters, group=group, display_name=display_name)
        

Jerome Mariette's avatar
Jerome Mariette committed
404
class InputFile(Parameter, AbstractIOFile):
405
    
Jerome Mariette's avatar
Jerome Mariette committed
406
    def __new__(self, name, help, file_format="any", default="", type="localfile", choices=None, 
407
                required=False, flag=None, group="default", display_name=None):
Jerome Mariette's avatar
Jerome Mariette committed
408
409
410
411
412
413
414
415
416
        
        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)+"'")
        
417
418
        return str.__new__(self, default)
    
Jerome Mariette's avatar
Jerome Mariette committed
419
    def __init__(self, name, help, file_format="any", default="", type="localfile", choices=None, 
420
                required=False, flag=None, group="default", display_name=None):
Jerome Mariette's avatar
Jerome Mariette committed
421
        AbstractIOFile.__init__(self, file_format)
Jerome Mariette's avatar
Jerome Mariette committed
422
        Parameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, 
423
                           required=required, group=group, display_name=display_name)
Jerome Mariette's avatar
Jerome Mariette committed
424

425

Jerome Mariette's avatar
Jerome Mariette committed
426
class OutputFile(Parameter, AbstractIOFile):
427
    
Jerome Mariette's avatar
Jerome Mariette committed
428
    def __new__(self, name, help, file_format="any", default="", choices=None, 
429
430
431
                required=False, flag=None, group="default", display_name=None):
        return str.__new__(self, default)
    
Jerome Mariette's avatar
Jerome Mariette committed
432
    def __init__(self, name, help, file_format="any", default="", choices=None, 
433
                required=False, flag=None, group="default", display_name=None):
Jerome Mariette's avatar
Jerome Mariette committed
434
        AbstractIOFile.__init__(self, file_format)
Jerome Mariette's avatar
Jerome Mariette committed
435
        Parameter.__init__(self, name, help, flag=flag, default=default, type="localfile", choices=choices, 
436
437
438
439
440
                           required=required, group=group, display_name=display_name)

        
class ParameterList(list, AbstractParameter):
    
Jerome Mariette's avatar
Jerome Mariette committed
441
    def __init__(self, name, help, default=None, type=types.StringType, choices=None, required=False,
442
                 flag=None, sub_parameters=None, group="default", display_name=None):
Jerome Mariette's avatar
Jerome Mariette committed
443
        if default == None: default = []
Jerome Mariette's avatar
Jerome Mariette committed
444
        AbstractParameter.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, required=required, 
445
446
447
448
449
450
451
                                   action="append", sub_parameters=sub_parameters, group=group, display_name=display_name)
        if default.__class__.__name__ == "str":
            return list.__init__(self, [default])
        elif default.__class__.__name__ == "list":
            return list.__init__(self, default)
        

Jerome Mariette's avatar
Jerome Mariette committed
452
class InputFileList(ParameterList, AbstractIOFile):
453
    
Jerome Mariette's avatar
Jerome Mariette committed
454
    def __init__(self, name, help, file_format="any", default=None, type="localfile", choices=None, 
455
                 required=False, flag=None, group="default", display_name=None):
Jerome Mariette's avatar
Jerome Mariette committed
456
        
Jerome Mariette's avatar
Jerome Mariette committed
457
        if default == None: default = []   
Jerome Mariette's avatar
Jerome Mariette committed
458
459
460
461
462
463
464
465
        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)+"'")
        
Jerome Mariette's avatar
Jerome Mariette committed
466
        AbstractIOFile.__init__(self, file_format)
Jerome Mariette's avatar
Jerome Mariette committed
467
        ParameterList.__init__(self, name, help, flag=flag, default=default, type=type, choices=choices, 
468
                               required=required, group=group, display_name=display_name)
Jerome Mariette's avatar
Jerome Mariette committed
469
        
470
471
        if default.__class__.__name__ == "str":
            return list.__init__(self, [default])
Jerome Mariette's avatar
Jerome Mariette committed
472
473
474
475
        elif default.__class__.__name__ == "InputFile":
            return list.__init__(self, default)
        elif default.__class__.__name__ == "OutputFile":
            return list.__init__(self, default)
476
477
        elif default.__class__.__name__ == "list":
            return list.__init__(self, default)
Jerome Mariette's avatar
Jerome Mariette committed
478
479
        elif default.__class__.__name__ == "InputFileList":
            return list.__init__(self, default)
Jerome Mariette's avatar
Jerome Mariette committed
480
481
        elif default.__class__.__name__ == "OutputFileList":
            return list.__init__(self, default)
482

Jerome Mariette's avatar
Jerome Mariette committed
483
class OutputFileList(ParameterList, AbstractIOFile):
484
    
Jerome Mariette's avatar
Jerome Mariette committed
485
486
487
    def __init__(self, name, help, file_format="any", default=None, choices=None, 
                 required=False, flag=None, group="default", display_name=None):
        if default == None: default = []
Jerome Mariette's avatar
Jerome Mariette committed
488
        AbstractIOFile.__init__(self, file_format)
Jerome Mariette's avatar
Jerome Mariette committed
489
        ParameterList.__init__(self, name, help, flag=flag, default=default, type="localfile", choices=choices, 
490
491
492
493
494
                               required=required, group=group, display_name=display_name)
        if default.__class__.__name__ == "str":
            return list.__init__(self, [default])
        elif default.__class__.__name__ == "list":
            return list.__init__(self, default)