From 008bb9052faf7ba9e93a4b7549d4517a80e388a4 Mon Sep 17 00:00:00 2001 From: ryneeverett Date: Sat, 6 Jun 2020 04:38:43 +0000 Subject: [PATCH] Pass description as positional argument. Similarly to #134, passing description via description:{description} doesn't appear to be documented and can lead to problems. See ralphbean/bugwarrior#733 and consider the following scenario: ```sh $ task --version 2.5.1 $ task add description:"depends filter does not work with ID" The expression could not be evaluated. $ task add "depends filter does not work with ID" Created task 1. ``` I've tried variations of the previous with various quoting and shells and have gotten the same result. --- taskw/test/test_utils.py | 9 ++++++++- taskw/test/test_warrior.py | 9 +++++++++ taskw/utils.py | 3 ++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/taskw/test/test_utils.py b/taskw/test/test_utils.py index 27801c7..7515be5 100644 --- a/taskw/test/test_utils.py +++ b/taskw/test/test_utils.py @@ -105,9 +105,10 @@ def test_ordering(self): def test_taskwarrior_null_encoding_bug_workaround(self): task = { + 'description': 'arbitrary description', 'priority': '' } - actual_encoded = encode_task_experimental(task)[0] + actual_encoded = encode_task_experimental(task)[1] expected_encoded = "priority:" assert actual_encoded == expected_encoded @@ -115,12 +116,14 @@ def test_taskwarrior_null_encoding_bug_workaround(self): def test_encodes_dates(self): arbitrary_date = datetime.date(2014, 3, 2) task = { + 'description': 'arbitrary description', 'arbitrary_field': arbitrary_date } actual_encoded_task = encode_task_experimental(task) expected_encoded_task = encode_task_experimental( { + 'description': 'arbitrary description', 'arbitrary_field': arbitrary_date.strftime(DATE_FORMAT) } ) @@ -130,12 +133,14 @@ def test_encodes_dates(self): def test_encodes_naive_datetimes(self): arbitrary_naive_datetime = datetime.datetime.now() task = { + 'description': 'arbitrary description', 'arbitrary_field': arbitrary_naive_datetime } actual_encoded_task = encode_task_experimental(task) expected_encoded_task = encode_task_experimental( { + 'description': 'arbitrary description', 'arbitrary_field': ( arbitrary_naive_datetime .replace(tzinfo=dateutil.tz.tzlocal()) @@ -152,12 +157,14 @@ def test_encodes_zoned_datetimes(self): tzinfo=arbitrary_timezone ) task = { + 'description': 'arbitrary description', 'arbitrary_field': arbitrary_zoned_datetime } actual_encoded_task = encode_task_experimental(task) expected_encoded_task = encode_task_experimental( { + 'description': 'arbitrary description', 'arbitrary_field': ( arbitrary_zoned_datetime .astimezone(pytz.utc).strftime(DATE_FORMAT) diff --git a/taskw/test/test_warrior.py b/taskw/test/test_warrior.py index 8c62931..bc740d7 100644 --- a/taskw/test/test_warrior.py +++ b/taskw/test/test_warrior.py @@ -49,3 +49,12 @@ def test_add_task_recurs(self): assert tasks['pending'][0]['recur'] == 'weekly' assert tasks['pending'][0]['parent'] is not None + def test_add_task_depends_keyword(self): + """Add a task with description beginning with keyword "depends". + See https://github.com/ralphbean/bugwarrior/issues/733. + """ + self.taskwarrior.task_add('depends filter does not work with IDs') + tasks = self.taskwarrior.load_tasks() + assert len(tasks['pending']) == 1 + assert (tasks['pending'][0]['description'] + == 'depends filter does not work with IDs') diff --git a/taskw/utils.py b/taskw/utils.py index 3d5e6e7..d4f80dc 100644 --- a/taskw/utils.py +++ b/taskw/utils.py @@ -134,7 +134,8 @@ def encode_task_experimental(task): task[k] = encode_task_value(k, task[k]) # Then, format it as a string - return [ + positionals = [task.pop('description')] if 'description' in task else [] + return positionals + [ "%s:\"%s\"" % (k, v) if v else "%s:" % (k, ) for k, v in sorted(task.items(), key=itemgetter(0)) ]