diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..ff6df15 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,22 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: end-of-file-fixer + exclude: "business-facing/layer" + - id: trailing-whitespace + exclude: "business-facing/layer" + - id: check-yaml + exclude: "business-facing/layer" + - id: check-json + exclude: "business-facing/layer" + + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.4.4 + hooks: + # Run the linter, and enable lint fixes + - id: ruff + args: [ --fix ] + # Run the formatter. + - id: ruff-format diff --git a/README.md b/README.md index 76aec1a..98e33b7 100644 --- a/README.md +++ b/README.md @@ -375,3 +375,20 @@ Example usage: Since the `EDTFField` and the `_earliest` and `_latest` field values are set automatically, you may want to make them readonly, or not visible in your model admin. + +## To develop +### Setup +- Clone the repository: `git clone https://github.com/ixc/python-edtf.git` +- Set up a virtual environment: `python3 -m venv venv` +- Install the dependencies: `pip install -r dev-requirements.txt` +- Install precommit hooks: `pre-commit install` + +### Running tests +- From `python-edtf`, run the unit tests: `pytest` +- From `python-edtf/edtf_django_tests`, run the integration tests: `python manage.py test edtf_integration` + +### Linting and formatting +- Check linting: `ruff check --output-format=github --config pyproject.toml` +- Check formatting: `ruff format --check --config pyproject.toml` +- Fix formatting: `ruff format --config pyproject.toml` +- Linting and formatting checks and attempted fixes are also run as precommit hooks if you installed them. diff --git a/dev-requirements.txt b/dev-requirements.txt new file mode 100644 index 0000000..1e37df5 --- /dev/null +++ b/dev-requirements.txt @@ -0,0 +1,5 @@ +-r requirements.txt # Include all main requirements +django>=4.2,<5.0 +pytest +ruff +pre-commit diff --git a/edtf/__init__.py b/edtf/__init__.py index 4d423fa..7bb2885 100644 --- a/edtf/__init__.py +++ b/edtf/__init__.py @@ -1,4 +1,31 @@ -from edtf.convert import ( +from edtf.natlang import text_to_edtf +from edtf.parser import ( + UA, + Consecutives, + Date, + DateAndTime, + EarlierConsecutives, + EDTFObject, + EDTFParseException, + ExponentialYear, + Interval, + LaterConsecutives, + Level1Interval, + Level2Interval, + Level2Season, + LongYear, + MultipleDates, + OneOfASet, + PartialUncertainOrApproximate, + PartialUnspecified, + Season, + UncertainOrApproximate, + Unspecified, + UnspecifiedIntervalSection, + parse_edtf, +) + +from .convert import ( dt_to_struct_time, jd_to_struct_time, old_specs_to_new_specs_expression, @@ -7,6 +34,40 @@ struct_time_to_jd, trim_struct_time, ) -from edtf.natlang import text_to_edtf -from edtf.parser.grammar import parse_edtf -from edtf.parser.parser_classes import * + +# public +__all__ = [ + "dt_to_struct_time", + "jd_to_struct_time", + "old_specs_to_new_specs_expression", + "struct_time_to_date", + "struct_time_to_datetime", + "struct_time_to_jd", + "trim_struct_time", + "text_to_edtf", + "parse_edtf", + # parser_exceptions + "EDTFParseException", + # parser_classes + "EDTFObject", + "Date", + "DateAndTime", + "Interval", + "UA", + "UncertainOrApproximate", + "UnspecifiedIntervalSection", + "Unspecified", + "Level1Interval", + "LongYear", + "Season", + "PartialUncertainOrApproximate", + "PartialUnspecified", + "Consecutives", + "EarlierConsecutives", + "LaterConsecutives", + "OneOfASet", + "MultipleDates", + "Level2Interval", + "Level2Season", + "ExponentialYear", +] diff --git a/edtf/fields.py b/edtf/fields.py index 525fef6..f717592 100644 --- a/edtf/fields.py +++ b/edtf/fields.py @@ -89,7 +89,7 @@ def from_db_value(self, value, expression, connection): try: # Try to unpickle if the value was pickled - return pickle.loads(value) + return pickle.loads(value) # noqa S301 except (pickle.PickleError, TypeError): # If it fails because it's not pickled data, try parsing as EDTF return parse_edtf(value, fail_silently=True) diff --git a/edtf/natlang/__init__.py b/edtf/natlang/__init__.py index 325672f..463863c 100644 --- a/edtf/natlang/__init__.py +++ b/edtf/natlang/__init__.py @@ -1 +1,3 @@ from .en import text_to_edtf + +__all__ = ["text_to_edtf"] diff --git a/edtf/parser/__init__.py b/edtf/parser/__init__.py index e5a0e5f..43197d5 100644 --- a/edtf/parser/__init__.py +++ b/edtf/parser/__init__.py @@ -1,2 +1,51 @@ -from edtf.parser.grammar import parse_edtf -from edtf.parser.parser_classes import * +from .edtf_exceptions import EDTFParseException +from .grammar import parse_edtf +from .parser_classes import ( + UA, + Consecutives, + Date, + DateAndTime, + EarlierConsecutives, + EDTFObject, + ExponentialYear, + Interval, + LaterConsecutives, + Level1Interval, + Level2Interval, + Level2Season, + LongYear, + MultipleDates, + OneOfASet, + PartialUncertainOrApproximate, + PartialUnspecified, + Season, + UncertainOrApproximate, + Unspecified, + UnspecifiedIntervalSection, +) + +__all__ = [ + "parse_edtf", + "EDTFParseException", + "EDTFObject", + "Date", + "DateAndTime", + "Interval", + "UA", + "UncertainOrApproximate", + "Unspecified", + "UnspecifiedIntervalSection", + "Level1Interval", + "LongYear", + "Season", + "PartialUncertainOrApproximate", + "PartialUnspecified", + "Consecutives", + "EarlierConsecutives", + "LaterConsecutives", + "OneOfASet", + "MultipleDates", + "Level2Interval", + "Level2Season", + "ExponentialYear", +] diff --git a/edtf_django_tests/edtf_integration/tests.py b/edtf_django_tests/edtf_integration/tests.py index fbea7f6..88fdca8 100644 --- a/edtf_django_tests/edtf_integration/tests.py +++ b/edtf_django_tests/edtf_integration/tests.py @@ -1,8 +1,7 @@ from django.test import TestCase -from edtf.convert import struct_time_to_jd -from edtf.parser import EDTFObject -from edtf.parser.grammar import parse_edtf as parse +from edtf import EDTFObject, struct_time_to_jd +from edtf import parse_edtf as parse from .models import TestEvent diff --git a/pyproject.toml b/pyproject.toml index 7cebc56..869daf6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,8 @@ classifiers = [ test = [ "django>=4.2,<5.0", "pytest", - "ruff" + "ruff", + "pre-commit", ] [project.urls] @@ -117,4 +118,3 @@ ignore = [ # Ignore McCabe complexity (for now). "C901", ] -