pypindou.color.resources 源代码

"""
Built-in palette resource loading.

The packaged ``palettes.json`` file is generated from domestic and
international submodules by ``make resource``.  Runtime code should load
palettes through this module instead of reading the resource file directly.

Example::

    >>> from pypindou.color.resources import list_palettes
    >>> isinstance(list_palettes(), list)
    True
"""

from __future__ import annotations

import json
from functools import lru_cache
from typing import Any, Dict, Iterable, List, Optional, Union

from .model import BeadColor, Palette

try:
    from importlib import resources

    resources.files
except (AttributeError, ImportError):
    import importlib_resources as resources  # type: ignore[no-redef]


def _read_json(name: str) -> Any:
    with resources.files("pypindou.resources").joinpath(name).open("r", encoding="utf-8") as f:
        return json.load(f)


@lru_cache()
def _registry() -> Dict[str, Any]:
    return _read_json("palettes.json")


[文档] def list_palettes() -> List[Dict[str, Any]]: """ List built-in palettes. :return: Summary dictionaries for packaged palettes. :rtype: List[Dict[str, Any]] """ return [ { "id": item["id"], "title": item["title"], "count": item["count"], "standard": item.get("standard", "domestic"), "source": item.get("source"), "source_id": item.get("source_id"), "description": item.get("description"), } for item in _registry()["palettes"] ]
[文档] def load_palette(palette_id: str, *, allow_unidentified: bool = False) -> Palette: """ Load a built-in palette by id. :param palette_id: Built-in palette id. :type palette_id: str :param allow_unidentified: Whether to include colors marked ``unidentified``, defaults to ``False``. :type allow_unidentified: bool, optional :return: Loaded palette. :rtype: pypindou.color.Palette :raises KeyError: If ``palette_id`` is unknown. """ for item in _registry()["palettes"]: if item["id"] == palette_id: colors = [] for raw in item["colors"]: if raw.get("unidentified") and not allow_unidentified: continue metadata = { key: value for key, value in raw.items() if key not in { "code", "name", "hex", "rgb", "group", "source", "unidentified", "original_code", "metadata", } } metadata.update(raw.get("metadata") or {}) colors.append( BeadColor( code=raw["code"], name=raw.get("name"), rgb=tuple(raw["rgb"]), hex=raw.get("hex"), group=raw.get("group"), source=raw.get("source"), unidentified=bool(raw.get("unidentified", False)), original_code=raw.get("original_code"), metadata=metadata, ) ) return Palette( id=item["id"], title=item["title"], colors=tuple(colors), description=item.get("description"), standard=item.get("standard", "domestic"), source=item.get("source"), source_id=item.get("source_id"), source_url=item.get("source_url"), metadata=item.get("metadata") or {}, ) raise KeyError(f"Built-in palette {palette_id!r} not found.")
[文档] def get_palette( palette: Union[str, Palette], *, include_codes: Optional[Iterable[str]] = None, exclude_codes: Optional[Iterable[str]] = None, allow_unidentified: bool = False, max_colors: Optional[int] = None, ) -> Palette: """ Resolve and optionally filter a palette. :param palette: Built-in palette id or explicit palette object. :type palette: Union[str, pypindou.color.Palette] :param include_codes: Optional allow-list of color codes. :type include_codes: Optional[Iterable[str]], optional :param exclude_codes: Optional deny-list of color codes. :type exclude_codes: Optional[Iterable[str]], optional :param allow_unidentified: Whether to include colors marked ``unidentified``, defaults to ``False``. :type allow_unidentified: bool, optional :param max_colors: Optional leading color count after filtering. :type max_colors: Optional[int], optional :return: Resolved palette. :rtype: pypindou.color.Palette """ result = load_palette(palette, allow_unidentified=allow_unidentified) if isinstance(palette, str) else palette return result.filter( include_codes=include_codes, exclude_codes=exclude_codes, allow_unidentified=allow_unidentified, max_colors=max_colors, )