mirror of
https://github.com/rendercv/rendercv.git
synced 2026-04-17 13:33:53 -04:00
Fix settings.current_date issues
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user