pythonevdev

Local variable not declared - cannot be fixed with any current stack solutions


I understand this is a question asked several times on here, but even after viewing and attempting to use all solutions on this site none fix my problem. Here is my code:

def trackMouse():
    global x, y
    x = 0
    y = 0
    x_max = 1000
    y_max = 1000
    keyboardEvent = evdev.InputDevice('/dev/input/event0')
    mouseEvent = evdev.InputDevice('/dev/input/event1')
    async def print_events(device):
            async for event in device.async_read_loop():
                    if event.type == ecodes.EV_REL:
                            if event.code == ecodes.REL_X:
                                    print("REL_X")
                                    x += 1
                            if event.code == ecodes.REL_Y:
                                    print("REL_Y")
                                    y += 1
                    if event.type == ecodes.EV_KEY:
                            c = categorize(event)
                            if c.keystate == c.key_down:
                                    print(c.keycode)

    for device in keyboardEvent, mouseEvent:
            asyncio.ensure_future(print_events(device))

    loop = asyncio.get_event_loop()
    loop.run_forever()

the error i get when running this loop is:

Task exception was never retrieved future: .print_events() done, defined at etho.py:113> exception=UnboundLocalError("local variable 'a' referenced before assignment",)>
Traceback (most recent call last):
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "etho.py", line 124, in print_events
if x += 1:
UnboundLocalError: local variable 'x' referenced before assignment

no matter where i assign the variable or declare it it will throw an error when i try to use it in an if statement or add to it, but not when i just set it equal to a number. I think it has something to do with the weird loop it is in.


Solution

  • print_events is treating x and y as local to itself, since they're modified inside the function and are not declared global inside the function. Since you want to modify them, you need to add declare them global inside print_events:

    async def print_events(device):
            global x, y
            async for event in device.async_read_loop():
            ...
    

    Note that passing them as arguments won't work since you want to modify them within the function and access the modified values outside the function.