Open WillTWinter opened 3 years ago
My issue is, do you know what's this issue. it also is Macbook M1。
from pynput import keyboard
File "/Users/admin/git/pynput/lib/pynput/__init__.py", line 40, in <module>
from . import keyboard
File "/Users/admin/git/pynput/lib/pynput/keyboard/__init__.py", line 31, in <module>
backend = backend(__name__)
File "/Users/admin/git/pynput/lib/pynput/_util/__init__.py", line 76, in backend
raise ImportError('this platform is not supported: {}'.format(
ImportError: this platform is not supported: dlopen(/Users/admin/virtulenv/py38/lib/python3.8/site-packages/objc/_objc.cpython-38-darwin.so, 2): Symbol not found: _ffi_find_closure_for_code_np
Referenced from: /Users/admin/virtulenv/py38/lib/python3.8/site-packages/objc/_objc.cpython-38-darwin.so
Expected in: flat namespace
in /Users/admin/virtulenv/py38/lib/python3.8/site-packages/objc/_objc.cpython-38-darwin.so
Try one of the following resolutions:
* Please make sure that you have Python bindings for the system frameworks installed
Sorry - I don't recognise that one. I had python installed from https://www.python.org/downloads/mac-osx/ and pynput installed using pip and didn't run into that issue.
Thank you for your very detailed report.
I know that there are issues on macOS when combining this library with other libraries that want to manage the mainloop, but those mostly relate to listeners.
Unfortunately I do not have access to an M1. Do you know whether your application runs natively on ARM, or is the binary translated?
Thank you very much! Big God, it works now, i install it on ARM Chip, python Python 3.9.2, pynput==1.7.3, Great!
Hi, I have problem with start keyboard listener from tkinter button command. When I press button application crash with only message "Process finished with exit code 133 (interrupted by signal 5: SIGTRAP)". When I start only listener or with tkinter but listener is started from main thread, everything works. When I try to run pynput mouse listener this way, there is no problem. I'm using pynput 1.7.6, Python 3.9 on macOS Monterey 12.4 M1 PRO. Thank you for any help.
import tkinter
from tkinter import Tk, Button
from pynput import keyboard
logo = b'iVBORw0KGgoAAAANSUhEUgAAACUAAAAlCAYAAADFniADAAAACXBIWXMAAAsSAAALEgHS3X78AAACOElEQVRYhc2Yy23CQBCG/1jcoYO4ATuc7GPcQdIB3H2hgzgdEMm+Ox2ECmKOvhFXAB1ABURjjdGyLHgX/PqlFcKP3Y+Z3WFmno7HI0zlJv4UQMBjAsAG8MzTrPkzA7ApwvzHdH5tKDfxafE5gIUAoKMDAAJbFmG+aQzKTfyIYcYGMCqtaJ4izLd3Q7GbUgAvD8KIOjBYagzlJn7AZn/UOtf0XYT5XBvKTfxq7+wNFnkFsAMgu6Y6BGvFO3QQFhdXCUocTuxNndjbO7EXyPduDSf2jk7sRYr5IrqneteJvcyJvVS+bkkWmvBRbstlKs3YMydZ0kNpx0CVlm7i2xdQvLHfegACGyKqvoyEG5H6eSPZ/ONE2ZoTkBsjimElFMej1wagZjzuFRlmXrlPGS960DuEPSWbvC+Nyf0Wh4Em/0YeVUCWmg4IiGRbnA8NSfaoK0tx+nNhFdWzI9XFlvShO+3IMBOo02cR5tpB2E38TBUfaU9ppahdymrYUk0osziZPwwIalNF9KxnEFFZBWVcm7WkVRHm+xKKK4shuLA0jph5LvtjKbWryi4ZatcfE05VzQmKfNljXrUSew5nhUMR5nQKvzoG2snGuFaMphzpTaL9L1W9XBHpKuIS/mydW2V7+mC+XSc67YGqEyPXfSdxnd+WK/8oZbrWGqptBXHJlBr2pG6pNpMwaZrNeQ/cC0f7LarrTRlBCXBUBtEgC9YBUpOMTnTKIUdLd/U8BUDK71Xp9FbHIkoB+AdGxhvJUKsuTwAAAABJRU5ErkJggg=='
root = Tk()
root.title("Test window")
root.geometry("400x200")
core_logo_icon = tkinter.PhotoImage(data=logo)
def start_listener():
def on_press(key):
print("Key ", key, " pressed")
def on_release(key):
print("Key ", key, " released")
keyboard_listener = keyboard.Listener(on_press=on_press, on_release=on_release)
keyboard_listener.start()
print("Keyboard listener ON")
button = Button(root, command=start_listener, image=core_logo_icon, borderwidth=0)
button.pack()
root.mainloop()
Edit: On Windows 11 everything works fine. When I run app from terminal, err msg is "zsh: trace trap path/to/py/script"...
I have tried the code posted by WillTWinter
(OP), and I also receive the same error. It is not an M1 issue. I am on an Intel CPU testing via KVM/QEMU.
My setup is macOS Catalina (Version 10.15.7) Processor: 2.11 GHz Quad-Core Intel Xeon Python 3.11.1 (v3.11.1:a7a450f87a CLang 13.0.0 on darwin) pynput 1.7.6
Here is the head of the error message received (also attached as a file)
Process: Python [1265]
Path: /Library/Frameworks/Python.framework/Versions/3.11/Resources/Python.app/Contents/MacOS/Python
Identifier: org.python.python
Version: 3.11.1 (3.11.1)
Code Type: X86-64 (Native)
Parent Process: Python [1167]
Responsible: Python [1167]
User ID: 501
Date/Time: 2022-12-23 12:41:53.453 -0600
OS Version: Mac OS X 10.15.7 (19H15)
Report Version: 12
Anonymous UUID: 8F3C4275-7530-4603-A4FA-C2D5E4640406
Time Awake Since Boot: 3100 seconds
System Integrity Protection: enabled
Crashed Thread: 8
Exception Type: EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Termination Signal: Illegal instruction: 4
Termination Reason: Namespace SIGNAL, Code 0x4
Terminating Process: exc handler [1265]
Application Specific Information:
BUG IN CLIENT OF LIBDISPATCH: Assertion failed: Block was expected to execute on queue [com.apple.main-thread]
I am having same error in my own program.
I, also, like OP believe this error is related to a threading issue. My first thought is the pynput controller thread is operating from within the tk inter thread and macOS does not like that. Just a though, I have not much programming experience.
I have modified the original code by OP. It is running without throwing an error.
#!/usr/bin/env python3
#!python3
import pynput
import time
import tkinter as tk
import string
def repeat_alphabet(i=0, characters=list(string.ascii_lowercase)):
key = characters[i % len(characters)]
i += 1
label.set(f'Pressing "{key}"')
print(f'Pressing "{key}"')
keyboard.press(key)
keyboard.release(key)
root.after(1000, repeat_alphabet, i)
if __name__ == '__main__':
keyboard = pynput.keyboard.Controller()
root = tk.Tk()
label = tk.StringVar()
label.set('Nothing yet')
tk.Label(root, textvariable=label,).pack()
repeat_alphabet()
root.mainloop()
So a similar approach solved my problem as well. I've simplified my code as much as possible to demonstrate the same functionality.
How to use it. Run the script. Open a text editor. Type letters. Then type the special key "F3" and it should type into the text editor.
Script #1 does not work and crashes when I press the special key "F3". Script #2 does work.
Can anyone tell me the reason?
script #1
#!/usr/bin/env python3
#!python3
import pynput
import tkinter as tk
thiskey = 'f3'
def on_press(presskey):
if presskey == pynput.keyboard.Key.esc:
print('bye!')
return False # stop listener
if presskey == pynput.keyboard.Key[thiskey]:
controller.type(f'{thiskey} found and typing!!!')
print(f'{thiskey} found')
label.set(f'{presskey=}')
else:
print(f'{presskey=}', type(presskey), sep=':')
label.set(f'{presskey=}')
return True
def do_basically_nothing():
root.after(100, do_basically_nothing)
controller = pynput.keyboard.Controller()
listener = pynput.keyboard.Listener(on_press=on_press)
listener.start() # start to listen on a separate thread
root = tk.Tk()
label = tk.StringVar()
label.set('Nothing yet')
tk.Label(root, textvariable=label,).pack()
do_basically_nothing()
root.mainloop()
script #2
#!/usr/bin/env python3
#!python3
import pynput
import tkinter as tk
thiskey = 'f3'
presskey = ''
def on_press(key):
global presskey
presskey = key
return True
def do_basically_nothing():
if presskey == pynput.keyboard.Key.esc:
print('bye!')
return False # stop listener
if presskey == pynput.keyboard.Key[thiskey]:
controller.type(f'{thiskey} found and typing!!!')
print(f'{thiskey} found')
label.set(f'{presskey=}')
else:
print(f'{presskey=}', type(presskey), sep=':')
label.set(f'{presskey=}')
root.after(100, do_basically_nothing)
controller = pynput.keyboard.Controller()
listener = pynput.keyboard.Listener(on_press=on_press)
listener.start() # start to listen on a separate thread
root = tk.Tk()
label = tk.StringVar()
label.set('Nothing yet')
tk.Label(root, textvariable=label,).pack()
do_basically_nothing()
root.mainloop()
I figured out my own question. So much code and learning in one day.
From how I understand it, tkinter (GUI) and the pynput keyboard controller both run on the main python thread. The listener runs on a separate thread. I was calling the controller from the listener thread. That is why it was crashing. (Oddly enough, the wrong way worked in both Windows and Linux, but not in macOS. I wonder why it worked on those, it really shouldn't. )
I fixed my mistake by setting global variables from my listener thread to tell me if a key is pressed or not. I then have a tkinter function which checks if the keys are pressed, does what it needs to, and then sets the key to not pressed.
WillTWinter I believe this to also be your issue. It looks like you are calling tkinter in your Window class, and in the same class you are starting another thread.
@toddthegeek Can you be more specific on how did you do this? I'm having the same problem but with GTK and by my tests I really think it has to do with threads.
I'm getting a crash in very specific circumstances. I've reduced it to the following code:
which results in a crash from the
self.keyboard.press(key)
line insend_key(...)
. Program output is:If I uncomment the marked line in the constructor then I have no problems. If I re-write without a gui then it runs fine. I guess that the issue is somewhere between pynput, tkinter, threading and the new Mac.
I have not had any issues running this code on any other machine, Mac or Linux, though I haven't managed to replicate the exact configuration.
Details of the offending computer: