Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/sqlparse/utils.py: 23%

57 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1# 

2# Copyright (C) 2009-2020 the sqlparse authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of python-sqlparse and is released under 

6# the BSD License: https://opensource.org/licenses/BSD-3-Clause 

7 

8import itertools 

9import re 

10from collections import deque 

11from contextlib import contextmanager 

12 

13# This regular expression replaces the home-cooked parser that was here before. 

14# It is much faster, but requires an extra post-processing step to get the 

15# desired results (that are compatible with what you would expect from the 

16# str.splitlines() method). 

17# 

18# It matches groups of characters: newlines, quoted strings, or unquoted text, 

19# and splits on that basis. The post-processing step puts those back together 

20# into the actual lines of SQL. 

21SPLIT_REGEX = re.compile(r""" 

22( 

23 (?: # Start of non-capturing group 

24 (?:\r\n|\r|\n) | # Match any single newline, or 

25 [^\r\n'"]+ | # Match any character series without quotes or 

26 # newlines, or 

27 "(?:[^"\\]|\\.)*" | # Match double-quoted strings, or 

28 '(?:[^'\\]|\\.)*' # Match single quoted strings 

29 ) 

30) 

31""", re.VERBOSE) 

32 

33LINE_MATCH = re.compile(r'(\r\n|\r|\n)') 

34 

35 

36def split_unquoted_newlines(stmt): 

37 """Split a string on all unquoted newlines. 

38 

39 Unlike str.splitlines(), this will ignore CR/LF/CR+LF if the requisite 

40 character is inside of a string.""" 

41 text = str(stmt) 

42 lines = SPLIT_REGEX.split(text) 

43 outputlines = [''] 

44 for line in lines: 

45 if not line: 

46 continue 

47 elif LINE_MATCH.match(line): 

48 outputlines.append('') 

49 else: 

50 outputlines[-1] += line 

51 return outputlines 

52 

53 

54def remove_quotes(val): 

55 """Helper that removes surrounding quotes from strings.""" 

56 if val is None: 

57 return 

58 if val[0] in ('"', "'", '`') and val[0] == val[-1]: 

59 val = val[1:-1] 

60 return val 

61 

62 

63def recurse(*cls): 

64 """Function decorator to help with recursion 

65 

66 :param cls: Classes to not recurse over 

67 :return: function 

68 """ 

69 def wrap(f): 

70 def wrapped_f(tlist): 

71 for sgroup in tlist.get_sublists(): 

72 if not isinstance(sgroup, cls): 

73 wrapped_f(sgroup) 

74 f(tlist) 

75 

76 return wrapped_f 

77 

78 return wrap 

79 

80 

81def imt(token, i=None, m=None, t=None): 

82 """Helper function to simplify comparisons Instance, Match and TokenType 

83 :param token: 

84 :param i: Class or Tuple/List of Classes 

85 :param m: Tuple of TokenType & Value. Can be list of Tuple for multiple 

86 :param t: TokenType or Tuple/List of TokenTypes 

87 :return: bool 

88 """ 

89 clss = i 

90 types = [t, ] if t and not isinstance(t, list) else t 

91 mpatterns = [m, ] if m and not isinstance(m, list) else m 

92 

93 if token is None: 

94 return False 

95 elif clss and isinstance(token, clss): 

96 return True 

97 elif mpatterns and any(token.match(*pattern) for pattern in mpatterns): 

98 return True 

99 elif types and any(token.ttype in ttype for ttype in types): 

100 return True 

101 else: 

102 return False 

103 

104 

105def consume(iterator, n): 

106 """Advance the iterator n-steps ahead. If n is none, consume entirely.""" 

107 deque(itertools.islice(iterator, n), maxlen=0) 

108 

109 

110@contextmanager 

111def offset(filter_, n=0): 

112 filter_.offset += n 

113 yield 

114 filter_.offset -= n 

115 

116 

117@contextmanager 

118def indent(filter_, n=1): 

119 filter_.indent += n 

120 yield 

121 filter_.indent -= n