From c0225bd4c15d33567bcf333d704e5882dd1b9f72 Mon Sep 17 00:00:00 2001 From: clarktr1 Date: Mon, 14 Sep 2026 15:46:20 -0500 Subject: [PATCH 1/5] upgrade python, update syntax, add pyproject --- .github/workflows/test.yml | 11 +++--- CHANGELOG.md | 10 +++++- README.md | 5 +++ edtf_validate/valid_edtf.py | 4 +-- pyproject.toml | 67 +++++++++++++++++++++++++++++++++++++ requirements.txt | 3 -- setup.py | 34 ------------------- tests/test_valid_edtf.py | 16 ++++----- tox.ini | 16 --------- 9 files changed, 94 insertions(+), 72 deletions(-) create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 setup.py delete mode 100644 tox.ini diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d7569c7..20ba308 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python: ["3.10", "3.11", "3.12", "3.13", "3.14"] steps: - uses: actions/checkout@v7 @@ -19,13 +19,10 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pytest flake8 -r requirements.txt - - name: Lint with flake8 + pip install .'[test]' + - name: Lint with ruff run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. - flake8 edtf_validate tests setup.py --count --exit-zero --max-line-length=99 --statistics + ruff check . - name: Run the tests run: | pytest diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d7eebb..689f0d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,15 @@ Change Log ========== -x.x.x +4.0.0 +----- +* Add support for Python Python 3.10 - 3.14 +* Drop support for Python >= 3.9 +* Transition setup.py to pyproject +* Removed print_function from __future__ import. + + +3.0.0 ----- * Drop testing for now unsupported Python 2.7, 3.4, 3.5. * Add testing for Python 3.8, 3.9. diff --git a/README.md b/README.md index 9a9e3b7..6ec69c8 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,11 @@ edtf-validate Valid EDTF provides validity testing against levels 0-2 of the official [EDTF Specification](https://www.loc.gov/standards/datetime/edtf.html) released February 2019. You might find it most useful for tasks involving date validation and comparison. Typical usage often looks like this: +## System Requirements +* Python 3.10 - 3.14 + +## How To Use + ```python >>> from edtf_validate.valid_edtf import is_valid, isLevel2 >>> is_valid('2015-03-05') diff --git a/edtf_validate/valid_edtf.py b/edtf_validate/valid_edtf.py index 37dcf42..cc9fe0f 100644 --- a/edtf_validate/valid_edtf.py +++ b/edtf_validate/valid_edtf.py @@ -6,8 +6,6 @@ Information about the extended date time format standard can be found here: https://www.loc.gov/standards/datetime/edtf.html """ -from __future__ import print_function - import argparse import calendar import datetime @@ -505,7 +503,7 @@ def is_valid_interval(edtf_candidate): from_date = datetime.datetime.strptime(parts[0], "%Y") if parts[1].count("-") == 0: # when the to_date is open and the from_date is valid, it's valid - if not parts[1] in [Empty(), '..']: + if parts[1] not in [Empty(), '..']: to_date = datetime.datetime.strptime(parts[1], "%Y") # if it starts negative and ends positive, that's always True if start == 'neg' and end == 'pos': diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..33df9c9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,67 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "edtf-validate" +description = "Extended Date Time Format Validation" +readme = "README.md" +version = "4.0.0" +keywords=["edtf", "extended", "datetime", "validate"] +requires-python = ">=3.10" +license = { text = "LICENSE.txt" } +authors = [ + {name = "University of North Texas Libraries", email = "mark.phillips@unt.edu"} +] +classifiers = [ + "Natural Language :: English", + "Programming Language :: Python", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", +] +dependencies = [ + "pyparsing~=3.3.0", +] + +[project.urls] +Homepage = "https://github.com/unt-libraries/edtf-validate" +Repository = "https://github.com/unt-libraries/edtf-validate.git" + +[project.optional-dependencies] +test = [ + "pytest~=9.0.3", + "ruff~=0.15.9", +] + +[tool.ruff] +line-length = 99 +target-version = "py314" + +[tool.ruff.format] +quote-style = "single" + +[tool.ruff.lint] +select = ["E", "F", "W", "UP"] + +[tool.tox] +legacy_tox_ini = """ + [tox] + envlist = + py{310,311,312,313,314} + ruff + + [testenv] + extras = + test + commands = + pytest + + [testenv:ruff] + deps = + ruff + commands = + ruff check +""" \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index fc0ddac..0000000 --- a/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -pyparsing -argparse -datetime \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index 05f79b4..0000000 --- a/setup.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup - - -setup( - name='edtf-validate', - version='2.0.0', - author='Mark Phillips', - author_email='mark.phillips@unt.edu', - packages=['edtf_validate'], - url='https://github.com/unt-libraries/edtf-validate', - license='BSD', - entry_points={ - 'console_scripts': ['edtf-validate=edtf_validate.valid_edtf:main'], - }, - description='Extended Date Time Format Validation', - long_description='See the home page for more information.', - install_requires=[ - "pyparsing", - "argparse", - "datetime", - ], - keywords=['edtf', 'extended', 'datetime', 'validate'], - classifiers=[ - 'Natural Language :: English', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - ] -) diff --git a/tests/test_valid_edtf.py b/tests/test_valid_edtf.py index 90876a2..04821f9 100644 --- a/tests/test_valid_edtf.py +++ b/tests/test_valid_edtf.py @@ -298,7 +298,7 @@ L0_L1_L2 = list(chain(Level0, Level1, Level2)) -class TestIsValidInterval(object): +class TestIsValidInterval: @pytest.mark.parametrize('date', invalid_edtf_intervals) def test_interval_malformed(self, date): # is_valid_interval should fail if not 8601 extended interval @@ -309,7 +309,7 @@ def test_valid_intervals(self, date): assert is_valid_interval(date) -class TestIsValid(object): +class TestIsValid: @pytest.mark.parametrize('date', L0_L1_L2) def test_valid_edtf_all(self, date): assert is_valid(date) @@ -320,7 +320,7 @@ def test_invalid_edtf_all(self, date): assert not is_valid(date) -class TestLevel0(object): +class TestLevel0: @pytest.mark.parametrize('date', Level0) def test_valid_level_0(self, date): assert isLevel0(date) @@ -330,7 +330,7 @@ def test_invalid_level_0(self, date): assert not isLevel0(date) -class TestLevel1(object): +class TestLevel1: @pytest.mark.parametrize('date', Level1) def test_valid_level_1(self, date): assert isLevel1(date) @@ -340,7 +340,7 @@ def test_invalid_level_1(self, date): assert not isLevel1(date) -class TestLevel2(object): +class TestLevel2: @pytest.mark.parametrize('date', Level2) def test_valid_level_2(self, date): assert isLevel2(date) @@ -350,7 +350,7 @@ def test_invalid_level_2(self, date): assert not isLevel2(date) -class TestConformsLevel0(object): +class TestConformsLevel0: @pytest.mark.parametrize('date', Level0) def test_valid_conformsLevel0(self, date): assert conformsLevel0(date) @@ -360,7 +360,7 @@ def test_invalid_conformsLevel0(self, date): assert not conformsLevel0(date) -class TestConformsLevel1(object): +class TestConformsLevel1: @pytest.mark.parametrize('date', L0_L1) def test_valid_conformsLevel1(self, date): assert conformsLevel1(date) @@ -370,7 +370,7 @@ def test_invalid_conformsLevel1(self, date): assert not conformsLevel1(date) -class TestConformsLevel2(object): +class TestConformsLevel2: @pytest.mark.parametrize('date', L0_L1_L2) def test_valid_conformsLevel2(self, date): assert conformsLevel2(date) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index e7688d2..0000000 --- a/tox.ini +++ /dev/null @@ -1,16 +0,0 @@ -[tox] -envlist = py36, py37, py37-flake8, py38, py39 - -[testenv] -deps = - pytest - -rrequirements.txt -commands = pytest - -[flake8] -max-line-length = 99 -ignore = E722, W503 - -[testenv:py37-flake8] -deps = flake8 -commands = flake8 edtf_validate setup.py tests From 734677f1902cbe47de09fec44e646aa7496da79e Mon Sep 17 00:00:00 2001 From: clarktr1 Date: Wed, 23 Sep 2026 10:03:56 -0500 Subject: [PATCH 2/5] update README, add validation script to pyproject, update License --- README.md | 2 +- pyproject.toml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6ec69c8..a65f420 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ You might find it most useful for tasks involving date validation and comparison ## How To Use ```python ->>> from edtf_validate.valid_edtf import is_valid, isLevel2 +>>> from edtf_validate.valid_edtf import is_valid, isLevel2, conformsLevel1 >>> is_valid('2015-03-05') True >>> is_valid('Jan 12, 1990') diff --git a/pyproject.toml b/pyproject.toml index 33df9c9..ac050d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,9 @@ dependencies = [ "pyparsing~=3.3.0", ] +[project.scripts] +edtf-validate = "edtf_validate.valid_edtf:main" + [project.urls] Homepage = "https://github.com/unt-libraries/edtf-validate" Repository = "https://github.com/unt-libraries/edtf-validate.git" @@ -44,7 +47,7 @@ target-version = "py314" quote-style = "single" [tool.ruff.lint] -select = ["E", "F", "W", "UP"] +select = ["E", "F", "W"] [tool.tox] legacy_tox_ini = """ From f635368945fc7ac666b5495b3ac08a739355d951 Mon Sep 17 00:00:00 2001 From: clarktr1 Date: Wed, 23 Sep 2026 10:14:32 -0500 Subject: [PATCH 3/5] actually add the license to the commit --- LICENSE.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 42173ac..4ff075e 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright © 2014, Regents of the University of North Texas +Copyright © 2026, Regents of the University of North Texas All rights reserved. Redistribution and use in source and binary forms, with or without @@ -27,4 +27,4 @@ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. +DAMAGE. \ No newline at end of file From fe77e52531c90b85b567e57d31cf494679d546cd Mon Sep 17 00:00:00 2001 From: clarktr1 Date: Mon, 5 Oct 2026 17:04:34 -0500 Subject: [PATCH 4/5] update changelog and readme --- CHANGELOG.md | 6 +++--- README.md | 19 ++++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 689f0d7..7bc7642 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,9 @@ Change Log 4.0.0 ----- -* Add support for Python Python 3.10 - 3.14 -* Drop support for Python >= 3.9 -* Transition setup.py to pyproject +* Add support for Python Python 3.10 - 3.14. +* Drop support and tests for Python <= 3.9. +* Transition from setup.py to pyproject.toml. * Removed print_function from __future__ import. diff --git a/README.md b/README.md index a65f420..7554414 100644 --- a/README.md +++ b/README.md @@ -56,13 +56,12 @@ If you're confused what exactly the different levels of EDTF validation implicat Installation ------------ -The easiest way to install is through pip. To use pip to install edtf-validate, along with all the dependencies, use: +You can install this project as a package through Github. ```console -$ pip install edtf-validate +$ pip install git+https://github.com/unt-libraries/edtf-validate.git ``` - License ------- @@ -74,13 +73,11 @@ Acknowledgements The edtf-validate was developed at the UNT Libraries and has been worked on by a number of developers over the years including: -[Joey Liechty](https://github.com/yeahdef) - -[Lauren Ko](https://github.com/ldko) - -[Mark Phillips](https://github.com/vphill) - -[Gio Gottardi](https://github.com/somexpert) +* [Joey Liechty](https://github.com/yeahdef) +* [Lauren Ko](https://github.com/ldko) +* [Mark Phillips](https://github.com/vphill) +* [Gio Gottardi](https://github.com/somexpert) +* [Madhulika Bayyavarapu](https://github.com/madhulika95b) +* [Trey Clark](https://github.com/clarktr1) -[Madhulika Bayyavarapu](https://github.com/madhulika95b) If you have questions about the project feel free to contact Mark Phillips at mark.phillips@unt.edu. From ea7934f71635f404d95484f263b73cc33d173774 Mon Sep 17 00:00:00 2001 From: clarktr1 Date: Mon, 12 Oct 2026 12:48:55 -0500 Subject: [PATCH 5/5] add testing section to readme, update tox configs --- README.md | 25 +++++++++++++++++++++++++ pyproject.toml | 1 + 2 files changed, 26 insertions(+) diff --git a/README.md b/README.md index 7554414..1183b82 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,31 @@ You can install this project as a package through Github. $ pip install git+https://github.com/unt-libraries/edtf-validate.git ``` +Testing +------- + +Install test dependencies +```console +$ pip install .'[test]' +``` + +Run unit tests +```console +$ pytest +``` + +Run the linter +```console +$ ruff check . +``` + +To run the tests against every supported Python version you can install and use [tox](https://tox.wiki/): + +```console +$ pip install tox +$ tox +``` + License ------- diff --git a/pyproject.toml b/pyproject.toml index ac050d4..17c1890 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,7 @@ legacy_tox_ini = """ envlist = py{310,311,312,313,314} ruff + skip_missing_interpreters = true [testenv] extras =