| 210 | |
| 211 | @lru_cache(3) |
| 212 | def _expression_to_evaluate(expression): |
| 213 | keepends = True |
| 214 | lines = expression.splitlines(keepends) |
| 215 | # find first non-empty line |
| 216 | chars_to_strip = 0 |
| 217 | for line in lines: |
| 218 | if line.strip(): # i.e.: check first non-empty line |
| 219 | for c in iter_chars(line): |
| 220 | if c.isspace(): |
| 221 | chars_to_strip += 1 |
| 222 | else: |
| 223 | break |
| 224 | break |
| 225 | |
| 226 | if chars_to_strip: |
| 227 | # I.e.: check that the chars we'll remove are really only whitespaces. |
| 228 | proceed = True |
| 229 | new_lines = [] |
| 230 | for line in lines: |
| 231 | if not proceed: |
| 232 | break |
| 233 | for c in iter_chars(line[:chars_to_strip]): |
| 234 | if not c.isspace(): |
| 235 | proceed = False |
| 236 | break |
| 237 | |
| 238 | new_lines.append(line[chars_to_strip:]) |
| 239 | |
| 240 | if proceed: |
| 241 | if isinstance(expression, bytes): |
| 242 | expression = b"".join(new_lines) |
| 243 | else: |
| 244 | expression = "".join(new_lines) |
| 245 | |
| 246 | return expression |
| 247 | |
| 248 | |
| 249 | def eval_in_context(expression, global_vars, local_vars, py_db=None): |