Edit on GitHub

hexdoc.minecraft.recipe

 1__all__ = [
 2    "BlastingRecipe",
 3    "CampfireCookingRecipe",
 4    "CookingRecipe",
 5    "CraftingRecipe",
 6    "CraftingShapedRecipe",
 7    "CraftingShapelessRecipe",
 8    "ItemIngredient",
 9    "ItemIngredientList",
10    "ItemResult",
11    "MinecraftItemIdIngredient",
12    "MinecraftItemTagIngredient",
13    "Recipe",
14    "SmeltingRecipe",
15    "SmithingRecipe",
16    "SmithingTransformRecipe",
17    "SmithingTrimRecipe",
18    "SmokingRecipe",
19    "StonecuttingRecipe",
20]
21
22from .ingredients import (
23    ItemIngredient,
24    ItemIngredientList,
25    ItemResult,
26    MinecraftItemIdIngredient,
27    MinecraftItemTagIngredient,
28)
29from .recipes import (
30    BlastingRecipe,
31    CampfireCookingRecipe,
32    CookingRecipe,
33    CraftingRecipe,
34    CraftingShapedRecipe,
35    CraftingShapelessRecipe,
36    Recipe,
37    SmeltingRecipe,
38    SmithingRecipe,
39    SmithingTransformRecipe,
40    SmithingTrimRecipe,
41    SmokingRecipe,
42    StonecuttingRecipe,
43)
class BlastingRecipe(hexdoc.minecraft.recipe.CookingRecipe):
151class BlastingRecipe(
152    CookingRecipe,
153    type="minecraft:blasting",
154    workstation="minecraft:blast_furnace",
155):
156    cookingtime: int = 100

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

cookingtime: int
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class CampfireCookingRecipe(hexdoc.minecraft.recipe.CookingRecipe):
159class CampfireCookingRecipe(
160    CookingRecipe,
161    type="minecraft:campfire_cooking",
162    workstation="minecraft:campfire",
163):
164    cookingtime: int = 100

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

cookingtime: int
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class CookingRecipe(hexdoc.minecraft.recipe.Recipe):
144class CookingRecipe(Recipe):
145    ingredient: ItemIngredientList
146    result: ItemWithTexture
147    experience: float
148    cookingtime: int

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

ingredient: typing.Annotated[list[ItemIngredient], BeforeValidator(func=<function _validate_single_item_to_list at 0x7fbdf4451440>, json_schema_input_type=PydanticUndefined), AfterValidator(func=<function _validate_flatten_nested_tags at 0x7fbdf44519e0>)]
experience: float
cookingtime: int
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class CraftingRecipe(hexdoc.minecraft.recipe.Recipe):
119class CraftingRecipe(Recipe, workstation="minecraft:crafting_table"):
120    result: ItemResult

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

result: ItemResult
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class CraftingShapedRecipe(hexdoc.minecraft.recipe.CraftingRecipe):
127class CraftingShapedRecipe(CraftingRecipe, type="minecraft:crafting_shaped"):
128    key: dict[str, ItemIngredientList]
129    pattern: list[str]
130
131    @property
132    def ingredients(self) -> Iterator[ItemIngredientList | None]:
133        for row in self.pattern:
134            if len(row) > 3:
135                raise ValueError(f"Expected len(row) <= 3, got {len(row)}: `{row}`")
136            for item_key in row.ljust(3):
137                match item_key:
138                    case " ":
139                        yield None
140                    case _:
141                        yield self.key[item_key]

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

