from __future__ import annotations

import json
from collections.abc import Mapping
from typing import TYPE_CHECKING, Any, TypeVar, cast

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from .. import types
from ..types import UNSET, Unset

if TYPE_CHECKING:
    from ..models.food_inherit_field import FoodInheritField
    from ..models.food_simple import FoodSimple
    from ..models.property_ import Property
    from ..models.recipe_simple import RecipeSimple
    from ..models.shopping_list import ShoppingList
    from ..models.supermarket_category import SupermarketCategory
    from ..models.unit import Unit


T = TypeVar("T", bound="PatchedFood")


@_attrs_define
class PatchedFood:
    """Moves `UniqueValidator`'s from the validation stage to the save stage.
    It solves the problem with nested validation for unique fields on update.

    If you want more details, you can read related issues and articles:
    https://github.com/beda-software/drf-writable-nested/issues/1
    http://www.django-rest-framework.org/api-guide/validators/#updating-nested-serializers

    Example of usage:
    ```
        class Child(models.Model):
        field = models.CharField(unique=True)


    class Parent(models.Model):
        child = models.ForeignKey('Child')


    class ChildSerializer(UniqueFieldsMixin, serializers.ModelSerializer):
        class Meta:
            model = Child


    class ParentSerializer(NestedUpdateMixin, serializers.ModelSerializer):
        child = ChildSerializer()

        class Meta:
            model = Parent
    ```

    Note: `UniqueFieldsMixin` must be applied only on the serializer
    which has unique fields.

    Note: When you are using both mixins
    (`UniqueFieldsMixin` and `NestedCreateMixin` or `NestedUpdateMixin`)
    you should put `UniqueFieldsMixin` ahead.

        Attributes:
            id (int | Unset):
            name (str | Unset):
            plural_name (None | str | Unset):
            description (str | Unset):
            shopping (str | Unset):
            recipe (None | RecipeSimple | Unset):
            url (None | str | Unset):
            properties (list[Property] | None | Unset):
            properties_food_amount (float | Unset):
            properties_food_unit (None | Unit | Unset):
            fdc_id (int | None | Unset):
            food_onhand (bool | None | Unset):
            supermarket_category (None | SupermarketCategory | Unset):
            parent (int | Unset):
            numchild (int | Unset):
            inherit_fields (list[FoodInheritField] | None | Unset):
            full_name (str | Unset): Returns a string representation of a tree node and it's ancestors,
                e.g. 'Cuisine > Asian > Chinese > Catonese'.
            ignore_shopping (bool | Unset):
            substitute (list[FoodSimple] | None | Unset):
            substitute_siblings (bool | Unset):
            substitute_children (bool | Unset):
            substitute_onhand (bool | Unset):
            child_inherit_fields (list[FoodInheritField] | None | Unset):
            open_data_slug (None | str | Unset):
            shopping_lists (list[ShoppingList] | Unset):
    """

    id: int | Unset = UNSET
    name: str | Unset = UNSET
    plural_name: None | str | Unset = UNSET
    description: str | Unset = UNSET
    shopping: str | Unset = UNSET
    recipe: None | RecipeSimple | Unset = UNSET
    url: None | str | Unset = UNSET
    properties: list[Property] | None | Unset = UNSET
    properties_food_amount: float | Unset = UNSET
    properties_food_unit: None | Unit | Unset = UNSET
    fdc_id: int | None | Unset = UNSET
    food_onhand: bool | None | Unset = UNSET
    supermarket_category: None | SupermarketCategory | Unset = UNSET
    parent: int | Unset = UNSET
    numchild: int | Unset = UNSET
    inherit_fields: list[FoodInheritField] | None | Unset = UNSET
    full_name: str | Unset = UNSET
    ignore_shopping: bool | Unset = UNSET
    substitute: list[FoodSimple] | None | Unset = UNSET
    substitute_siblings: bool | Unset = UNSET
    substitute_children: bool | Unset = UNSET
    substitute_onhand: bool | Unset = UNSET
    child_inherit_fields: list[FoodInheritField] | None | Unset = UNSET
    open_data_slug: None | str | Unset = UNSET
    shopping_lists: list[ShoppingList] | Unset = UNSET
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)

    def to_dict(self) -> dict[str, Any]:
        from ..models.recipe_simple import RecipeSimple
        from ..models.supermarket_category import SupermarketCategory
        from ..models.unit import Unit

        id = self.id

        name = self.name

        plural_name: None | str | Unset
        if isinstance(self.plural_name, Unset):
            plural_name = UNSET
        else:
            plural_name = self.plural_name

        description = self.description

        shopping = self.shopping

        recipe: dict[str, Any] | None | Unset
        if isinstance(self.recipe, Unset):
            recipe = UNSET
        elif isinstance(self.recipe, RecipeSimple):
            recipe = self.recipe.to_dict()
        else:
            recipe = self.recipe

        url: None | str | Unset
        if isinstance(self.url, Unset):
            url = UNSET
        else:
            url = self.url

        properties: list[dict[str, Any]] | None | Unset
        if isinstance(self.properties, Unset):
            properties = UNSET
        elif isinstance(self.properties, list):
            properties = []
            for properties_type_0_item_data in self.properties:
                properties_type_0_item = properties_type_0_item_data.to_dict()
                properties.append(properties_type_0_item)

        else:
            properties = self.properties

        properties_food_amount = self.properties_food_amount

        properties_food_unit: dict[str, Any] | None | Unset
        if isinstance(self.properties_food_unit, Unset):
            properties_food_unit = UNSET
        elif isinstance(self.properties_food_unit, Unit):
            properties_food_unit = self.properties_food_unit.to_dict()
        else:
            properties_food_unit = self.properties_food_unit

        fdc_id: int | None | Unset
        if isinstance(self.fdc_id, Unset):
            fdc_id = UNSET
        else:
            fdc_id = self.fdc_id

        food_onhand: bool | None | Unset
        if isinstance(self.food_onhand, Unset):
            food_onhand = UNSET
        else:
            food_onhand = self.food_onhand

        supermarket_category: dict[str, Any] | None | Unset
        if isinstance(self.supermarket_category, Unset):
            supermarket_category = UNSET
        elif isinstance(self.supermarket_category, SupermarketCategory):
            supermarket_category = self.supermarket_category.to_dict()
        else:
            supermarket_category = self.supermarket_category

        parent = self.parent

        numchild = self.numchild

        inherit_fields: list[dict[str, Any]] | None | Unset
        if isinstance(self.inherit_fields, Unset):
            inherit_fields = UNSET
        elif isinstance(self.inherit_fields, list):
            inherit_fields = []
            for inherit_fields_type_0_item_data in self.inherit_fields:
                inherit_fields_type_0_item = inherit_fields_type_0_item_data.to_dict()
                inherit_fields.append(inherit_fields_type_0_item)

        else:
            inherit_fields = self.inherit_fields

        full_name = self.full_name

        ignore_shopping = self.ignore_shopping

        substitute: list[dict[str, Any]] | None | Unset
        if isinstance(self.substitute, Unset):
            substitute = UNSET
        elif isinstance(self.substitute, list):
            substitute = []
            for substitute_type_0_item_data in self.substitute:
                substitute_type_0_item = substitute_type_0_item_data.to_dict()
                substitute.append(substitute_type_0_item)

        else:
            substitute = self.substitute

        substitute_siblings = self.substitute_siblings

        substitute_children = self.substitute_children

        substitute_onhand = self.substitute_onhand

        child_inherit_fields: list[dict[str, Any]] | None | Unset
        if isinstance(self.child_inherit_fields, Unset):
            child_inherit_fields = UNSET
        elif isinstance(self.child_inherit_fields, list):
            child_inherit_fields = []
            for child_inherit_fields_type_0_item_data in self.child_inherit_fields:
                child_inherit_fields_type_0_item = child_inherit_fields_type_0_item_data.to_dict()
                child_inherit_fields.append(child_inherit_fields_type_0_item)

        else:
            child_inherit_fields = self.child_inherit_fields

        open_data_slug: None | str | Unset
        if isinstance(self.open_data_slug, Unset):
            open_data_slug = UNSET
        else:
            open_data_slug = self.open_data_slug

        shopping_lists: list[dict[str, Any]] | Unset = UNSET
        if not isinstance(self.shopping_lists, Unset):
            shopping_lists = []
            for shopping_lists_item_data in self.shopping_lists:
                shopping_lists_item = shopping_lists_item_data.to_dict()
                shopping_lists.append(shopping_lists_item)

        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({})
        if id is not UNSET:
            field_dict["id"] = id
        if name is not UNSET:
            field_dict["name"] = name
        if plural_name is not UNSET:
            field_dict["plural_name"] = plural_name
        if description is not UNSET:
            field_dict["description"] = description
        if shopping is not UNSET:
            field_dict["shopping"] = shopping
        if recipe is not UNSET:
            field_dict["recipe"] = recipe
        if url is not UNSET:
            field_dict["url"] = url
        if properties is not UNSET:
            field_dict["properties"] = properties
        if properties_food_amount is not UNSET:
            field_dict["properties_food_amount"] = properties_food_amount
        if properties_food_unit is not UNSET:
            field_dict["properties_food_unit"] = properties_food_unit
        if fdc_id is not UNSET:
            field_dict["fdc_id"] = fdc_id
        if food_onhand is not UNSET:
            field_dict["food_onhand"] = food_onhand
        if supermarket_category is not UNSET:
            field_dict["supermarket_category"] = supermarket_category
        if parent is not UNSET:
            field_dict["parent"] = parent
        if numchild is not UNSET:
            field_dict["numchild"] = numchild
        if inherit_fields is not UNSET:
            field_dict["inherit_fields"] = inherit_fields
        if full_name is not UNSET:
            field_dict["full_name"] = full_name
        if ignore_shopping is not UNSET:
            field_dict["ignore_shopping"] = ignore_shopping
        if substitute is not UNSET:
            field_dict["substitute"] = substitute
        if substitute_siblings is not UNSET:
            field_dict["substitute_siblings"] = substitute_siblings
        if substitute_children is not UNSET:
            field_dict["substitute_children"] = substitute_children
        if substitute_onhand is not UNSET:
            field_dict["substitute_onhand"] = substitute_onhand
        if child_inherit_fields is not UNSET:
            field_dict["child_inherit_fields"] = child_inherit_fields
        if open_data_slug is not UNSET:
            field_dict["open_data_slug"] = open_data_slug
        if shopping_lists is not UNSET:
            field_dict["shopping_lists"] = shopping_lists

        return field_dict

    def to_multipart(self) -> types.RequestFiles:
        files: types.RequestFiles = []

        if not isinstance(self.id, Unset):
            files.append(("id", (None, str(self.id).encode(), "text/plain")))

        if not isinstance(self.name, Unset):
            files.append(("name", (None, str(self.name).encode(), "text/plain")))

        if not isinstance(self.plural_name, Unset):
            if isinstance(self.plural_name, str):
                files.append(("plural_name", (None, str(self.plural_name).encode(), "text/plain")))
            else:
                files.append(("plural_name", (None, str(self.plural_name).encode(), "text/plain")))

        if not isinstance(self.description, Unset):
            files.append(("description", (None, str(self.description).encode(), "text/plain")))

        if not isinstance(self.shopping, Unset):
            files.append(("shopping", (None, str(self.shopping).encode(), "text/plain")))

        if not isinstance(self.recipe, Unset):
            if self.recipe is None:
                files.append(("recipe", (None, str(self.recipe).encode(), "text/plain")))
            else:
                files.append(("recipe", (None, json.dumps(self.recipe.to_dict()).encode(), "application/json")))

        if not isinstance(self.url, Unset):
            if isinstance(self.url, str):
                files.append(("url", (None, str(self.url).encode(), "text/plain")))
            else:
                files.append(("url", (None, str(self.url).encode(), "text/plain")))

        if not isinstance(self.properties, Unset):
            if isinstance(self.properties, list):
                for properties_type_0_item_element in self.properties:
                    files.append(
                        (
                            "properties",
                            (None, json.dumps(properties_type_0_item_element.to_dict()).encode(), "application/json"),
                        )
                    )
            else:
                files.append(("properties", (None, str(self.properties).encode(), "text/plain")))

        if not isinstance(self.properties_food_amount, Unset):
            files.append(("properties_food_amount", (None, str(self.properties_food_amount).encode(), "text/plain")))

        if not isinstance(self.properties_food_unit, Unset):
            if self.properties_food_unit is None:
                files.append(("properties_food_unit", (None, str(self.properties_food_unit).encode(), "text/plain")))
            else:
                files.append(
                    (
                        "properties_food_unit",
                        (None, json.dumps(self.properties_food_unit.to_dict()).encode(), "application/json"),
                    )
                )

        if not isinstance(self.fdc_id, Unset):
            if isinstance(self.fdc_id, int):
                files.append(("fdc_id", (None, str(self.fdc_id).encode(), "text/plain")))
            else:
                files.append(("fdc_id", (None, str(self.fdc_id).encode(), "text/plain")))

        if not isinstance(self.food_onhand, Unset):
            if isinstance(self.food_onhand, bool):
                files.append(("food_onhand", (None, str(self.food_onhand).encode(), "text/plain")))
            else:
                files.append(("food_onhand", (None, str(self.food_onhand).encode(), "text/plain")))

        if not isinstance(self.supermarket_category, Unset):
            if self.supermarket_category is None:
                files.append(("supermarket_category", (None, str(self.supermarket_category).encode(), "text/plain")))
            else:
                files.append(
                    (
                        "supermarket_category",
                        (None, json.dumps(self.supermarket_category.to_dict()).encode(), "application/json"),
                    )
                )

        if not isinstance(self.parent, Unset):
            files.append(("parent", (None, str(self.parent).encode(), "text/plain")))

        if not isinstance(self.numchild, Unset):
            files.append(("numchild", (None, str(self.numchild).encode(), "text/plain")))

        if not isinstance(self.inherit_fields, Unset):
            if isinstance(self.inherit_fields, list):
                for inherit_fields_type_0_item_element in self.inherit_fields:
                    files.append(
                        (
                            "inherit_fields",
                            (
                                None,
                                json.dumps(inherit_fields_type_0_item_element.to_dict()).encode(),
                                "application/json",
                            ),
                        )
                    )
            else:
                files.append(("inherit_fields", (None, str(self.inherit_fields).encode(), "text/plain")))

        if not isinstance(self.full_name, Unset):
            files.append(("full_name", (None, str(self.full_name).encode(), "text/plain")))

        if not isinstance(self.ignore_shopping, Unset):
            files.append(("ignore_shopping", (None, str(self.ignore_shopping).encode(), "text/plain")))

        if not isinstance(self.substitute, Unset):
            if isinstance(self.substitute, list):
                for substitute_type_0_item_element in self.substitute:
                    files.append(
                        (
                            "substitute",
                            (None, json.dumps(substitute_type_0_item_element.to_dict()).encode(), "application/json"),
                        )
                    )
            else:
                files.append(("substitute", (None, str(self.substitute).encode(), "text/plain")))

        if not isinstance(self.substitute_siblings, Unset):
            files.append(("substitute_siblings", (None, str(self.substitute_siblings).encode(), "text/plain")))

        if not isinstance(self.substitute_children, Unset):
            files.append(("substitute_children", (None, str(self.substitute_children).encode(), "text/plain")))

        if not isinstance(self.substitute_onhand, Unset):
            files.append(("substitute_onhand", (None, str(self.substitute_onhand).encode(), "text/plain")))

        if not isinstance(self.child_inherit_fields, Unset):
            if isinstance(self.child_inherit_fields, list):
                for child_inherit_fields_type_0_item_element in self.child_inherit_fields:
                    files.append(
                        (
                            "child_inherit_fields",
                            (
                                None,
                                json.dumps(child_inherit_fields_type_0_item_element.to_dict()).encode(),
                                "application/json",
                            ),
                        )
                    )
            else:
                files.append(("child_inherit_fields", (None, str(self.child_inherit_fields).encode(), "text/plain")))

        if not isinstance(self.open_data_slug, Unset):
            if isinstance(self.open_data_slug, str):
                files.append(("open_data_slug", (None, str(self.open_data_slug).encode(), "text/plain")))
            else:
                files.append(("open_data_slug", (None, str(self.open_data_slug).encode(), "text/plain")))

        if not isinstance(self.shopping_lists, Unset):
            for shopping_lists_item_element in self.shopping_lists:
                files.append(
                    (
                        "shopping_lists",
                        (None, json.dumps(shopping_lists_item_element.to_dict()).encode(), "application/json"),
                    )
                )

        for prop_name, prop in self.additional_properties.items():
            files.append((prop_name, (None, str(prop).encode(), "text/plain")))

        return files

    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        from ..models.food_inherit_field import FoodInheritField
        from ..models.food_simple import FoodSimple
        from ..models.property_ import Property
        from ..models.recipe_simple import RecipeSimple
        from ..models.shopping_list import ShoppingList
        from ..models.supermarket_category import SupermarketCategory
        from ..models.unit import Unit

        d = dict(src_dict)
        id = d.pop("id", UNSET)

        name = d.pop("name", UNSET)

        def _parse_plural_name(data: object) -> None | str | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(None | str | Unset, data)

        plural_name = _parse_plural_name(d.pop("plural_name", UNSET))

        description = d.pop("description", UNSET)

        shopping = d.pop("shopping", UNSET)

        def _parse_recipe(data: object) -> None | RecipeSimple | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                recipe_type_1 = RecipeSimple.from_dict(data)

                return recipe_type_1
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(None | RecipeSimple | Unset, data)

        recipe = _parse_recipe(d.pop("recipe", UNSET))

        def _parse_url(data: object) -> None | str | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(None | str | Unset, data)

        url = _parse_url(d.pop("url", UNSET))

        def _parse_properties(data: object) -> list[Property] | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, list):
                    raise TypeError()
                properties_type_0 = []
                _properties_type_0 = data
                for properties_type_0_item_data in _properties_type_0:
                    properties_type_0_item = Property.from_dict(properties_type_0_item_data)

                    properties_type_0.append(properties_type_0_item)

                return properties_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(list[Property] | None | Unset, data)

        properties = _parse_properties(d.pop("properties", UNSET))

        properties_food_amount = d.pop("properties_food_amount", UNSET)

        def _parse_properties_food_unit(data: object) -> None | Unit | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                properties_food_unit_type_1 = Unit.from_dict(data)

                return properties_food_unit_type_1
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(None | Unit | Unset, data)

        properties_food_unit = _parse_properties_food_unit(d.pop("properties_food_unit", UNSET))

        def _parse_fdc_id(data: object) -> int | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(int | None | Unset, data)

        fdc_id = _parse_fdc_id(d.pop("fdc_id", UNSET))

        def _parse_food_onhand(data: object) -> bool | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(bool | None | Unset, data)

        food_onhand = _parse_food_onhand(d.pop("food_onhand", UNSET))

        def _parse_supermarket_category(data: object) -> None | SupermarketCategory | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, dict):
                    raise TypeError()
                supermarket_category_type_1 = SupermarketCategory.from_dict(data)

                return supermarket_category_type_1
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(None | SupermarketCategory | Unset, data)

        supermarket_category = _parse_supermarket_category(d.pop("supermarket_category", UNSET))

        parent = d.pop("parent", UNSET)

        numchild = d.pop("numchild", UNSET)

        def _parse_inherit_fields(data: object) -> list[FoodInheritField] | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, list):
                    raise TypeError()
                inherit_fields_type_0 = []
                _inherit_fields_type_0 = data
                for inherit_fields_type_0_item_data in _inherit_fields_type_0:
                    inherit_fields_type_0_item = FoodInheritField.from_dict(inherit_fields_type_0_item_data)

                    inherit_fields_type_0.append(inherit_fields_type_0_item)

                return inherit_fields_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(list[FoodInheritField] | None | Unset, data)

        inherit_fields = _parse_inherit_fields(d.pop("inherit_fields", UNSET))

        full_name = d.pop("full_name", UNSET)

        ignore_shopping = d.pop("ignore_shopping", UNSET)

        def _parse_substitute(data: object) -> list[FoodSimple] | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, list):
                    raise TypeError()
                substitute_type_0 = []
                _substitute_type_0 = data
                for substitute_type_0_item_data in _substitute_type_0:
                    substitute_type_0_item = FoodSimple.from_dict(substitute_type_0_item_data)

                    substitute_type_0.append(substitute_type_0_item)

                return substitute_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(list[FoodSimple] | None | Unset, data)

        substitute = _parse_substitute(d.pop("substitute", UNSET))

        substitute_siblings = d.pop("substitute_siblings", UNSET)

        substitute_children = d.pop("substitute_children", UNSET)

        substitute_onhand = d.pop("substitute_onhand", UNSET)

        def _parse_child_inherit_fields(data: object) -> list[FoodInheritField] | None | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            try:
                if not isinstance(data, list):
                    raise TypeError()
                child_inherit_fields_type_0 = []
                _child_inherit_fields_type_0 = data
                for child_inherit_fields_type_0_item_data in _child_inherit_fields_type_0:
                    child_inherit_fields_type_0_item = FoodInheritField.from_dict(child_inherit_fields_type_0_item_data)

                    child_inherit_fields_type_0.append(child_inherit_fields_type_0_item)

                return child_inherit_fields_type_0
            except (TypeError, ValueError, AttributeError, KeyError):
                pass
            return cast(list[FoodInheritField] | None | Unset, data)

        child_inherit_fields = _parse_child_inherit_fields(d.pop("child_inherit_fields", UNSET))

        def _parse_open_data_slug(data: object) -> None | str | Unset:
            if data is None:
                return data
            if isinstance(data, Unset):
                return data
            return cast(None | str | Unset, data)

        open_data_slug = _parse_open_data_slug(d.pop("open_data_slug", UNSET))

        _shopping_lists = d.pop("shopping_lists", UNSET)
        shopping_lists: list[ShoppingList] | Unset = UNSET
        if _shopping_lists is not UNSET:
            shopping_lists = []
            for shopping_lists_item_data in _shopping_lists:
                shopping_lists_item = ShoppingList.from_dict(shopping_lists_item_data)

                shopping_lists.append(shopping_lists_item)

        patched_food = cls(
            id=id,
            name=name,
            plural_name=plural_name,
            description=description,
            shopping=shopping,
            recipe=recipe,
            url=url,
            properties=properties,
            properties_food_amount=properties_food_amount,
            properties_food_unit=properties_food_unit,
            fdc_id=fdc_id,
            food_onhand=food_onhand,
            supermarket_category=supermarket_category,
            parent=parent,
            numchild=numchild,
            inherit_fields=inherit_fields,
            full_name=full_name,
            ignore_shopping=ignore_shopping,
            substitute=substitute,
            substitute_siblings=substitute_siblings,
            substitute_children=substitute_children,
            substitute_onhand=substitute_onhand,
            child_inherit_fields=child_inherit_fields,
            open_data_slug=open_data_slug,
            shopping_lists=shopping_lists,
        )

        patched_food.additional_properties = d
        return patched_food

    @property
    def additional_keys(self) -> list[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties
