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)))