Search code examples
pythonstructural-pattern-matching

How to call a function inside python's match pattern?


I have code

join_prefix = lambda text: config.get("CM_PREFIX") + text

match shlex.split(message.message):
    case [join_prefix("setmode"), mode] if mode.isdigit():
        await self._set_mode_handler(message, int(mode))
        return
    case [join_prefix("getmode")]:
        await self._get_mode_handler(message)
        return

mode is not defined, so it is used for list unpacking. But python throws an error:

    case [join_prefix("getmode")]:
TypeError: called match pattern must be a type

How do i call a function inside match pattern?


Solution

  • The pattern is not an expression, so you cannot build up a pattern dynamically with other expressions at runtime. In fact, [join_prefix("setmode"), mode] is not a list; it's a sequence pattern consisting of a class pattern join_prefix("setmode") and a capture pattern mode.

    Instead, you need to match against a namespace you define before the match statement with a value pattern (which, roughly speaking, is a dotted name, not a simple name). For example,

    from types import SimpleNamespace
    
    
    modes = SimpleNamespace(
        set=join_prefix("setmode"),
        get=join_prefix("getmode")
    )
    
    
    match shlex.split(message.message):
        case [modes.set, mode] if mode.isdigit():
            ...
        case [modes.get]:
            ...