vortex-nwp 2.0.0b1__py3-none-any.whl → 2.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. vortex/__init__.py +75 -47
  2. vortex/algo/__init__.py +3 -2
  3. vortex/algo/components.py +944 -618
  4. vortex/algo/mpitools.py +802 -497
  5. vortex/algo/mpitools_templates/__init__.py +1 -0
  6. vortex/algo/serversynctools.py +34 -33
  7. vortex/config.py +19 -22
  8. vortex/data/__init__.py +9 -3
  9. vortex/data/abstractstores.py +593 -655
  10. vortex/data/containers.py +217 -162
  11. vortex/data/contents.py +65 -39
  12. vortex/data/executables.py +93 -102
  13. vortex/data/flow.py +40 -34
  14. vortex/data/geometries.py +228 -132
  15. vortex/data/handlers.py +436 -227
  16. vortex/data/outflow.py +15 -15
  17. vortex/data/providers.py +185 -163
  18. vortex/data/resources.py +48 -42
  19. vortex/data/stores.py +540 -417
  20. vortex/data/sync_templates/__init__.py +0 -0
  21. vortex/gloves.py +114 -87
  22. vortex/layout/__init__.py +1 -8
  23. vortex/layout/contexts.py +150 -84
  24. vortex/layout/dataflow.py +353 -202
  25. vortex/layout/monitor.py +264 -128
  26. vortex/nwp/__init__.py +5 -2
  27. vortex/nwp/algo/__init__.py +14 -5
  28. vortex/nwp/algo/assim.py +205 -151
  29. vortex/nwp/algo/clim.py +683 -517
  30. vortex/nwp/algo/coupling.py +447 -225
  31. vortex/nwp/algo/eda.py +437 -229
  32. vortex/nwp/algo/eps.py +403 -231
  33. vortex/nwp/algo/forecasts.py +416 -275
  34. vortex/nwp/algo/fpserver.py +683 -307
  35. vortex/nwp/algo/ifsnaming.py +205 -145
  36. vortex/nwp/algo/ifsroot.py +215 -122
  37. vortex/nwp/algo/monitoring.py +137 -76
  38. vortex/nwp/algo/mpitools.py +330 -190
  39. vortex/nwp/algo/odbtools.py +637 -353
  40. vortex/nwp/algo/oopsroot.py +454 -273
  41. vortex/nwp/algo/oopstests.py +90 -56
  42. vortex/nwp/algo/request.py +287 -206
  43. vortex/nwp/algo/stdpost.py +878 -522
  44. vortex/nwp/data/__init__.py +22 -4
  45. vortex/nwp/data/assim.py +125 -137
  46. vortex/nwp/data/boundaries.py +121 -68
  47. vortex/nwp/data/climfiles.py +193 -211
  48. vortex/nwp/data/configfiles.py +73 -69
  49. vortex/nwp/data/consts.py +426 -401
  50. vortex/nwp/data/ctpini.py +59 -43
  51. vortex/nwp/data/diagnostics.py +94 -66
  52. vortex/nwp/data/eda.py +50 -51
  53. vortex/nwp/data/eps.py +195 -146
  54. vortex/nwp/data/executables.py +440 -434
  55. vortex/nwp/data/fields.py +63 -48
  56. vortex/nwp/data/gridfiles.py +183 -111
  57. vortex/nwp/data/logs.py +250 -217
  58. vortex/nwp/data/modelstates.py +180 -151
  59. vortex/nwp/data/monitoring.py +72 -99
  60. vortex/nwp/data/namelists.py +254 -202
  61. vortex/nwp/data/obs.py +400 -308
  62. vortex/nwp/data/oopsexec.py +22 -20
  63. vortex/nwp/data/providers.py +90 -65
  64. vortex/nwp/data/query.py +71 -82
  65. vortex/nwp/data/stores.py +49 -36
  66. vortex/nwp/data/surfex.py +136 -137
  67. vortex/nwp/syntax/__init__.py +1 -1
  68. vortex/nwp/syntax/stdattrs.py +173 -111
  69. vortex/nwp/tools/__init__.py +2 -2
  70. vortex/nwp/tools/addons.py +22 -17
  71. vortex/nwp/tools/agt.py +24 -12
  72. vortex/nwp/tools/bdap.py +16 -5
  73. vortex/nwp/tools/bdcp.py +4 -1
  74. vortex/nwp/tools/bdm.py +3 -0
  75. vortex/nwp/tools/bdmp.py +14 -9
  76. vortex/nwp/tools/conftools.py +728 -378
  77. vortex/nwp/tools/drhook.py +12 -8
  78. vortex/nwp/tools/grib.py +65 -39
  79. vortex/nwp/tools/gribdiff.py +22 -17
  80. vortex/nwp/tools/ifstools.py +82 -42
  81. vortex/nwp/tools/igastuff.py +167 -143
  82. vortex/nwp/tools/mars.py +14 -2
  83. vortex/nwp/tools/odb.py +234 -125
  84. vortex/nwp/tools/partitioning.py +61 -37
  85. vortex/nwp/tools/satrad.py +27 -12
  86. vortex/nwp/util/async.py +83 -55
  87. vortex/nwp/util/beacon.py +10 -10
  88. vortex/nwp/util/diffpygram.py +174 -86
  89. vortex/nwp/util/ens.py +144 -63
  90. vortex/nwp/util/hooks.py +30 -19
  91. vortex/nwp/util/taskdeco.py +28 -24
  92. vortex/nwp/util/usepygram.py +278 -172
  93. vortex/nwp/util/usetnt.py +31 -17
  94. vortex/sessions.py +72 -39
  95. vortex/syntax/__init__.py +1 -1
  96. vortex/syntax/stdattrs.py +410 -171
  97. vortex/syntax/stddeco.py +31 -22
  98. vortex/toolbox.py +327 -192
  99. vortex/tools/__init__.py +11 -2
  100. vortex/tools/actions.py +110 -121
  101. vortex/tools/addons.py +111 -92
  102. vortex/tools/arm.py +42 -22
  103. vortex/tools/compression.py +72 -69
  104. vortex/tools/date.py +11 -4
  105. vortex/tools/delayedactions.py +242 -132
  106. vortex/tools/env.py +75 -47
  107. vortex/tools/folder.py +342 -171
  108. vortex/tools/grib.py +341 -162
  109. vortex/tools/lfi.py +423 -216
  110. vortex/tools/listings.py +109 -40
  111. vortex/tools/names.py +218 -156
  112. vortex/tools/net.py +655 -299
  113. vortex/tools/parallelism.py +93 -61
  114. vortex/tools/prestaging.py +55 -31
  115. vortex/tools/schedulers.py +172 -105
  116. vortex/tools/services.py +403 -334
  117. vortex/tools/storage.py +293 -358
  118. vortex/tools/surfex.py +24 -24
  119. vortex/tools/systems.py +1234 -643
  120. vortex/tools/targets.py +156 -100
  121. vortex/util/__init__.py +1 -1
  122. vortex/util/config.py +378 -327
  123. vortex/util/empty.py +2 -2
  124. vortex/util/helpers.py +56 -24
  125. vortex/util/introspection.py +18 -12
  126. vortex/util/iosponge.py +8 -4
  127. vortex/util/roles.py +4 -6
  128. vortex/util/storefunctions.py +39 -13
  129. vortex/util/structs.py +3 -3
  130. vortex/util/worker.py +29 -17
  131. vortex_nwp-2.1.0.dist-info/METADATA +67 -0
  132. vortex_nwp-2.1.0.dist-info/RECORD +144 -0
  133. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info}/WHEEL +1 -1
  134. vortex/layout/appconf.py +0 -109
  135. vortex/layout/jobs.py +0 -1276
  136. vortex/layout/nodes.py +0 -1424
  137. vortex/layout/subjobs.py +0 -464
  138. vortex_nwp-2.0.0b1.dist-info/METADATA +0 -50
  139. vortex_nwp-2.0.0b1.dist-info/RECORD +0 -146
  140. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info/licenses}/LICENSE +0 -0
  141. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.1.0.dist-info}/top_level.txt +0 -0
