Coverage for src/lektor_ng/types/base.py: 82%

57 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-08-03 16:19 +0000

1from jinja2 import Undefined 

2 

3from lektor_ng.constants import PRIMARY_ALT 

4 

5 

6class BadValue(Undefined): 

7 __slots__ = () 

8 

9 

10def get_undefined_info(undefined): 

11 if isinstance(undefined, Undefined): 

12 try: 

13 undefined._fail_with_undefined_error() 

14 except Exception as e: 

15 return str(e) 

16 return "defined value" 

17 

18 

19class RawValue: 

20 __slots__ = ("field", "name", "pad", "value") 

21 

22 def __init__(self, name, value=None, field=None, pad=None): 

23 self.name = name 

24 self.value = value 

25 self.field = field 

26 self.pad = pad 

27 

28 def _get_hint(self, prefix, reason): 

29 if self.field is not None: 

30 return f"{prefix} in field '{self.field.name}': {reason}" 

31 return f"{prefix}: {reason}" 

32 

33 def bad_value(self, reason): 

34 return BadValue(hint=self._get_hint("Bad value", reason), obj=self.value) 

35 

36 def missing_value(self, reason): 

37 return Undefined(hint=self._get_hint("Missing value", reason), obj=self.value) 

38 

39 

40class _NameDescriptor: 

41 def __get__(self, obj, type): 

42 rv = type.__name__ 

43 rv = rv.removesuffix("Type") 

44 return rv.lower() 

45 

46 

47class Type: 

48 widget = "multiline-text" 

49 

50 def __init__(self, env, options): 

51 self.env = env 

52 self.options = options 

53 

54 @property 

55 def size(self): 

56 size = self.options.get("size") or "normal" 

57 if size not in ("normal", "small", "large"): 

58 size = "normal" 

59 return size 

60 

61 @property 

62 def width(self): 

63 return self.options.get("width") or "1/1" 

64 

65 name = _NameDescriptor() 

66 

67 def to_json(self, pad, record=None, alt=PRIMARY_ALT): 

68 return { 

69 "name": self.name, 

70 "widget": self.widget, 

71 "size": self.size, 

72 "width": self.width, 

73 } 

74 

75 def value_from_raw(self, raw): 

76 # pylint: disable=no-self-use 

77 return raw 

78 

79 def value_from_raw_with_default(self, raw): 

80 value = self.value_from_raw(raw) 

81 if isinstance(value, Undefined) and raw.field is not None and raw.field.default is not None: 

82 return self.value_from_raw(RawValue(raw.name, raw.field.default, field=raw.field, pad=raw.pad)) 

83 return value 

84 

85 def __repr__(self): 

86 return f"{self.__class__.__name__}()"