2
2
3
3
import copy
4
4
import logging
5
- from typing import Any , Callable , Dict , List , Optional , Set , Union , Tuple
6
- from typing_extensions import Text , Type , TYPE_CHECKING # pylint: disable=unused-import
7
- # move to a regular typing import when Python 3.3-3.6 is no longer supported
5
+ from typing import (Any , Callable , Dict , List , MutableMapping , MutableSequence ,
6
+ Optional , Set , Tuple , Union )
8
7
9
8
from rdflib import Graph , URIRef # pylint: disable=unused-import
10
9
from rdflib .namespace import OWL , RDFS
11
- import schema_salad . schema # pylint: disable=unused- import
10
+ from ruamel . yaml . comments import CommentedMap
12
11
from schema_salad import validate
13
- from schema_salad .schema import AvroSchemaFromJSONData
12
+ from schema_salad .schema import AvroSchemaFromJSONData , Names
14
13
from schema_salad .sourceline import SourceLine
15
14
from six import iteritems , string_types
15
+ from typing_extensions import (TYPE_CHECKING , # pylint: disable=unused-import
16
+ Text , Type )
17
+ # move to a regular typing import when Python 3.3-3.6 is no longer supported
16
18
17
19
from . import expression
18
20
from .errors import WorkflowException
19
21
from .loghandler import _logger
20
22
from .mutation import MutationManager # pylint: disable=unused-import
21
- from .pathmapper import ( PathMapper , # pylint: disable=unused-import
22
- get_listing , normalizeFilesDirs , visit_class )
23
+ from .pathmapper import PathMapper # pylint: disable=unused-import
24
+ from . pathmapper import get_listing , normalizeFilesDirs , visit_class
23
25
from .stdfsaccess import StdFsAccess # pylint: disable=unused-import
24
- from .utils import (aslist , docker_windows_path_adjust ,
25
- json_dumps , onWindows )
26
+ from .utils import aslist , docker_windows_path_adjust , json_dumps , onWindows
27
+
28
+
29
+
26
30
if TYPE_CHECKING :
27
31
from .provenance import CreateProvProfile # pylint: disable=unused-import
28
32
CONTENT_LIMIT = 64 * 1024
@@ -109,7 +113,7 @@ def __init__(self,
109
113
files = None , # type: List[Dict[Text, Text]]
110
114
bindings = None , # type: List[Dict[Text, Any]]
111
115
schemaDefs = None , # type: Dict[Text, Dict[Text, Any]]
112
- names = None , # type: schema_salad.schema. Names
116
+ names = None , # type: Names
113
117
requirements = None , # type: List[Dict[Text, Any]]
114
118
hints = None , # type: List[Dict[Text, Any]]
115
119
timeout = None , # type: float
@@ -129,7 +133,7 @@ def __init__(self,
129
133
): # type: (...) -> None
130
134
131
135
if names is None :
132
- self .names = schema_salad . schema . Names ()
136
+ self .names = Names ()
133
137
else :
134
138
self .names = names
135
139
@@ -194,22 +198,23 @@ def build_job_script(self, commands):
194
198
return None
195
199
196
200
def bind_input (self ,
197
- schema , # type: Dict [Text, Any]
201
+ schema , # type: MutableMapping [Text, Any]
198
202
datum , # type: Any
199
203
discover_secondaryFiles , # type: bool
200
204
lead_pos = None , # type: Optional[Union[int, List[int]]]
201
205
tail_pos = None , # type: Optional[List[int]]
202
- ): # type: (...) -> List[Dict [Text, Any]]
206
+ ): # type: (...) -> List[MutableMapping [Text, Any]]
203
207
204
208
if tail_pos is None :
205
209
tail_pos = []
206
210
if lead_pos is None :
207
211
lead_pos = []
208
- bindings = [] # type: List[Dict [Text,Text]]
209
- binding = None # type: Optional[Dict [Text,Any]]
212
+ bindings = [] # type: List[MutableMapping [Text, Text]]
213
+ binding = None # type: Optional[MutableMapping [Text,Any]]
210
214
value_from_expression = False
211
- if "inputBinding" in schema and isinstance (schema ["inputBinding" ], dict ):
212
- binding = copy .copy (schema ["inputBinding" ])
215
+ if "inputBinding" in schema and isinstance (schema ["inputBinding" ], MutableMapping ):
216
+ binding = CommentedMap (schema ["inputBinding" ].items ())
217
+ assert binding is not None
213
218
214
219
if "position" in binding :
215
220
binding ["position" ] = aslist (lead_pos ) + aslist (binding ["position" ]) + aslist (tail_pos )
@@ -221,12 +226,12 @@ def bind_input(self,
221
226
value_from_expression = True
222
227
223
228
# Handle union types
224
- if isinstance (schema ["type" ], list ):
229
+ if isinstance (schema ["type" ], MutableSequence ):
225
230
bound_input = False
226
231
for t in schema ["type" ]:
227
232
if isinstance (t , string_types ) and self .names .has_name (t , "" ):
228
233
avsc = self .names .get_name (t , "" )
229
- elif isinstance (t , dict ) and "name" in t and self .names .has_name (t ["name" ], "" ):
234
+ elif isinstance (t , MutableMapping ) and "name" in t and self .names .has_name (t ["name" ], "" ):
230
235
avsc = self .names .get_name (t ["name" ], "" )
231
236
else :
232
237
avsc = AvroSchemaFromJSONData (t , self .names )
@@ -240,7 +245,7 @@ def bind_input(self,
240
245
bound_input = True
241
246
if not bound_input :
242
247
raise validate .ValidationException (u"'%s' is not a valid union %s" % (datum , schema ["type" ]))
243
- elif isinstance (schema ["type" ], dict ):
248
+ elif isinstance (schema ["type" ], MutableMapping ):
244
249
st = copy .deepcopy (schema ["type" ])
245
250
if binding and "inputBinding" not in st and st ["type" ] == "array" and "itemSeparator" not in binding :
246
251
st ["inputBinding" ] = {}
@@ -289,7 +294,7 @@ def bind_input(self,
289
294
if "secondaryFiles" not in datum :
290
295
datum ["secondaryFiles" ] = []
291
296
for sf in aslist (schema ["secondaryFiles" ]):
292
- if isinstance (sf , dict ) or "$(" in sf or "${" in sf :
297
+ if isinstance (sf , MutableMapping ) or "$(" in sf or "${" in sf :
293
298
sfpath = self .do_eval (sf , context = datum )
294
299
else :
295
300
sfpath = substitute (datum ["basename" ], sf )
@@ -301,7 +306,7 @@ def bind_input(self,
301
306
if d ["basename" ] == sfname :
302
307
found = True
303
308
if not found :
304
- if isinstance (sfname , dict ):
309
+ if isinstance (sfname , MutableMapping ):
305
310
datum ["secondaryFiles" ].append (sfname )
306
311
elif discover_secondaryFiles :
307
312
datum ["secondaryFiles" ].append ({
@@ -344,7 +349,7 @@ def _capture_files(f):
344
349
return bindings
345
350
346
351
def tostr (self , value ): # type: (Any) -> Text
347
- if isinstance (value , dict ) and value .get ("class" ) in ("File" , "Directory" ):
352
+ if isinstance (value , MutableMapping ) and value .get ("class" ) in ("File" , "Directory" ):
348
353
if "path" not in value :
349
354
raise WorkflowException (u"%s object missing \" path\" : %s" % (value ["class" ], value ))
350
355
@@ -372,8 +377,8 @@ def generate_arg(self, binding): # type: (Dict[Text, Any]) -> List[Text]
372
377
with SourceLine (binding , "separate" , WorkflowException , _logger .isEnabledFor (logging .DEBUG )):
373
378
raise WorkflowException ("'separate' option can not be specified without prefix" )
374
379
375
- argl = [] # type: List[Dict [Text,Text]]
376
- if isinstance (value , list ):
380
+ argl = [] # type: MutableSequence[MutableMapping [Text, Text]]
381
+ if isinstance (value , MutableSequence ):
377
382
if binding .get ("itemSeparator" ) and value :
378
383
argl = [binding ["itemSeparator" ].join ([self .tostr (v ) for v in value ])]
379
384
elif binding .get ("valueFrom" ):
@@ -383,9 +388,9 @@ def generate_arg(self, binding): # type: (Dict[Text, Any]) -> List[Text]
383
388
return [prefix ]
384
389
else :
385
390
return []
386
- elif isinstance (value , dict ) and value .get ("class" ) in ("File" , "Directory" ):
391
+ elif isinstance (value , MutableMapping ) and value .get ("class" ) in ("File" , "Directory" ):
387
392
argl = [value ]
388
- elif isinstance (value , dict ):
393
+ elif isinstance (value , MutableMapping ):
389
394
return [prefix ] if prefix else []
390
395
elif value is True and prefix :
391
396
return [prefix ]
@@ -407,10 +412,10 @@ def generate_arg(self, binding): # type: (Dict[Text, Any]) -> List[Text]
407
412
def do_eval (self , ex , context = None , recursive = False , strip_whitespace = True ):
408
413
# type: (Union[Dict[Text, Text], Text], Any, bool, bool) -> Any
409
414
if recursive :
410
- if isinstance (ex , dict ):
415
+ if isinstance (ex , MutableMapping ):
411
416
return {k : self .do_eval (v , context , recursive )
412
417
for k , v in iteritems (ex )}
413
- if isinstance (ex , list ):
418
+ if isinstance (ex , MutableSequence ):
414
419
return [self .do_eval (v , context , recursive )
415
420
for v in ex ]
416
421
0 commit comments