diff options
| author | John Anderson <sontek@gmail.com> | 2014-12-25 23:42:05 -0800 |
|---|---|---|
| committer | John Anderson <sontek@gmail.com> | 2014-12-25 23:42:05 -0800 |
| commit | bc26debd9ed2a46fca1b0931c78b4054bd37841d (patch) | |
| tree | 6f0ece0645d3ceabfcd2c071de1de43311a62dda | |
| parent | 731a8e8380bbf9b41298c0417795e68899b91953 (diff) | |
| download | pyramid-bc26debd9ed2a46fca1b0931c78b4054bd37841d.tar.gz pyramid-bc26debd9ed2a46fca1b0931c78b4054bd37841d.tar.bz2 pyramid-bc26debd9ed2a46fca1b0931c78b4054bd37841d.zip | |
Add support for passing unbound class methods to `add_view`
| -rw-r--r-- | pyramid/config/views.py | 13 | ||||
| -rw-r--r-- | pyramid/tests/test_config/test_views.py | 21 |
2 files changed, 33 insertions, 1 deletions
diff --git a/pyramid/config/views.py b/pyramid/config/views.py index c01b72e12..3e305055f 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -42,7 +42,8 @@ from pyramid.compat import ( url_quote, WIN, is_bound_method, - is_nonstr_iter + is_nonstr_iter, + im_self, ) from pyramid.exceptions import ( @@ -418,6 +419,16 @@ class DefaultViewMapper(object): self.attr = kw.get('attr') def __call__(self, view): + # Map the attr directly if the passed in view is method and a + # constructor is defined and must be unbound (for backwards + # compatibility) + if inspect.ismethod(view): + is_bound = getattr(view, im_self, None) is not None + + if not is_bound: + self.attr = view.__name__ + view = view.im_class + if inspect.isclass(view): view = self.map_class(view) else: diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py index b0d03fb72..664208fad 100644 --- a/pyramid/tests/test_config/test_views.py +++ b/pyramid/tests/test_config/test_views.py @@ -1666,6 +1666,27 @@ class TestViewsConfigurationMixin(unittest.TestCase): renderer=null_renderer) self.assertRaises(ConfigurationConflictError, config.commit) + def test_add_view_class_method_no_attr(self): + from pyramid.renderers import null_renderer + from zope.interface import directlyProvides + + class ViewClass(object): + def __init__(self, request): + self.request = request + + def run(self): + return 'OK' + + config = self._makeOne(autocommit=True) + config.add_view(view=ViewClass.run, renderer=null_renderer) + + wrapper = self._getViewCallable(config) + context = DummyContext() + directlyProvides(context, IDummy) + request = self._makeRequest(config) + result = wrapper(context, request) + self.assertEqual(result, 'OK') + def test_derive_view_function(self): from pyramid.renderers import null_renderer def view(request): |
