1# Copyright 2008-2015 Nokia Networks 2# Copyright 2016- Robot Framework Foundation 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import re 17import fnmatch 18from functools import partial 19 20from .compat import py2to3 21from .normalizing import normalize 22from .platform import IRONPYTHON, PY3 23from .robottypes import is_string 24 25 26def eq(str1, str2, ignore=(), caseless=True, spaceless=True): 27 str1 = normalize(str1, ignore, caseless, spaceless) 28 str2 = normalize(str2, ignore, caseless, spaceless) 29 return str1 == str2 30 31 32@py2to3 33class Matcher(object): 34 35 def __init__(self, pattern, ignore=(), caseless=True, spaceless=True, 36 regexp=False): 37 if PY3 and isinstance(pattern, bytes): 38 raise TypeError('Matching bytes is not supported on Python 3.') 39 self.pattern = pattern 40 self._normalize = partial(normalize, ignore=ignore, caseless=caseless, 41 spaceless=spaceless) 42 self._regexp = self._compile(self._normalize(pattern), regexp=regexp) 43 44 def _compile(self, pattern, regexp=False): 45 if not regexp: 46 pattern = fnmatch.translate(pattern) 47 # https://github.com/IronLanguages/ironpython2/issues/515 48 if IRONPYTHON and "\\'" in pattern: 49 pattern = pattern.replace("\\'", "'") 50 return re.compile(pattern, re.DOTALL) 51 52 def match(self, string): 53 return self._regexp.match(self._normalize(string)) is not None 54 55 def match_any(self, strings): 56 return any(self.match(s) for s in strings) 57 58 def __nonzero__(self): 59 return bool(self._normalize(self.pattern)) 60 61 62class MultiMatcher(object): 63 64 def __init__(self, patterns=None, ignore=(), caseless=True, spaceless=True, 65 match_if_no_patterns=False, regexp=False): 66 self._matchers = [Matcher(pattern, ignore, caseless, spaceless, regexp) 67 for pattern in self._ensure_list(patterns)] 68 self._match_if_no_patterns = match_if_no_patterns 69 70 def _ensure_list(self, patterns): 71 if patterns is None: 72 return [] 73 if is_string(patterns): 74 return [patterns] 75 return patterns 76 77 def match(self, string): 78 if self._matchers: 79 return any(m.match(string) for m in self._matchers) 80 return self._match_if_no_patterns 81 82 def match_any(self, strings): 83 return any(self.match(s) for s in strings) 84 85 def __len__(self): 86 return len(self._matchers) 87 88 def __iter__(self): 89 for matcher in self._matchers: 90 yield matcher.pattern 91