@@ -74,7 +74,7 @@ class Tokens(dict):
74
74
<id: w//c>
75
75
>>> Tokens(workflow='w', cycle='c')['job']
76
76
77
- # Make a copy (note Tokens are mutable ):
77
+ # Make a copy (note Tokens are immutable ):
78
78
>>> tokens.duplicate()
79
79
<id: ~u/w//c/t/01>
80
80
>>> tokens.duplicate(job='02') # make changes at the same time
@@ -118,9 +118,10 @@ def __init__(
118
118
dict .__init__ (self , ** kwargs )
119
119
120
120
def __setitem__ (self , key , value ):
121
- if key not in self ._KEYS :
122
- raise ValueError (f'Invalid token: { key } ' )
123
- dict .__setitem__ (self , key , value )
121
+ raise Exception ('Tokens objects are not mutable' )
122
+
123
+ def update (self , other ):
124
+ raise Exception ('Tokens objects are not mutable' )
124
125
125
126
def __getitem__ (self , key ):
126
127
try :
@@ -151,6 +152,9 @@ def __repr__(self):
151
152
id_ = self .id
152
153
return f'<id: { id_ } >'
153
154
155
+ def __hash__ (self ):
156
+ return hash (tuple (self .values ()))
157
+
154
158
def __eq__ (self , other ):
155
159
if not isinstance (other , self .__class__ ):
156
160
return False
@@ -336,62 +340,20 @@ def is_null(self) -> bool:
336
340
>>> tokens = Tokens()
337
341
>>> tokens.is_null
338
342
True
339
- >>> tokens['job_sel'] = 'x'
340
- >>> tokens.is_null
343
+ >>> tokens.duplicate(job_sel='x').is_null
341
344
True
342
- >>> tokens['job'] = '01'
343
- >>> tokens.is_null
345
+ >>> tokens.duplicate(job='01').is_null
344
346
False
345
347
346
348
"""
347
349
return not any (
348
350
self [key ] for key in self ._REGULAR_KEYS
349
351
)
350
352
351
- def update_tokens (
352
- self ,
353
- tokens : 'Optional[Tokens]' = None ,
354
- ** kwargs
355
- ) -> None :
356
- """Update the tokens dictionary.
357
-
358
- Similar to dict.update but with an optional Tokens argument.
359
-
360
- Examples:
361
- >>> tokens = Tokens('x')
362
- >>> tokens.update_tokens(workflow='y')
363
- >>> tokens
364
- <id: y>
365
- >>> tokens.update_tokens(Tokens('z'))
366
- >>> tokens
367
- <id: z>
368
- >>> tokens.update_tokens(Tokens('a'), cycle='b')
369
- >>> tokens
370
- <id: a//b>
371
-
372
- """
373
- if tokens :
374
- for key , value in tokens .items ():
375
- self [key ] = value
376
- for key , value in kwargs .items ():
377
- self [key ] = value
378
-
379
- def update (self , other ):
380
- """dict.update.
381
-
382
- Example:
383
- >>> tokens = Tokens(workflow='w')
384
- >>> tokens.update({'cycle': 'c'})
385
- >>> tokens.id
386
- 'w//c'
387
-
388
- """
389
- return self .update_tokens (** other )
390
-
391
353
def duplicate (
392
354
self ,
393
- tokens : 'Optional[Tokens]' = None ,
394
- ** kwargs
355
+ * tokens_list ,
356
+ ** kwargs ,
395
357
) -> 'Tokens' :
396
358
"""Duplicate a tokens object.
397
359
@@ -408,17 +370,28 @@ def duplicate(
408
370
>>> id(tokens1) == id(tokens2)
409
371
False
410
372
411
- Make a copy and modify it :
373
+ Make a copy with a modification :
412
374
>>> tokens1.duplicate(cycle='1').id
413
375
'~u/w//1'
414
376
415
- Original not changed
377
+ The Original is not changed:
416
378
>>> tokens1.id
417
379
'~u/w'
380
+
381
+ Arguments override in definition order:
382
+ >>> Tokens.duplicate(
383
+ ... tokens1,
384
+ ... Tokens(cycle='c', task='a', job='01'),
385
+ ... task='b'
386
+ ... ).id
387
+ '~u/w//c/b/01'
388
+
418
389
"""
419
- ret = Tokens (self )
420
- ret .update_tokens (tokens , ** kwargs )
421
- return ret
390
+ _kwargs = {}
391
+ for tokens in (self , * tokens_list ):
392
+ _kwargs .update (tokens )
393
+ _kwargs .update (kwargs )
394
+ return Tokens (** _kwargs )
422
395
423
396
424
397
# //cycle[:sel][/task[:sel][/job[:sel]]]
0 commit comments