:param str expression: The expression to be evaluated. Note that if the expression is indented it's automatically dedented (based on the indentation found on the first non-empty line). i.e.: something as: ` def method(): a =
(py_db, frame, expression, is_exec)
| 443 | |
| 444 | @_evaluate_with_timeouts |
| 445 | def evaluate_expression(py_db, frame, expression, is_exec): |
| 446 | """ |
| 447 | :param str expression: |
| 448 | The expression to be evaluated. |
| 449 | |
| 450 | Note that if the expression is indented it's automatically dedented (based on the indentation |
| 451 | found on the first non-empty line). |
| 452 | |
| 453 | i.e.: something as: |
| 454 | |
| 455 | ` |
| 456 | def method(): |
| 457 | a = 1 |
| 458 | ` |
| 459 | |
| 460 | becomes: |
| 461 | |
| 462 | ` |
| 463 | def method(): |
| 464 | a = 1 |
| 465 | ` |
| 466 | |
| 467 | Also, it's possible to evaluate calls with a top-level await (currently this is done by |
| 468 | creating a new event loop in a new thread and making the evaluate at that thread -- note |
| 469 | that this is still done synchronously so the evaluation has to finish before this |
| 470 | function returns). |
| 471 | |
| 472 | :param is_exec: determines if we should do an exec or an eval. |
| 473 | There are some changes in this function depending on whether it's an exec or an eval. |
| 474 | |
| 475 | When it's an exec (i.e.: is_exec==True): |
| 476 | This function returns None. |
| 477 | Any exception that happens during the evaluation is reraised. |
| 478 | If the expression could actually be evaluated, the variable is printed to the console if not None. |
| 479 | |
| 480 | When it's an eval (i.e.: is_exec==False): |
| 481 | This function returns the result from the evaluation. |
| 482 | If some exception happens in this case, the exception is caught and a ExceptionOnEvaluate is returned. |
| 483 | Also, in this case we try to resolve name-mangling (i.e.: to be able to add a self.__my_var watch). |
| 484 | |
| 485 | :param py_db: |
| 486 | The debugger. Only needed if some top-level await is detected (for creating a |
| 487 | PyDBDaemonThread). |
| 488 | """ |
| 489 | if frame is None: |
| 490 | return |
| 491 | |
| 492 | # This is very tricky. Some statements can change locals and use them in the same |
| 493 | # call (see https://github.com/microsoft/debugpy/issues/815), also, if locals and globals are |
| 494 | # passed separately, it's possible that one gets updated but apparently Python will still |
| 495 | # try to load from the other, so, what's done is that we merge all in a single dict and |
| 496 | # then go on and update the frame with the results afterwards. |
| 497 | |
| 498 | # -- see tests in test_evaluate_expression.py |
| 499 | |
| 500 | # This doesn't work because the variables aren't updated in the locals in case the |
| 501 | # evaluation tries to set a variable and use it in the same expression. |
| 502 | # updated_globals = frame.f_globals |