File: common.py

package info (click to toggle)
dpdk 25.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 127,892 kB
  • sloc: ansic: 2,358,479; python: 16,426; sh: 4,474; makefile: 1,713; awk: 70
file content (59 lines) | stat: -rw-r--r-- 1,797 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2025 Arm Limited

"""Common definitions and objects for the configuration."""

from collections.abc import Callable, MutableMapping
from typing import TYPE_CHECKING, Any, TypedDict, cast

from pydantic import BaseModel, ConfigDict, ValidationInfo

if TYPE_CHECKING:
    from framework.settings import Settings


class ValidationContext(TypedDict):
    """A context dictionary to use for validation."""

    #: The command line settings.
    settings: "Settings"


def load_fields_from_settings(
    *fields: str | tuple[str, str],
) -> Callable[[Any, ValidationInfo], Any]:
    """Before model validator that injects values from :attr:`ValidationContext.settings`.

    Args:
        *fields: The name of the fields to apply the argument value to. If the settings field name
            is not the same as the configuration field, supply a tuple with the respective names.

    Returns:
        Pydantic before model validator.
    """

    def _loader(data: Any, info: ValidationInfo) -> Any:
        if not isinstance(data, MutableMapping):
            return data

        settings = cast(ValidationContext, info.context)["settings"]
        for field in fields:
            if isinstance(field, tuple):
                settings_field = field[0]
                config_field = field[1]
            else:
                settings_field = config_field = field

            if settings_data := getattr(settings, settings_field):
                data[config_field] = settings_data

        return data

    return _loader


class FrozenModel(BaseModel):
    """A pre-configured :class:`~pydantic.BaseModel`."""

    #: Fields are set as read-only and any extra fields are forbidden.
    model_config = ConfigDict(frozen=True, extra="forbid")