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/layout/contexts.py CHANGED
@@ -18,10 +18,10 @@ __all__ = []
18
18
 
19
19
  logger = loggers.getLogger(__name__)
20
20
 
21
- _RHANDLERS_OBSBOARD = 'Resources-Handlers'
22
- _STORES_OBSBOARD = 'Stores-Activity'
21
+ _RHANDLERS_OBSBOARD = "Resources-Handlers"
22
+ _STORES_OBSBOARD = "Stores-Activity"
23
23
 
24
- _PRESTAGE_REQ_ACTION = 'prestage_req'
24
+ _PRESTAGE_REQ_ACTION = "prestage_req"
25
25
 
26
26
 
27
27
  # Module Interface
@@ -105,14 +105,14 @@ class ContextObserverRecorder(observer.Observer):
105
105
 
106
106
  def updobsitem(self, item, info):
107
107
  if (self._binded_context is not None) and self._binded_context.active:
108
- logger.debug('Recording upd item %s', item)
109
- if info['observerboard'] == _RHANDLERS_OBSBOARD:
108
+ logger.debug("Recording upd item %s", item)
109
+ if info["observerboard"] == _RHANDLERS_OBSBOARD:
110
110
  processed_item = item.as_dict()
111
111
  self._stages_recorder.append((processed_item, info))
112
112
  self._tracker_recorder.update_rh(item, info)
113
- elif info['observerboard'] == _STORES_OBSBOARD:
113
+ elif info["observerboard"] == _STORES_OBSBOARD:
114
114
  self._tracker_recorder.update_store(item, info)
115
- if info['action'] == _PRESTAGE_REQ_ACTION:
115
+ if info["action"] == _PRESTAGE_REQ_ACTION:
116
116
  self._prestaging_recorder.append(info)
117
117
 
118
118
  def replay_in(self, context):
