Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
4 changes: 2 additions & 2 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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.
49 changes: 38 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down Expand Up @@ -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
-------
Expand All @@ -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.
4 changes: 1 addition & 3 deletions edtf_validate/valid_edtf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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':
Expand Down
71 changes: 71 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -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",
]

Comment thread
ldko marked this conversation as resolved.
[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
"""
3 changes: 0 additions & 3 deletions requirements.txt

This file was deleted.

34 changes: 0 additions & 34 deletions setup.py

This file was deleted.

16 changes: 8 additions & 8 deletions tests/test_valid_edtf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down
16 changes: 0 additions & 16 deletions tox.ini

This file was deleted.

Loading