Coverage for src/configuraptor/postpone.py: 47%
19 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-09 20:12 +0100
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-09 20:12 +0100
1"""
2File contains logic to do with the 'postpone' feature.
3"""
5from typing import Any, Optional
7from typing_extensions import Never
9from .errors import IsPostponedError
10from .singleton import Singleton
13class Postponed(Singleton):
14 """
15 Class returned by `postpone` below.
16 """
18 def __get_property_name__(self, instance: type[Any], owner: type[Any]) -> Optional[str]:
19 """
20 Internal method to get the property name of the class this descriptor is being used on.
21 """
22 if not instance: # pragma: no cover
23 return None
25 # instance: the instance the descriptor is accessed from
26 # owner: the class that owns the descriptor
27 property_name = None
28 for attr_name, attr_value in owner.__dict__.items():
29 if attr_value is self:
30 property_name = attr_name
31 break
32 # return instance.__dict__.get(property_name, None)
33 return property_name
35 def __get__(self, instance: type[Any], owner: type[Any]) -> Never:
36 """
37 This magic method is called when a property is accessed.
39 Example:
40 someclass.someprop will trigger the __get__ of `someprop`
42 Args:
43 instance: the class on which the postponed property is defined,
44 owner: `SingletonMeta`
45 """
46 msg = f"Err: Using postponed property on {owner.__name__}"
48 if name := self.__get_property_name__(instance, owner):
49 msg += f".{name}"
51 raise IsPostponedError(msg)
54def postpone() -> Any:
55 """
56 Can be used to mark a property as postponed, meaning the user will fill it in later (they promose).
58 If they don't fill it in and still try to use it, they will be met with a IsPostponedError.
59 """
60 return Postponed()