From 8a14426f9719f9c5df1c31820b9aaa4148fa0f75 Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mon, 20 Nov 2023 08:25:21 -0500 Subject: [PATCH] Update for python-3.12 Also, drop testing for some older versions and adopt testing against newer taskwarrior. --- .github/workflows/test.yml | 12 +++--------- requirements.txt | 1 + setup.py | 11 +++++------ taskw/fields/commaseparateduuid.py | 6 +++--- taskw/utils.py | 4 ++-- taskw/warrior.py | 16 ++++++++-------- tox.ini | 15 ++++++++------- 7 files changed, 30 insertions(+), 35 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e9affa9..1c2dea5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,14 +9,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.5, 3.6, 3.7, 3.8] - taskwarrior-version: [2.5.0, 2.5.1, 2.5.3] - exclude: - # Taskwarriror 3.5.3 only supported on Python 3.7+. - - python-version: 3.5 - taskwarrior-version: 2.5.3 - - python-version: 3.6 - taskwarrior-version: 2.5.3 + python-version: [3.9, "3.10", 3.11, 3.12] + taskwarrior-version: [2.5.3, 2.6.2] steps: - uses: actions/checkout@v2 - name: Set up Python ${{matrix.python-version}} @@ -25,7 +19,7 @@ jobs: python-version: ${{matrix.python-version}} - name: Install Taskwarrior ${{matrix.taskwarrior-version}} run: | - sudo apt-get install -y python-dev cmake build-essential libgnutls28-dev uuid-dev gnutls-bin chrpath libssl-dev libfontconfig1-dev + sudo apt-get install -y python3-dev cmake build-essential libgnutls28-dev uuid-dev gnutls-bin chrpath libssl-dev libfontconfig1-dev git clone https://github.com/GothenburgBitFactory/taskwarrior.git cd taskwarrior git checkout v${{matrix.taskwarrior-version}} diff --git a/requirements.txt b/requirements.txt index b6f1dac..9a5ed8d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ python-dateutil pytz kitchen +packaging diff --git a/setup.py b/setup.py index f71aa14..71f1379 100644 --- a/setup.py +++ b/setup.py @@ -38,17 +38,16 @@ REQUIREMENTS[category] = requirements setup(name='taskw', - version='2.0.0', + version='2.1.0', description="Python bindings for your taskwarrior database", long_description=long_description, classifiers=[ "Development Status :: 5 - Production/Stable", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.4", - "Programming Language :: Python :: 3.5", - "Programming Language :: Python :: 3.6", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "License :: OSI Approved :: GNU General Public License (GPL)", "Intended Audience :: Developers", ], diff --git a/taskw/fields/commaseparateduuid.py b/taskw/fields/commaseparateduuid.py index 92838c5..d7ec4c0 100644 --- a/taskw/fields/commaseparateduuid.py +++ b/taskw/fields/commaseparateduuid.py @@ -1,4 +1,4 @@ -from distutils.version import LooseVersion +from packaging.version import Version import uuid @@ -6,7 +6,7 @@ class CommaSeparatedUUIDField(Field): - version = LooseVersion('2.4') + version = Version('2.4') def deserialize(self, value): if not value: @@ -27,7 +27,7 @@ def serialize(self, value): if not hasattr(value, '__iter__'): raise ValueError("Value must be list or tuple, not %r." % value) - if self.version < LooseVersion('2.5'): + if self.version < Version('2.5'): return ','.join([str(v) for v in value]) else: # We never hit this second code branch now. taskwarrior changed diff --git a/taskw/utils.py b/taskw/utils.py index 73b3f8c..8837d2b 100644 --- a/taskw/utils.py +++ b/taskw/utils.py @@ -8,7 +8,7 @@ import dateutil.tz import pytz -from distutils.version import LooseVersion +from packaging.version import Version DATE_FORMAT = '%Y%m%dT%H%M%SZ' @@ -91,7 +91,7 @@ def encode_query(value, version, query=True): ]) ) else: - if k.endswith(".is") and version >= LooseVersion('2.4'): + if k.endswith(".is") and version >= Version('2.4'): args.append( '%s == "%s"' % ( k[:-3], diff --git a/taskw/warrior.py b/taskw/warrior.py index 915e5e3..99eb2eb 100644 --- a/taskw/warrior.py +++ b/taskw/warrior.py @@ -11,7 +11,7 @@ """ import abc import copy -from distutils.version import LooseVersion +from packaging.version import Version import logging import os import re @@ -432,13 +432,13 @@ def __init__( self._marshal = marshal self.config = TaskRc(config_filename, overrides=config_overrides) - if self.get_version() >= LooseVersion('2.4'): + if self.get_version() >= Version('2.4'): self.DEFAULT_CONFIG_OVERRIDES['verbose'] = 'new-uuid' # Combination of # https://github.com/GothenburgBitFactory/taskwarrior/issues/1953 # and dictionaries random order may cause task add failures in # Python versions before 3.7 - if (self.get_version() >= LooseVersion('2.5.3') and + if (self.get_version() >= Version('2.5.3') and sys.hexversion < 0x03070000): warnings.once( "Python < 3.7 with TaskWarrior => 2.5.3 is not suppoprted. " @@ -553,7 +553,7 @@ def can_use(cls): """ Returns true if runtime requirements of experimental mode are met """ try: - return cls.get_version() > LooseVersion('2') + return cls.get_version() > Version('2') except FileNotFoundError: # FileNotFound is raised if subprocess.Popen fails to find # the executable. @@ -570,10 +570,10 @@ def get_version(cls): raise FileNotFoundError( "Unable to find the 'task' command-line tool." ) - return LooseVersion(taskwarrior_version.decode()) + return Version(taskwarrior_version.decode()) def sync(self, init=False): - if self.get_version() < LooseVersion('2.3'): + if self.get_version() < Version('2.3'): raise UnsupportedVersionException( "'sync' requires version 2.3 of taskwarrior or later." ) @@ -682,7 +682,7 @@ def task_add(self, description, tags=None, **kw): # With older versions of taskwarrior, you can specify whatever uuid you # want when adding a task. - if self.get_version() < LooseVersion('2.4'): + if self.get_version() < Version('2.4'): task['uuid'] = str(uuid.uuid4()) elif 'uuid' in task: del task['uuid'] @@ -697,7 +697,7 @@ def task_add(self, description, tags=None, **kw): # However, in 2.4 and later, you cannot specify whatever uuid you want # when adding a task. Instead, you have to specify rc.verbose=new-uuid # and then parse the assigned uuid out from stdout. - if self.get_version() >= LooseVersion('2.4'): + if self.get_version() >= Version('2.4'): task['uuid'] = re.search(UUID_REGEX, stdout).group(0) id, added_task = self.get_task(uuid=task['uuid']) diff --git a/tox.ini b/tox.ini index 6f17a73..bcfa4d2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,20 +1,21 @@ [tox] -envlist = py{35,36,37,38}-tw{250,251} py{38}-tw{253} +envlist = py{39,310,311,312}-tw{253,262} downloadcache = {toxworkdir}/_download/ [testenv] basepython = - py35: python3.5 - py36: python3.6 - py37: python3.7 - py38: python3.8 + py39: python3.9 + py310: python3.10 + py311: python3.11 + py312: python3.12 +allowlist_externals = + {toxinidir}/.tox_build_taskwarrior.sh deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test_requirements.txt setenv = - tw250: TASKWARRIOR=v2.5.0 - tw251: TASKWARRIOR=v2.5.1 tw253: TASKWARRIOR=v2.5.3 + tw262: TASKWARRIOR=v2.6.2 sitepackages = False commands = {toxinidir}/.tox_build_taskwarrior.sh "{envdir}" "{toxinidir}"