Coverage for src/griffe_pydantic/_internal/common.py: 100.00%
28 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-05 17:55 +0200
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-05 17:55 +0200
1from __future__ import annotations
3import json
4from functools import partial
5from typing import TYPE_CHECKING
7if TYPE_CHECKING:
8 from collections.abc import Sequence
10 from griffe import Attribute, Class, Function
11 from pydantic import BaseModel
13_self_namespace = "griffe_pydantic"
14_mkdocstrings_namespace = "mkdocstrings"
16_field_constraints = {
17 "gt",
18 "ge",
19 "lt",
20 "le",
21 "multiple_of",
22 "min_length",
23 "max_length",
24 "pattern",
25 "allow_inf_nan",
26 "max_digits",
27 "decimal_place",
28}
31def _model_fields(cls: Class) -> dict[str, Attribute]:
32 return {name: attr for name, attr in cls.all_members.items() if "pydantic-field" in attr.labels} # type: ignore[misc]
35def _model_validators(cls: Class) -> dict[str, Function]:
36 return {name: func for name, func in cls.all_members.items() if "pydantic-validator" in func.labels} # type: ignore[misc]
39def _json_schema(model: type[BaseModel]) -> str:
40 """Produce a model schema as JSON.
42 Parameters:
43 model: A Pydantic model.
45 Returns:
46 A schema as JSON.
47 """
48 return json.dumps(model.model_json_schema(), indent=2)
51def _process_class(cls: Class) -> None:
52 """Set metadata on a Pydantic model.
54 Parameters:
55 cls: The Griffe class representing the Pydantic model.
56 """
57 cls.labels.add("pydantic-model")
58 cls.extra[_self_namespace]["fields"] = partial(_model_fields, cls)
59 cls.extra[_self_namespace]["validators"] = partial(_model_validators, cls)
60 cls.extra[_mkdocstrings_namespace]["template"] = "pydantic_model.html.jinja"
63def _process_function(func: Function, cls: Class, fields: Sequence[str]) -> None:
64 """Set metadata on a Pydantic validator.
66 Parameters:
67 cls: A Griffe function representing the Pydantic validator.
68 """
69 func.labels = {"pydantic-validator"}
70 if fields and fields[0] == "*":
71 targets = [member for member in cls.all_members.values() if "pydantic-field" in member.labels]
72 else:
73 targets = [cls.all_members[field] for field in fields]
75 func.extra[_self_namespace].setdefault("targets", [])
76 func.extra[_self_namespace]["targets"].extend(targets)
77 for target in targets:
78 target.extra[_self_namespace].setdefault("validators", [])
79 target.extra[_self_namespace]["validators"].append(func)