Coverage for src/robotide/utils/__init__.py: 86%

111 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-06 10:40 +0100

1# Copyright 2008-2015 Nokia Networks 

2# Copyright 2016- Robot Framework Foundation 

3# 

4# Licensed under the Apache License, Version 2.0 (the "License"); 

5# you may not use this file except in compliance with the License. 

6# You may obtain a copy of the License at 

7# 

8# http://www.apache.org/licenses/LICENSE-2.0 

9# 

10# Unless required by applicable law or agreed to in writing, software 

11# distributed under the License is distributed on an "AS IS" BASIS, 

12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 

13# See the License for the specific language governing permissions and 

14# limitations under the License. 

15 

16import os 1ab

17import re 1ab

18import sys 1ab

19import inspect 1ab

20import subprocess 1ab

21 

22import robotide.lib.robot.utils 1ab

23from robotide.lib.robot.utils.encoding import SYSTEM_ENCODING 1ab

24from robotide.lib.robot.utils import printable_name, normalize, _normalize, eq, ET, \ 1ab

25 HtmlWriter, NormalizedDict, timestr_to_secs, secs_to_timestr, normpath,\ 

26 unic, asserts, unescape, html_escape, attribute_escape, robottime,\ 

27 get_timestamp, Matcher, is_list_like, is_dict_like, system_decode,\ 

28 ArgumentParser, get_error_details, is_unicode, is_string, py2to3 

29from .eventhandler import RideFSWatcherHandler 1ab

30from .printing import Printing 1ab

31 

32 

33def html_format(text): 1ab

34 return robotide.lib.robot.utils.html_format(text) 2]b^b

35 

36 

37def name_from_class(item, drop=None): 1ab

38 cls = inspect.isclass(item) and item or item.__class__ 

39 name = cls.__name__ 

40 if drop and name.endswith(drop): 

41 name = name[:-len(drop)] 

42 return printable_name(name, code_style=True) 

43 

44 

45def split_value(value, sep='|'): 1ab

46 if not value: 2a K Q p R L M yb+b,bzbAbBbCb-b.bDbEbFb/bGbHbo Ib:bJbKbLb;bMbNbObPbQbJ N d RbSbTb=bUbVbWb?bXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b@b$b%b'b(be )b*bT

47 return [] 2a Q p R +b,b-b.b/b:b;bMbNbJ =b?b@b

48 return [v.strip() for v in _split_value(value, sep)] 2K L M ybzbAbBbCbDbEbFbGbHbo IbJbKbLbObPbQbJ N d RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(be )b*bT

49 

50 

51def _split_value(value, sep): 1ab

52 if '\\' not in value: 2K L M ybzbAbBbCbDbEbFbGbHbo IbJbKbLbObPbQbJ N d RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(be )b*bT

53 return value.split(sep) 2K L M ybzbAbBbCbDbEbFbGbHbIbJbKbLbObPbQbJ N d RbSbTbUbVbWbXbYbZb0b1b2b3b4b5b6b7b8b9b!b#b$b%b'b(be )b*bT

54 ret = [] 1oe

55 catenate_next = False 1oe

56 for item in value.split(sep): 1oe

57 bslash_count = len(item) - len(item.rstrip('\\')) 1oe

58 escaped = bslash_count % 2 == 1 1oe

59 if escaped: 1oe

60 item = item[:-1] 1oe

61 if catenate_next: 1oe

62 ret[-1] += sep + item 1oe

63 else: 

64 ret.append(item) 1oe

65 catenate_next = escaped 1oe

66 return ret 1oe

67 

68 

69def join_value(value, sep='|', joiner=None): 1ab

70 if not joiner: 70 ↛ 72line 70 didn't jump to line 72 because the condition on line 70 was always true1T

71 joiner = ' %s ' % sep 1T

72 return joiner.join([v.replace(sep, '\\' + sep) for v in value]) 1T

73 

74 

75def find_from_pythonpath(name): 1ab

76 for dirpath in sys.path: 1apYZ0S12dcU3V4WX56789!#

77 if not os.path.isdir(dirpath): 1apYZ0S12dcU3V4WX56789!#

78 continue 1apYZ0S12dcU3V4WX56789!#

79 path = os.path.join(dirpath, name) 1apYZ0S12dcU3V4WX56789!#

80 if os.path.isfile(path): 1apYZ0S12dcU3V4WX56789!#

81 return path 1acUVWX678

82 return None 1apYZ0S12dcU3V4WX59!#

83 

84 

85def replace_extension(path, new_extension): 1ab

