Skip to content

Performance enhancements #73

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Jun 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
86b9451
Enable packratting for pyparser
ahankinson Apr 13, 2021
7fdf8dd
#37 update for Django 3.x compat
jacobcolyvan Jul 26, 2021
6e4a627
Minor updates
ahankinson Apr 26, 2024
80fdd60
Update dependency management
ahankinson Apr 26, 2024
c12d759
Deps
ahankinson Apr 26, 2024
6e508d0
Optimized regexes
ahankinson Jul 23, 2024
f2252f0
Package updates
ahankinson Jul 23, 2024
06ab934
Further optimizations
ahankinson Jul 24, 2024
c9cb56f
Update gitignore
ahankinson Aug 12, 2024
9e51373
Black formatting, updates
ahankinson Aug 13, 2024
1aa53cf
Update imports
ahankinson Aug 13, 2024
ddd8f7b
Merge branch 'main' into performance-enhancements
ahankinson Aug 13, 2024
8c4f968
Merge fixes
ahankinson Aug 13, 2024
6f08bce
ruff formatting
ahankinson Aug 13, 2024
973ccf4
Remove accidentally committed poetry file
ahankinson Aug 13, 2024
ee450a5
Fixed: f-string formatting
ahankinson Aug 14, 2024
46bdce6
Fixed: return type of statement
ahankinson Sep 12, 2024
656f8ad
Updated parser classes
ahankinson Sep 12, 2024
add79bd
Fixed: Remove SHORT_YEAR_RE
ahankinson Sep 12, 2024
fee0b64
Problem with f-string
ahankinson Sep 12, 2024
89f3692
Another f-string fix
ahankinson Sep 12, 2024
9da1d94
Fixed: pyproject errors
ahankinson Sep 12, 2024
95b83aa
Testing without lru_cache
ahankinson Jan 16, 2025
6262a38
Fixed: New ruff rules
ahankinson Jan 16, 2025
8fbce49
Fixed formatting
ahankinson Jan 16, 2025
adc1805
Bad formatting conversion
ahankinson Jan 16, 2025
ffbe2d4
Replace range len with enumerate
ahankinson Jan 17, 2025
f7aeddb
reinstate lru cache
ahankinson Jan 21, 2025
4885de5
Updates to typing etc.
ahankinson May 26, 2025
98bfe36
Update GH actions
ahankinson May 26, 2025
af98f87
New: Add a validator helper function
ahankinson May 26, 2025
f97b627
Add validator to init
ahankinson May 26, 2025
ae82b11
Rename validator
ahankinson May 26, 2025
86b1546
Annotate appsettings
ahankinson May 27, 2025
a771ec2
parseString is an alias to parse_string
ahankinson May 27, 2025
24a5f60
More fixes for correctness
ahankinson May 27, 2025
df15fd8
Try 3.10
ahankinson Jun 2, 2025
6a91fa0
More type annotations
ahankinson Jun 2, 2025
d3d0cd5
Update supported python in pyproject
ahankinson Jun 2, 2025
9bd142d
Fixed: UA is a single state, no need for append
ahankinson Jun 2, 2025
517ba18
Add mypy and pip to test dependencies
ahankinson Jun 2, 2025
1c480b0
Merge branch 'main' into performance-enhancements
ahankinson Jun 2, 2025
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
defaults:
run:
working-directory: .
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/coverage_readme.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ jobs:
persist-credentials: false
fetch-depth: 0

- name: Set up Python 3.12
- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: 3.12
python-version: 3.13
cache: 'pip'
cache-dependency-path: '**/pyproject.toml'

Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ docs/_build/

# PyBuilder
target/
.idea
.DS_Store
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,6 @@ Since the `EDTFField` and the `_earliest` and `_latest` field values are set aut
* Fix formatting: `ruff format --config pyproject.toml`
* Linting and formatting checks and attempted fixes are also run as precommit hooks if you installed them.

