181 for key in attr.split("."): |
181 for key in attr.split("."): |
182 obj = getattr(obj, key) |
182 obj = getattr(obj, key) |
183 return obj |
183 return obj |
184 |
184 |
185 |
185 |
|
186 def calcLineRange(node): |
|
187 """ |
|
188 Function to calculate the line range for a subtree. |
|
189 |
|
190 @param node node to calculate the line range for |
|
191 @type ast.AST |
|
192 @return tuple containing the start and end line of the subtree |
|
193 @rtype tuple of (int, int) |
|
194 """ |
|
195 if hasattr(node, "_securityLineRange"): |
|
196 return node._securityLineRange |
|
197 |
|
198 lines_min = 9999999999 |
|
199 lines_max = -1 |
|
200 if hasattr(node, "lineno"): |
|
201 lines_min = node.lineno |
|
202 lines_max = node.lineno |
|
203 for n in ast.iter_child_nodes(node): |
|
204 lines_minmax = calcLineRange(n) |
|
205 lines_min = min(lines_min, lines_minmax[0]) |
|
206 lines_max = max(lines_max, lines_minmax[1]) |
|
207 |
|
208 node._securityLineRange = (lines_min, lines_max) |
|
209 |
|
210 return (lines_min, lines_max) |
|
211 |
|
212 |
186 def linerange(node): |
213 def linerange(node): |
187 """ |
214 """ |
188 Function to get line number range from a node. |
215 Function to get line number range from a node. |
189 |
216 |
190 @param node node to extract a line range from |
217 @param node node to extract a line range from |
191 @type ast.AST |
218 @type ast.AST |
192 @return list containing the line number range |
219 @return list containing the line number range |
193 @rtype list of int |
220 @rtype list of int |
194 """ |
221 """ |
195 strip = {"body": None, "orelse": None, "handlers": None, "finalbody": None} |
222 if hasattr(node, "lineno") and hasattr(node, "end_lineno"): |
196 for key in strip: |
223 return list(range(node.lineno, node.end_lineno + 1)) |
197 if hasattr(node, key): |
224 else: |
198 strip[key] = getattr(node, key) |
225 if hasattr(node, "_securityLineRangeStripped"): |
199 node.key = [] |
226 lines_minmax = node._securityLineRangeStripped |
200 |
227 return list(range(lines_minmax[0], lines_minmax[1] + 1)) |
201 lines_min = 9999999999 |
228 |
202 lines_max = -1 |
229 strip = { |
203 for n in ast.walk(node): |
230 "body": None, |
204 if hasattr(n, "lineno"): |
231 "orelse": None, |
205 lines_min = min(lines_min, n.lineno) |
232 "handlers": None, |
206 lines_max = max(lines_max, n.lineno) |
233 "finalbody": None, |
207 |
234 } |
208 for key in strip: |
235 for key in strip: |
209 if strip[key] is not None: |
236 if hasattr(node, key): |
210 node.key = strip[key] |
237 strip[key] = getattr(node, key) |
211 |
238 setattr(node, key, []) |
212 if lines_max > -1: |
239 |
213 return list(range(lines_min, lines_max + 1)) |
240 lines_min = 9999999999 |
214 |
241 lines_max = -1 |
215 return [0, 1] |
242 if hasattr(node, "lineno"): |
216 |
243 lines_min = node.lineno |
217 |
244 lines_max = node.lineno |
218 def linerange_fix(node): |
245 for n in ast.iter_child_nodes(node): |
219 """ |
246 lines_minmax = calcLineRange(n) |
220 Function to get a line number range working around a known Python bug |
247 lines_min = min(lines_min, lines_minmax[0]) |
221 with multi-line strings. |
248 lines_max = max(lines_max, lines_minmax[1]) |
222 |
249 |
223 @param node node to extract a line range from |
250 for key in strip: |
224 @type ast.AST |
251 if strip[key] is not None: |
225 @return list containing the line number range |
252 setattr(node, key, strip[key]) |
226 @rtype list of int |
253 |
227 """ |
254 if lines_max == -1: |
228 # deal with multiline strings lineno behavior (Python issue #16806) |
255 lines_min = 0 |
229 lines = linerange(node) |
256 lines_max = 1 |
230 if hasattr(node, "_securitySibling") and hasattr(node._securitySibling, "lineno"): |
257 |
231 start = min(lines) |
258 node._securityLineRangeStripped = (lines_min, lines_max) |
232 delta = node._securitySibling.lineno - start |
259 |
233 if delta > 1: |
260 lines = list(range(lines_min, lines_max + 1)) |
234 return list(range(start, node._securitySibling.lineno)) |
261 # deal with multi-line strings lineno behavior (Python issue #16806) |
235 |
262 if hasattr(node, "_securitySibling") and hasattr( |
236 return lines |
263 node._securitySibling, "lineno" |
|
264 ): |
|
265 start = min(lines) |
|
266 delta = node._securitySibling.lineno - start |
|
267 if delta > 1: |
|
268 return list(range(start, node._securitySibling.lineno)) |
|
269 |
|
270 return lines |
237 |
271 |
238 |
272 |
239 def escapedBytesRepresentation(b): |
273 def escapedBytesRepresentation(b): |
240 """ |
274 """ |
241 Function to escape bytes for comparison with other strings. |
275 Function to escape bytes for comparison with other strings. |