# Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See LICENSE in the project root # for license information. """Pattern matching for recursive Python data structures. Usage:: from tests.patterns import some assert object() == some.object assert None == some.object assert None != some.thing assert None == ~some.thing # inverse assert None == some.thing | None assert 123 == some.thing.in_range(0, 200) assert "abc" == some.thing.such_that(lambda s: s.startswith("ab")) xs = [] assert xs == some.specific_object(xs) # xs is xs assert xs != some.specific_object([]) # xs is not [] assert Exception() == some.instanceof(Exception) assert 123 == some.instanceof((int, str)) assert "abc" == some.instanceof((int, str)) assert True == some.bool assert 123.456 == some.number assert 123 == some.int assert Exception() == some.error assert object() == some.object.same_as(object()) assert b"abc" == some.bytes assert "abc" == some.str assert b"abc" != some.str assert "abbc" == some.str.starting_with("ab") assert "abbc" == some.str.ending_with("bc") assert "abbc" == some.str.containing("bb") assert "abbc" == some.str.matching(r".(b+).") assert "abbc" != some.str.matching(r"ab") assert "abbc" != some.str.matching(r"bc") if sys.platform == "win32": assert "\\Foo\\Bar" == some.path("/foo/bar") else: assert "/Foo/Bar" != some.path("/foo/bar") assert { "bool": True, "list": [None, True, 123], "dict": { "int": 123, "str": "abc", }, } == some.dict.containing({ "list": [None, some.bool, some.int | some.str], "dict": some.dict.containing({ "int": some.int.in_range(100, 200), }) }) """ __all__ = [ "bool", "bytes", "dap", "dict", "error", "instanceof", "int", "list", "number", "path", "str", "thing", "tuple", ] import builtins import numbers import re from tests.patterns import _impl object = _impl.Object() thing = _impl.Thing() instanceof = _impl.InstanceOf path = _impl.Path bool = instanceof(builtins.bool) number = instanceof(numbers.Real, "number") int = instanceof(numbers.Integral, "int") tuple = instanceof(builtins.tuple) error = instanceof(Exception) bytes = instanceof(builtins.bytes) bytes.starting_with = lambda prefix: bytes.matching( re.escape(prefix) + b".*", re.DOTALL ) bytes.ending_with = lambda suffix: bytes.matching(b".*" + re.escape(suffix), re.DOTALL) bytes.containing = lambda sub: bytes.matching(b".*" + re.escape(sub) + b".*", re.DOTALL) str = instanceof(builtins.str) str.starting_with = lambda prefix: str.matching(re.escape(prefix) + ".*", re.DOTALL) str.ending_with = lambda suffix: str.matching(".*" + re.escape(suffix), re.DOTALL) str.containing = lambda sub: str.matching(".*" + re.escape(sub) + ".*", re.DOTALL) list = instanceof(builtins.list) list.containing = _impl.ListContaining dict = instanceof(builtins.dict) dict.containing = _impl.DictContaining # Set in __init__.py to avoid circular dependency. dap = None