key: dict[str, typing.Annotated[list[ItemIngredient], BeforeValidator(func=<function _validate_single_item_to_list at 0x7fbdf4451440>, json_schema_input_type=PydanticUndefined), AfterValidator(func=<function _validate_flatten_nested_tags at 0x7fbdf44519e0>)]]
pattern: list[str]
ingredients: Iterator[Optional[Annotated[list[ItemIngredient], BeforeValidator(func=<function _validate_single_item_to_list at 0x7fbdf4451440>, json_schema_input_type=PydanticUndefined), AfterValidator(func=<function _validate_flatten_nested_tags at 0x7fbdf44519e0>)]]]
131    @property
132    def ingredients(self) -> Iterator[ItemIngredientList | None]:
133        for row in self.pattern:
134            if len(row) > 3:
135                raise ValueError(f"Expected len(row) <= 3, got {len(row)}: `{row}`")
136            for item_key in row.ljust(3):
137                match item_key:
138                    case " ":
139                        yield None
140                    case _:
141                        yield self.key[item_key]
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class CraftingShapelessRecipe(hexdoc.minecraft.recipe.CraftingRecipe):
123class CraftingShapelessRecipe(CraftingRecipe, type="minecraft:crafting_shapeless"):
124    ingredients: list[ItemIngredientList]

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

ingredients: list[typing.Annotated[list[ItemIngredient], BeforeValidator(func=<function _validate_single_item_to_list at 0x7fbdf4451440>, json_schema_input_type=PydanticUndefined), AfterValidator(func=<function _validate_flatten_nested_tags at 0x7fbdf44519e0>)]]
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class ItemIngredient(hexdoc.model.tagged_union.TypeTaggedUnion, abc.ABC):
23class ItemIngredient(TypeTaggedUnion, ABC):
24    @property
25    def item(self) -> ItemWithTexture | TagWithTexture: ...

Implements internally tagged unions using the Registry pattern.

To ensure your subtypes are loaded even if they're not imported by any file, add a Pluggy hook implementation for hexdoc_load_tagged_unions() -> list[Package].

Subclasses MUST NOT be generic unless they provide a default value for all __init_subclass__ arguments. See pydantic/7171 for more info.

Args: key: The dict key for the internal tag. If None, the parent's value is used. value: The expected tag value for this class. Should be None for types which shouldn't be instantiated (eg. abstract classes).

24    @property
25    def item(self) -> ItemWithTexture | TagWithTexture: ...
ItemIngredientList = typing.Annotated[list[ItemIngredient], BeforeValidator(func=<function _validate_single_item_to_list>, json_schema_input_type=PydanticUndefined), AfterValidator(func=<function _validate_flatten_nested_tags>)]
class ItemResult(hexdoc.model.base.HexdocModel):
44class ItemResult(HexdocModel):
45    item: ItemWithTexture
46    count: int = 1

Base class for all Pydantic models in hexdoc.

Sets the default model config, and overrides __init__ to allow using the init_context context manager to set validation context for constructors.

count: int
class MinecraftItemIdIngredient(hexdoc.minecraft.recipe.ItemIngredient):
28class MinecraftItemIdIngredient(ItemIngredient, type=NoValue):
29    item_: ItemWithTexture = Field(alias="item")
30
31    @property
32    def item(self):
33        return self.item_

Implements internally tagged unions using the Registry pattern.

To ensure your subtypes are loaded even if they're not imported by any file, add a Pluggy hook implementation for hexdoc_load_tagged_unions() -> list[Package].

Subclasses MUST NOT be generic unless they provide a default value for all __init_subclass__ arguments. See pydantic/7171 for more info.

Args: key: The dict key for the internal tag. If None, the parent's value is used. value: The expected tag value for this class. Should be None for types which shouldn't be instantiated (eg. abstract classes).

item
31    @property
32    def item(self):
33        return self.item_
class MinecraftItemTagIngredient(hexdoc.minecraft.recipe.ItemIngredient):
36class MinecraftItemTagIngredient(ItemIngredient, type=NoValue):
37    tag: AssumeTag[TagWithTexture]
38
39    @property
40    def item(self):
41        return self.tag

Implements internally tagged unions using the Registry pattern.

To ensure your subtypes are loaded even if they're not imported by any file, add a Pluggy hook implementation for hexdoc_load_tagged_unions() -> list[Package].

Subclasses MUST NOT be generic unless they provide a default value for all __init_subclass__ arguments. See pydantic/7171 for more info.