@@ -122,24 +122,33 @@ class ContextObserverRecorder(observer.Observer):
122
122
  """
123
123
  # First the stages of the sequence
124
124
  if self._stages_recorder:
125
- logger.info('The recorder is replaying stages for context <%s>', context.tag)
126
- for (pr_item, info) in self._stages_recorder:
125
+ logger.info(
126
+ "The recorder is replaying stages for context <%s>",
127
+ context.tag,
128
+ )
129
+ for pr_item, info in self._stages_recorder:
127
130
  rh_stack = set()
128
131
  for section in context.sequence.fastsearch(pr_item):
129
132
  if section.rh.as_dict() == pr_item:
130
133
  context.sequence.section_updstage(section, info)
131
134
  rh_stack.add(section.rh)
132
135
  for rh in rh_stack:
133
- rh.external_stage_update(info.get('stage'))
136
+ rh.external_stage_update(info.get("stage"))
134
137
  # Then the localtracker
135
138
  if self._tracker_recorder is not None:
136
- logger.info('The recorder is updating the LocalTracker for context <%s>', context.tag)
139
+ logger.info(
140
+ "The recorder is updating the LocalTracker for context <%s>",
141
+ context.tag,
142
+ )
137
143
  context.localtracker.append(self._tracker_recorder)
138
144
  # Finally the prestaging requests
139
145
  if self._prestaging_recorder:
140
- logger.info('The recorder is replaying prestaging requests for context <%s>', context.tag)
146
+ logger.info(
147
+ "The recorder is replaying prestaging requests for context <%s>",
148
+ context.tag,
149
+ )
141
150
  for info in self._prestaging_recorder:
142
- context.prestaging_hub(** info)
151
+ context.prestaging_hub(**info)
143
152
 
144
153
 
145
154
  class DiffHistory(PrivateHistory):
@@ -147,11 +156,17 @@ class DiffHistory(PrivateHistory):
147
156
 
148
157
  def append_record(self, rc, localcontainer, remotehandler):
149
158
  """Adds a new diff record in the current DiffHistory."""
150
- rcmap = {True: 'PASS', False: 'FAIL'}
151
- containerstr = (str(localcontainer) if localcontainer.is_virtual()
152
- else localcontainer.localpath())
153
- self.append('{:s}: {:s} (Ref: {!s})'.format(rcmap[bool(rc)], containerstr,
154
- remotehandler.provider))
159
+ rcmap = {True: "PASS", False: "FAIL"}
160
+ containerstr = (
161
+ str(localcontainer)
162
+ if localcontainer.is_virtual()
163
+ else localcontainer.localpath()
164
+ )
165
+ self.append(
166
+ "{:s}: {:s} (Ref: {!s})".format(
167
+ rcmap[bool(rc)], containerstr, remotehandler.provider
168
+ )
169
+ )
155
170
 
156
171
  def datastore_inplace_overwrite(self, other):
157
172
  """Used by a DataStore object to refill a DiffHistory."""
@@ -163,23 +178,26 @@ class DiffHistory(PrivateHistory):
163
178
  class Context(getbytag.GetByTag, observer.Observer):
164
179
  """Physical layout of a session or task, etc."""
165
180
 
166
- _tag_default = 'ctx'
181
+ _tag_default = "ctx"
167
182
 
168
- def __init__(self, path=None, topenv=None, sequence=None, localtracker=None):
183
+ def __init__(
184
+ self, path=None, topenv=None, sequence=None, localtracker=None
185
+ ):
169
186
  """Initiate a new execution context."""
170
- logger.debug('Context initialisation %s', self)
187
+ logger.debug("Context initialisation %s", self)
171
188
  if path is None:
172
- logger.critical('Try to define a new context without virtual path')
173
- raise ValueError('No virtual path given to new context.')
189
+ logger.critical("Try to define a new context without virtual path")
190
+ raise ValueError("No virtual path given to new context.")
174
191
  if topenv is None:
175
- logger.critical('Try to define a new context without a topenv.')
176
- raise ValueError('No top environment given to new context.')
177
- self._env = Environment(env=topenv, verbose=topenv.verbose(),
178
- contextlock=self)
179
- self._path = path + '/' + self.tag
192
+ logger.critical("Try to define a new context without a topenv.")
193
+ raise ValueError("No top environment given to new context.")
194
+ self._env = Environment(
195
+ env=topenv, verbose=topenv.verbose(), contextlock=self
196
+ )
197
+ self._path = path + "/" + self.tag
180
198
  self._session = None
181
199
  self._rundir = None
182
- self._stamp = '-'.join(('vortex', 'stamp', self.tag, str(id(self))))
200
+ self._stamp = "-".join(("vortex", "stamp", self.tag, str(id(self))))
183
201
  self._fstore = dict()
184
202
  self._fstamps = set()
185
203
  self._wkdir = None
@@ -196,22 +214,30 @@ class Context(getbytag.GetByTag, observer.Observer):
196
214
  self._localtracker = localtracker
197
215
  else:
198
216
  # Create the localtracker within the Session's datastore
199
- if self.session.datastore.check('context_localtracker', dict(path=self.path)):
200
- self._localtracker = self.session.datastore.get('context_localtracker',
201
- dict(path=self.path))
217
+ if self.session.datastore.check(
218
+ "context_localtracker", dict(path=self.path)
219
+ ):
220
+ self._localtracker = self.session.datastore.get(
221
+ "context_localtracker", dict(path=self.path)
222
+ )
202
223
  else:
203
- self._localtracker = self.session.datastore.insert('context_localtracker',
204
- dict(path=self.path),
205
- dataflow.LocalTracker())
224
+ self._localtracker = self.session.datastore.insert(
225
+ "context_localtracker",
226
+ dict(path=self.path),
227
+ dataflow.LocalTracker(),
228
+ )
206
229
 
207
230
  # Create the localtracker within the Session's datastore
208
- if self.session.datastore.check('context_diffhistory', dict(path=self.path)):
209
- self._dhistory = self.session.datastore.get('context_diffhistory',
210
- dict(path=self.path))
231
+ if self.session.datastore.check(
232
+ "context_diffhistory", dict(path=self.path)
233
+ ):
234
+ self._dhistory = self.session.datastore.get(
235
+ "context_diffhistory", dict(path=self.path)
236
+ )
211
237
  else:
212
- self._dhistory = self.session.datastore.insert('context_diffhistory',
213
- dict(path=self.path),
214
- DiffHistory())
238
+ self._dhistory = self.session.datastore.insert(
239
+ "context_diffhistory", dict(path=self.path), DiffHistory()
240
+ )
215
241
 
216
242
  observer.get(tag=_RHANDLERS_OBSBOARD).register(self)
217
243
  observer.get(tag=_STORES_OBSBOARD).register(self)
@@ -223,7 +249,9 @@ class Context(getbytag.GetByTag, observer.Observer):
223
249
 
224
250
  def _enforce_active(self):
225
251
  if not self.active:
226
- raise RuntimeError("It's not allowed to call this method on an inactive Context.")
252
+ raise RuntimeError(
253
+ "It's not allowed to call this method on an inactive Context."
254
+ )
227
255
 
228
256
  def newobsitem(self, item, info):
229
257
  """
