1

In the "non-blocking fashion" of starting a pynput Listener, I'm getting different behaviors with the code below:

from time import sleep
import pynput

def stop(k):
    if k: 
        print("end")
        l.stop()

l = pynput.keyboard.Listener(on_press=stop)

l.start()

print(l.running)

while True:
    if l.running: 
        print("running\n")
        sleep(1)
    else: break

Sometimes I get False and program ends. Other times, False then loop runs.
If I duplicate print(l.running), I might event get True, for both statements.
Adding code after l.start() (e.g. duplicating print(l.running)) seems to increase the odds of getting True from l.running. Finally, debugging instead of just running guarantees getting True.
It feels almost as if I need to provide enough time to the interpreter in order to running to be able to "catch" the listener working.

I've seen some posts on getting different outputs when running vs debugging, but they involved generating random values, usually in C++, or even misuse of variable scope.
They didn't seem very useful, at least to my poor knowledge.

Question is as straightforward as it gets: what is happening here?

I'm using VSCode on Windows11.

101is5
  • 309
  • 2
  • 12

1 Answers1

1

A pynput listener runs on a separate thread to get keyboard input while your main program continues to execute. There could be a timing issue where the listener might not yet have registered as running when you check its status right away. The more time you provide by adding extra statements, the more likely you are to have the listener running when you check on it.

Also you're kinda creating a race condition: both the main program and the listener thread are accessing l.running. Depending on how the operating system schedules threads and when the listener thread updates l.running, the behaviour can be different.

Ada
  • 427
  • 2
  • 13