86 base = path.rsplit('.', 1) 2a [bMbS Nb

87 return '%s.%s' % (base[0], new_extension.lower()) 2a [bMbS Nb

88 

89 

90def overrides(interface_class): 1ab

91 # type: (object) -> object 

92 """ 

93 A decorator that can be used to validate method override 

94 

95 http://stackoverflow.com/questions/1167617/in-python-how-do-i-indicate-im-overriding-a-method/8313042#8313042 

96 """ 

97 def overrider(method): 

98 assert(method.__name__ in dir(interface_class)) 

99 return method 

100 return overrider 

101 

102 

103def is_same_drive(path1, path2): 1ab

104 return os.path.splitdrive(path1)[0].lower() == \ 

105 os.path.splitdrive(path2)[0].lower() 

106 

107 

108def run_python_command(command, mode='c'): 1ab

109 cmd = [sys.executable, '-{0}'.format(mode)] + command 

110 # DEBUG: Let the user select which robot to use 

111 process = subprocess.Popen( 

112 cmd, 

113 stdout=subprocess.PIPE, 

114 stderr=subprocess.PIPE) 

115 output, _ = process.communicate() 

116 return output 

117 

118 

119def converttypes(data, prefer_str=True): 1ab

120 """ 

121 Convert all types from Python2 to Python3 

122 """ 

123 enc = sys.stdout and sys.stdout.encoding or "utf-8" 

124 data_type = type(data) 

125 

126 if data_type == bytes: 

127 if prefer_str: 

128 return str(data.decode(enc)) 

129 return data.decode(enc) 

130 if data_type in (str, int): 

131 return str(data) 

132 

133 if data_type == dict: 

134 data = data.items() 

135 return data_type(map(converttypes, data)) 

136 

137 

138_regexps = (re.compile(r'(\\+)r\\n'), 1ab

139 re.compile(r'(\\+)n'), 

140 re.compile(r'(\\+)r'), 

141 re.compile(r'(\\+) ')) 

142 

143 

144def unescape_newlines_and_whitespaces(item): 1ab

145 for regexp in _regexps: 2a O P nbobpbqbrbsbtbubvbwbxb

146 if regexp.pattern.endswith(' '): 2a O P nbobpbqbrbsbtbubvbwbxb

147 item = regexp.sub(_whitespace_replacer, item) 2a O P nbobpbqbrbsbtbubvbwbxb

148 else: 

149 item = regexp.sub(_newline_replacer, item) 2a O P nbobpbqbrbsbtbubvbwbxb

150 return item 2a O P nbobpbqbrbsbtbubvbwbxb

151 

152 

153def _whitespace_replacer(match): 1ab

154 return _replacer(' ', match) 

155 

156 

157def _newline_replacer(match): 1ab

158 return _replacer(os.linesep, match) 1aOP

159 

160 

161def _replacer(char, match): 1ab

162 slashes = len(match.group(1)) 1aOP

163 if slashes % 2 == 1: 1aOP

164 return '\\' * (slashes - 1) + char 1aOP

165 return match.group() 1aO

166 

167 

168def normalize_lc(string, remove='', spaces=True): 1ab

169 string = string.lower() 2a $ K Q p R L M % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbJ N d ibf q r s t u v w x y z g A B C D E F G H h c i j k l I m n jbkblbmb

170 if spaces: 2a $ K Q p R L M % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbJ N d ibf q r s t u v w x y z g A B C D E F G H h c i j k l I m n jbkblbmb

171 remove = remove + ' ' 1afqrstuvwxyzgABCDEFGHhcijklImn

172 for char in remove: 2a $ K Q p R L M % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbJ N d ibf q r s t u v w x y z g A B C D E F G H h c i j k l I m n jbkblbmb

173 if char in string: 1afqrstuvwxyzgABCDEFGHhcijklImn

174 string = string.replace(char, '') 1afqrstuvwxyzgABCDEFGHhcijklImn

175 return string 2a $ K Q p R L M % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbJ N d ibf q r s t u v w x y z g A B C D E F G H h c i j k l I m n jbkblbmb

176 

177 

178def normalize_dict(table: dict) -> dict: 1ab

179 ndict = {} 1afqrstuvwxyzgABCDEFGHhcijklImn

180 for key, value in table.items(): 1afqrstuvwxyzgABCDEFGHhcijklImn

181 if key: 1afqrstuvwxyzgABCDEFGHhcijklImn

182 k = normalize_lc(key) 1afqrstuvwxyzgABCDEFGHhcijklImn

183 v = normalize_lc(value) 1afqrstuvwxyzgABCDEFGHhcijklImn

184 ndict[k] = v 1afqrstuvwxyzgABCDEFGHhcijklImn

185 return ndict 1afqrstuvwxyzgABCDEFGHhcijklImn

186 

187 

188def normalize_pipe_list(data: list, spaces: bool = True) -> str: 1ab

189 pipe_list = "|".join(data) 2a $ K Q p R L M % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbJ N d ibf g h c i j k l m n jbkblbmb

190 return normalize_lc(pipe_list, spaces=spaces) 2a $ K Q p R L M % ' ( ) * + , - . / : ; = ? @ [ ] ^ _ ` { | } ~ abbbcbdbebfbgbhbJ N d ibf g h c i j k l m n jbkblbmb

191