mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
33 lines
1.1 KiB
Python
33 lines
1.1 KiB
Python
import inspect
|
|
from typing import Any, Callable
|
|
|
|
|
|
class private:
|
|
"""Decorator that raises if a _-prefixed method is called from outside its class."""
|
|
|
|
func: Callable[..., Any]
|
|
name: str
|
|
owner: type
|
|
|
|
def __init__(self, func: Callable[..., Any]) -> None:
|
|
self.func = func
|
|
self.name = getattr(func, "__name__", "<anonymous>")
|
|
|
|
def __set_name__(self, owner: type, name: str) -> None:
|
|
self.owner = owner
|
|
|
|
def __get__(self, instance: Any, owner: type) -> Callable[..., Any]:
|
|
# Walk up one frame to see who's calling
|
|
frame = inspect.currentframe()
|
|
if frame is None or frame.f_back is None:
|
|
raise RuntimeError("cannot inspect caller frame")
|
|
caller_frame = frame.f_back
|
|
caller_self = caller_frame.f_locals.get("self")
|
|
|
|
if not isinstance(caller_self, self.owner):
|
|
raise RuntimeError(
|
|
f"{self.owner.__name__}.{self.name} is private; "
|
|
f"called from {caller_frame.f_code.co_name}"
|
|
)
|
|
|
|
return getattr(self.func, "__get__")(instance, owner)
|