# SPDX-License-Identifier: GPLv3-or-later
# Copyright © 2025 pygaindalf Rui Pinheiro
from collections.abc import Callable, Iterable, Iterator
from dataclasses import dataclass
from typing import Any, overload, override
from pydantic import BaseModel, Field
from .context_stack import ContextStack
# MARK : Inherit Factory
[docs]
class InheritFactory[T]:
[docs]
def __init__(self, default: T | None = None, default_factory: Callable[..., T] | None = None) -> None:
self.default = default
self.default_factory = default_factory
[docs]
def search(self, name: str) -> dict[str, Any] | BaseModel | None:
return ContextStack.find_inheritance(name)
def __call__(self) -> T:
if self.default_factory is not None:
return self.default_factory()
elif self.default is not None:
return self.default
else:
return None # pyright: ignore[reportReturnType]
@override
def __repr__(self) -> str:
return f"InheritFactory(default={self.default})"
@overload
def FieldInherit[T](default: T, *args, **kwargs) -> T: ...
@overload
def FieldInherit[T](default_factory: Callable[..., T], *args, **kwargs) -> T: ...
[docs]
def FieldInherit[T](default: T | None = None, default_factory: Callable[..., T] | None = None, *args, **kwargs) -> T: # pyright: ignore[reportInconsistentOverload] # noqa: N802
return Field(default_factory=InheritFactory(*args, default=default, default_factory=default_factory), validate_default=True, **kwargs)
# MARK : Diffing
[docs]
@dataclass
class AttributeSet:
attrs: frozenset[str] | None = None
[docs]
def __init__(self, attrs: Iterable[str] | None = None) -> None:
self.attrs = frozenset(attrs) if attrs is not None else None
def __contains__(self, item: str) -> bool:
if self.attrs is None:
return False
return item in self.attrs
def __iter__(self) -> Iterator[str]:
if self.attrs is None:
return iter(())
return iter(self.attrs)
@override
def __repr__(self) -> str:
if self.attrs is None:
return f"{type(self).__name__}()"
return f"{type(self).__name__}({', '.join(self.attrs)})"
[docs]
class Inherit(AttributeSet):
pass
[docs]
class Default(AttributeSet):
pass