diff options
| author | Chris McDonough <chrism@plope.com> | 2012-08-02 00:37:32 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2012-08-02 00:37:32 -0400 |
| commit | 1bbe668972a6ac3b116f44e50825c66ae5813326 (patch) | |
| tree | 147ed65503684a0ab1edb7a333f66755e52e439c | |
| parent | b4f193258837f94d6e4d069f37538dc6f55af709 (diff) | |
| parent | 92b456610438bdd94b7906683f8b2049fe5765bd (diff) | |
| download | pyramid-1bbe668972a6ac3b116f44e50825c66ae5813326.tar.gz pyramid-1bbe668972a6ac3b116f44e50825c66ae5813326.tar.bz2 pyramid-1bbe668972a6ac3b116f44e50825c66ae5813326.zip | |
Merge branch 'master' of github.com:Pylons/pyramid
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | pyramid/config/util.py | 7 | ||||
| -rw-r--r-- | pyramid/config/views.py | 12 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_views.py | 31 |
4 files changed, 47 insertions, 7 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index c6afaf0c7..ecb2bf659 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -54,3 +54,7 @@ Features result for the view being called. The uri format using an asset spec is package:path/to/template#defname.mako. The old way of returning a tuple from the view is supported for backward compatibility, ('defname', {}). + +- When there is a predicate mismatch exception (seen when no view matches for + a given request due to predicates not working), the exception now contains + a textual description of the predicate which didn't match. diff --git a/pyramid/config/util.py b/pyramid/config/util.py index b8d0f2319..4e4c93be3 100644 --- a/pyramid/config/util.py +++ b/pyramid/config/util.py @@ -113,6 +113,12 @@ def make_predicates(xhr=None, request_method=None, path_info=None, # any predicates get an order of MAX_ORDER, meaning that they will # be tried very last. + # NB: each predicate callable constructed by this function (or examined + # by this function, in the case of custom predicates) must leave this + # function with a ``__text__`` attribute. The subsystem which reports + # errors when no predicates match depends upon the existence of this + # attribute on each predicate callable. + predicates = [] weights = [] h = md5() @@ -273,6 +279,7 @@ def make_predicates(xhr=None, request_method=None, path_info=None, tvalue = tgenerate(m) # tvalue will be urlquoted string m['traverse'] = traversal_path(tvalue) # will be seq of unicode return True + traverse_predicate.__text__ = 'traverse matchdict pseudo-predicate' # This isn't actually a predicate, it's just a infodict # modifier that injects ``traverse`` into the matchdict. As a # result, the ``traverse_predicate`` function above always diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 9e9b5321b..4354b4691 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -276,11 +276,13 @@ class ViewDeriver(object): if not predicates: return view def predicate_wrapper(context, request): - if all((predicate(context, request) for predicate in predicates)): - return view(context, request) - view_name = getattr(view, '__name__', view) - raise PredicateMismatch( - 'predicate mismatch for view %s' % view_name) + for predicate in predicates: + if not predicate(context, request): + view_name = getattr(view, '__name__', view) + raise PredicateMismatch( + 'predicate mismatch for view %s (%s)' % ( + view_name, predicate.__text__)) + return view(context, request) def checker(context, request): return all((predicate(context, request) for predicate in predicates)) diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index 9b46f83c9..ebf1dfb39 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -2905,6 +2905,7 @@ class TestViewDeriver(unittest.TestCase): view = lambda *arg: response def predicate1(context, request): return False + predicate1.__text__ = 'text' deriver = self._makeOne(predicates=[predicate1]) result = deriver(view) request = self._makeRequest() @@ -2912,7 +2913,8 @@ class TestViewDeriver(unittest.TestCase): try: result(None, None) except PredicateMismatch as e: - self.assertEqual(e.detail, 'predicate mismatch for view <lambda>') + self.assertEqual(e.detail, + 'predicate mismatch for view <lambda> (text)') else: # pragma: no cover raise AssertionError @@ -2921,6 +2923,7 @@ class TestViewDeriver(unittest.TestCase): def myview(request): pass def predicate1(context, request): return False + predicate1.__text__ = 'text' deriver = self._makeOne(predicates=[predicate1]) result = deriver(myview) request = self._makeRequest() @@ -2928,7 +2931,29 @@ class TestViewDeriver(unittest.TestCase): try: result(None, None) except PredicateMismatch as e: - self.assertEqual(e.detail, 'predicate mismatch for view myview') + self.assertEqual(e.detail, + 'predicate mismatch for view myview (text)') + else: # pragma: no cover + raise AssertionError + + def test_predicate_mismatch_exception_has_text_in_detail(self): + from pyramid.exceptions import PredicateMismatch + def myview(request): pass + def predicate1(context, request): + return True + predicate1.__text__ = 'pred1' + def predicate2(context, request): + return False + predicate2.__text__ = 'pred2' + deriver = self._makeOne(predicates=[predicate1, predicate2]) + result = deriver(myview) + request = self._makeRequest() + request.method = 'POST' + try: + result(None, None) + except PredicateMismatch as e: + self.assertEqual(e.detail, + 'predicate mismatch for view myview (pred2)') else: # pragma: no cover raise AssertionError @@ -2974,9 +2999,11 @@ class TestViewDeriver(unittest.TestCase): def predicate1(context, request): predicates.append(True) return True + predicate1.__text__ = 'text' def predicate2(context, request): predicates.append(True) return False + predicate2.__text__ = 'text' deriver = self._makeOne(predicates=[predicate1, predicate2]) result = deriver(view) request = self._makeRequest() |