@@ -231,9 +259,14 @@ class Context(getbytag.GetByTag, observer.Observer):
231
259
  Register a new section in void active context with the resource handler ``item``.
232
260
  """
233
261
  if self.active:
234
- logger.debug('Notified %s new item of class %s and id %s', self, item.__class__, id(item))
235
- if self._record and info['observerboard'] == _RHANDLERS_OBSBOARD:
236
- self._sequence.section(rh=item, stage='load')
262
+ logger.debug(
263
+ "Notified %s new item of class %s and id %s",
264
+ self,
265
+ item.__class__,
266
+ id(item),
267
+ )
268
+ if self._record and info["observerboard"] == _RHANDLERS_OBSBOARD:
269
+ self._sequence.section(rh=item, stage="load")
237
270
 
238
271
  def updobsitem(self, item, info):
239
272
  """
@@ -241,21 +274,21 @@ class Context(getbytag.GetByTag, observer.Observer):
241
274
  Track the new stage of the section containing the resource handler ``item``.
242
275
  """
243
276
  if self.active:
244
- logger.debug('Notified %s upd item %s', self, item)
245
- if info['observerboard'] == _RHANDLERS_OBSBOARD:
246
- if 'stage' in info:
277
+ logger.debug("Notified %s upd item %s", self, item)
278
+ if info["observerboard"] == _RHANDLERS_OBSBOARD:
279
+ if "stage" in info:
247
280
  # Update the sequence
248
281
  for section in self._sequence.fastsearch(item):
249
282
  if section.rh is item:
250
283
  self._sequence.section_updstage(section, info)
251
- if ('stage' in info) or ('clear' in info):
284
+ if ("stage" in info) or ("clear" in info):
252
285
  # Update the local tracker
253
286
  self._localtracker.update_rh(item, info)
254
- elif info['observerboard'] == _STORES_OBSBOARD:
287
+ elif info["observerboard"] == _STORES_OBSBOARD:
255
288
  # Update the local tracker
256
289
  self._localtracker.update_store(item, info)
257
- if info['action'] == _PRESTAGE_REQ_ACTION:
258
- self.prestaging_hub.record(** info)
290
+ if info["action"] == _PRESTAGE_REQ_ACTION:
291
+ self.prestaging_hub.record(**info)
259
292
 
260
293
  def get_recorder(self):
261
294
  """Return a :obj:`ContextObserverRecorder` object recording the changes in this Context."""
@@ -275,7 +308,9 @@ class Context(getbytag.GetByTag, observer.Observer):
275
308
  # It's not possible to activate a Context that lies outside the current
276
309
  # session
277
310
  if not self.session.active:
278
- raise RuntimeError("It's not allowed to switch to a Context that belongs to an inactive session")
311
+ raise RuntimeError(
312
+ "It's not allowed to switch to a Context that belongs to an inactive session"
313
+ )
279
314
 
280
315
  def focus_gain_hook(self):
281
316
  super().focus_gain_hook()
@@ -297,7 +332,7 @@ class Context(getbytag.GetByTag, observer.Observer):
297
332
  obj.catch_focus()
298
333
  return obj
299
334
  else:
300
- logger.error('Try to switch to an undefined context: %s', tag)
335
+ logger.error("Try to switch to an undefined context: %s", tag)
301
336
  return None
302
337
 
303
338
  def activate(self):
@@ -314,7 +349,10 @@ class Context(getbytag.GetByTag, observer.Observer):
314
349
  """Return the session bound to the current virtual context path."""
315
350
  if self._session is None:
316
351
  from vortex import sessions
317
- self._session = sessions.get(tag=[x for x in self.path.split('/') if x][0])
352
+
353
+ self._session = sessions.get(
354
+ tag=[x for x in self.path.split("/") if x][0]
355
+ )
318
356
  return self._session
319
357
 
320
358
  def _get_rundir(self):
@@ -324,12 +362,20 @@ class Context(getbytag.GetByTag, observer.Observer):
324
362
  def _set_rundir(self, path):
325
363
  """Set a new rundir."""
326
364
  if self._rundir:
327
- logger.warning('Context <%s> is changing its working directory <%s>', self.tag, self._rundir)
365
+ logger.warning(
366
+ "Context <%s> is changing its working directory <%s>",
367
+ self.tag,
368
+ self._rundir,
369
+ )
328
370
  if self.system.path.isdir(path):
329
371
  self._rundir = path
330
- logger.info('Context <%s> set rundir <%s>', self.tag, self._rundir)
372
+ logger.info("Context <%s> set rundir <%s>", self.tag, self._rundir)
331
373
  else:
332
- logger.error('Try to change context <%s> to invalid path <%s>', self.tag, path)
374
+ logger.error(
375
+ "Try to change context <%s> to invalid path <%s>",
376
+ self.tag,
377
+ path,
378
+ )
333
379
 
334
380
  rundir = property(_get_rundir, _set_rundir)
335
381
 
@@ -337,7 +383,7 @@ class Context(getbytag.GetByTag, observer.Observer):
337
383
  """Change directory to the one associated to that context."""
338
384
  self._enforce_active()
339
385
  if self.rundir is None:
340
- subpath = self.path.replace(self.session.path, '', 1)
386
+ subpath = self.path.replace(self.session.path, "", 1)
341
387
  self._rundir = self.session.rundir + subpath
342
388
  self.system.cd(self.rundir, create=True)
343
389
  self._wkdir = self.rundir
@@ -357,9 +403,11 @@ class Context(getbytag.GetByTag, observer.Observer):
357
403
  see :class:`vortex.tools.prestaging` for more details.
358
404
  """
