Trim the code until it is a valid expression and not a tuple; return the trimmed expression for guarded_eval.
(self, code: str)
| 1335 | ) |
| 1336 | |
| 1337 | def _trim_expr(self, code: str) -> str: |
| 1338 | """ |
| 1339 | Trim the code until it is a valid expression and not a tuple; |
| 1340 | |
| 1341 | return the trimmed expression for guarded_eval. |
| 1342 | """ |
| 1343 | while code: |
| 1344 | code = code[1:] |
| 1345 | try: |
| 1346 | res = ast.parse(code) |
| 1347 | except SyntaxError: |
| 1348 | continue |
| 1349 | |
| 1350 | assert res is not None |
| 1351 | if len(res.body) != 1: |
| 1352 | continue |
| 1353 | if not isinstance(res.body[0], ast.Expr): |
| 1354 | continue |
| 1355 | expr = res.body[0].value |
| 1356 | if isinstance(expr, ast.Tuple) and not code[-1] == ")": |
| 1357 | # we skip implicit tuple, like when trimming `fun(a,b`<completion> |
| 1358 | # as `a,b` would be a tuple, and we actually expect to get only `b` |
| 1359 | continue |
| 1360 | return code |
| 1361 | return "" |
| 1362 | |
| 1363 | def _evaluate_expr(self, expr): |
| 1364 | obj = not_found |