4 new revisions:

Revision: 8a2fab4ca591
Author:   Pekka Klärck
Date:     Fri Nov  4 22:14:26 2011
Log: Implemented utils.Matcher to speed up matching same pattern multiple t...
http://code.google.com/p/robotframework/source/detail?r=8a2fab4ca591

Revision: b4f9aa1bca7e
Author:   Pekka Klärck
Date:     Fri Nov  4 22:47:41 2011
Log:      store original pattern in utils.Matcher
http://code.google.com/p/robotframework/source/detail?r=b4f9aa1bca7e

Revision: 5729004c40f8
Author:   Pekka Klärck
Date:     Fri Nov  4 22:48:40 2011
Log:      TagPatterns: support for seq2str
http://code.google.com/p/robotframework/source/detail?r=5729004c40f8

Revision: 5f3d7fe63c61
Author:   Pekka Klärck
Date:     Fri Nov  4 22:48:58 2011
Log:      use reusable TagPatterns when we can
http://code.google.com/p/robotframework/source/detail?r=5f3d7fe63c61

==============================================================================
Revision: 8a2fab4ca591
Author:   Pekka Klärck
Date:     Fri Nov  4 22:14:26 2011
Log: Implemented utils.Matcher to speed up matching same pattern multiple times. Also took it into use in few places.
http://code.google.com/p/robotframework/source/detail?r=8a2fab4ca591

Modified:
 /src/robot/model/tags.py
 /src/robot/result/filter.py
 /src/robot/utils/__init__.py
 /src/robot/utils/match.py

=======================================
--- /src/robot/model/tags.py    Fri Nov  4 06:56:29 2011
+++ /src/robot/model/tags.py    Fri Nov  4 22:14:26 2011
@@ -83,15 +83,10 @@
 class _SingleTagPattern(object):

     def __init__(self, pattern):
-        self._pattern = pattern
+        self._matcher = utils.Matcher(pattern, ignore=['_'])

     def match(self, tags):
-        return any(self._match(tag) for tag in tags)
-
-    def _match(self, tag):
- # TODO: We should create utils.Matcher that could normalize patterns
-        # only once and also compile the regexp used internally
-        return utils.matches(tag, self._pattern, ignore=['_'])
+        return any(self._matcher.match(tag) for tag in tags)


 class _AndTagPattern(object):
=======================================
--- /src/robot/result/filter.py Fri Nov  4 06:57:47 2011
+++ /src/robot/result/filter.py Fri Nov  4 22:14:26 2011
@@ -101,18 +101,24 @@
 class _NameFilter(object):

     def __init__(self, patterns):
+        self._matchers = [utils.Matcher(p, ignore=['_'])
+                          for p in self._ensure_list(patterns)]
+
+    def _ensure_list(self, patterns):
+        if patterns is None:
+            return []
         if isinstance(patterns, basestring):
-            patterns = [patterns]
-        self._patterns = patterns
+            return  [patterns]
+        return patterns

     def match(self, item):
return self._match(item.name) or self._match_longname(item.longname)

     def _match(self, name):
-        return utils.matches_any(name, self._patterns, ignore=['_'])
+        return any(matcher.match(name) for matcher in self._matchers)

     def __nonzero__(self):
-        return bool(self._patterns)
+        return bool(self._matchers)


 class _SuiteNameFilter(_NameFilter):
=======================================
--- /src/robot/utils/__init__.py        Wed Oct 26 02:11:28 2011
+++ /src/robot/utils/__init__.py        Fri Nov  4 22:14:26 2011
@@ -23,7 +23,7 @@
 from htmlutils import html_format, html_escape, html_attr_escape
 from htmlwriter import HtmlWriter
 from importing import simple_import, import_
-from match import eq, eq_any, matches, matches_any
+from match import eq, eq_any, matches, matches_any, Matcher
 from misc import plural_or_not, printable_name, seq2str, seq2str2, getdoc
 from normalizing import normalize, normalize_tags, NormalizedDict
 from robotpath import normpath, abspath, get_link_path
=======================================
--- /src/robot/utils/match.py   Sun Feb  6 01:24:10 2011
+++ /src/robot/utils/match.py   Fri Nov  4 22:14:26 2011
@@ -12,15 +12,12 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.

-
 import re
+from functools import partial

 from normalizing import normalize


-_match_pattern_tokenizer = re.compile('(\*|\?)')
-
-
 def eq(str1, str2, ignore=[], caseless=True, spaceless=True):
     str1 = normalize(str1, ignore, caseless, spaceless)
     str2 = normalize(str2, ignore, caseless, spaceless)
@@ -35,22 +32,33 @@
     return False


-def matches(string, pattern, ignore=[], caseless=True, spaceless=True):
-    string = normalize(string, ignore, caseless, spaceless)
-    pattern = normalize(pattern, ignore, caseless, spaceless)
-    regexp = _get_match_regexp(pattern)
-    return re.match(regexp, string, re.DOTALL) is not None
-
-def _get_match_regexp(pattern):
-    regexp = []
-    for token in _match_pattern_tokenizer.split(pattern):
-        if token == '*':
-            regexp.append('.*')
-        elif token == '?':
-            regexp.append('.')
-        else:
-            regexp.append(re.escape(token))
-    return '^%s$' % ''.join(regexp)
+
+class Matcher(object):
+    _match_pattern_tokenizer = re.compile('(\*|\?)')
+    _wildcards = {'*': '.*', '?': '.'}
+
+    def __init__(self, pattern, ignore=[], caseless=True, spaceless=True):
+ self._normalize = partial(normalize, ignore=ignore, caseless=caseless,
+                                  spaceless=spaceless)
+ self._regexp = self._get_and_compile_regexp(self._normalize(pattern))
+
+    def _get_and_compile_regexp(self, pattern):
+        pattern = '^%s$' % ''.join(self._get_regexp(pattern))
+        return re.compile(pattern, re.DOTALL)
+
+    def _get_regexp(self, pattern):
+        for token in self._match_pattern_tokenizer.split(pattern):
+            if token in self._wildcards:
+                yield self._wildcards[token]
+            else:
+                yield re.escape(token)
+
+    def match(self, string):
+        return self._regexp.match(self._normalize(string)) is not None
+
+
+def matches(string, pattern, ignore=[], caseless=True, spaceless=True):
+    return Matcher(pattern, ignore, caseless, spaceless).match(string)