vortex/data/contents.py CHANGED
@@ -26,6 +26,7 @@ logger = loggers.getLogger(__name__)
26
26
 
27
27
  class DataContentError(ValueError):
28
28
  """General content error."""
29
+
29
30
  pass
30
31
 
31
32
 
@@ -40,12 +41,12 @@ class DataContent:
40
41
  self._metadata = ReadOnlyDict()
41
42
  self._size = 0
42
43
  for k, v in kw.items():
43
- self.__dict__['_' + k] = v
44
+ self.__dict__["_" + k] = v
44
45
 
45
46
  @secure_getattr
46
47
  def __getattr__(self, attr):
47
48
  """Forward get attribute request to internal data object."""
48
- if attr not in ('__getstate__', '__deepcopy__'):
49
+ if attr not in ("__getstate__", "__deepcopy__"):
49
50
  return getattr(self.data, attr)
50
51
  else:
51
52
  raise AttributeError(attr)
@@ -83,8 +84,10 @@ class DataContent:
83
84
  one hour before the date specified in the resource's footprint.
84
85
  """
85
86
  if not len(self.metadata):
86
- logger.error('Metadata check is not implemented for this format. ' +
87
- 'The check will always succeed...')
87
+ logger.error(
88
+ "Metadata check is not implemented for this format. "
89
+ + "The check will always succeed..."
90
+ )
88
91
  delta = delta or {}
89
92
  outcome = True
90
93
  for mkey, mval in self.metadata.items():
@@ -94,8 +97,10 @@ class DataContent:
94
97
  cval += delta[mkey]
95
98
  outcome = outcome and cval == mval
96
99
  if not outcome:
97
- logger.warning("The ressource in the container doesn't match the resource footprint: %s",
98
- str(self.metadata))
100
+ logger.warning(
101
+ "The ressource in the container doesn't match the resource footprint: %s",
102
+ str(self.metadata),
103
+ )
99
104
  return outcome
100
105
 
101
106
  @property
@@ -119,7 +124,9 @@ class DataContent:
119
124
  def _merge_checkclass(self, *kargs):
120
125
  """Utility method to check that all the kargs objects are compatible self."""
121
126
  if not all([isinstance(obj, self.__class__) for obj in kargs]):
122
- raise DataContentError("The object's types are not compatible with self")
127
+ raise DataContentError(
128
+ "The object's types are not compatible with self"
129
+ )
123
130
 
124
131
  def merge(self, *kargs):
125
132
  """Merge several DataContents into one.
