[Python-modules-commits] [taskw] 01/03: Import taskw_1.2.0.orig.tar.gz
Edward Betts
edward at moszumanska.debian.org
Sat Nov 12 11:07:14 UTC 2016
This is an automated email from the git hooks/post-receive script.
edward pushed a commit to branch master
in repository taskw.
commit 797ff9c162ea13f936b6f50f90c1561362f0e4a4
Author: Edward Betts <edward at 4angle.com>
Date: Sat Nov 12 10:08:08 2016 +0000
Import taskw_1.2.0.orig.tar.gz
---
PKG-INFO | 2 +-
requirements.txt | 1 +
setup.py | 2 +-
taskw.egg-info/PKG-INFO | 2 +-
taskw.egg-info/SOURCES.txt | 2 ++
taskw.egg-info/pbr.json | 2 +-
taskw.egg-info/requires.txt | 1 +
taskw/fields/string.py | 2 +-
taskw/test/data/empty.taskrc | 0
taskw/test/test_utils.py | 14 +++++++++++++-
taskw/test/test_warrior.py | 39 +++++++++++++++++++++++++++++++++++++++
taskw/utils.py | 7 +++++++
taskw/warrior.py | 29 +++++++++++++++++++++++++----
tox.ini | 6 ++++--
14 files changed, 97 insertions(+), 12 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index 8f244a6..1681f94 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: taskw
-Version: 1.1.0
+Version: 1.2.0
Summary: Python bindings for your taskwarrior database
Home-page: http://github.com/ralphbean/taskw
Author: Ralph Bean
diff --git a/requirements.txt b/requirements.txt
index c95f002..6ecdc62 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
six
python-dateutil
pytz
+kitchen
diff --git a/setup.py b/setup.py
index ea61e4e..47fde92 100644
--- a/setup.py
+++ b/setup.py
@@ -42,7 +42,7 @@ if sys.version_info < (2, 7):
REQUIREMENTS['install'].append('ordereddict')
setup(name='taskw',
- version='1.1.0',
+ version='1.2.0',
description="Python bindings for your taskwarrior database",
long_description=long_description,
classifiers=[
diff --git a/taskw.egg-info/PKG-INFO b/taskw.egg-info/PKG-INFO
index 8f244a6..1681f94 100644
--- a/taskw.egg-info/PKG-INFO
+++ b/taskw.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: taskw
-Version: 1.1.0
+Version: 1.2.0
Summary: Python bindings for your taskwarrior database
Home-page: http://github.com/ralphbean/taskw
Author: Ralph Bean
diff --git a/taskw.egg-info/SOURCES.txt b/taskw.egg-info/SOURCES.txt
index 95afe83..fbf125d 100644
--- a/taskw.egg-info/SOURCES.txt
+++ b/taskw.egg-info/SOURCES.txt
@@ -38,5 +38,7 @@ taskw/test/test_recursive.py
taskw/test/test_task.py
taskw/test/test_taskrc.py
taskw/test/test_utils.py
+taskw/test/test_warrior.py
taskw/test/data/default.taskrc
+taskw/test/data/empty.taskrc
taskw/test/data/included.taskrc
\ No newline at end of file
diff --git a/taskw.egg-info/pbr.json b/taskw.egg-info/pbr.json
index 534fbcb..71148aa 100644
--- a/taskw.egg-info/pbr.json
+++ b/taskw.egg-info/pbr.json
@@ -1 +1 @@
-{"is_release": false, "git_version": "b739058"}
\ No newline at end of file
+{"is_release": false, "git_version": "ac720a5"}
\ No newline at end of file
diff --git a/taskw.egg-info/requires.txt b/taskw.egg-info/requires.txt
index c95f002..6ecdc62 100644
--- a/taskw.egg-info/requires.txt
+++ b/taskw.egg-info/requires.txt
@@ -1,3 +1,4 @@
six
python-dateutil
pytz
+kitchen
diff --git a/taskw/fields/string.py b/taskw/fields/string.py
index 6542f51..fac94c5 100644
--- a/taskw/fields/string.py
+++ b/taskw/fields/string.py
@@ -26,7 +26,7 @@ class StringField(Field):
return value
if not isinstance(value, six.string_types):
string_value = six.text_type(value)
- logger.warning(
+ logger.debug(
"Value %s serialized to string as '%s'",
repr(value),
string_value
diff --git a/taskw/test/data/empty.taskrc b/taskw/test/data/empty.taskrc
new file mode 100644
index 0000000..e69de29
diff --git a/taskw/test/test_utils.py b/taskw/test/test_utils.py
index 6fddc7e..3c920bd 100644
--- a/taskw/test/test_utils.py
+++ b/taskw/test/test_utils.py
@@ -11,7 +11,8 @@ from taskw.utils import (
decode_task,
encode_task,
encode_task_experimental,
- DATE_FORMAT
+ DATE_FORMAT,
+ clean_ctrl_chars,
)
TASK = {'description': "task 2 http://www.google.com/",
@@ -200,3 +201,14 @@ class TestUtils(object):
actual_overrides = convert_dict_to_override_args(overrides)
eq_(set(actual_overrides), set(expected_overrides))
+
+
+class TestCleanExecArg(object):
+ def test_clean_null(self):
+ eq_(b"", clean_ctrl_chars(b"\x00"))
+
+ def test_all_ctrl_chars(self):
+ """ Test that most (but not all) control characters are removed """
+ # input = bytes(range(0x20))
+ input = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f' # For python 2 compatibility
+ eq_(b"\t\n\v\f\r", clean_ctrl_chars(input))
diff --git a/taskw/test/test_warrior.py b/taskw/test/test_warrior.py
new file mode 100644
index 0000000..4da8088
--- /dev/null
+++ b/taskw/test/test_warrior.py
@@ -0,0 +1,39 @@
+import tempfile
+import os
+import shutil
+
+from taskw.warrior import TaskWarrior
+
+
+class TestTaskWarrior(object):
+ def setUp(self):
+ self.taskdata = tempfile.mkdtemp()
+ taskrc = os.path.join(os.path.dirname(__file__), 'data/empty.taskrc')
+ self.taskwarrior = TaskWarrior(
+ config_filename=taskrc,
+ config_overrides={'data.location': self.taskdata})
+ # Just a sanity check to make sure that after the setup, the list of
+ # tasks is empty, otherwise we are probably using the current user's
+ # TASKDATA and we should not continue.
+ assert self.taskwarrior.load_tasks() == {'completed': [], 'pending': []}
+
+ def tearDown(self):
+ # Remove the directory after the test
+ shutil.rmtree(self.taskdata)
+
+ def test_add_task_foobar(self):
+ """ Add a task with description 'foobar' and checks that the task is
+ indeed created """
+ self.taskwarrior.task_add("foobar")
+ tasks = self.taskwarrior.load_tasks()
+ assert len(tasks['pending']) == 1
+ assert tasks['pending'][0]['description'] == 'foobar'
+
+ def test_add_task_null_char(self):
+ """ Try adding a task where the description contains a NULL character
+ (0x00). This should not fail but instead simply add a task with the
+ same description minus the NULL character """
+ self.taskwarrior.task_add("foo\x00bar")
+ tasks = self.taskwarrior.load_tasks()
+ assert len(tasks['pending']) == 1
+ assert tasks['pending'][0]['description'] == 'foobar'
diff --git a/taskw/utils.py b/taskw/utils.py
index c6583c3..3d5e6e7 100644
--- a/taskw/utils.py
+++ b/taskw/utils.py
@@ -261,3 +261,10 @@ def convert_dict_to_override_args(config, prefix=''):
right = v if ' ' not in v else '"%s"' % v
args.append('='.join([left, right]))
return args
+
+
+CTRLCHAR = re.compile(b"[\x00-\x08\x0e-\x1f]")
+
+def clean_ctrl_chars(s):
+ """ Clean string removing most (but not all) control characters """
+ return CTRLCHAR.sub(b'', s)
diff --git a/taskw/warrior.py b/taskw/warrior.py
index cb34bd1..62c15b1 100644
--- a/taskw/warrior.py
+++ b/taskw/warrior.py
@@ -19,6 +19,9 @@ import time
import uuid
import subprocess
import json
+import errno
+
+import kitchen.text.converters
import six
from six import with_metaclass
@@ -451,9 +454,11 @@ class TaskWarriorShellout(TaskWarriorBase):
)
# subprocess is expecting bytestrings only, so nuke unicode if present
+ # and remove control characters
for i in range(len(command)):
if isinstance(command[i], six.text_type):
- command[i] = command[i].encode('utf-8')
+ command[i] = (
+ taskw.utils.clean_ctrl_chars(command[i].encode('utf-8')))
try:
proc = subprocess.Popen(
@@ -463,7 +468,7 @@ class TaskWarriorShellout(TaskWarriorBase):
)
stdout, stderr = proc.communicate()
except OSError as e:
- if 'No such file or directory' in e:
+ if e.errno == errno.ENOENT:
raise OSError("Unable to find the 'task' command-line tool.")
raise
@@ -472,8 +477,24 @@ class TaskWarriorShellout(TaskWarriorBase):
# We should get bytes from the outside world. Turn those into unicode
# as soon as we can.
- stdout = stdout.decode(self.config.get('encoding', 'utf-8'))
- stderr = stderr.decode(self.config.get('encoding', 'utf-8'))
+ # Everything going into and coming out of taskwarrior *should* be
+ # utf-8, but there are weird edge cases where something totally unusual
+ # made it in.. so we need to be able to handle (or at least try to
+ # handle) whatever. Kitchen tries its best.
+ try:
+ stdout = stdout.decode(self.config.get('encoding', 'utf-8'))
+ except UnicodeDecodeError as e:
+ stdout = kitchen.text.converters.to_unicode(stdout)
+ try:
+ stderr = stderr.decode(self.config.get('encoding', 'utf-8'))
+ except UnicodeDecodeError as e:
+ stderr = kitchen.text.converters.to_unicode(stderr)
+
+ # strip any crazy terminal escape characters like bells, backspaces,
+ # and form feeds
+ for c in ('\a', '\b', '\f', ''):
+ stdout = stdout.replace(c, '?')
+ stderr = stderr.replace(c, '?')
return stdout, stderr
diff --git a/tox.ini b/tox.ini
index 68418d1..6060f6d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = {py26,py27,py33,py34}-tw{22,23,24,241,242,250}
+envlist = {py27,py35}-tw{22,23,24,241,242,250,251}
downloadcache = {toxworkdir}/_download/
[testenv]
@@ -8,6 +8,7 @@ basepython =
py27: python2.7
py33: python3.3
py34: python3.4
+ py35: python3.5
deps =
-r{toxinidir}/requirements.txt
-r{toxinidir}/test_requirements.txt
@@ -19,7 +20,8 @@ setenv =
tw24: TASKWARRIOR=v2.4.0
tw241: TASKWARRIOR=v2.4.1
tw242: TASKWARRIOR=v2.4.2
- tw250: TASKWARRIOR=v2.5.0.beta1
+ tw250: TASKWARRIOR=v2.5.0
+ tw251: TASKWARRIOR=2.5.1
sitepackages = False
commands =
{toxinidir}/.tox_build_taskwarrior.sh "{envdir}" "{toxinidir}"
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/taskw.git
More information about the Python-modules-commits
mailing list