From a6bb816d676e7305de1b89cff574a09f7c49618e Mon Sep 17 00:00:00 2001 From: Michael Overmeyer Date: Tue, 25 Oct 2022 16:23:37 -0400 Subject: [PATCH 1/4] Add Python 3.11 to tooling --- .circleci/config.yml | 4 ++-- .github/workflows/build-wheels.yml | 4 ++-- README.rst | 2 +- benchmarking/Dockerfile | 21 ++++++++++++--------- benchmarking/tox.ini | 2 +- setup.py | 1 + tox.ini | 2 +- 7 files changed, 20 insertions(+), 16 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 40c36a2..4a3a3f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,7 +6,7 @@ workflows: - test: matrix: parameters: - python_version: ["2.7", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"] + python_version: ["2.7", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] - test_pypy: matrix: parameters: @@ -54,4 +54,4 @@ jobs: . venv/bin/activate rst-lint --encoding=utf-8 README.rst docker: - - image: circleci/python:3.10 + - image: circleci/python:3.11 diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index 21c0715..e1137b8 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -16,7 +16,7 @@ jobs: - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.10' + python-version: '3.11' - run: | pip install packaging @@ -107,7 +107,7 @@ jobs: - uses: actions/setup-python@v2 name: Install Python with: - python-version: '3.10' + python-version: '3.11' - name: Build sdist run: python setup.py sdist diff --git a/README.rst b/README.rst index 468c556..eab719a 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ ciso8601 ``ciso8601`` converts `ISO 8601`_ or `RFC 3339`_ date time strings into Python datetime objects. Since it's written as a C module, it is much faster than other Python libraries. -Tested with cPython 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10. +Tested with cPython 2.7, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11. **Note:** ciso8601 doesn't support the entirety of the ISO 8601 spec, `only a popular subset`_. diff --git a/benchmarking/Dockerfile b/benchmarking/Dockerfile index efb8e9b..c8bc6c4 100644 --- a/benchmarking/Dockerfile +++ b/benchmarking/Dockerfile @@ -5,20 +5,23 @@ RUN apt-get update && \ add-apt-repository ppa:deadsnakes/ppa && \ apt-get update +# Install the other dependencies +RUN apt-get install -y git curl gcc build-essential + +# Install tzdata non-iteractively +# https://stackoverflow.com/questions/44331836/apt-get-install-tzdata-noninteractive/44333806#44333806 +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata + # Install the Python versions -RUN apt install -y python python-dev && \ - apt install -y python3.5 python3.5-dev python3.5-venv && \ - apt install -y python3.6 python3.6-dev python3.6-venv && \ +RUN apt install -y python2 python2-dev && \ apt install -y python3.7 python3.7-dev python3.7-venv && \ apt install -y python3.8 python3.8-dev python3.8-venv && \ apt install -y python3.9 python3.9-dev python3.9-venv && \ - apt install -y python3.10 python3.10-dev python3.10-venv - -# Install the other dependencies -RUN apt-get install -y git curl gcc build-essential + apt install -y python3.10 python3.10-dev python3.10-venv && \ + apt install -y python3.11 python3.11-dev python3.11-venv -# Make Python 3.10 the default `python` -RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 10 +# Make Python 3.11 the default `python` +RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.11 10 # Get pip RUN python -m ensurepip --upgrade diff --git a/benchmarking/tox.ini b/benchmarking/tox.ini index 05bbc03..f4e94c2 100644 --- a/benchmarking/tox.ini +++ b/benchmarking/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py310,py39,py38,py37,py36,py35,py34,py27 +envlist = py311,py310,py39,py38,py37,py36,py35,py34,py27 setupdir=.. [testenv] diff --git a/setup.py b/setup.py index 1142b28..5ae3906 100644 --- a/setup.py +++ b/setup.py @@ -73,6 +73,7 @@ "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "Topic :: Software Development :: Libraries :: Python Modules", ], ) diff --git a/tox.ini b/tox.ini index 578fe66..ae25c0d 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = {py27,py34,py35,py36,py37,py38,py39}-caching_{enabled,disabled} +envlist = {py27,py34,py35,py36,py37,py38,py39,py310,py311}-caching_{enabled,disabled} [testenv] setenv = From 7ef83ea6810ea11c5d8bb14c53ad947601256794 Mon Sep 17 00:00:00 2001 From: Michael Overmeyer Date: Thu, 27 Oct 2022 16:17:23 -0400 Subject: [PATCH 2/4] Update benchmarking scripts --- benchmarking/format_results.py | 5 ++++- benchmarking/perform_comparison.py | 22 +++++++++++++++++----- benchmarking/tox.ini | 9 +++++---- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/benchmarking/format_results.py b/benchmarking/format_results.py index 5c39caa..4fe17b1 100644 --- a/benchmarking/format_results.py +++ b/benchmarking/format_results.py @@ -5,6 +5,7 @@ import re from collections import defaultdict, UserDict +from packaging import version as version_parse import pytablewriter @@ -64,9 +65,11 @@ def format_used_module_versions(module_versions_used): if len(versions) == 1: results.append(f"{module}=={next(iter(versions.keys()))}") else: - results.append(", ".join([f"{module}=={version} (on Python {', '.join(sorted(py_versions))})" for version, py_versions in versions.items()])) + results.append(", ".join([f"{module}=={version} (on Python {', '.join(version_sort(py_versions))})" for version, py_versions in versions.items()])) return results +def version_sort(versions): + return [str(v) for v in sorted([version_parse.parse(v) for v in versions])] def relative_slowdown(subject, comparison): most_modern_common_version = next(iter(sorted(set(subject.keys()).intersection(set(comparison)), reverse=True)), None) diff --git a/benchmarking/perform_comparison.py b/benchmarking/perform_comparison.py index da35833..e9ffc75 100644 --- a/benchmarking/perform_comparison.py +++ b/benchmarking/perform_comparison.py @@ -22,13 +22,16 @@ "python-dateutil": ("import dateutil.parser", "dateutil.parser.parse('{timestamp}')"), "iso8601": ("import iso8601", "iso8601.parse_date('{timestamp}')"), "isodate": ("import isodate", "isodate.parse_datetime('{timestamp}')"), - "maya": ("import maya", "maya.parse('{timestamp}').datetime()"), "pendulum": ("from pendulum.parsing import parse_iso8601", "parse_iso8601('{timestamp}')"), "PySO8601": ("import PySO8601", "PySO8601.parse('{timestamp}')"), "str2date": ("from str2date import str2date", "str2date('{timestamp}')"), } -if os.name != "nt" and (sys.version_info.major, sys.version_info.minor) < (3, 9): +if (sys.version_info.major, sys.version_info.minor) >= (3, 11): + # Python 3.11 added full ISO 8601 parsing + ISO_8601_MODULES["datetime (builtin)"] = ("from datetime import datetime", "datetime.fromisoformat('{timestamp}')") + +if os.name != "nt": # udatetime doesn't support Windows. ISO_8601_MODULES["udatetime"] = ("import udatetime", "udatetime.from_string('{timestamp}')") @@ -40,7 +43,7 @@ # zulu v2.0.0+ no longer supports Python < 3.6 ISO_8601_MODULES["zulu"] = ("import zulu", "zulu.parse('{timestamp}')") -if (sys.version_info.major, sys.version_info.minor) != (3, 6) and (sys.version_info.major, sys.version_info.minor) != (3, 10): +if (sys.version_info.major, sys.version_info.minor) != (3, 6) and (sys.version_info.major, sys.version_info.minor) <= (3, 9): # iso8601utils installs enum34, which messes with tox in Python 3.6 # https://stackoverflow.com/q/43124775 # https://github.com/silverfernsys/iso8601utils/pull/5 @@ -49,9 +52,16 @@ ISO_8601_MODULES["iso8601utils"] = ("from iso8601utils import parsers", "parsers.datetime('{timestamp}')") if (sys.version_info.major, sys.version_info.minor) != (3, 4): - # arrow no longer supports Python 3.4 + # `arrow` no longer supports Python 3.4 ISO_8601_MODULES["arrow"] = ("import arrow", "arrow.get('{timestamp}').datetime") - # moment is built on `times`, which is built on `arrow`, which no longer supports Python 3.4 + +if sys.version_info.major >= 3: + # `maya` uses a version of `regex` which no longer supports Python 2 + ISO_8601_MODULES["maya"] = ("import maya", "maya.parse('{timestamp}').datetime()") + +if (sys.version_info.major, sys.version_info.minor) >= (3, 5): + # `moment` is built on `times`, which is built on `arrow`, which no longer supports Python 3.4 + # `moment` uses a version of `regex` which no longer supports Python 2 ISO_8601_MODULES["moment"] = ("import moment", "moment.date('{timestamp}').date") class Result: @@ -132,6 +142,8 @@ def write_module_versions(filepath): module_version_writer = csv.writer(fout, delimiter=",", quotechar='"', lineterminator="\n") module_version_writer.writerow([sys.version_info.major, sys.version_info.minor]) for module, (_setup, _stmt) in sorted(ISO_8601_MODULES.items(), key=lambda x: x[0].lower()): + if module == "datetime (builtin)": + continue module_version_writer.writerow([module, get_module_version(module)]) def run_tests(timestamp, results_directory, compare_to): diff --git a/benchmarking/tox.ini b/benchmarking/tox.ini index f4e94c2..45b2c19 100644 --- a/benchmarking/tox.ini +++ b/benchmarking/tox.ini @@ -21,17 +21,18 @@ deps= # https://github.com/silverfernsys/iso8601utils/issues/6 iso8601utils; python_version != '3.6' and python_version != '3.10' isodate - maya + ; `maya` uses a version of `regex` which no longer supports Python 2 + maya; python_version > '3' metomi-isodatetime; python_version >= '3.5' ; `moment` is built on `times`, which is built on `arrow`, which no longer supports Python 3.4 - moment; python_version != '3.4' + ; `moment` uses a version of `regex` which no longer supports Python 2 + moment; python_version >= '3.5' pendulum pyso8601 python-dateutil str2date ; `udatetime` doesn't support Windows - ; `udatetime` doesn't compile on Python 3.9 (https://github.com/freach/udatetime/issues/32) - udatetime; os_name != 'nt' and python_version < '3.9' + udatetime; os_name != 'nt' ; `zulu` v2.0.0+ no longer supports Python < 3.6 zulu; python_version >= '3.6' pytz From 923c9f3b2a645064b4a4182d6fd11e5d289e98a6 Mon Sep 17 00:00:00 2001 From: Michael Overmeyer Date: Thu, 27 Oct 2022 16:37:22 -0400 Subject: [PATCH 3/4] Migrate Docker image to modern CircleCI images --- .circleci/config.yml | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4a3a3f1..99fc3ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,10 +3,11 @@ version: 2.1 workflows: workflow: jobs: + - test_python_34 - test: matrix: parameters: - python_version: ["2.7", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] + python_version: ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"] - test_pypy: matrix: parameters: @@ -14,6 +15,17 @@ workflows: - lint-rst jobs: + # `cimg/python` doesn't support Python 3.4, + # but old `circleci/python` is still around! + test_python_34: + steps: + - checkout + - run: + name: Test + command: python setup.py test + docker: + - image: circleci/python:3.4 + test: parameters: python_version: @@ -24,7 +36,7 @@ jobs: name: Test command: python setup.py test docker: - - image: circleci/python:<> + - image: cimg/python:<> test_pypy: parameters: @@ -54,4 +66,4 @@ jobs: . venv/bin/activate rst-lint --encoding=utf-8 README.rst docker: - - image: circleci/python:3.11 + - image: cimg/python:3.11 From f9de61cbfb4b044b52d1a8c0d9b5a4a9cf6984ce Mon Sep 17 00:00:00 2001 From: Michael Overmeyer Date: Thu, 27 Oct 2022 16:53:26 -0400 Subject: [PATCH 4/4] Add PyPy 3.9 to CI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 99fc3ee..e846400 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,7 +11,7 @@ workflows: - test_pypy: matrix: parameters: - python_version: ["2.7", "3.7", "3.8"] + python_version: ["2.7", "3.7", "3.8", "3.9"] - lint-rst jobs: