Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlparse/utils.py: 48%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

63 statements  

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 if token is None: 

90 return False 

91 if i and isinstance(token, i): 

92 return True 

93 if m: 

94 if isinstance(m, list): 

95 if any(token.match(*pattern) for pattern in m): 

96 return True 

97 elif token.match(*m): 

98 return True 

99 if t: 

100 if isinstance(t, list): 

101 if any(token.ttype in ttype for ttype in t): 

102 return True 

103 elif token.ttype in t: 

104 return True 

105 return False 

106 

107 

108def consume(iterator, n): 

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

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

111 

112 

113@contextmanager 

114def offset(filter_, n=0): 

115 filter_.offset += n 

116 yield 

117 filter_.offset -= n 

118 

119 

120@contextmanager 

121def indent(filter_, n=1): 

122 filter_.indent += n 

123 yield 

124 filter_.indent -= n