Args: key: The dict key for the internal tag. If None, the parent's value is used. value: The expected tag value for this class. Should be None for types which shouldn't be instantiated (eg. abstract classes).

tag: typing.Annotated[hexdoc.minecraft.assets.TagWithTexture, BeforeValidator(func=<function _add_hashtag_to_tag at 0x7fbdf47600e0>, json_schema_input_type=PydanticUndefined)]
item
39    @property
40    def item(self):
41        return self.tag
class Recipe(hexdoc.model.tagged_union.TypeTaggedTemplate, hexdoc.model.id.ResourceModel):
 21class Recipe(TypeTaggedTemplate, ResourceModel):
 22    """Base model for Minecraft recipes.
 23
 24    https://minecraft.wiki/w/Recipe
 25    """
 26
 27    category: str | None = None
 28    group: str | None = None
 29    show_notification: AtLeast_1_20[bool] | Before_1_20[None] = Field(
 30        default_factory=ValueIfVersion(">=1.20", True, None)
 31    )
 32
 33    fabric_load_conditions: list[dict[str, Any]] | None = Field(
 34        default=None, alias="fabric:load_conditions"
 35    )
 36    """Fabric resource conditions.
 37
 38    https://github.com/FabricMC/fabric/blob/761f669d0a6fbfe2ae6d71d767651f32a13d37fc/fabric-resource-conditions-api-v1/src/main/java/net/fabricmc/fabric/api/resource/conditions/v1/ResourceConditions.java#L64
 39    """
 40
 41    # not in the actual model
 42
 43    _workstation: ClassVar[ResourceLocation | None] = None
 44
 45    _gui_name: LocalizedStr | None = PrivateAttr(None)
 46    _gui_texture: ImageTexture | None = PrivateAttr(None)
 47
 48    def __init_subclass__(
 49        cls,
 50        *,
 51        type: str | InheritType | None = Inherit,
 52        workstation: str | InheritType | None = Inherit,
 53        **kwargs: Unpack[ConfigDict],
 54    ):
 55        super().__init_subclass__(type=type, **kwargs)
 56
 57        match workstation:
 58            case str():
 59                cls._workstation = ResourceLocation.from_str(workstation)
 60            case None:
 61                cls._workstation = None
 62            case _:
 63                pass
 64
 65    @classmethod
 66    def load_resource(cls, id: ResourceLocation, loader: ModResourceLoader):
 67        return loader.load_resource("data", "recipes", id)
 68
 69    @classproperty
 70    @classmethod
 71    @override
 72    def template(cls):
 73        return cls.template_id.template_path("recipes")
 74
 75    @classproperty
 76    @classmethod
 77    @override
 78    def template_id(cls):
 79        assert cls._workstation is not None
 80        return cls._workstation
 81
 82    @property
 83    def gui_name(self):
 84        return self._gui_name
 85
 86    @property
 87    def gui_texture(self):
 88        return self._gui_texture
 89
 90    @classproperty
 91    @classmethod
 92    def _gui_texture_id(cls) -> ResourceLocation | None:
 93        """ResourceLocation of the background image for this recipe type."""
 94        if cls._workstation is None:
 95            return None
 96        return ResourceLocation(
 97            cls._workstation.namespace,
 98            f"textures/gui/hexdoc/{cls._workstation.path}.png",
 99        )
100
101    def _localize_workstation(self, i18n: I18n):
102        if self._workstation is not None:
103            return i18n.localize_item(self._workstation)
104
105    @model_validator(mode="after")
106    def _load_gui_texture(self, info: ValidationInfo):
107        self._gui_name = self._localize_workstation(I18n.of(info))
108
109        if self._gui_texture_id is not None:
110            self._gui_texture = validate_texture(
111                self._gui_texture_id,
112                context=info,
113                model_type=ImageTexture,
114            )
115
116        return self

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

