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..7bc7642 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 and tests for Python <= 3.9. +* Transition from setup.py to pyproject.toml. +* 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/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 diff --git a/README.md b/README.md index 9a9e3b7..1183b82 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,13 @@ 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 +>>> from edtf_validate.valid_edtf import is_valid, isLevel2, conformsLevel1 >>> is_valid('2015-03-05') True >>> is_valid('Jan 12, 1990') @@ -51,12 +56,36 @@ 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 git+https://github.com/unt-libraries/edtf-validate.git +``` + +Testing +------- +Install test dependencies ```console -$ pip install edtf-validate +$ 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 ------- @@ -69,13 +98,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. 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..17c1890 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,71 @@ +[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.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" + +[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"] + +[tool.tox] +legacy_tox_ini = """ + [tox] + envlist = + py{310,311,312,313,314} + ruff + skip_missing_interpreters = true + + [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