vortex-nwp 2.0.0b1__py3-none-any.whl → 2.0.0b2__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 (139) hide show
  1. vortex/__init__.py +59 -45
  2. vortex/algo/__init__.py +3 -2
  3. vortex/algo/components.py +940 -614
  4. vortex/algo/mpitools.py +802 -497
  5. vortex/algo/serversynctools.py +34 -33
  6. vortex/config.py +19 -22
  7. vortex/data/__init__.py +9 -3
  8. vortex/data/abstractstores.py +593 -655
  9. vortex/data/containers.py +217 -162
  10. vortex/data/contents.py +65 -39
  11. vortex/data/executables.py +93 -102
  12. vortex/data/flow.py +40 -34
  13. vortex/data/geometries.py +228 -132
  14. vortex/data/handlers.py +428 -225
  15. vortex/data/outflow.py +15 -15
  16. vortex/data/providers.py +185 -163
  17. vortex/data/resources.py +48 -42
  18. vortex/data/stores.py +544 -413
  19. vortex/gloves.py +114 -87
  20. vortex/layout/__init__.py +1 -8
  21. vortex/layout/contexts.py +150 -84
  22. vortex/layout/dataflow.py +353 -202
  23. vortex/layout/monitor.py +264 -128
  24. vortex/nwp/__init__.py +5 -2
  25. vortex/nwp/algo/__init__.py +14 -5
  26. vortex/nwp/algo/assim.py +205 -151
  27. vortex/nwp/algo/clim.py +683 -517
  28. vortex/nwp/algo/coupling.py +447 -225
  29. vortex/nwp/algo/eda.py +437 -229
  30. vortex/nwp/algo/eps.py +403 -231
  31. vortex/nwp/algo/forecasts.py +420 -271
  32. vortex/nwp/algo/fpserver.py +683 -307
  33. vortex/nwp/algo/ifsnaming.py +205 -145
  34. vortex/nwp/algo/ifsroot.py +210 -122
  35. vortex/nwp/algo/monitoring.py +132 -76
  36. vortex/nwp/algo/mpitools.py +321 -191
  37. vortex/nwp/algo/odbtools.py +617 -353
  38. vortex/nwp/algo/oopsroot.py +449 -273
  39. vortex/nwp/algo/oopstests.py +90 -56
  40. vortex/nwp/algo/request.py +287 -206
  41. vortex/nwp/algo/stdpost.py +878 -522
  42. vortex/nwp/data/__init__.py +22 -4
  43. vortex/nwp/data/assim.py +125 -137
  44. vortex/nwp/data/boundaries.py +121 -68
  45. vortex/nwp/data/climfiles.py +193 -211
  46. vortex/nwp/data/configfiles.py +73 -69
  47. vortex/nwp/data/consts.py +426 -401
  48. vortex/nwp/data/ctpini.py +59 -43
  49. vortex/nwp/data/diagnostics.py +94 -66
  50. vortex/nwp/data/eda.py +50 -51
  51. vortex/nwp/data/eps.py +195 -146
  52. vortex/nwp/data/executables.py +440 -434
  53. vortex/nwp/data/fields.py +63 -48
  54. vortex/nwp/data/gridfiles.py +183 -111
  55. vortex/nwp/data/logs.py +250 -217
  56. vortex/nwp/data/modelstates.py +180 -151
  57. vortex/nwp/data/monitoring.py +72 -99
  58. vortex/nwp/data/namelists.py +254 -202
  59. vortex/nwp/data/obs.py +400 -308
  60. vortex/nwp/data/oopsexec.py +22 -20
  61. vortex/nwp/data/providers.py +90 -65
  62. vortex/nwp/data/query.py +71 -82
  63. vortex/nwp/data/stores.py +49 -36
  64. vortex/nwp/data/surfex.py +136 -137
  65. vortex/nwp/syntax/__init__.py +1 -1
  66. vortex/nwp/syntax/stdattrs.py +173 -111
  67. vortex/nwp/tools/__init__.py +2 -2
  68. vortex/nwp/tools/addons.py +22 -17
  69. vortex/nwp/tools/agt.py +24 -12
  70. vortex/nwp/tools/bdap.py +16 -5
  71. vortex/nwp/tools/bdcp.py +4 -1
  72. vortex/nwp/tools/bdm.py +3 -0
  73. vortex/nwp/tools/bdmp.py +14 -9
  74. vortex/nwp/tools/conftools.py +728 -378
  75. vortex/nwp/tools/drhook.py +12 -8
  76. vortex/nwp/tools/grib.py +65 -39
  77. vortex/nwp/tools/gribdiff.py +22 -17
  78. vortex/nwp/tools/ifstools.py +82 -42
  79. vortex/nwp/tools/igastuff.py +167 -143
  80. vortex/nwp/tools/mars.py +14 -2
  81. vortex/nwp/tools/odb.py +234 -125
  82. vortex/nwp/tools/partitioning.py +61 -37
  83. vortex/nwp/tools/satrad.py +27 -12
  84. vortex/nwp/util/async.py +83 -55
  85. vortex/nwp/util/beacon.py +10 -10
  86. vortex/nwp/util/diffpygram.py +174 -86
  87. vortex/nwp/util/ens.py +144 -63
  88. vortex/nwp/util/hooks.py +30 -19
  89. vortex/nwp/util/taskdeco.py +28 -24
  90. vortex/nwp/util/usepygram.py +278 -172
  91. vortex/nwp/util/usetnt.py +31 -17
  92. vortex/sessions.py +72 -39
  93. vortex/syntax/__init__.py +1 -1
  94. vortex/syntax/stdattrs.py +410 -171
  95. vortex/syntax/stddeco.py +31 -22
  96. vortex/toolbox.py +327 -192
  97. vortex/tools/__init__.py +11 -2
  98. vortex/tools/actions.py +125 -59
  99. vortex/tools/addons.py +111 -92
  100. vortex/tools/arm.py +42 -22
  101. vortex/tools/compression.py +72 -69
  102. vortex/tools/date.py +11 -4
  103. vortex/tools/delayedactions.py +242 -132
  104. vortex/tools/env.py +75 -47
  105. vortex/tools/folder.py +342 -171
  106. vortex/tools/grib.py +311 -149
  107. vortex/tools/lfi.py +423 -216
  108. vortex/tools/listings.py +109 -40
  109. vortex/tools/names.py +218 -156
  110. vortex/tools/net.py +632 -298
  111. vortex/tools/parallelism.py +93 -61
  112. vortex/tools/prestaging.py +55 -31
  113. vortex/tools/schedulers.py +172 -105
  114. vortex/tools/services.py +402 -333
  115. vortex/tools/storage.py +293 -358
  116. vortex/tools/surfex.py +24 -24
  117. vortex/tools/systems.py +1211 -631
  118. vortex/tools/targets.py +156 -100
  119. vortex/util/__init__.py +1 -1
  120. vortex/util/config.py +377 -327
  121. vortex/util/empty.py +2 -2
  122. vortex/util/helpers.py +56 -24
  123. vortex/util/introspection.py +18 -12
  124. vortex/util/iosponge.py +8 -4
  125. vortex/util/roles.py +4 -6
  126. vortex/util/storefunctions.py +39 -13
  127. vortex/util/structs.py +3 -3
  128. vortex/util/worker.py +29 -17
  129. vortex_nwp-2.0.0b2.dist-info/METADATA +66 -0
  130. vortex_nwp-2.0.0b2.dist-info/RECORD +142 -0
  131. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/WHEEL +1 -1
  132. vortex/layout/appconf.py +0 -109
  133. vortex/layout/jobs.py +0 -1276
  134. vortex/layout/nodes.py +0 -1424
  135. vortex/layout/subjobs.py +0 -464
  136. vortex_nwp-2.0.0b1.dist-info/METADATA +0 -50
  137. vortex_nwp-2.0.0b1.dist-info/RECORD +0 -146
  138. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/LICENSE +0 -0
  139. {vortex_nwp-2.0.0b1.dist-info → vortex_nwp-2.0.0b2.dist-info}/top_level.txt +0 -0
