Skip to content

Commit b7cd03e

Browse files
authored
fix: ensure value_string is not an int or a float (#454)
Closes #453.
1 parent 3d4fa68 commit b7cd03e

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/openfoodfacts/types.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import enum
22
from typing import Any, Dict, Literal, Optional, Union
33

4-
from pydantic import BaseModel, Field, model_validator
4+
from pydantic import BaseModel, Field, field_validator, model_validator
55

66
#: A precise expectation of what mappings looks like in json.
77
#: (dict where keys are always of type `str`).
@@ -931,6 +931,16 @@ class NutritionV3NutrientInput(BaseModel):
931931
value_string: str | None = None
932932
modifier: str | None = None
933933

934+
@field_validator("value_string", mode="before")
935+
@classmethod
936+
def ensure_value_string_is_not_an_int_or_float(cls, value: Any) -> Any:
937+
# Sometimes, Product Opener uses an int for `value_string` instead
938+
# of a string, which causes Pydantic validation to fail.
939+
# See https://github.com/openfoodfacts/openfoodfacts-python/issues/452
940+
if isinstance(value, int) or isinstance(value, float):
941+
return str(value)
942+
return value
943+
934944

935945
class NutritionV3AggregatedSet(BaseModel):
936946
preparation: Literal["as_sold", "prepared"]

tests/unit/test_types.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import pytest
22

3-
from openfoodfacts.types import Flavor, JSONType, NutritionV3, NutritionV3InputSet
3+
from openfoodfacts.types import (
4+
Flavor,
5+
JSONType,
6+
NutritionV3,
7+
NutritionV3InputSet,
8+
NutritionV3NutrientInput,
9+
)
410

511

612
def test_from_product_type_food():
@@ -420,3 +426,16 @@ def test_get_input_nutrient(self):
420426
assert result.value_string == "5.2"
421427
assert result.unit == "g"
422428
assert result.modifier is None
429+
430+
431+
class TestNutritionV3NutrientInput:
432+
def test_ensure_value_string_is_not_an_int_or_float(self):
433+
parsed = NutritionV3NutrientInput.model_validate(
434+
{
435+
"unit": "g",
436+
"value": 5.2,
437+
"value_string": 5.2,
438+
"modifier": "<",
439+
}
440+
)
441+
assert parsed.value_string == "5.2"

0 commit comments

Comments
 (0)