X-Git-Url: https://git.madduck.net/etc/taskwarrior.git/blobdiff_plain/57704ed4307af96a5216711fd9bfdc6e170b4a66..8a2ba91cb471ad97094311172b86b9bf3afed725:/tasklib/task.py diff --git a/tasklib/task.py b/tasklib/task.py index 0f8d963..cbc1192 100644 --- a/tasklib/task.py +++ b/tasklib/task.py @@ -237,8 +237,15 @@ class SerializingObject(object): return ','.join(task['uuid'] for task in value) def deserialize_depends(self, raw_uuids): - raw_uuids = raw_uuids or '' # Convert None to empty string - uuids = raw_uuids.split(',') + raw_uuids = raw_uuids or [] # Convert None to empty list + + # TW 2.4.4 encodes list of dependencies as a single string + if type(raw_uuids) is not list: + uuids = raw_uuids.split(',') + # TW 2.4.5 and later exports them as a list, no conversion needed + else: + uuids = raw_uuids + return set(self.warrior.tasks.get(uuid=uuid) for uuid in uuids if uuid) def datetime_normalizer(self, value): @@ -670,7 +677,13 @@ class Task(TaskResource): "task: %s" % '\n'.join(id_lines)) # Circumvent the ID storage, since ID is considered read-only - self._data['id'] = int(id_lines[0].split(' ')[2].rstrip('.')) + identifier = id_lines[0].split(' ')[2].rstrip('.') + + # Identifier can be either ID or UUID for completed tasks + try: + self._data['id'] = int(identifier) + except ValueError: + self._data['uuid'] = identifier # Refreshing is very important here, as not only modification time # is updated, but arbitrary attribute may have changed due hooks @@ -740,6 +753,14 @@ class Task(TaskResource): # of newly saved tasks. Any other place in the code is fine # with using UUID only. args = [self['uuid'] or self['id'], 'export'] + output = self.warrior.execute_command(args) + + # If more than 1 task has been matched, raise exception + if len(output) > 1: + raise TaskWarriorException( + "Unique identifier {0} matches multiple tasks: {1}".format( + self['uuid'] or self['id'], output)) + new_data = json.loads(self.warrior.execute_command(args)[0]) if only_fields: to_update = dict( @@ -919,6 +940,10 @@ class TaskWarrior(object): 'confirmation': 'no', 'dependency.confirmation': 'no', # See TW-1483 or taskrc man page 'recurrence.confirmation': 'no', # Necessary for modifying R tasks + + # Defaults to on since 2.4.5, we expect off during parsing + 'json.array': 'off', + # 2.4.3 onwards supports 0 as infite bulk, otherwise set just # arbitrary big number which is likely to be large enough 'bulk': 0 if self.version >= VERSION_2_4_3 else 100000, @@ -957,7 +982,7 @@ class TaskWarrior(object): ) config = dict() - config_regex = re.compile(r'^(?P[_a-z\.]+)\s+(?P[^\s].+$)') + config_regex = re.compile(r'^(?P[^\s]+)\s+(?P[^\s].+$)') for line in raw_output: match = config_regex.match(line)