Coverage for tarjinja/reversefilter.py: 98%

39 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-09-05 14:24 +0000

1from logging import getLogger 

2from typing import ClassVar 

3 

4from .iface import Filter 

5 

6log = getLogger(__name__) 

7 

8 

9class AbstractReverseFilter(Filter): 

10 def placeholder(self, name: str) -> str: 

11 raise NotImplementedError("placeholder") 

12 

13 tag_escape: ClassVar[dict[str, str]] = {} 

14 

15 def render(self, s: str, vals: dict) -> str: 

16 valmap = {} 

17 for k, v in vals.items(): 

18 if not v.__hash__: 

19 continue 

20 if v not in valmap: 20 ↛ 17line 20 didn't jump to line 17 because the condition on line 20 was always true

21 valmap[str(v)] = self.placeholder(k) 

22 for k, v in self.tag_escape.items(): 

23 valmap[k] = v 

24 log.debug("strtr: %s", valmap) 

25 res = self.strtr(s, valmap) 

26 log.debug("changed: %s <- %s", repr(res[:100]), repr(s[:100])) 

27 return res 

28 

29 

30class ReverseJinjaFilter(AbstractReverseFilter): 

31 tag_escape: ClassVar[dict[str, str]] = { 

32 x: "{%raw%}" + x + "{%endraw%}" for x in ["{{", "}}", "{%", "%}"] 

33 } 

34 

35 def placeholder(self, name: str) -> str: 

36 return "{{" + name + "}}" 

37 

38 

39class ReverseTemplateFilter(AbstractReverseFilter): 

40 tag_escape: ClassVar[dict[str, str]] = {"$": "$$"} 

41 

42 def placeholder(self, name: str) -> str: 

43 return "${" + name + "}" 

44 

45 

46class ReverseFormatFilter(AbstractReverseFilter): 

47 tag_escape: ClassVar[dict[str, str]] = {"{": "{{", "}": "}}"} 

48 

49 def placeholder(self, name: str) -> str: 

50 return "{" + name + "}" 

51 

52 

53class ReversePercentFilter(AbstractReverseFilter): 

54 tag_escape: ClassVar[dict[str, str]] = {"%": "%%"} 

55 

56 def placeholder(self, name: str) -> str: 

57 return "%(" + name + ")s" 

58 

59 

60class ReverseFstringFilter(ReverseFormatFilter): 

61 pass