Coverage for src/regex_template/__init__.py: 100%

22 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-13 11:01 -0700

1# SPDX-FileCopyrightText: 2025-present Trey Hunner 

2# 

3# SPDX-License-Identifier: MIT 

4"""regex_template - Compiled regular expressions with auto-escaped interpolations""" 

5 

6import re 

7from string import Formatter 

8from string.templatelib import Interpolation, Template 

9 

10 

11__all__ = ["compile"] 

12 

13 

14# https://discuss.python.org/t/add-convert-function-to-string-templatelib/94569/10 

15_convert = classmethod(Formatter.convert_field).__get__(Formatter) 

16 

17 

18def compile(template, flags=0, verbose=True): 

19 """ 

20 Compile a regular expression with auto-escaped interpolations. 

21  

22 Only accepts t-string Templates. Automatically escapes interpolated values 

23 unless they use the :safe format specifier. 

24  

25 Args: 

26 template: A t-string Template to compile 

27 flags: Regular expression flags (same as re.compile) 

28 verbose: If True, adds re.VERBOSE flag for readable patterns 

29  

30 Returns: 

31 A compiled regular expression Pattern object 

32  

33 Raises: 

34 TypeError: If template is not a Template object (t-string) 

35 """ 

36 if not isinstance(template, Template): 

37 raise TypeError( 

38 f"regex_template.compile() only accepts t-string Templates, " 

39 f"got {type(template).__name__}. Use re.compile() for regular strings." 

40 ) 

41 

42 if verbose: 

43 flags |= re.VERBOSE 

44 

45 # Process t-string Template 

46 parts = [] 

47 for item in template: 

48 match item: 

49 case Interpolation(value, _, conversion, format_spec): 

50 value = _convert(value, conversion) 

51 if format_spec == "safe": 

52 parts.append(str(value)) 

53 else: 

54 formatted_value = format(value, format_spec) 

55 parts.append(re.escape(str(formatted_value))) 

56 case _: 

57 parts.append(item) 

58 return re.compile("".join(parts), flags=flags) 

59