From 523132fe530f3ed19316c569351b6d0e3539c5e0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Fri, 30 Jul 2010 01:19:46 +0000 Subject: cm --- TODO.txt | 2 ++ docs/narr/urldispatch.rst | 22 ++++++++++++++++++++-- repoze/bfg/tests/test_urldispatch.py | 11 ++++++++--- repoze/bfg/urldispatch.py | 2 +- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/TODO.txt b/TODO.txt index c46ec76ff..ae9ef2168 100644 --- a/TODO.txt +++ b/TODO.txt @@ -27,6 +27,8 @@ - Debug option to print view matching decision. +- Ability to use configurator as a context manager. + - These methods of Configurator should allow the arguments it receives named below them to be strings: diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst index 59bcde13f..3c7555636 100644 --- a/docs/narr/urldispatch.rst +++ b/docs/narr/urldispatch.rst @@ -258,6 +258,24 @@ It will not match the following patterns however: foo/1/2/ -> No match (trailing slash) bar/abc/def -> First segment literal mismatch +The match for a segment replacement marker in a segment will be done +only up to the first non-alphanumeric character in the segment in the +pattern. So, for instance, if this route pattern was used: + +.. code-block:: text + + foo/:name.html + +The literal path ``/foo/biz.html`` will match the above route pattern, +and the match result will be ``{'name':u'biz'}``. However, the +literal path ``/foo/biz`` will not match, because it does not contain +a literal ``.html`` at the end of the segment represented by +``:name.html`` (it only contains ``biz``, not ``biz.html``). + +This does not mean, however, that you can use two segment replacement +markers in the same segment. For instance, ``/:foo:bar`` is a +nonsensical route pattern. It will never match anything. + Note that values representing path segments matched with a ``:segment`` match will be url-unquoted and decoded from UTF-8 into Unicode within the matchdict. So for instance, the following @@ -294,8 +312,8 @@ matchdicts: .. code-block:: text - foo/1/2/ -> {'baz':1, 'bar':2, 'fizzle':()} - foo/abc/def/a/b/c -> {'baz':abc, 'bar':def, 'fizzle':('a', 'b', 'c')} + foo/1/2/ -> {'baz':'1', 'bar':'2', 'fizzle':()} + foo/abc/def/a/b/c -> {'baz':'abc', 'bar':'def', 'fizzle':('a', 'b', 'c')} Note that when a ``*stararg`` remainder match is matched, the value put into the matchdict is turned into a tuple of path segments diff --git a/repoze/bfg/tests/test_urldispatch.py b/repoze/bfg/tests/test_urldispatch.py index c5fa37758..89454e63b 100644 --- a/repoze/bfg/tests/test_urldispatch.py +++ b/repoze/bfg/tests/test_urldispatch.py @@ -230,9 +230,11 @@ class TestCompileRoute(unittest.TestCase): self.assertRaises(URLDecodeError, matcher, '/%FF%FE%8B%00') class TestCompileRouteMatchFunctional(unittest.TestCase): - def matches(self, pattern, path, result): + def matches(self, pattern, path, expected): from repoze.bfg.urldispatch import _compile_route - self.assertEqual(_compile_route(pattern)[0](path), result) + matcher = _compile_route(pattern)[0] + result = matcher(path) + self.assertEqual(result, expected) def generates(self, pattern, dict, result): from repoze.bfg.urldispatch import _compile_route @@ -244,9 +246,12 @@ class TestCompileRouteMatchFunctional(unittest.TestCase): self.matches('/', '/foo', None) self.matches('/foo/', '/foo', None) self.matches('/:x', '', None) + self.matches('/:x', '/', None) + self.matches('/abc/:def', '/abc/', None) + import pdb; pdb.set_trace() + self.matches('/abc/:def:baz', '/abc/bleep', None) # bad pattern self.matches('', '/', {}) self.matches('/', '/', {}) - self.matches('/:x', '/', {'x':''}) self.matches('/:x', '/a', {'x':'a'}) self.matches('zzz/:x', '/zzz/abc', {'x':'abc'}) self.matches('zzz/:x*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) diff --git a/repoze/bfg/urldispatch.py b/repoze/bfg/urldispatch.py index 80880d8f0..a07f902f6 100644 --- a/repoze/bfg/urldispatch.py +++ b/repoze/bfg/urldispatch.py @@ -79,7 +79,7 @@ def _compile_route(route): name = pat.pop() name = name[2:] gen.append('/%%(%s)s' % name) - name = '/(?P<%s>[^/]*)' % name + name = '/(?P<%s>[^/]+)' % name rpat.append(name) s = pat.pop() if s: -- cgit v1.2.3