@@ -137,7 +144,9 @@ class DataContent:
137
144
  def diff(self, ref):
138
145
  """Compare the present content with the ``ref`` content."""
139
146
  if not self.is_diffable():
140
- raise NotImplementedError("Diff is not implemented for this content")
147
+ raise NotImplementedError(
148
+ "Diff is not implemented for this content"
149
+ )
141
150
  else:
142
151
  return self._actual_diff(ref)
143
152
 
@@ -152,6 +161,7 @@ class DataContent:
152
161
 
153
162
  class UnknownContent(DataContent):
154
163
  """Fake DataContent subclass."""
164
+
155
165
  pass
156
166
 
157
167
 
@@ -221,7 +231,13 @@ class IndexedTable(AlmostDictContent):
221
231
  """Get data from the ``container``."""
222
232
  with container.preferred_decoding(byte=False):
223
233
  container.rewind()
224
- self.extend([x.split() for x in container.readlines() if not x.startswith('#')])
234
+ self.extend(
235
+ [
236
+ x.split()
237
+ for x in container.readlines()
238
+ if not x.startswith("#")
239
+ ]
240
+ )
225
241
  self._size = container.totalsize
226
242
 
227
243
 
@@ -232,7 +248,7 @@ class JsonDictContent(AlmostDictContent):
232
248
 
233
249
  def __init__(self, **kw):
234
250
  self._bronx_tpl = None
235
- super().__init__(** kw)
251
+ super().__init__(**kw)
236
252
 
237
253
  def slurp(self, container):
238
254
  """Get data from the ``container``."""
@@ -275,7 +291,7 @@ class AlmostListContent(DataContent):
275
291
  _diffable = True
276
292
 
277
293
  def __init__(self, **kw):
278
- self._maxprint = kw.pop('maxprint', 20)
294
+ self._maxprint = kw.pop("maxprint", 20)
279
295
  super().__init__(**kw)
280
296
  if self._data is None:
281
297
  self._data = list()
@@ -346,7 +362,7 @@ class AlmostListContent(DataContent):
346
362
 
347
363
  def merge(self, *kargs, **kwargs):
348
364
  """Merge several data contents into one."""