### Coverage and benchmraks
### Coverage and benchmarks

Coverage reports are generated and added as comments to commits, and also visible in the actions log. Benchmarks are run on pull requests and are published [here]( https://ixc.github.io/python-edtf/dev/bench/) and also visible in the actions log.
2 changes: 2 additions & 0 deletions edtf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
UncertainOrApproximate,
Unspecified,
UnspecifiedIntervalSection,
is_valid_edtf,
parse_edtf,
)

Expand All @@ -46,6 +47,7 @@
"trim_struct_time",
"text_to_edtf",
"parse_edtf",
"is_valid_edtf",
# parser_exceptions
"EDTFParseException",
# parser_classes
Expand Down
47 changes: 30 additions & 17 deletions edtf/appsettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
except ImportError:
EDTF = {}

SEASON_MONTHS_RANGE = EDTF.get(
SEASON_MONTHS_RANGE: dict[int, list[int]] = EDTF.get(
"SEASON_MONTHS_RANGE",
{
# season id: [earliest_month, last_month]
Expand All @@ -27,7 +27,7 @@
},
)

SEASON_L2_MONTHS_RANGE = EDTF.get(
SEASON_L2_MONTHS_RANGE: dict[int, list[int]] = EDTF.get(
"SEASON_L2_MONTHS_RANGE",
{
# season id: [earliest_month, last_month]
Expand Down Expand Up @@ -67,9 +67,9 @@
},
)

DAY_FIRST = EDTF.get("DAY_FIRST", False) # Americans!
DAY_FIRST: bool = EDTF.get("DAY_FIRST", False) # Americans!

SEASONS = EDTF.get(
SEASONS: dict[int, str] = EDTF.get(
"SEASONS",
{
21: "spring",
Expand All @@ -78,25 +78,38 @@
24: "winter",
},
)
INVERSE_SEASONS = EDTF.get("INVERSE_SEASONS", {v: k for k, v in SEASONS.items()})
INVERSE_SEASONS: dict[str, int] = EDTF.get(
"INVERSE_SEASONS", {v: k for k, v in SEASONS.items()}
)
# also need to interpret `fall`
INVERSE_SEASONS["fall"] = 23

# changing these will break tests
PADDING_DAY_PRECISION = EDTF.get("PADDING_DAY_PRECISION", relativedelta(days=1))
PADDING_MONTH_PRECISION = EDTF.get("PADDING_MONTH_PRECISION", relativedelta(months=1))
PADDING_YEAR_PRECISION = EDTF.get("PADDING_YEAR_PRECISION", relativedelta(years=1))
PADDING_SEASON_PRECISION = EDTF.get("PADDING_SEASON_PRECISION", relativedelta(weeks=12))
PADDING_DECADE_PRECISION = EDTF.get("PADDING_DECADE_PRECISION", relativedelta(years=10))
PADDING_CENTURY_PRECISION = EDTF.get(
PADDING_DAY_PRECISION: relativedelta = EDTF.get(
"PADDING_DAY_PRECISION", relativedelta(days=1)
)
PADDING_MONTH_PRECISION: relativedelta = EDTF.get(
"PADDING_MONTH_PRECISION", relativedelta(months=1)
)
PADDING_YEAR_PRECISION: relativedelta = EDTF.get(
"PADDING_YEAR_PRECISION", relativedelta(years=1)
)
PADDING_SEASON_PRECISION: relativedelta = EDTF.get(
"PADDING_SEASON_PRECISION", relativedelta(weeks=12)
)
PADDING_DECADE_PRECISION: relativedelta = EDTF.get(
"PADDING_DECADE_PRECISION", relativedelta(years=10)
)
PADDING_CENTURY_PRECISION: relativedelta = EDTF.get(
"PADDING_CENTURY_PRECISION", relativedelta(years=100)
)
PADDING_MILLENNIUM_PRECISION = EDTF.get(
PADDING_MILLENNIUM_PRECISION: relativedelta = EDTF.get(
"PADDING_MILLENNIUM_PRECISION", relativedelta(years=1000)
)
MULTIPLIER_IF_UNCERTAIN = EDTF.get("MULTIPLIER_IF_UNCERTAIN", 1.0)
MULTIPLIER_IF_APPROXIMATE = EDTF.get("MULTIPLIER_IF_APPROXIMATE", 1.0)
MULTIPLIER_IF_BOTH = EDTF.get("MULTIPLIER_IF_BOTH", 2.0)
DELTA_IF_UNKNOWN = EDTF.get("DELTA_IF_UNKNOWN", relativedelta(years=10))
MULTIPLIER_IF_UNCERTAIN: float = EDTF.get("MULTIPLIER_IF_UNCERTAIN", 1.0)
MULTIPLIER_IF_APPROXIMATE: float = EDTF.get("MULTIPLIER_IF_APPROXIMATE", 1.0)
MULTIPLIER_IF_BOTH: float = EDTF.get("MULTIPLIER_IF_BOTH", 2.0)
DELTA_IF_UNKNOWN: relativedelta = EDTF.get("DELTA_IF_UNKNOWN", relativedelta(years=10))
DELTA_IF_EMPTY: relativedelta = relativedelta(None)

DEBUG_PYPARSING = False
DEBUG_PYPARSING: bool = False
10 changes: 5 additions & 5 deletions edtf/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def old_specs_to_new_specs_expression(expression):
return expression


def dt_to_struct_time(dt):
def dt_to_struct_time(dt) -> struct_time:
"""
Convert a `datetime.date` or `datetime.datetime` to a `struct_time`
representation *with zero values* for data fields that we cannot always
Expand Down Expand Up @@ -70,8 +70,7 @@ def trim_struct_time(st: struct_time, strip_time: bool = False) -> struct_time:
"""
if strip_time:
return struct_time(list(st[:3]) + TIME_EMPTY_TIME + TIME_EMPTY_EXTRAS)
else:
return struct_time(list(st[:6]) + TIME_EMPTY_EXTRAS)
return struct_time(list(st[:6]) + TIME_EMPTY_EXTRAS)


def struct_time_to_jd(st: struct_time) -> float:
Expand Down Expand Up @@ -116,7 +115,7 @@ def jd_to_struct_time(jd: float) -> struct_time:
return struct_time([year, month, day, hour, minute, second] + TIME_EMPTY_EXTRAS)


def _roll_negative_time_fields(year, month, day, hour, minute, second):
def _roll_negative_time_fields(year, month, day, hour, minute, second) -> tuple:
"""
Fix date/time fields which have nonsense negative values for any field
except for year by rolling the overall date/time value backwards, treating
Expand Down Expand Up @@ -152,4 +151,5 @@ def _roll_negative_time_fields(year, month, day, hour, minute, second):
year += int(month / 12.0) # Adjust by whole year in months
year -= 1 # Subtract 1 for negative minutes
month %= 12 # Convert negative month to positive remainder
return (year, month, day, hour, minute, second)

return year, month, day, hour, minute, second
4 changes: 2 additions & 2 deletions edtf/jdutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ def __sub__(self, other):

return jd_to_datetime(combined)

elif isinstance(other, (datetime, dt.datetime)):
elif isinstance(other, datetime | dt.datetime):
diff = datetime_to_jd(self) - datetime_to_jd(other)

return dt.timedelta(diff)
Expand All @@ -407,7 +407,7 @@ def __sub__(self, other):
raise TypeError(s)

def __rsub__(self, other):
if not isinstance(other, (datetime, dt.datetime)):
if not isinstance(other, datetime | dt.datetime):
s = "jdutil.datetime supports '-' with: "
s += "jdutil.datetime and datetime.datetime"
raise TypeError(s)
Expand Down
Loading
Loading