vortex/data/containers.py CHANGED
@@ -24,7 +24,7 @@ from vortex import sessions
24
24
  from vortex.syntax.stdattrs import a_actualfmt
25
25
 
26
26
  #: Automatic export
27
- __all__ = ['Container']
27
+ __all__ = ["Container"]
28
28
 
29
29
  logger = loggers.getLogger(__name__)
30
30
 
@@ -34,6 +34,7 @@ CONTAINER_MAXREADSIZE = 1048576 * 200
34
34
 
35
35
  class DataSizeTooBig(IOError):
36
36
  """Exception raised when totasize is over the container MaxReadSize limit."""
37
+
37
38
  pass
38
39
 
39
40
 
@@ -41,44 +42,58 @@ class Container(footprints.FootprintBase):
41
42
  """Abstract class for any Container."""
42
43
 
43
44
  _abstract = True
44
- _collector = ('container',)
45
+ _collector = ("container",)
45
46
  _footprint = dict(
46
- info = 'Abstract Container',
47
- attr = dict(
48
- actualfmt = a_actualfmt,
49
- maxreadsize = dict(
50
- info = "The maximum amount of data that can be read (in bytes).",
51
- type = int,
52
- optional = True,
53
- default = CONTAINER_MAXREADSIZE,
54
- doc_visibility = footprints.doc.visibility.GURU,
47
+ info="Abstract Container",
48
+ attr=dict(
49
+ actualfmt=a_actualfmt,
50
+ maxreadsize=dict(
51
+ info="The maximum amount of data that can be read (in bytes).",
52
+ type=int,
53
+ optional=True,
54
+ default=CONTAINER_MAXREADSIZE,
55
+ doc_visibility=footprints.doc.visibility.GURU,
55
56
  ),
56
- mode = dict(
57
- info = "The file mode used to open the container.",
58
- optional = True,
59
- values = ['a', 'a+', 'ab', 'a+b', 'ab+',
60
- 'r', 'r+', 'rb', 'rb+', 'r+b',
61
- 'w', 'w+', 'wb', 'w+b', 'wb+'],
62
- remap = {'a+b': 'ab+', 'r+b': 'rb+', 'w+b': 'wb+'},
63
- doc_visibility = footprints.doc.visibility.ADVANCED,
57
+ mode=dict(
58
+ info="The file mode used to open the container.",
59
+ optional=True,
60
+ values=[
61
+ "a",
62
+ "a+",
63
+ "ab",
64
+ "a+b",
65
+ "ab+",
66
+ "r",
67
+ "r+",
68
+ "rb",
69
+ "rb+",
70
+ "r+b",
71
+ "w",
72
+ "w+",
73
+ "wb",
74
+ "w+b",
75
+ "wb+",
76
+ ],
77
+ remap={"a+b": "ab+", "r+b": "rb+", "w+b": "wb+"},
78
+ doc_visibility=footprints.doc.visibility.ADVANCED,
64
79
  ),
65
- encoding = dict(
66
- info = "When opened in text mode, the encoding that will be used.",
67
- optional = True,
68
- doc_visibility = footprints.doc.visibility.ADVANCED,
80
+ encoding=dict(
81
+ info="When opened in text mode, the encoding that will be used.",
82
+ optional=True,
83
+ doc_visibility=footprints.doc.visibility.ADVANCED,
69
84
  ),
70
- )
85
+ ),
71
86
  )
72
87
 
73
- _DEFAULTMODE = 'rb'
88
+ _DEFAULTMODE = "rb"
74
89
 
75
90
  @property
76
91
  def realkind(self):
77
- return 'container'
92
+ return "container"
78
93
 
79
94
  def __init__(self, *args, **kw):
80
95
  """Preset to None or False hidden attributes ``iod``, ``iomode`` and ``filled``."""
81
- logger.debug('Container %s init', self.__class__)
96
+ logger.debug("Container %s init", self.__class__)
82
97
  super().__init__(*args, **kw)
83
98
  self._iod = None
84
99
  self._iomode = None
@@ -93,24 +108,28 @@ class Container(footprints.FootprintBase):
93
108
  def __getstate__(self):
94
109
  d = super().__getstate__()
95
110
  # Start from a clean slate regarding IO descriptors
96
- d['_iod'] = None
97
- d['_acmode'] = None
98
- d['_acencoding'] = None
111
+ d["_iod"] = None
112
+ d["_acmode"] = None
113
+ d["_acencoding"] = None
99
114
  return d
100
115
 
101
116
  @secure_getattr
102
117
  def __getattr__(self, key):
103
118
  """Gateway to undefined method or attributes if present in internal io descriptor."""
104
119
  # It avoids to call self.iodesc() when footprint_export is called...
105
- if (key.startswith('footprint_export') or
106
- key in ('export_dict', 'as_dump', 'as_dict', '_iod')):
107
- raise AttributeError('Could not get an io descriptor')
120
+ if key.startswith("footprint_export") or key in (
121
+ "export_dict",
122
+ "as_dump",
123
+ "as_dict",
124
+ "_iod",
125
+ ):
126
+ raise AttributeError("Could not get an io descriptor")
108
127
  # Normal processing
109
128
  iod = self.iodesc()
110
129
  if iod:
111
130
  return getattr(iod, key)
112
131
  else:
113
- raise AttributeError('Could not get an io descriptor')
132
+ raise AttributeError("Could not get an io descriptor")
114
133
 
115
134
  @contextlib.contextmanager
116
135
  def iod_context(self):
@@ -132,8 +151,12 @@ class Container(footprints.FootprintBase):
132
151
  def iodesc(self, mode=None, encoding=None):
133
152
  """Returns the file object descriptor."""
134
153
  mode1, encoding1 = self._get_mode(mode, encoding)
135
- if not (self._iod and not self._iod.closed and
136
- mode1 == self._acmode and encoding1 == self._acencoding):
154
+ if not (
155
+ self._iod
156
+ and not self._iod.closed
157
+ and mode1 == self._acmode
158
+ and encoding1 == self._acencoding
159
+ ):
137
160
  if self._iod and not self._iod.closed:
138
161
  self.close()
139
162
  mode1, encoding1 = self._get_mode(mode, encoding)
@@ -193,7 +216,9 @@ class Container(footprints.FootprintBase):
193
216
  if self.totalsize < self.maxreadsize or (0 < n < self.maxreadsize):
194
217
  return iod.read(n)
195
218
  else:
196
- raise DataSizeTooBig('Input is more than {:d} bytes.'.format(self.maxreadsize))
219
+ raise DataSizeTooBig(
220
+ "Input is more than {:d} bytes.".format(self.maxreadsize)
221
+ )
197
222
 
198
223
  def dataread(self, mode=None, encoding=None):
199
224
  """
@@ -218,7 +243,11 @@ class Container(footprints.FootprintBase):
218
243
  lines.append(iod.readline())
219
244
  lsize += len(lines[-1])
220
245
  if lsize > self.maxreadsize:
221
- raise DataSizeTooBig('Input is more than {:d} bytes.'.format(self.maxreadsize))
246
+ raise DataSizeTooBig(
247
+ "Input is more than {:d} bytes.".format(
248
+ self.maxreadsize
249
+ )
250
+ )
222
251
  nread += 1
223
252
  return lines
224
253
 
@@ -230,7 +259,9 @@ class Container(footprints.FootprintBase):
230
259
  self.rewind()
231
260
  return iod.readlines()
232
261
  else:
233
- raise DataSizeTooBig('Input is more than {:d} bytes.'.format(self.maxreadsize))
262
+ raise DataSizeTooBig(
263
+ "Input is more than {:d} bytes.".format(self.maxreadsize)
264
+ )
234
265
 
235
266
  def __iter__(self):
236
267
  with self.preferred_decoding(byte=False):
@@ -267,22 +298,22 @@ class Container(footprints.FootprintBase):
267
298
  @staticmethod
268
299
  def _set_amode(actualmode):
269
300
  """Upgrade the ``actualmode`` to a append-compatible mode."""
270
- am = re.sub('[rw]', 'a', actualmode)
271
- am = am.replace('+', '')
272
- return am + '+'
301
+ am = re.sub("[rw]", "a", actualmode)
302
+ am = am.replace("+", "")
303
+ return am + "+"
273
304
 
274
305
  @staticmethod
275
306
  def _set_wmode(actualmode):
276
307
  """Upgrade the ``actualmode`` to a write-compatible mode."""
277
- wm = re.sub('r', 'w', actualmode)
278
- wm = wm.replace('+', '')
279
- return wm + '+'
308
+ wm = re.sub("r", "w", actualmode)
309
+ wm = wm.replace("+", "")
310
+ return wm + "+"
280
311
 
281
312
  @staticmethod
282
313
  def _set_bmode(actualmode):
283
314
  """Upgrade the ``actualmode`` to byte mode."""
284
- if 'b' not in actualmode:
285
- wm = re.sub(r'([arw])', r'\1b', actualmode)
315
+ if "b" not in actualmode:
316
+ wm = re.sub(r"([arw])", r"\1b", actualmode)
286
317
  return wm
287
318
  else:
288
319
  return actualmode
@@ -290,7 +321,7 @@ class Container(footprints.FootprintBase):
290
321
  @staticmethod
291
322
  def _set_tmode(actualmode):
292
323
  """Upgrade the ``actualmode`` to a text-mode."""
293
- wm = actualmode.replace('b', '')
324
+ wm = actualmode.replace("b", "")
294
325
  return wm
295
326
 
296
327
  @contextlib.contextmanager
@@ -366,7 +397,7 @@ class Container(footprints.FootprintBase):
366
397
  pos = iod.tell()
367
398
  iod.seek(0)
368
399
  for xchunk in iod:
369
- print(xchunk.rstrip('\n'))
400
+ print(xchunk.rstrip("\n"))
370
401
  iod.seek(pos)
371
402
 
372
403
  def is_virtual(self):
@@ -378,21 +409,20 @@ class Container(footprints.FootprintBase):
378
409
 
379
410
 
380
411
  class Virtual(Container):
381
-
382
412
  _abstract = True
383
413
  _footprint = dict(
384
- info = 'Abstract Virtual Container',
385
- attr = dict(
386
- prefix = dict(
387
- info = "Prefix used if a temporary file needs to be written.",
388
- optional = True,
389
- default = 'vortex.tmp.',
390
- doc_visibility = footprints.doc.visibility.GURU,
414
+ info="Abstract Virtual Container",
415
+ attr=dict(
416
+ prefix=dict(
417
+ info="Prefix used if a temporary file needs to be written.",
418
+ optional=True,
419
+ default="vortex.tmp.",
420
+ doc_visibility=footprints.doc.visibility.GURU,
391
421
  )
392
- )
422
+ ),
393
423
  )
394
424
 
395
- _DEFAULTMODE = 'wb+'
425
+ _DEFAULTMODE = "wb+"
396
426
 
397
427
  def is_virtual(self):
398
428
  """
@@ -411,32 +441,33 @@ class Virtual(Container):
411
441
 
412
442
 
413
443
  class InCore(Virtual):
414
-
415
444
  _footprint = dict(
416
- info = 'Incore container (data are kept in memory as long as possible).',
417
- attr = dict(
418
- incore = dict(
419
- info = 'Activate the incore container.',
420
- type = bool,
421
- values = [True, ],
422
- alias = ('mem', 'memory'),
423
- doc_zorder = 90,
445
+ info="Incore container (data are kept in memory as long as possible).",
446
+ attr=dict(
447
+ incore=dict(
448
+ info="Activate the incore container.",
449
+ type=bool,
450
+ values=[
451
+ True,
452
+ ],
453
+ alias=("mem", "memory"),
454
+ doc_zorder=90,
424
455
  ),
425
- incorelimit = dict(
426
- info = 'If this limit (in bytes) is exceeded, data are flushed to file.',
427
- type = int,
428
- optional = True,
429
- default = CONTAINER_INCORELIMIT,
430
- alias = ('memlimit', 'spooledlimit', 'maxsize'),
431
- doc_visibility = footprints.doc.visibility.ADVANCED,
456
+ incorelimit=dict(
457
+ info="If this limit (in bytes) is exceeded, data are flushed to file.",
458
+ type=int,
459
+ optional=True,
460
+ default=CONTAINER_INCORELIMIT,
461
+ alias=("memlimit", "spooledlimit", "maxsize"),
462
+ doc_visibility=footprints.doc.visibility.ADVANCED,
432
463
  ),
433
464
  ),
434
- fastkeys = {'incore'}
465
+ fastkeys={"incore"},
435
466
  )
436
467
 
437
468
  def __init__(self, *args, **kw):
438
- logger.debug('InCore container init %s', self.__class__)
439
- kw.setdefault('incore', True)
469
+ logger.debug("InCore container init %s", self.__class__)
470
+ kw.setdefault("incore", True)
440
471
  super().__init__(*args, **kw)
441
472
  self._tempo = False
442
473
 
@@ -446,14 +477,16 @@ class InCore(Virtual):
446
477
  if self._tempo or self._iod._rolled:
447
478
  actualfile = self._iod.name
448
479
  else:
449
- actualfile = 'MemoryResident'
480
+ actualfile = "MemoryResident"
450
481
  else:
451
- actualfile = 'NotSpooled'
482
+ actualfile = "NotSpooled"
452
483
  return actualfile
453
484
 
454
485
  def _str_more(self):
455
486
  """Additional information to print representation."""
456
- return 'incorelimit={:d} tmpfile="{:s}"'.format(self.incorelimit, self.actualpath())
487
+ return 'incorelimit={:d} tmpfile="{:s}"'.format(
488
+ self.incorelimit, self.actualpath()
489
+ )
457
490
 
458
491
  def _new_iodesc(self, mode, encoding):
459
492
  """Returns an active (opened) spooled file descriptor in binary read mode by default."""
@@ -464,7 +497,7 @@ class InCore(Virtual):
464
497
  prefix=self.prefix,
465
498
  dir=os.getcwd(),
466
499
  delete=True,
467
- encoding=encoding
500
+ encoding=encoding,
468
501
  )
469
502
  else:
470
503
  iod = tempfile.SpooledTemporaryFile(
@@ -472,7 +505,7 @@ class InCore(Virtual):
472
505
  prefix=self.prefix,
473
506
  dir=os.getcwd(),
474
507
  max_size=self.incorelimit,
475
- encoding=encoding
508
+ encoding=encoding,
476
509
  )
477
510
  return iod
478
511
 
@@ -491,7 +524,7 @@ class InCore(Virtual):
491
524
  prefix=self.prefix,
492
525
  dir=os.getcwd(),
493
526
  delete=True,
494
- encoding=self._acencoding
527
+ encoding=self._acencoding,
495
528
  )
496
529
  for data in iomem:
497
530
  self._iod.write(data)
@@ -509,7 +542,7 @@ class InCore(Virtual):
509
542
  prefix=self.prefix,
510
543
  dir=os.getcwd(),
511
544
  max_size=self.incorelimit,
512
- encoding=self._acencoding
545
+ encoding=self._acencoding,
513
546
  )
514
547
  for data in iotmp:
515
548
  self._iod.write(data)
@@ -525,36 +558,39 @@ class InCore(Virtual):
525
558
  try:
526
559
  return iod.name
527
560
  except Exception:
528
- logger.warning('Could not get local temporary rolled file pathname %s', self)
561
+ logger.warning(
562
+ "Could not get local temporary rolled file pathname %s", self
563
+ )
529
564
  raise
530
565
 
531
566
 
532
567
  class MayFly(Virtual):
533
-
534
568
  _footprint = dict(
535
- info = 'MayFly container (a temporary file is created only when needed).',
536
- attr = dict(
537
- mayfly = dict(
538
- info = 'Activate the mayfly container.',
539
- type = bool,
540
- values = [True, ],
541
- alias = ('tempo',),
542
- doc_zorder = 90,
569
+ info="MayFly container (a temporary file is created only when needed).",
570
+ attr=dict(
571
+ mayfly=dict(
572
+ info="Activate the mayfly container.",
573
+ type=bool,
574
+ values=[
575
+ True,
576
+ ],
577
+ alias=("tempo",),
578
+ doc_zorder=90,
543
579
  ),
544
- delete = dict(
545
- info = 'Delete the file when the container object is destroyed.',
546
- type = bool,
547
- optional = True,
548
- default = True,
549
- doc_visibility = footprints.doc.visibility.ADVANCED,
580
+ delete=dict(
581
+ info="Delete the file when the container object is destroyed.",
582
+ type=bool,
583
+ optional=True,
584
+ default=True,
585
+ doc_visibility=footprints.doc.visibility.ADVANCED,
550
586
  ),
551
587
  ),
552
- fastkeys = {'mayfly'}
588
+ fastkeys={"mayfly"},
553
589
  )
554
590
 
555
591
  def __init__(self, *args, **kw):
556
- logger.debug('MayFly container init %s', self.__class__)
557
- kw.setdefault('mayfly', True)
592
+ logger.debug("MayFly container init %s", self.__class__)
593
+ kw.setdefault("mayfly", True)
558
594
  super().__init__(*args, **kw)
559
595
 
560
596
  def actualpath(self):
@@ -562,12 +598,14 @@ class MayFly(Virtual):
562
598
  if self._iod:
563
599
  return self._iod.name
564
600
  else:
565
- return 'NotDefined'
601
+ return "NotDefined"
566
602
 
567
603
  def _str_more(self):
568
604
  """Additional information to internal representation."""
569
605
 
570
- return 'delete={!s} tmpfile="{:s}"'.format(self.delete, self.actualpath())
606
+ return 'delete={!s} tmpfile="{:s}"'.format(
607
+ self.delete, self.actualpath()
608
+ )
571
609
 
572
610
  def _new_iodesc(self, mode, encoding):
573
611
  """Returns an active (opened) temporary file descriptor in binary read mode by default."""
@@ -577,7 +615,7 @@ class MayFly(Virtual):
577
615
  prefix=self.prefix,
578
616
  dir=os.getcwd(),
579
617
  delete=self.delete,
580
- encoding=encoding
618
+ encoding=encoding,
581
619
  )
582
620
 
583
621
  def localpath(self):
@@ -589,7 +627,9 @@ class MayFly(Virtual):
589
627
  try:
590
628
  return iod.name
591
629
  except Exception:
592
- logger.warning('Could not get local temporary file pathname %s', self)
630
+ logger.warning(
631
+ "Could not get local temporary file pathname %s", self
632
+ )
593
633
  raise
594
634
 
595
635
 
@@ -597,23 +637,24 @@ class _SingleFileStyle(Container):
597
637
  """
598
638
  Template for any file container. Data is stored as a file object.
599
639
  """
600
- _abstract = True,
640
+
641
+ _abstract = (True,)
601
642
  _footprint = dict(
602
- info = 'File container',
603
- attr = dict(
604
- cwdtied = dict(
605
- info = "If *filename* is a relative path, replace it by its absolute path.",
606
- type = bool,
607
- optional = True,
608
- default = False,
609
- doc_visibility = footprints.doc.visibility.ADVANCED,
643
+ info="File container",
644
+ attr=dict(
645
+ cwdtied=dict(
646
+ info="If *filename* is a relative path, replace it by its absolute path.",
647
+ type=bool,
648
+ optional=True,
649
+ default=False,
650
+ doc_visibility=footprints.doc.visibility.ADVANCED,
610
651
  ),
611
- )
652
+ ),
612
653
  )
613
654
 
614
655
  def __init__(self, *args, **kw):
615
656
  """Business as usual... but define actualpath according to ``cwdtied`` attribute."""
616
- logger.debug('_SingleFileStyle container init %s', self.__class__)
657
+ logger.debug("_SingleFileStyle container init %s", self.__class__)
617
658
  super().__init__(*args, **kw)
618
659
  if self.cwdtied:
619
660
  self._actualpath = os.path.realpath(self.filename)
@@ -646,7 +687,7 @@ class _SingleFileStyle(Container):
646
687
 
647
688
  def _str_more(self):
648
689
  """Additional information to print representation."""
649
- return 'path=\'{:s}\''.format(self.actualpath())
690
+ return "path='{:s}'".format(self.actualpath())
650
691
 
651
692
  def localpath(self):
652
693
  """Returns the actual name of the file object."""
@@ -655,7 +696,11 @@ class _SingleFileStyle(Container):
655
696
  def _new_iodesc(self, mode, encoding):
656
697
  """Returns an active (opened) file descriptor in binary read mode by default."""
657
698
  self.close()
658
- currentpath = self._actualpath if self.cwdtied else os.path.realpath(self.filename)
699
+ currentpath = (
700
+ self._actualpath
701
+ if self.cwdtied
702
+ else os.path.realpath(self.filename)
703
+ )
659
704
  return open(currentpath, mode, encoding=encoding)
660
705
 
661
706
  def iotarget(self):
@@ -667,7 +712,7 @@ class _SingleFileStyle(Container):
667
712
  rst = super().clear(*kargs, **kw)
668
713
  # Physically delete the file if it exists
669
714
  if self.exists():
670
- sh = kw.pop('system', sessions.system())
715
+ sh = kw.pop("system", sessions.system())
671
716
  rst = rst and sh.remove(self.localpath(), fmt=self.actualfmt)
672
717
  return rst
673
718
 
@@ -680,15 +725,16 @@ class SingleFile(_SingleFileStyle):
680
725
  """
681
726
  Default file container. Data is stored as a file object.
682
727
  """
728
+
683
729
  _footprint = dict(
684
- attr = dict(
685
- filename = dict(
686
- info = 'Path to the file where data are stored.',
687
- alias = ('filepath', 'local'),
688
- doc_zorder = 50,
730
+ attr=dict(
731
+ filename=dict(
732
+ info="Path to the file where data are stored.",
733
+ alias=("filepath", "local"),
734
+ doc_zorder=50,
689
735
  ),
690
736
  ),
691
- fastkeys = {'filename'}
737
+ fastkeys={"filename"},
692
738
  )
693
739
 
694
740
 
@@ -697,27 +743,30 @@ class UnnamedSingleFile(_SingleFileStyle):
697
743
 
698
744
  The filename is chosen arbitrarily when the object is created.
699
745
  """
746
+
700
747
  _footprint = dict(
701
- info = 'File container (a temporary filename is chosen at runtime)',
702
- attr = dict(
703
- shouldfly = dict(
704
- info = 'Activate the UnnamedSingleFile container',
705
- type = bool,
706
- values = [True, ],
707
- doc_zorder = 90,
748
+ info="File container (a temporary filename is chosen at runtime)",
749
+ attr=dict(
750
+ shouldfly=dict(
751
+ info="Activate the UnnamedSingleFile container",
752
+ type=bool,
753
+ values=[
754
+ True,
755
+ ],
756
+ doc_zorder=90,
708
757
  ),
709
- cwdtied = dict(
710
- default = True,
711
- doc_visibility = footprints.doc.visibility.GURU,
758
+ cwdtied=dict(
759
+ default=True,
760
+ doc_visibility=footprints.doc.visibility.GURU,
712
761
  ),
713
762
  ),
714
- fastkeys = {'shouldfly'}
763
+ fastkeys={"shouldfly"},
715
764
  )
716
765
 
717
766
  def __init__(self, *args, **kw):
718
- logger.debug('UnnamedSingleFile container init %s', self.__class__)
767
+ logger.debug("UnnamedSingleFile container init %s", self.__class__)
719
768
  self._auto_filename = None
720
- kw.setdefault('shouldfly', True)
769
+ kw.setdefault("shouldfly", True)
721
770
  super().__init__(*args, **kw)
722
771
 
723
772
  @property
@@ -730,51 +779,57 @@ class UnnamedSingleFile(_SingleFileStyle):
730
779
 
731
780
  def __getstate__(self):
732
781
  st = super().__getstate__()
733
- st['_auto_filename'] = None
782
+ st["_auto_filename"] = None
734
783
  return st
735
784
 
736
785
  def exists(self, empty=False):
737
786
  """Check the existence of the actual file."""
738
- return (os.path.exists(self.localpath()) and
739
- (empty or os.path.getsize(self.localpath())))
787
+ return os.path.exists(self.localpath()) and (
788
+ empty or os.path.getsize(self.localpath())
789
+ )
740
790
 
741
791
 
742
792
  class Uuid4UnamedSingleFile(_SingleFileStyle):
743
793
  """Unamed file container created in a temporary diectory."""
744
794
 
745
795
  _footprint = dict(
746
- info = 'File container (a temporary filename is chosen at runtime)',
747
- attr = dict(
748
- uuid4fly = dict(
749
- info = 'Activate the Uuid4UnnamedSingleFile container',
750
- type = bool,
751
- values = [True, ],
752
- doc_zorder = 90,
796
+ info="File container (a temporary filename is chosen at runtime)",
797
+ attr=dict(
798
+ uuid4fly=dict(
799
+ info="Activate the Uuid4UnnamedSingleFile container",
800
+ type=bool,
801
+ values=[
802
+ True,
803
+ ],
804
+ doc_zorder=90,
753
805
  ),
754
- uuid4flydir = dict(
755
- info = 'The subdirectory where to create the unamed file',
756
- optional = True,
757
- default = '.',
758
- doc_zorder = 90,
806
+ uuid4flydir=dict(
807
+ info="The subdirectory where to create the unamed file",
808
+ optional=True,
809
+ default=".",
810
+ doc_zorder=90,
759
811
  ),
760
812
  ),
761
- fastkeys = {'uuid4fly'}
813
+ fastkeys={"uuid4fly"},
762
814
  )
763
815
 
764
816
  def __init__(self, *args, **kw):
765
- logger.debug('UuidBasedUnamedSingleFile container init %s', self.__class__)
817
+ logger.debug(
818
+ "UuidBasedUnamedSingleFile container init %s", self.__class__
819
+ )
766
820
  self._auto_filename = None
767
- kw.setdefault('uuid4fly', True)
821
+ kw.setdefault("uuid4fly", True)
768
822
  super().__init__(*args, **kw)
769
823
 
770
824
  @property
771
825
  def filename(self):
772
826
  if self._auto_filename is None:
773
- self._auto_filename = os.path.join(self.uuid4flydir,
774
- uuid.uuid4().hex)
827
+ self._auto_filename = os.path.join(
828
+ self.uuid4flydir, uuid.uuid4().hex
829
+ )
775
830
  return self._auto_filename
776
831
 
777
832
  def __getstate__(self):
778
833
  st = super().__getstate__()
779
- st['_auto_filename'] = None
834
+ st["_auto_filename"] = None
780
835
  return st