349
- unique = kwargs.get('unique', False)
365
+ unique = kwargs.get("unique", False)
350
366
  self._merge_checkclass(*kargs)
351
367
  for obj in kargs:
352
368
  self.data.extend(obj.data)
@@ -354,12 +370,18 @@ class AlmostListContent(DataContent):
354
370
  # Check if the item are unique, raise an error if not (option unique = True)
355
371
  if unique:
356
372
  arg_elements = collections.Counter(self.data)
357
- repeated_elements = [element for element, count in arg_elements.items() if count > 1]
373
+ repeated_elements = [
374
+ element for element, count in arg_elements.items() if count > 1
375
+ ]
358
376
  if len(repeated_elements) > 0:
359
- logger.exception('Repeated argument are present. It should not. Stop.' +
360
- 'The list of the repeated elements follows: %s',
361
- str(sorted(repeated_elements)))
362
- raise DataContentError('Repeated argument are present. It should not.')
377
+ logger.exception(
378
+ "Repeated argument are present. It should not. Stop."
379
+ + "The list of the repeated elements follows: %s",
380
+ str(sorted(repeated_elements)),
381
+ )
382
+ raise DataContentError(
383
+ "Repeated argument are present. It should not."
384
+ )
363
385
 
364
386
 
365
387
  class TextContent(AlmostListContent):
@@ -369,25 +391,27 @@ class TextContent(AlmostListContent):
369
391
  """
370
392
 
371
393
  def __init__(self, **kw):
372
- kw.setdefault('fmt', None)
394
+ kw.setdefault("fmt", None)
373
395
  super().__init__(**kw)
374
396
 
375
397
  def __str__(self):
376
398
  if len(self) > self.maxprint:
377
- catlist = self[0:3] + ['...'] + self[-3:]
399
+ catlist = self[0:3] + ["..."] + self[-3:]
378
400
  else:
379
401
  catlist = self[:]
380
- return '\n'.join([str(x) for x in catlist])
402
+ return "\n".join([str(x) for x in catlist])
381
403
 
382
404
  def slurp(self, container):
383
405
  with container.preferred_decoding(byte=False):
384
- self._data.extend([x.split() for x in container if not x.startswith('#')])
406
+ self._data.extend(
407
+ [x.split() for x in container if not x.startswith("#")]
408
+ )
385
409
  self._size = container.totalsize
386
410
 
387
411
  def formatted_data(self, item):
388
412
  """Return a formatted string according to optional internal fmt."""
389
413
  if self._fmt is None:
390
- return ' '.join([str(x) for x in item])
414
+ return " ".join([str(x) for x in item])
391
415
  else:
392
416
  return self._fmt.format(*item)
393
417
 
@@ -397,7 +421,7 @@ class TextContent(AlmostListContent):
397
421
  with container.iod_context():
398
422
  with container.preferred_decoding(byte=False):
399
423
  for item in self:
400
- container.write(self.formatted_data(item) + '\n')
424
+ container.write(self.formatted_data(item) + "\n")
401
425
 
402
426
 
403
427
  class DataRaw(AlmostListContent):
@@ -459,7 +483,7 @@ class FormatAdapter(DataContent):
459
483
  def __init__(self, **kw):
460
484
  super().__init__(**kw)
461
485
  if self._data is None and footprints.proxy.dataformats is None:
462
- logger.warning('No collector for data formats')
486
+ logger.warning("No collector for data formats")
463
487
  self._datafmt = None
464
488
 
465
489
  def __enter__(self):
@@ -469,7 +493,7 @@ class FormatAdapter(DataContent):
469
493
  """
470
494
  t = sessions.current()
