alexmojaki / heartrate

Simple real time visualisation of the execution of a Python program.
MIT License
1.76k stars 123 forks source link

AttributeError: 'Call' object has no attribute 'first_token' #11

Open ProsperousHeart opened 2 years ago

ProsperousHeart commented 2 years ago

On a fresh install of python 3.10 and heartrate, the following code:

from time import sleep
import heartrate
heartrate.trace(browser=True)

def factorial(x):
    if x == 1:
        return 1
    else:
        sleep(0.5)
        return (x * factorial(x-1))

if __name__ == "__main__":
    while True:
        try:
            num = int(input("What number >= 0 would you like to see a factorial of?\t"))
        except ValueError as err:
            print("Please provide an integer >= 0.")
        else:
            if num <= 0:
                print("Please provide an integer greater than 0.")
            else:
                break
    print(f"The factorial of {num} is {factorial(num)}")

.... never ends the program!

image

Here is the error message that happens:

[2022-02-26 22:30:47,754] ERROR in app: Exception on /stacktrace/ [GET]
Traceback (most recent call last):
  File "C:\Users\Kat\.virtualenvs\My-Projects\lib\site-packages\flask\app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\Kat\.virtualenvs\My-Projects\lib\site-packages\flask\app.py", line 1518, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\Kat\.virtualenvs\My-Projects\lib\site-packages\flask\app.py", line 1516, in full_dispatch_request
    rv = self.dispatch_request()
  File "C:\Users\Kat\.virtualenvs\My-Projects\lib\site-packages\flask\app.py", line 1502, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "C:\Users\Kat\.virtualenvs\My-Projects\lib\site-packages\heartrate\core.py", line 181, in stacktrace
    list(gen())[::-1]
  File "C:\Users\Kat\.virtualenvs\My-Projects\lib\site-packages\heartrate\core.py", line 172, in gen
    highlight_stack_frame(frame),
  File "C:\Users\Kat\.virtualenvs\My-Projects\lib\site-packages\heartrate\core.py", line 55, in highlight_stack_frame
    start = node.first_token.start[0]
AttributeError: 'Call' object has no attribute 'first_token'

What am I missing here?

Sukrut3107 commented 2 years ago

After removing sleep(0.5) it worked perfectly on my machine. Screenshot

alexmojaki commented 2 years ago

never ends the program!

That's normal, heartrate always keeps the process alive even after the main program finishes. It printed the factorial of 20, so it was still successful.

The error is in the flask logs as it tries to show a stacktrace highlighting the current node in each frame. It's failing because of the {factorial(num)} in the f-string. f-strings have some issues which prevent asttokens from retrieving the source code. The fix here is just to prevent it from trying.

After removing sleep(0.5) it worked perfectly on my machine.

Probably becaues the program finished before the webpage had a chance to poll for the stacktrace while it was in the middle of evaluating the f-string.

ProsperousHeart commented 2 years ago

Oh, really? Shoot, I was creating content based on this post. I didn't know that it keeps it going. How do we stop it?

Do you have a suggestion to allow for this code to work @alexmojaki?

alexmojaki commented 2 years ago

You can set daemon=True in the trace call to prevent the flask thread from keeping the process alive. Or just Ctrl+C to kill it.

You can prevent the error in the logs by not doing any logic inside f-strings, e.g.

result = factorial(num)
print(f"The factorial of {num} is {result}")