def matches_any(string, patterns, ignore=[], caseless=True, spaceless=True):

==============================================================================
Revision: b4f9aa1bca7e
Author:   Pekka Klärck
Date:     Fri Nov  4 22:47:41 2011
Log:      store original pattern in utils.Matcher
http://code.google.com/p/robotframework/source/detail?r=b4f9aa1bca7e

Modified:
 /src/robot/utils/match.py
 /utest/utils/test_match.py

=======================================
--- /src/robot/utils/match.py   Fri Nov  4 22:14:26 2011
+++ /src/robot/utils/match.py   Fri Nov  4 22:47:41 2011
@@ -38,6 +38,7 @@
     _wildcards = {'*': '.*', '?': '.'}

     def __init__(self, pattern, ignore=[], caseless=True, spaceless=True):
+        self.pattern = pattern
self._normalize = partial(normalize, ignore=ignore, caseless=caseless,
                                   spaceless=spaceless)
self._regexp = self._get_and_compile_regexp(self._normalize(pattern))
=======================================
--- /utest/utils/test_match.py  Thu May 27 07:11:21 2010
+++ /utest/utils/test_match.py  Fri Nov  4 22:47:41 2011
@@ -45,6 +45,13 @@
         assert matches_any('abc', ['*','asdf','foo','*b?'])
         assert not matches_any('abc', ['asdf','foo','*c?'])

+    def test_matcher(self):
+ matcher = Matcher('F *', ignore=['-'], caseless=False, spaceless=True)
+        assert matcher.pattern == 'F *'
+        assert matcher.match('Foo')
+        assert matcher.match('--Foo')
+        assert not matcher.match('foo')
+

 if __name__ == "__main__":
     unittest.main()

==============================================================================
Revision: 5729004c40f8
Author:   Pekka Klärck
Date:     Fri Nov  4 22:48:40 2011
Log:      TagPatterns: support for seq2str
http://code.google.com/p/robotframework/source/detail?r=5729004c40f8

Modified:
 /src/robot/model/tags.py
 /utest/model/test_tags.py

=======================================
--- /src/robot/model/tags.py    Fri Nov  4 22:14:26 2011
+++ /src/robot/model/tags.py    Fri Nov  4 22:48:40 2011
@@ -70,6 +70,9 @@
     def __iter__(self):
         return iter(self._patterns)

+    def __getitem__(self, index):
+        return self._patterns[index]
+

 def TagPattern(pattern):
pattern = pattern.replace('&', 'AND') # TODO: where should this be done?
@@ -88,6 +91,9 @@
     def match(self, tags):
         return any(self._matcher.match(tag) for tag in tags)

+    def __unicode__(self):
+        return self._matcher.pattern
+

 class _AndTagPattern(object):

=======================================
--- /utest/model/test_tags.py   Fri Nov  4 05:27:22 2011
+++ /utest/model/test_tags.py   Fri Nov  4 22:48:40 2011
@@ -1,6 +1,7 @@
 import unittest

 from robot.utils.asserts import assert_equal, assert_true, assert_false
+from robot import utils
 from robot.model.tags import *


@@ -149,6 +150,10 @@
         assert_true(patterns.match(['a', 'b', 'c', 'd', 'e', 'f']))
         assert_false(patterns.match(['a', 'b', 'c', 'd', 'e']))

+    def test_seq2str(self):
+        patterns = TagPatterns([u'is\xe4', u'\xe4iti'])
+        assert_equal(utils.seq2str(patterns), u"'is\xe4' and '\xe4iti'")
+

 if __name__ == '__main__':
     unittest.main()

==============================================================================
Revision: 5f3d7fe63c61
Author:   Pekka Klärck
Date:     Fri Nov  4 22:48:58 2011
Log:      use reusable TagPatterns when we can
http://code.google.com/p/robotframework/source/detail?r=5f3d7fe63c61

Modified:
 /src/robot/libraries/BuiltIn.py

=======================================
--- /src/robot/libraries/BuiltIn.py     Fri Aug 26 06:29:08 2011
+++ /src/robot/libraries/BuiltIn.py     Fri Nov  4 22:48:58 2011
@@ -25,6 +25,7 @@
 from robot.running.model import ExecutionContext
 from robot.common import UserErrorHandler
 from robot.version import get_version
+from robot.model import TagPatterns

 if utils.is_jython:
     from java.lang import String, Number
@@ -1818,9 +1819,8 @@
         Example:
         | Remove Tags | mytag | something-* | ?ython |
         """
-        tags = utils.normalize_tags(tags)
-        handler = lambda test: [t for t in test.tags
-                                if not utils.matches_any(t, tags)]
+        tags = TagPatterns(tags)
+        handler = lambda test: [t for t in test.tags if not tags.match(t)]
         self._set_or_remove_tags(handler)
         self.log('Removed tag%s %s.' % (utils.plural_or_not(tags),
                                         utils.seq2str(tags)))

Reply via email to