471
495
  t.env.delta(
472
- LFI_HNDL_SPEC=':1',
496
+ LFI_HNDL_SPEC=":1",
473
497
  DR_HOOK_SILENT=1,
474
498
  DR_HOOK_NOT_MPI=1,
475
499
  OMP_NUM_THREADS=1,
@@ -487,12 +511,15 @@ class FormatAdapter(DataContent):
487
511
  with self:
488
512
  self._data = footprints.proxy.dataformat(
489
513
  filename=container.abspath,
490
- openmode='r',
514
+ openmode="r",
491
515
  fmtdelayedopen=True,
492
516
  format=container.actualfmt.upper(),
493
517
  )
494
518
  # Look for a metadatareader object
495
- if self._data is not None and footprints.proxy.metadatareaders is not None:
519
+ if (
520
+ self._data is not None
521
+ and footprints.proxy.metadatareaders is not None
522
+ ):
496
523
  mreader = footprints.proxy.metadatareader(
497
524
  format=container.actualfmt.upper(),
498
525
  _emptywarning=False,
@@ -511,14 +538,14 @@ class MetaDataReader(footprints.FootprintBase):
511
538
  """
512
539
 
513
540
  _abstract = True
514
- _collector = ('metadatareader',)
541
+ _collector = ("metadatareader",)
515
542
  _footprint = dict(
516
- info = 'Abstract MetaDataReader',
517
- attr = dict(
518
- format = dict(
519
- type = str,
543
+ info="Abstract MetaDataReader",
544
+ attr=dict(
545
+ format=dict(
546
+ type=str,
520
547
  )
521
- )
548
+ ),
522
549
  )
523
550
 
524
551
  def __init__(self, *kargs, **kwargs):
@@ -557,7 +584,7 @@ class MetaDataReader(footprints.FootprintBase):
557
584
 
558
585
  def __repr__(self):
559
586
  if self._datahide is None:
560
- return '{}: Not yet initialised'.format(self.__class__)
587
+ return "{}: Not yet initialised".format(self.__class__)
561
588
  else:
562
589
  return repr(self._data)
563
590
 
@@ -572,7 +599,7 @@ class FormatAdapterAbstractImplementation(footprints.FootprintBase):
572
599
  """
573
600
 
574
601
  _abstract = True
575
- _collector = ('dataformat',)
602
+ _collector = ("dataformat",)
576
603
  _footprint = dict(
577
604
  attr=dict(
578
605
  filename=dict(
@@ -580,8 +607,8 @@ class FormatAdapterAbstractImplementation(footprints.FootprintBase):
580
607
  ),
581
608
  openmode=dict(
582
609
  info="File open-mode.",
583
- values=['r', 'rw'],
584
- default='r',
610
+ values=["r", "rw"],
611
+ default="r",
585
612
  optional=True,
586
613
  ),
587
614
  fmtdelayedopen=dict(
@@ -590,7 +617,6 @@ class FormatAdapterAbstractImplementation(footprints.FootprintBase):
590
617
  default=True,
591
618
  optional=True,
592
619
  ),
593
- format=dict(
594
- ),
620
+ format=dict(),
595
621
  )
596
622
  )
@@ -24,6 +24,7 @@ __all__ = []
24
24
 
25
25
  class Jacket:
26
26
  """The class definition of in and out resources from a given executable."""
27
+
27
28
  def __init__(self, afile=None):
28
29
  if afile:
29
30
  self.config = JacketConfigParser(afile)
@@ -44,25 +45,25 @@ class Executable(Resource):
44
45
 
45
46
  _abstract = True
46
47
  _footprint = dict(
47
- info = 'Miscellaneaous executable resource',
48
- attr = dict(
49
- cycle = dict(
50
- info = "Any kind of cycle name",
51
- optional = True,
52
- default = None,
53
- access = 'rwx',
48
+ info="Miscellaneaous executable resource",
49
+ attr=dict(
50
+ cycle=dict(
51
+ info="Any kind of cycle name",
52
+ optional=True,
53
+ default=None,
54
+ access="rwx",
54
55
  ),
55
- kind = dict(
56
- info = "The resource's kind.",
57
- doc_zorder = 90,
56
+ kind=dict(
57
+ info="The resource's kind.",
58
+ doc_zorder=90,
58
59
  ),
59
- nativefmt = dict(
60
- doc_visibility = footprints.doc.visibility.GURU,
60
+ nativefmt=dict(
61
+ doc_visibility=footprints.doc.visibility.GURU,
61
62
  ),
62
- clscontents = dict(
63
- doc_visibility = footprints.doc.visibility.GURU,
64
- )
65
- )
63
+ clscontents=dict(
64
+ doc_visibility=footprints.doc.visibility.GURU,
65
+ ),
66
+ ),
66
67
  )
67
68
 
68
69
  def stdin_text(self, **opts):
@@ -74,33 +75,33 @@ class Script(Executable):
74
75
  """Basic interpreted executable associated to a specific language."""
75
76
 
76
77
  _footprint = dict(
77
- attr = dict(
78
- rawopts = dict(
79
- info = "Options that will be passed directly to the script",
80
- optional = True,
81
- default = '',
78
+ attr=dict(
79
+ rawopts=dict(
80
+ info="Options that will be passed directly to the script",
81
+ optional=True,
82
+ default="",
83
+ ),
84
+ language=dict(
85
+ info="The programming language",
86
+ values=["perl", "python", "ksh", "bash", "sh", "awk"],
82
87
  ),
83
- language = dict(
84
- info = "The programming language",
85
- values = ['perl', 'python', 'ksh', 'bash', 'sh', 'awk'],
88
+ kind=dict(
89
+ optional=True,
90
+ default="script",
91
+ values=["script"],
86
92
  ),
87
- kind = dict(
88
- optional = True,
89
- default = 'script',
90
- values = ['script'],
91
- )
92
93
  ),
93
- fastkeys = {'language'},
94
+ fastkeys={"language"},
94
95
  )
95
96
 
96
97
  @property
97
98
  def realkind(self):
98
- return 'script'
99
+ return "script"
99
100
 
100
101
  def command_line(self, **opts):
101
102
  """Returns optional attribute :attr:`rawopts`."""
102
103
  if self.rawopts is None:
103
- return ''
104
+ return ""
104
105
  else:
105
106
  return self.rawopts
106
107
 
@@ -109,28 +110,31 @@ class GnuScript(Executable):
109
110
  """Basic interpreted executable with standard command line arguments."""
110
111
 
111
112
  _footprint = dict(
112
- attr = dict(
113
- language = dict(
114
- info = "The programming language",
115
- values = ['perl', 'python', 'ksh', 'bash', 'sh', 'awk'],
113
+ attr=dict(
114
+ language=dict(
115
+ info="The programming language",
116
+ values=["perl", "python", "ksh", "bash", "sh", "awk"],
117
+ ),
118
+ kind=dict(
119
+ default="gnuscript",
120
+ values=["gnuscript", "argscript"],
116
121
  ),
117
- kind = dict(
118
- default = 'gnuscript',
119
- values = ['gnuscript', 'argscript'],
120
- )
121
122
  ),
122
- fastkeys = {'kind', 'language'},
123
+ fastkeys={"kind", "language"},
123
124
  )
124
125
 
125
126
  @property
126
127
  def realkind(self):
127
- return 'script'
128
+ return "script"
128
129
 
129
130
  def command_line(self, **opts):
130
131
  """Returns a blank separated list of options."""
131
- return ' '.join(['--' + k + ' ' + ' '.join([str(x)
132
- for x in mktuple(v)])
133
- for k, v in opts.items()])
132
+ return " ".join(
133
+ [
134
+ "--" + k + " " + " ".join([str(x) for x in mktuple(v)])
135
+ for k, v in opts.items()
136
+ ]
137
+ )
134
138
 
135
139
 
136
140
  class Binary(Executable):
@@ -138,25 +142,25 @@ class Binary(Executable):
138
142
 
139
143
  _abstract = True
140
144
  _footprint = dict(
141
- attr = dict(
142
- static = dict(
143
- info = "Statically linked binary.",
144
- type = bool,
145
- optional = True,
146
- doc_visibility = footprints.doc.visibility.ADVANCED,
145
+ attr=dict(
146
+ static=dict(
147
+ info="Statically linked binary.",
148
+ type=bool,
149
+ optional=True,
150
+ doc_visibility=footprints.doc.visibility.ADVANCED,
151
+ ),
152
+ jacket=dict(
153
+ type=Jacket,
154
+ optional=True,
155
+ default=Jacket(),
156
+ doc_visibility=footprints.doc.visibility.ADVANCED,
147
157
  ),
148
- jacket = dict(
149
- type = Jacket,
150
- optional = True,
151
- default = Jacket(),
152
- doc_visibility = footprints.doc.visibility.ADVANCED,
153
- )
154
158
  )
155
159
  )
156
160
 
157
161
  @property
158
162
  def realkind(self):
159
- return 'binary'
163
+ return "binary"
160
164
 
161
165
  def guess_binary_sources(self, provider): # @UnusedVariable
162
166
  """A list of path that contains source files (for debugging purposes)."""
@@ -167,15 +171,15 @@ class BlackBox(Binary):
167
171
  """Binary resource with explicit command line options."""
168
172
 
169
173
  _footprint = dict(
170
- attr = dict(
171
- binopts = dict(
172
- info = "Options that will be passed directly to the binary",
173
- optional = True,
174
- default = '',
174
+ attr=dict(
175
+ binopts=dict(
176
+ info="Options that will be passed directly to the binary",
177
+ optional=True,
178
+ default="",
175
179
  ),
176
- kind = dict(
177
- values = ['binbox', 'blackbox'],
178
- remap = dict(binbox = 'blackbox'),
180
+ kind=dict(
181
+ values=["binbox", "blackbox"],
182
+ remap=dict(binbox="blackbox"),
179
183
  ),
180
184
  )
181
185
  )
@@ -191,23 +195,16 @@ class NWPModel(Binary):
191
195
  _abstract = True
192
196
  _footprint = [
193
197
  model_deco,
194
- dict(
195
- info = 'NWP Model',
196
- attr = dict(
197
- kind = dict(
198
- values = ['nwpmodel']
199
- )
200
- )
201
- )
198
+ dict(info="NWP Model", attr=dict(kind=dict(values=["nwpmodel"]))),
202
199
  ]
203
200
 
204
201
  @property
205
202
  def realkind(self):
206
- return 'nwpmodel'
203
+ return "nwpmodel"
207
204
 
208
205
  def command_line(self, **opts):
209
206
  """Abstract method."""
210
- return ''
207
+ return ""
211
208
 
212
209
 
213
210
  class OceanographicModel(Binary):
@@ -217,68 +214,62 @@ class OceanographicModel(Binary):
217
214
  _footprint = [
218
215
  model_deco,
219
216
  dict(
220
- info = 'Oceanographic Model',
221
- attr = dict(
222
- kind = dict(
223
- values = ['oceanmodel']
224
- )
225
- )
226
- )
217
+ info="Oceanographic Model",
218
+ attr=dict(kind=dict(values=["oceanmodel"])),
219
+ ),
227
220
  ]
228
221
 
229
222
  @property
230
223
  def realkind(self):
231
- return 'oceanmodel'
224
+ return "oceanmodel"
232
225
 
233
226
  def command_line(self, **opts):
234
227
  """Abstract method."""
235
- return ''
228
+ return ""
236
229
 
237
230
 
238
231
  class SurfaceModel(Binary):
239
-
240
232
  _abstract = True
241
233
  _footprint = [
242
234
  model_deco,
243
235
  dict(
244
- info = 'Model used for the Safran-Surfex-Mepra chain.',
245
- attr = dict(
246
- kind = dict(
247
- values = ['surfacemodel', 'snowmodel'],
248
- remap = dict(autoremap = 'first'),
236
+ info="Model used for the Safran-Surfex-Mepra chain.",
237
+ attr=dict(
238
+ kind=dict(
239
+ values=["surfacemodel", "snowmodel"],
240
+ remap=dict(autoremap="first"),
249
241
  ),
250
242
  ),
251
- )
243
+ ),
252
244
  ]
253
245
 
254
246
  @property
255
247
  def realkind(self):
256
- return 'surfacemodel'
248
+ return "surfacemodel"
257
249
 
258
250
  def command_line(self, **opts):
259
251
  """Abstract method."""
260
- return ''
252
+ return ""
261
253
 
262
254
 
263
255
  class ChemistryModel(Binary):
264
-
265
256
  _abstract = True
266
257
  _footprint = [
267
258
  model_deco,
268
259
  dict(
269
- info = 'Base class for Chemistry models.',
270
- attr = dict(
271
- kind = dict(
272
- values = ['chemistrymodel'],
260
+ info="Base class for Chemistry models.",
261
+ attr=dict(
262
+ kind=dict(
263
+ values=["chemistrymodel"],
273
264
  ),
274
265
  ),
275
- )
266
+ ),
276
267
  ]
277
268
 
278
269
  @property
279
270
  def realkind(self):
280
- return 'chemistrymodel'
271
+ return "chemistrymodel"
281
272
 
282
273
  def command_line(self, **opts):
283
274
  """Abstract method."""
284
- return ''
275
+ return ""