category: str | None
group: str | None
show_notification: Union[Annotated[bool, IsVersion(version_spec='>=1.20', version_source=<class 'hexdoc.core.MinecraftVersion'>)], Annotated[NoneType, IsVersion(version_spec='<1.20', version_source=<class 'hexdoc.core.MinecraftVersion'>)]]
@classmethod
def load_resource( cls, id: hexdoc.core.ResourceLocation, loader: hexdoc.core.ModResourceLoader):
65    @classmethod
66    def load_resource(cls, id: ResourceLocation, loader: ModResourceLoader):
67        return loader.load_resource("data", "recipes", id)
def template(unknown):

Equivalent of classmethod(property(...)).

Use @classproperty. Do not instantiate this class directly.

def template_id(unknown):

Equivalent of classmethod(property(...)).

Use @classproperty. Do not instantiate this class directly.

gui_name
82    @property
83    def gui_name(self):
84        return self._gui_name
gui_texture
86    @property
87    def gui_texture(self):
88        return self._gui_texture
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class SmeltingRecipe(hexdoc.minecraft.recipe.CookingRecipe):
167class SmeltingRecipe(
168    CookingRecipe,
169    type="minecraft:smelting",
170    workstation="minecraft:furnace",
171):
172    cookingtime: int = 200

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

cookingtime: int
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class SmithingRecipe(hexdoc.minecraft.recipe.Recipe):
183class SmithingRecipe(Recipe, workstation="minecraft:smithing_table"):
184    base: ItemIngredient
185    addition: ItemIngredient
186    template_ingredient: ItemIngredient = Field(alias="template")
187
188    @property
189    def result_item(self):
190        return self.base.item

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

addition: ItemIngredient
template_ingredient: ItemIngredient
result_item
188    @property
189    def result_item(self):
190        return self.base.item
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class SmithingTransformRecipe(hexdoc.minecraft.recipe.SmithingRecipe):
193class SmithingTransformRecipe(SmithingRecipe, type="minecraft:smithing_transform"):
194    result: ItemWithTexture
195
196    @property
197    def result_item(self):
198        return self.result

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

result_item
196    @property
197    def result_item(self):
198        return self.result
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class SmithingTrimRecipe(hexdoc.minecraft.recipe.SmithingRecipe):
201class SmithingTrimRecipe(SmithingRecipe, type="minecraft:smithing_trim"):
202    pass

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class SmokingRecipe(hexdoc.minecraft.recipe.CookingRecipe):
175class SmokingRecipe(
176    CookingRecipe,
177    type="minecraft:smoking",
178    workstation="minecraft:smoker",
179):
180    cookingtime: int = 100

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

cookingtime: int
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.

class StonecuttingRecipe(hexdoc.minecraft.recipe.Recipe):
205class StonecuttingRecipe(
206    Recipe,
207    type="minecraft:stonecutting",
208    workstation="minecraft:stonecutter",
209):
210    ingredient: ItemIngredientList
211    result: ItemWithTexture
212    count: int

Base model for Minecraft recipes.

https://minecraft.wiki/w/Recipe

ingredient: typing.Annotated[list[ItemIngredient], BeforeValidator(func=<function _validate_single_item_to_list at 0x7fbdf4451440>, json_schema_input_type=PydanticUndefined), AfterValidator(func=<function _validate_flatten_nested_tags at 0x7fbdf44519e0>)]
count: int
def model_post_init(self: pydantic.main.BaseModel, context: Any, /) -> None:
358def init_private_attributes(self: BaseModel, context: Any, /) -> None:
359    """This function is meant to behave like a BaseModel method to initialise private attributes.
360
361    It takes context as an argument since that's what pydantic-core passes when calling it.
362
363    Args:
364        self: The BaseModel instance.
365        context: The context.
366    """
367    if getattr(self, '__pydantic_private__', None) is None:
368        pydantic_private = {}
369        for name, private_attr in self.__private_attributes__.items():
370            default = private_attr.get_default()
371            if default is not PydanticUndefined:
372                pydantic_private[name] = default
373        object_setattr(self, '__pydantic_private__', pydantic_private)

This function is meant to behave like a BaseModel method to initialise private attributes.

It takes context as an argument since that's what pydantic-core passes when calling it.

Args: self: The BaseModel instance. context: The context.