| # SPDX-License-Identifier: MIT |
| |
| import pytest |
| |
| import attr |
| |
| |
| class TestPatternMatching: |
| """ |
| Pattern matching syntax test cases. |
| """ |
| |
| @pytest.mark.parametrize("dec", [attr.s, attr.define, attr.frozen]) |
| def test_simple_match_case(self, dec): |
| """ |
| Simple match case statement works as expected with all class |
| decorators. |
| """ |
| |
| @dec |
| class C: |
| a = attr.ib() |
| |
| assert ("a",) == C.__match_args__ |
| |
| matched = False |
| c = C(a=1) |
| match c: |
| case C(a): |
| matched = True |
| |
| assert matched |
| assert 1 == a |
| |
| def test_explicit_match_args(self): |
| """ |
| Does not overwrite a manually set empty __match_args__. |
| """ |
| |
| ma = () |
| |
| @attr.define |
| class C: |
| a = attr.field() |
| __match_args__ = ma |
| |
| c = C(a=1) |
| |
| msg = r"C\(\) accepts 0 positional sub-patterns \(1 given\)" |
| with pytest.raises(TypeError, match=msg): |
| match c: |
| case C(_): |
| pass |
| |
| def test_match_args_kw_only(self): |
| """ |
| kw_only classes don't generate __match_args__. |
| kw_only fields are not included in __match_args__. |
| """ |
| |
| @attr.define |
| class C: |
| a = attr.field(kw_only=True) |
| b = attr.field() |
| |
| assert ("b",) == C.__match_args__ |
| |
| c = C(a=1, b=1) |
| msg = r"C\(\) accepts 1 positional sub-pattern \(2 given\)" |
| with pytest.raises(TypeError, match=msg): |
| match c: |
| case C(a, b): |
| pass |
| |
| found = False |
| match c: |
| case C(b, a=a): |
| found = True |
| |
| assert found |
| |
| @attr.define(kw_only=True) |
| class C: |
| a = attr.field() |
| b = attr.field() |
| |
| c = C(a=1, b=1) |
| msg = r"C\(\) accepts 0 positional sub-patterns \(2 given\)" |
| with pytest.raises(TypeError, match=msg): |
| match c: |
| case C(a, b): |
| pass |
| |
| found = False |
| match c: |
| case C(a=a, b=b): |
| found = True |
| |
| assert found |
| assert (1, 1) == (a, b) |