"""Signal pattern matching."""

import re


class PatternError(Exception):
    """Pattern error."""


class Pattern:
    """Signal pattern representation."""

    PATTERN_REGEX = re.compile(r"[01xX]+")

    def __init__(self, pattern: str):
        """Initialize."""
        if not isinstance(pattern, str):
            raise TypeError("pattern must be a string")
        m = self.PATTERN_REGEX.match(pattern)
        if m is None:
            raise PatternError("pattern is invalid")

        self._pattern = pattern

    @property
    def pattern(self):
        """Get pattern."""
        return self._pattern

    def __len__(self):
        """Get length."""
        return len(self._pattern)

    def match(self, value: str) -> bool:
        """Match against value."""
        if not isinstance(value, str):
            raise TypeError("value must be string")

        pattern = self._pattern
        if len(value) < len(self._pattern):
            # zero-extend incomin value
            count = len(self._pattern) - len(value)
            value = "0" * count + value
        elif len(value) > len(self._pattern):
            # zero-extend pattern
            count = len(value) - len(self._pattern)
            pattern = "0" * count + self._pattern
        for value_bit, expected_bit in zip(value, pattern):
            if expected_bit in ("x", "X"):
                # don't care
                continue
            if expected_bit != value_bit:
                return False

        return True

@@ -35,16 +35,41 @@
 port re%0A
+from typing import Union%0A
 %0A%0Aclass 
@@ -219,16 +219,65 @@
 01xX%5D+%22)
+%0A    PATTERN_REGEX_BYTES = re.compile(b%22%5B01xX%5D+%22)
 %0A%0A    de
@@ -302,19 +302,33 @@
 attern: 
-str
+Union%5Bstr, bytes%5D
 ):%0A     
@@ -383,19 +383,28 @@
 attern, 
+(
 str
+, bytes)
 ):%0A     
@@ -451,19 +451,69 @@
 a string
+ or bytes
 %22)%0A
+        if isinstance(pattern, str):%0A    
         
@@ -542,32 +542,102 @@
 .match(pattern)%0A
+        else:%0A            m = self.PATTERN_REGEX_BYTES.match(pattern)%0A
         if m is 
@@ -934,19 +934,33 @@
  value: 
-str
+Union%5Bstr, bytes%5D
 ) -%3E boo
@@ -1030,19 +1030,28 @@
 (value, 
+(
 str
+, bytes)
 ):%0A     
@@ -1094,16 +1094,145 @@
 e string
+ or bytes%22)%0A%0A        if type(value) != type(self._pattern):%0A            raise TypeError(%22incompatible types for value and pattern
 %22)%0A%0A    

allow bytearrays for patterns