359
405
  if self._prestaging_hub is None:
360
- self._prestaging_hub = vortex.tools.prestaging.get_hub(tag='contextbound_{:s}'.format(self.tag),
361
- sh=self.system,
362
- email=self.session.glove.email)
406
+ self._prestaging_hub = vortex.tools.prestaging.get_hub(
407
+ tag="contextbound_{:s}".format(self.tag),
408
+ sh=self.system,
409
+ email=self.session.glove.email,
410
+ )
363
411
  return self._prestaging_hub
364
412
 
365
413
  @property
@@ -369,8 +417,9 @@ class Context(getbytag.GetByTag, observer.Observer):
369
417
  see :class:`vortex.tools.delayedactions` for more details.
370
418
  """
371
419
  if self._delayedactions_hub is None:
372
- self._delayedactions_hub = PrivateDelayedActionsHub(sh=self.system,
373
- contextrundir=self.rundir)
420
+ self._delayedactions_hub = PrivateDelayedActionsHub(
421
+ sh=self.system, contextrundir=self.rundir
422
+ )
374
423
  return self._delayedactions_hub
375
424
 
376
425
  @property
@@ -395,8 +444,12 @@ class Context(getbytag.GetByTag, observer.Observer):
395
444
  @property
396
445
  def subcontexts(self):
397
446
  """The current contexts virtually included in the current one."""
398
- rootpath = self.path + '/'
399
- return [x for x in self.__class__.tag_values() if x.path.startswith(rootpath)]
447
+ rootpath = self.path + "/"
448
+ return [
449
+ x
450
+ for x in self.__class__.tag_values()
451
+ if x.path.startswith(rootpath)
452
+ ]
400
453
 
401
454
  def newcontext(self, name, focus=False):
402
455
  """
@@ -405,17 +458,19 @@ class Context(getbytag.GetByTag, observer.Observer):
405
458
  as well as the default ``focus``.
406
459
  """
407
460
  if name in self.__class__.tag_keys():
408
- raise RuntimeError("A context with tag={!s} already exists.".format(name))
461
+ raise RuntimeError(
462
+ "A context with tag={!s} already exists.".format(name)
463
+ )
409
464
  newctx = self.__class__(tag=name, topenv=self.env, path=self.path)
410
465
  if focus:
411
466
  self.__class__.set_focus(newctx)
412
467
  return newctx
413
468
 
414
- def stamp(self, tag='default'):
469
+ def stamp(self, tag="default"):
415
470
  """Return a stamp name that could be used for any generic purpose."""
416
- return self._stamp + '.' + str(tag)
471
+ return self._stamp + "." + str(tag)
417
472
 
418
- def fstrack_stamp(self, tag='default'):
473
+ def fstrack_stamp(self, tag="default"):
419
474
  """Set a stamp to track changes on the filesystem."""
420
475
  self._enforce_active()
421
476
  stamp = self.stamp(tag)
@@ -423,7 +478,7 @@ class Context(getbytag.GetByTag, observer.Observer):
423
478
  self.system.touch(stamp)
424
479
  self._fstore[stamp] = set(self.system.ffind())
425
480
 
426
- def fstrack_check(self, tag='default'):
481
+ def fstrack_check(self, tag="default"):
427
482
  """
