libtcod / python-tcod

A high-performance Python port of libtcod. Includes the libtcodpy module for backwards compatibility with older projects.
BSD 2-Clause "Simplified" License
413 stars 36 forks source link

Add __match_args__ to Event #120

Closed slavfox closed 2 years ago

slavfox commented 2 years ago

See PEP-0622. Adds __match_args__ to all Event subclasses mirroring their initializers to allow for positional pattern matching - the example from docs:

while True:
    console = context.new_console()
    context.present(console, integer_scaling=True)
    for event in tcod.event.wait():
        context.convert_event(event)  # Adds tile coordinates to mouse events.
        match event:
            case tcod.event.Quit():
                raise SystemExit()
            case tcod.event.KeyDown(sym) if sym in KEY_COMMANDS:
                print(f"Command: {KEY_COMMANDS[sym]}")
            case tcod.event.KeyDown(sym, scancode, mod, repeat):
                print(f"KeyDown: {sym=}, {scancode=}, {mod=}, {repeat=}")
            case tcod.event.MouseButtonDown(button, pixel, tile):
                print(f"MouseButtonDown: {button=}, {pixel=}, {tile=}")
            case tcod.event.MouseMotion(pixel, pixel_motion, tile, tile_motion):
                print(f"MouseMotion: {pixel=}, {pixel_motion=}, {tile=}, {tile_motion=}")
            case tcod.event.Event() as event:
                print(event)  # Show any unhandled events.

Doesn't work without __match_args__ since only namedtuples and dataclasses support positional pattern matching out of the box.

HexDecimal commented 2 years ago

I'm not sure __match_args__ is the best way to handle this. The positional placement of these parameters are unintuitive compared to other examples. Undefined should definitely not have __match_args__, and type should probably not be part of __match_args__ even when it's needed to tell events apart.

I'd rather update the docs to use keywords.

HexDecimal commented 2 years ago

The previous documentation was from a misunderstanding. For now I've updated the docs to use keywords in all cases. I'd be willing to discuss about __match_args__ but I think there's too much variation in the event parameters for positional binding to be a good idea.