@@ -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
@@ -159,6 +163,12 @@ def __eq__(self, other):
159
163
for key in self ._KEYS
160
164
)
161
165
166
+ def __lt__ (self , other ):
167
+ return self .id < other .id
168
+
169
+ def __gt__ (self , other ):
170
+ return self .id > other .id
171
+
162
172
def __ne__ (self , other ):
163
173
if not isinstance (other , self .__class__ ):
164
174
return True
@@ -336,62 +346,20 @@ def is_null(self) -> bool:
336
346
>>> tokens = Tokens()
337
347
>>> tokens.is_null
338
348
True
339
- >>> tokens['job_sel'] = 'x'
340
- >>> tokens.is_null
349
+ >>> tokens.duplicate(job_sel='x').is_null
341
350
True
342
- >>> tokens['job'] = '01'
343
- >>> tokens.is_null
351
+ >>> tokens.duplicate(job='01').is_null
344
352
False
345
353
346
354
"""
347
355
return not any (
348
356
self [key ] for key in self ._REGULAR_KEYS
349
357
)
350
358
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
359
def duplicate (
392
360
self ,
393
- tokens : 'Optional[Tokens]' = None ,
394
- ** kwargs
361
+ * tokens_list ,
362
+ ** kwargs ,
395
363
) -> 'Tokens' :
396
364
"""Duplicate a tokens object.
397
365
@@ -408,17 +376,28 @@ def duplicate(
408
376
>>> id(tokens1) == id(tokens2)
409
377
False
410
378
411
- Make a copy and modify it :
379
+ Make a copy with a modification :
412
380
>>> tokens1.duplicate(cycle='1').id
413
381
'~u/w//1'
414
382
415
- Original not changed
383
+ The Original is not changed:
416
384
>>> tokens1.id
417
385
'~u/w'
386
+
387
+ Arguments override in definition order:
388
+ >>> Tokens.duplicate(
389
+ ... tokens1,
390
+ ... Tokens(cycle='c', task='a', job='01'),
391
+ ... task='b'
392
+ ... ).id
393
+ '~u/w//c/b/01'
394
+
418
395
"""
419
- ret = Tokens (self )
420
- ret .update_tokens (tokens , ** kwargs )
421
- return ret
396
+ _kwargs = {}
397
+ for tokens in (self , * tokens_list ):
398
+ _kwargs .update (tokens )
399
+ _kwargs .update (kwargs )
400
+ return Tokens (** _kwargs )
422
401
423
402
424
403
# //cycle[:sel][/task[:sel][/job[:sel]]]
0 commit comments