Evaluate provided code in the evaluation context. If evaluation policy given by context is set to ``forbidden`` no evaluation will be performed; if it is set to ``dangerous`` standard :func:`eval` will be used; finally, for any other, policy :func:`eval_node` will be called on parse
(code: str, context: EvaluationContext)
| 431 | |
| 432 | |
| 433 | def guarded_eval(code: str, context: EvaluationContext): |
| 434 | """Evaluate provided code in the evaluation context. |
| 435 | |
| 436 | If evaluation policy given by context is set to ``forbidden`` |
| 437 | no evaluation will be performed; if it is set to ``dangerous`` |
| 438 | standard :func:`eval` will be used; finally, for any other, |
| 439 | policy :func:`eval_node` will be called on parsed AST. |
| 440 | """ |
| 441 | locals_ = context.locals |
| 442 | |
| 443 | if context.evaluation == "forbidden": |
| 444 | raise GuardRejection("Forbidden mode") |
| 445 | |
| 446 | # note: not using `ast.literal_eval` as it does not implement |
| 447 | # getitem at all, for example it fails on simple `[0][1]` |
| 448 | |
| 449 | if context.in_subscript: |
| 450 | # syntactic sugar for ellipsis (:) is only available in subscripts |
| 451 | # so we need to trick the ast parser into thinking that we have |
| 452 | # a subscript, but we need to be able to later recognise that we did |
| 453 | # it so we can ignore the actual __getitem__ operation |
| 454 | if not code: |
| 455 | return tuple() |
| 456 | locals_ = locals_.copy() |
| 457 | locals_[SUBSCRIPT_MARKER] = IDENTITY_SUBSCRIPT |
| 458 | code = SUBSCRIPT_MARKER + "[" + code + "]" |
| 459 | context = context.replace(locals=locals_) |
| 460 | |
| 461 | if context.evaluation == "dangerous": |
| 462 | return eval(code, context.globals, context.locals) |
| 463 | |
| 464 | node = ast.parse(code, mode="exec") |
| 465 | |
| 466 | return eval_node(node, context) |
| 467 | |
| 468 | |
| 469 | BINARY_OP_DUNDERS: dict[type[ast.operator], tuple[str]] = { |
searching dependent graphs…