428
483
  Return a anonymous dictionary with for the each key, the list of entries
429
484
  in the file system that are concerned since the last associated ``tag`` stamp.
@@ -432,14 +487,18 @@ class Context(getbytag.GetByTag, observer.Observer):
432
487
  self._enforce_active()
433
488
  stamp = self.stamp(tag)
434
489
  if not self.system.path.exists(stamp):
435
- logger.warning('Missing stamp %s', stamp)
490
+ logger.warning("Missing stamp %s", stamp)
436
491
  return None
437
492
  ffinded = set(self.system.ffind())
438
493
  bkuptrace = self.system.trace
439
494
  self.system.trace = False
440
495
  fscheck = Tracker(self._fstore[stamp], ffinded)
441
496
  stroot = self.system.stat(stamp)
442
- fscheck.updated = [f for f in fscheck.unchanged if self.system.stat(f).st_mtime > stroot.st_mtime]
497
+ fscheck.updated = [
498
+ f
499
+ for f in fscheck.unchanged
500
+ if self.system.stat(f).st_mtime > stroot.st_mtime
501
+ ]
443
502
  self.system.trace = bkuptrace
444
503
  return fscheck
445
504
 
@@ -456,35 +515,42 @@ class Context(getbytag.GetByTag, observer.Observer):
456
515
  """Activate automatic recording of section while loading resource handlers."""
457
516
  self._record = True
458
517
 
459
- def clear_promises(self, netloc='promise.cache.fr', scheme='vortex', storeoptions=None):
518
+ def clear_promises(
519
+ self, netloc="promise.cache.fr", scheme="vortex", storeoptions=None
520
+ ):
460
521
  """Remove all promises that have been made in this context.
461
522
 
462
523
  :param netloc: Netloc of the promise's cache store to clean up
463
524
  :param scheme: Scheme of the promise's cache store to clean up
464
525
  :param storeoptions: Option dictionary passed to the store (may be None)
465
526
  """
466
- self.system.header('Clear promises for {}://{} in context {}'.format(scheme, netloc, self.path))
527
+ self.system.header(
528
+ "Clear promises for {}://{} in context {}".format(
529
+ scheme, netloc, self.path
530
+ )
531
+ )
467
532
  skeleton = dict(scheme=scheme, netloc=netloc)
468
- promises = self.localtracker.grep_uri('put', skeleton)
533
+ promises = self.localtracker.grep_uri("put", skeleton)
469
534
  if promises:
470
- logger.info('Some promises are left pending...')
535
+ logger.info("Some promises are left pending...")
471
536
  if storeoptions is None:
472
537
  storeoptions = dict()
473
- store = footprints.proxy.store(scheme=scheme, netloc=netloc,
474
- **storeoptions)
538
+ store = footprints.proxy.store(
539
+ scheme=scheme, netloc=netloc, **storeoptions
540
+ )
475
541
  for promise in [pr.copy() for pr in promises]:
476
- del promise['scheme']
477
- del promise['netloc']
542
+ del promise["scheme"]
543
+ del promise["netloc"]
478
544
  store.delete(promise)
479
545
  else:
480
- logger.info('No promises were left pending.')
546
+ logger.info("No promises were left pending.")
481
547
 
482
548
  def clear_stamps(self):
483
549
  """Remove local context stamps."""
484
550
  if self._fstore:
485
551
  fstamps = list(self._fstamps)
486
552
  self.system.rmall(*fstamps)
487
- logger.info('Removing context stamps %s', fstamps)
553
+ logger.info("Removing context stamps %s", fstamps)
488
554
  self._fstore = dict()
489
555
  self._fstamps = set()
490
556
 
@@ -503,7 +569,7 @@ class Context(getbytag.GetByTag, observer.Observer):
503
569
  try:
504
570
  self.clear()
505
571
  except TypeError:
506
- logger.error('Could not clear local context <%s>', self.tag)
572
+ logger.error("Could not clear local context <%s>", self.tag)
507
573
  # Nullify some variable to help during garbage collection
508
574
  self._prestaging_hub = None
509
575
  if self._delayedactions_hub: