MagicStack / immutables

A high-performance immutable mapping type for Python.
Other
1.14k stars 57 forks source link

Pattern matching isn't working for C implementation #95

Closed antonagestam closed 2 years ago

antonagestam commented 2 years ago

For some reason pattern matching isn't working with the C implementation.

Minimal reproduction:

from immutables import Map

match Map({"foo": 123}):
    case {"foo": 123 as exact}:
        print(f"{exact=}")
    case _:
        print("no match")

-> "no match"

With the Python implementation, matching works as expected:

from immutables.map import Map

match Map({"foo": 123}):
    case {"foo": 123 as exact}:
        print(f"{exact=}")
    case _:
        print("no match")

-> "exact=123"

I'm posting here, but really I'm pondering whether this is a bug in Python. The spec PEP reads:

For a mapping pattern to succeed the subject must be a mapping, where being a mapping is defined as its class being one of the following:

  • a class that inherits from collections.abc.Mapping
  • a Python class that has been registered as a collections.abc.Mapping
  • a builtin class that has its Py_TPFLAGS_MAPPING bit set
  • a class that inherits from any of the above (including classes defined before a parent’s Mapping registration)

And I'm fairly certain Map should be fulfilling the second predicate. But perhaps things are special for non-Python implementations? Would the key be to set Py_TPFLAGS_MAPPING?

antonagestam commented 2 years ago

I'll take a stab at this.