pynput
pynput copied to clipboard
I can't use pynput in MacOS Monterey 12.0.1 + M1 environment
Description Hello, I want to ask for help, I can't use pynput in MacOS Monterey 12.0.1 + M1 environment
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py", line 113, in __enter__
return next(self.gen)
File "/Users/yjx/Documents/my/xueqiu2/venv/lib/python3.8/site-packages/pynput/_util/darwin.py", line 130, in keycode_context
layout = _wrap_value(CarbonExtra.TISGetInputSourceProperty(
File "/Users/yjx/Documents/my/xueqiu2/venv/lib/python3.8/site-packages/pynput/_util/darwin.py", line 45, in _wrap_value
return objc.objc_object(c_void_p=value)
AttributeError: 'NoneType' object has no attribute 'value'
Exception in thread Thread-6:
Traceback (most recent call last):
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/Users/yjx/Documents/my/xueqiu2/venv/lib/python3.8/site-packages/pynput/_util/__init__.py", line 193, in run
self._run()
File "/Users/yjx/Documents/my/xueqiu2/venv/lib/python3.8/site-packages/pynput/keyboard/_darwin.py", line 250, in _run
with keycode_context() as context:
File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/contextlib.py", line 113, in __enter__
return next(self.gen)
File "/Users/yjx/Documents/my/xueqiu2/venv/lib/python3.8/site-packages/pynput/_util/darwin.py", line 130, in keycode_context
layout = _wrap_value(CarbonExtra.TISGetInputSourceProperty(
File "/Users/yjx/Documents/my/xueqiu2/venv/lib/python3.8/site-packages/pynput/_util/darwin.py", line 45, in _wrap_value
return objc.objc_object(c_void_p=value)
AttributeError: 'NoneType' object has no attribute 'value'
Platform and pynput version System:macOS Monterey 12.0.1 + M1 pynput 1.7.5 python 3.8
To Reproduce Use official examples
#!venv/bin/python3
import os
from pynput import keyboard
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
os.system('echo "Press any key to continue..." && read')
I made a temporary solution, but I hope the author can help to see why
drawin.py
def _wrap_value(value):
"""Converts a pointer to a *Python objc* value.
:param value: The pointer to convert.
:return: a wrapped value
"""
if value is None:
return
return objc.objc_object(c_void_p=value)
Thank you for your report and proposed fix.
I think your proposition is the way to go; previously this library used a function loaded by ctypes, and I presume it just silently returned None when passed None, whereas the new managed method presumably checks its arguments.
I have included your fix in the branch fixup-macos-objc-none. If you should find time, please test it; otherwise, I will merge it eventually.
Thank you for your report and proposed fix.
I think your proposition is the way to go; previously this library used a function loaded by
ctypes, and I presume it just silently returnedNonewhen passedNone, whereas the new managed method presumably checks its arguments.I have included your fix in the branch
fixup-macos-objc-none. If you should find time, please test it; otherwise, I will merge it eventually.
I've tested this branch on my M1 mbp with Big Sur, no errors like before. Maybe you could merge it now.
I'm having similar issues with my M1 mac running macOS Ventura but only when I use pynput with Qt... seems to fail similarly to the above issue with TISGetInputSourceProperty crashing my app.
I have rearranged Qt / pynput startup order and encountered some lazy load race conditions / timing issues with pyobjc behind the scenes such that I can get both to work in simple setups but I have another setup where I'm getting the following trace and haven't had much luck finding out why... I'll keep plugging away on it and share what I find.
All of the issues I've had (race conditions, and the following) stem from the same spot (or nearby) with regards to the keycode_context creation and involve Carbon API calls.
ffi_call_SYSV (in libffi.dylib) + 80
TSMGetInputSourceProperty (in HIToolbox) + 44
isValidateInputSourceRef (in HIToolbox) + 92
islGetInputSourceListWithAdditions (in HIToolbox) + 160
_dispatch_assert_queue_fail (in libdispatch.dylib) + 0
0xffff80018b7f991c
_sigtramp (in libsystem_platform.dylib) + 56
I also ran into a crash when TSMCurrentAsciiCapableKeyboardLayoutInputSourceRefCreate was invoked (if I bypass the call to TISGetInputSourceProperty... so I commented out both calls and key logging worked... :)
In my case, I'm also using a QT as a frontend. I'm creating a Controller at the start, and a Listener on demand. My app crashes when starting the Listener.
I've modified _wrap_value in _util/darwin.py to log some info:
def _wrap_value(value):
"""Converts a pointer to a *Python objc* value.
:param value: The pointer to convert.
:return: a wrapped value
"""
print(f"Called _wrap_value({value})")
object = objc.objc_object(c_void_p=value) if value is not None else None
print(f"Called _wrap_value({value}) = {object}")
return object
When loading Controller at the start, I get this:
Called _wrap_value(4649539536)
Called _wrap_value(4649539536) = <TSMInputSource 0x1152257d0> KB Layout: Latin American (id=89)
Called _wrap_value(5195413504)
Called _wrap_value(5195413504) = b'\x02\x10\x00\x01\x00\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x03\x00\x00<\x1c\x00\x00P"\x00\x00\...
And then, when starting the listener:
Called _wrap_value(4649539536)
And then it crashes. Maybe it has something to do with the pointer being reused?
EDIT: Turned off the Controller, and the Listener keeps crashing the app :(
It’s an issue with pyobjc and how it registers/resolves arg types and results
try adding this when your script/program starts up (before invoking pynput) and see if the issue resolves:
import objc import CoreFoundation
objc.registerCFSignature("CFStringRef", b"^{__CFString=}", CoreFoundation.CFStringGetTypeID(), "NSString")
On Fri, Oct 21, 2022 at 9:26 AM Alvaro @.***> wrote:
In my case, I'm also using a QT as a frontend. I'm creating a Controller at the start, and a Listener on demand.
I've modified _wrap_value in _util/darwin.py to log some info:
def _wrap_value(value): """Converts a pointer to a Python objc value. :param value: The pointer to convert. :return: a wrapped value """ print(f"Called _wrap_value({value})") object = objc.objc_object(c_void_p=value) if value is not None else None print(f"Called _wrap_value({value}) = {object}") return object
When loading Controller at the start, I get this:
Called _wrap_value(4649539536) Called _wrap_value(4649539536) = <TSMInputSource 0x1152257d0> KB Layout: Latin American (id=89) Called _wrap_value(5195413504) Called _wrap_value(5195413504) = b'\x02\x10\x00\x01\x00\x03\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x03\x00\x00<\x1c\x00\x00P"\x00\x00...
And then, when starting the listener:
Called _wrap_value(4649539536)
And then it crashes. Maybe it has something to do with the pointer being reused?
— Reply to this email directly, view it on GitHub https://github.com/moses-palmer/pynput/issues/424#issuecomment-1287042585, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABL7XPNHJN46ZFW6QZXR5TWEKRZHANCNFSM5I6ZI2FQ . You are receiving this because you commented.Message ID: @.***>
It’s an issue with pyobjc and how it registers/resolves arg types and results try adding this when your script/program starts up (before invoking pynput) and see if the issue resolves: import objc import CoreFoundation objc.registerCFSignature("CFStringRef", b"^{__CFString=}", CoreFoundation.CFStringGetTypeID(), "NSString") …
Sadly, no, it keeps crashing only when Listener.start/join is called, even if Controller is not started, but my bug seems to be a new one...
... Something to do with the thread it's running in. The Controller is called on the main thread, while the listener in its own new thread. If I start the Controller and the Listener in the same object the application doesn't crash.
This MUST be a bug with objc way of creating objects from pointers. This line is the culprit: https://github.com/moses-palmer/pynput/blob/078491edf7025033c22a364ee76fb9e79db65fcc/lib/pynput/_util/darwin.py#L45
When invoking that line on creating a Listener from a new thread, on MacOS Monterey Apple Silicon, it crashes. The same software on Windows runs fine.
So @g0t4 is right on this one. If I start the pynput keyboard Listener before QT, it works. But if I start it after QT, it fails and crashes the app.
I'm having similar issues with my M1 mac running macOS Ventura but only when I use pynput with Qt... seems to fail similarly to the above issue with
TISGetInputSourcePropertycrashing my app.I have rearranged Qt / pynput startup order and encountered some lazy load race conditions / timing issues with pyobjc behind the scenes such that I can get both to work in simple setups but I have another setup where I'm getting the following trace and haven't had much luck finding out why... I'll keep plugging away on it and share what I find.
All of the issues I've had (race conditions, and the following) stem from the same spot (or nearby) with regards to the keycode_context creation and involve Carbon API calls.
ffi_call_SYSV (in libffi.dylib) + 80 TSMGetInputSourceProperty (in HIToolbox) + 44 isValidateInputSourceRef (in HIToolbox) + 92 islGetInputSourceListWithAdditions (in HIToolbox) + 160 _dispatch_assert_queue_fail (in libdispatch.dylib) + 0 0xffff80018b7f991c _sigtramp (in libsystem_platform.dylib) + 56
@g0t4 Hi!
I'm having an issue with all the same symptoms as this, only using tkinter instead. Your proposed fix does not seem to work for me either.
Is there an issue we can file with pyobjc or do you know of an existing one to track the progress of this? It's impractical in my case to start the listener before I start tkinter.
Thank you.
Also impractical for me, and this is enough of a blocker that I'll have to switch away to another library. @moses-palmer can we reopen this issue for more visibility please?
@Raymo111, sure, I'll reopen.
EDIT: I take it back, #541 does fix it for me! I probably installed it wrong the first time.
I think I'm running into the same issue, using PySide6 on a Macbook Air M2. It crashes when trying to start a Listener. #541 didn't fix it for me.
Macbook Air M2, Sonoma 14.4.1
python=3.12
pynput=1.7.7
Crashed Thread: 15
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000018e340828
Termination Reason: Namespace SIGNAL, Code 5 Trace/BPT trap: 5
Terminating Process: exc handler [21598]
Thread 15 Crashed:
0 libdispatch.dylib 0x18e340828 _dispatch_assert_queue_fail + 120
1 libdispatch.dylib 0x18e3407b0 dispatch_assert_queue + 196
2 HIToolbox 0x198d696c4 islGetInputSourceListWithAdditions + 160
3 HIToolbox 0x198d6bd00 isValidateInputSourceRef + 92
4 HIToolbox 0x198d6bbc0 TSMGetInputSourceProperty + 44
5 libffi.8.dylib 0x1012ac04c ffi_call_SYSV + 76
6 libffi.8.dylib 0x1012a974c ffi_call_int + 1208
7 _ctypes.cpython-312-darwin.so 0x10128c958 _ctypes_callproc + 1216
8 _ctypes.cpython-312-darwin.so 0x10128647c PyCFuncPtr_call + 1208
I can confirm that #541 fixes the issue (M1 chip, Sonoma 14.5)