Search code examples
pythonpython-3.xswitch-statementpython-3.10structural-pattern-matching

How to use values stored in variables as case patterns?


I'm trying to understand the new structural pattern matching syntax in Python 3.10. I understand that it is possible to match on literal values like this:

def handle(retcode):
    match retcode:
        case 200:
            print('success')
        case 404:
            print('not found')
        case _:
            print('unknown')

handle(404)
# not found

However, if I refactor and move these values to module-level variables, it results in an error because the statements now represent structures or patterns rather than values:

SUCCESS = 200
NOT_FOUND = 404

def handle(retcode):
    match retcode:
        case SUCCESS:
            print('success')
        case NOT_FOUND:
            print('not found')
        case _:
            print('unknown')

handle(404)
#  File "<ipython-input-2-fa4ae710e263>", line 6
#    case SUCCESS:
#         ^
# SyntaxError: name capture 'SUCCESS' makes remaining patterns unreachable

Is there any way to use the match statement to match values that are stored within variables?


Solution

  • If the constant you're testing against is a dotted name, then it should be treated as a constant instead of as the name of the variable to put the capture in (see PEP 636 # Matching against constants and enums):

    class Codes:
        SUCCESS = 200
        NOT_FOUND = 404
    
    def handle(retcode):
        match retcode:
            case Codes.SUCCESS:
                print('success')
            case Codes.NOT_FOUND:
                print('not found')
            case _:
                print('unknown')
    

    Although, given how python is trying to implement pattern-matching, I think that for situations like this it's probably safer and clearer code to just use an if/elif/else tower when checking against constant values.