Fix settings.current_date issues

This commit is contained in:
Sina Atalay
2026-02-18 15:46:06 +03:00
parent fd5409c142
commit 87c7640322
7 changed files with 78 additions and 9 deletions

View File

@@ -30,7 +30,7 @@ build-backend = "uv_build" # Build-backend object for building RenderCV
# Metadata about RenderCV.
name = "rendercv"
version = "2.7"
description = "Typst-based CV/resume generator"
description = "CV/resume generator for academics and engineers"
readme = "README.md"
requires-python = ">=3.12"
license = "MIT"
@@ -41,8 +41,6 @@ classifiers = [
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"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",

View File

@@ -1,13 +1,15 @@
import pathlib
from dataclasses import dataclass
from datetime import date as Date
from typing import Literal, cast
from typing import Any, cast
import pydantic
class ValidationContext(pydantic.BaseModel):
@dataclass
class ValidationContext:
input_file_path: pathlib.Path | None = None
current_date: Date | Literal["today"] | None = None
current_date: Any = None
def get_input_file_path(info: pydantic.ValidationInfo) -> pathlib.Path | None:
@@ -38,7 +40,8 @@ def get_current_date(info: pydantic.ValidationInfo) -> Date:
Date calculations (like months of experience) must use consistent
reference dates. Users can override via settings.current_date for
reproducible builds, otherwise defaults to today. The ``"today"``
keyword is resolved to the actual current date.
keyword is resolved to the actual current date. Invalid values fall
back to today so the Settings model can report the error properly.
Args:
info: Pydantic validation info containing context.
@@ -48,7 +51,8 @@ def get_current_date(info: pydantic.ValidationInfo) -> Date:
"""
if isinstance(info.context, dict):
context = cast(ValidationContext, info.context["context"])
if isinstance(context.current_date, Date):
return context.current_date
if context.current_date == "today":
return Date.today()
return context.current_date or Date.today()
return Date.today()

View File

@@ -74,6 +74,18 @@ def parse_plain_pydantic_error(
' or YYYY format or "present"!'
)
# Special case for current_date: the field is typed as datetime.date |
# Literal["today"]. Pydantic appends "date" to the loc for the datetime.date
# union branch (e.g. ("settings", "current_date", "date")). Strip that suffix
# first so the field name lands at location[-1], matching the end_date pattern.
if len(location) >= 2 and location[-1] == "date" and location[-2] == "current_date":
location = location[:-1]
if location and "current_date" in location[-1]:
plain_error["msg"] = (
"This is not a valid `current_date`! Please use YYYY-MM-DD format or"
' "today".'
)
for old_error_message, new_error_message in error_dictionary.items():
if old_error_message in plain_error["msg"]:
plain_error["msg"] = new_error_message

View File

@@ -176,7 +176,9 @@ def build_rendercv_model_from_commented_map(
validation_context = {
"context": ValidationContext(
input_file_path=input_file_path,
current_date=commented_map.get("settings", {}).get("current_date"),
current_date=commented_map.get("settings", {}).get(
"current_date", "today"
),
)
}
model = RenderCVModel.model_validate(commented_map, context=validation_context)

View File

@@ -389,6 +389,51 @@ class TestBuildRendercvModelFromDictionary:
with pytest.raises(RenderCVUserValidationError):
build_rendercv_model_from_commented_map(invalid_dict)
@pytest.mark.parametrize(
"invalid_date",
["todady", "not-a-date", "2024-13-01", "yesterday"],
)
def test_invalid_current_date_raises_user_validation_error(
self, minimal_input_dict, invalid_date
):
# current_date uses datetime.date | Literal["today"]. Pydantic emits one
# error per union branch, including a "date" suffix that has no counterpart
# in the YAML. parse_plain_pydantic_error must truncate the location to
# ("settings", "current_date") or the coordinate lookup raises an error.
yaml_input = dictionary_to_yaml(
{**minimal_input_dict, "settings": {"current_date": invalid_date}}
)
with pytest.raises(RenderCVUserValidationError) as exc_info:
build_rendercv_dictionary_and_model(yaml_input)
errors = exc_info.value.validation_errors
assert len(errors) >= 1
assert any(
error.schema_location is not None
and "settings" in error.schema_location
and "current_date" in error.schema_location
for error in errors
)
def test_valid_current_date_string_works(self, minimal_input_dict):
yaml_input = dictionary_to_yaml(
{**minimal_input_dict, "settings": {"current_date": "2024-06-15"}}
)
_, model = build_rendercv_dictionary_and_model(yaml_input)
assert model.settings.current_date == Date(2024, 6, 15)
def test_today_keyword_in_current_date_works(self, minimal_input_dict):
yaml_input = dictionary_to_yaml(
{**minimal_input_dict, "settings": {"current_date": "today"}}
)
_, model = build_rendercv_dictionary_and_model(yaml_input)
assert model.settings.current_date == "today"
class TestBuildRendercvModel:
def test_basic_model_creation(self, minimal_input_dict):

View File

@@ -143,3 +143,9 @@ expected_errors:
input: not_a_valid_theme
yaml_location: [[58, 3], [58, 9]]
yaml_source: main_yaml_file
- schema_location: ["settings", "current_date"]
message: 'This is not a valid `current_date`! Please use YYYY-MM-DD format or "today".'
input: todady
yaml_location: [[61, 3], [61, 16]]
yaml_source: main_yaml_file

View File

@@ -57,3 +57,5 @@ cv:
design:
theme: not_a_valid_theme
extra_field_in_design: I don't think this is allowed.
settings:
current_date: todady