summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-02-07 20:18:47 -0500
committerChris McDonough <chrism@plope.com>2012-02-07 20:18:47 -0500
commit89eeb971cdc0d499015a39300ff8662b0f31f0e5 (patch)
tree93b19aab92368cac99bf591f3bcea0107f7e17b3
parentf4952ee0d30eeb67976684d6422f5db05d9f5264 (diff)
parent1ceae4adac7c050e955778c71b3680edb9a3cb8c (diff)
downloadpyramid-89eeb971cdc0d499015a39300ff8662b0f31f0e5.tar.gz
pyramid-89eeb971cdc0d499015a39300ff8662b0f31f0e5.tar.bz2
pyramid-89eeb971cdc0d499015a39300ff8662b0f31f0e5.zip
Merge branch '1.3-branch' of github.com:Pylons/pyramid into 1.3-branch
-rw-r--r--CHANGES.txt11
-rw-r--r--docs/narr/urldispatch.rst2
-rw-r--r--pyramid/config/util.py14
-rw-r--r--pyramid/config/views.py8
-rw-r--r--pyramid/tests/test_config/test_util.py16
5 files changed, 37 insertions, 14 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 7d20796e1..8bfdc6d66 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -10,6 +10,10 @@ Features
- Internal: catch unhashable discriminators early (raise an error instead of
allowing them to find their way into resolveConflicts).
+- The `match_param` view predicate now accepts a string or a tuple.
+ This replaces the broken behavior of accepting a dict. See
+ https://github.com/Pylons/pyramid/issues/425 for more information.
+
Bug Fixes
---------
@@ -21,6 +25,13 @@ Bug Fixes
- The ``prequest`` script would fail when used against URLs which did not
return HTML or text. See https://github.com/Pylons/pyramid/issues/381
+Backwards Incompatibilities
+---------------------------
+
+- The `match_param` view predicate no longer accepts a dict. This will
+ have no negative affect because the implementation was broken for
+ dict-based arguments.
+
Documentation
-------------
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index dfa4e629d..a7bf74786 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -340,7 +340,7 @@ The above pattern will match these URLs, generating the following matchdicts:
.. code-block:: text
- foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':()}
+ foo/1/2/ -> {'baz':u'1', 'bar':u'2', 'fizzle':u''}
foo/abc/def/a/b/c -> {'baz':u'abc', 'bar':u'def', 'fizzle': u'a/b/c'}
This occurs because the default regular expression for a marker is ``[^/]+``
diff --git a/pyramid/config/util.py b/pyramid/config/util.py
index 6c1bb8368..b39fb8ee0 100644
--- a/pyramid/config/util.py
+++ b/pyramid/config/util.py
@@ -221,19 +221,21 @@ def make_predicates(xhr=None, request_method=None, path_info=None,
h.update(bytes_('request_type:%r' % hash(request_type)))
if match_param is not None:
- if isinstance(match_param, string_types):
- match_param, match_param_val = match_param.split('=', 1)
- match_param = {match_param: match_param_val}
- text = "match_param %s" % match_param
+ if not is_nonstr_iter(match_param):
+ match_param = (match_param,)
+ match_param = sorted(match_param)
+ text = "match_param %s" % repr(match_param)
+ reqs = [p.split('=', 1) for p in match_param]
def match_param_predicate(context, request):
- for k, v in match_param.items():
+ for k, v in reqs:
if request.matchdict.get(k) != v:
return False
return True
match_param_predicate.__text__ = text
weights.append(1 << 9)
predicates.append(match_param_predicate)
- h.update(bytes_('match_param:%r' % match_param))
+ for p in match_param:
+ h.update(bytes_('match_param:%r' % p))
if custom:
for num, predicate in enumerate(custom):
diff --git a/pyramid/config/views.py b/pyramid/config/views.py
index 0359c46f7..a87ab54c7 100644
--- a/pyramid/config/views.py
+++ b/pyramid/config/views.py
@@ -843,18 +843,18 @@ class ViewsConfiguratorMixin(object):
.. note:: This feature is new as of :app:`Pyramid` 1.2.
- This param may be either a single string of the format "key=value"
- or a dict of key/value pairs.
+ This value can be a string of the format "key=value" or a tuple
+ containing one or more of these strings.
A view declaration with this argument ensures that the view will
only be called when the :term:`request` has key/value pairs in its
:term:`matchdict` that equal those supplied in the predicate.
e.g. ``match_param="action=edit" would require the ``action``
- parameter in the :term:`matchdict` match the right hande side of
+ parameter in the :term:`matchdict` match the right hand side of
the expression (``edit``) for the view to "match" the current
request.
- If the ``match_param`` is a dict, every key/value pair must match
+ If the ``match_param`` is a tuple, every key/value pair must match
for the predicate to pass.
containment
diff --git a/pyramid/tests/test_config/test_util.py b/pyramid/tests/test_config/test_util.py
index ebf308929..1ad1fb3c1 100644
--- a/pyramid/tests/test_config/test_util.py
+++ b/pyramid/tests/test_config/test_util.py
@@ -281,7 +281,7 @@ class Test__make_predicates(unittest.TestCase):
self.assertEqual(predicates[5].__text__, 'accept = accept')
self.assertEqual(predicates[6].__text__, 'containment = containment')
self.assertEqual(predicates[7].__text__, 'request_type = request_type')
- self.assertEqual(predicates[8].__text__, "match_param {'foo': 'bar'}")
+ self.assertEqual(predicates[8].__text__, "match_param ['foo=bar']")
self.assertEqual(predicates[9].__text__, 'custom predicate')
self.assertEqual(predicates[10].__text__, 'classmethod predicate')
self.assertEqual(predicates[11].__text__, '<unknown custom predicate>')
@@ -299,13 +299,13 @@ class Test__make_predicates(unittest.TestCase):
self.assertFalse(predicates[0](Dummy(), request))
def test_match_param_from_dict(self):
- _, predicates, _ = self._callFUT(match_param={'foo':'bar','baz':'bum'})
+ _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum'))
request = DummyRequest()
request.matchdict = {'foo':'bar', 'baz':'bum'}
self.assertTrue(predicates[0](Dummy(), request))
def test_match_param_from_dict_fails(self):
- _, predicates, _ = self._callFUT(match_param={'foo':'bar','baz':'bum'})
+ _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum'))
request = DummyRequest()
request.matchdict = {'foo':'bar', 'baz':'foo'}
self.assertFalse(predicates[0](Dummy(), request))
@@ -328,6 +328,16 @@ class Test__make_predicates(unittest.TestCase):
hash2, _, __= self._callFUT(request_method='GET')
self.assertEqual(hash1, hash2)
+ def test_match_param_hashable(self):
+ # https://github.com/Pylons/pyramid/issues/425
+ import pyramid.testing
+ def view(request): pass
+ config = pyramid.testing.setUp(autocommit=False)
+ config.add_route('foo', '/foo/{a}/{b}')
+ config.add_view(view, route_name='foo', match_param='a=bar')
+ config.add_view(view, route_name='foo', match_param=('a=bar', 'b=baz'))
+ config.commit()
+
class TestActionInfo(unittest.TestCase):
def _getTargetClass(self):
from pyramid.config.util import ActionInfo