summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheron Luhn <theron@luhn.com>2019-04-01 17:42:22 -0700
committerTheron Luhn <theron@luhn.com>2019-04-01 17:42:22 -0700
commite51069db045ccc648435e3535723f3ac4a24b168 (patch)
tree21780c4699d56926983358a07d89764b83c5f541
parent01618a1399f547fb1f89cf8b56600325b4f8d04b (diff)
downloadpyramid-e51069db045ccc648435e3535723f3ac4a24b168.tar.gz
pyramid-e51069db045ccc648435e3535723f3ac4a24b168.tar.bz2
pyramid-e51069db045ccc648435e3535723f3ac4a24b168.zip
Improve debugging info from view_config decorator.
Grab a frame when instanciating view_config, rather than pulling info from venusian's AttachInfo. See discussion at https://github.com/Pylons/pyramid/issues/3471 This fixes the build for Python 3.8.
-rw-r--r--src/pyramid/view.py17
-rw-r--r--tests/test_view.py12
2 files changed, 21 insertions, 8 deletions
diff --git a/src/pyramid/view.py b/src/pyramid/view.py
index 944ad93ea..524e06fb2 100644
--- a/src/pyramid/view.py
+++ b/src/pyramid/view.py
@@ -1,5 +1,6 @@
import itertools
import sys
+import inspect
import venusian
@@ -216,6 +217,13 @@ class view_config(object):
if settings.get('context') is None:
settings['context'] = settings['for_']
self.__dict__.update(settings)
+ self._get_info()
+
+ def _get_info(self):
+ frame = sys._getframe(2)
+ frameinfo = inspect.getframeinfo(frame)
+ sourceline = frameinfo[3][0].strip()
+ self._info = frameinfo[0], frameinfo[1], frameinfo[2], sourceline
def __call__(self, wrapped):
settings = self.__dict__.copy()
@@ -237,14 +245,13 @@ class view_config(object):
if settings.get('attr') is None:
settings['attr'] = wrapped.__name__
- settings['_info'] = info.codeinfo # fbo "action_method"
return wrapped
bfg_view = view_config # bw compat (forever)
-class view_defaults(view_config):
+def view_defaults(**settings):
""" A class :term:`decorator` which, when applied to a class, will
provide defaults for all view configurations that use the class. This
decorator accepts all the arguments accepted by
@@ -253,10 +260,12 @@ class view_defaults(view_config):
See :ref:`view_defaults` for more information.
"""
- def __call__(self, wrapped):
- wrapped.__view_defaults__ = self.__dict__.copy()
+ def wrap(wrapped):
+ wrapped.__view_defaults__ = settings
return wrapped
+ return wrap
+
class AppendSlashNotFoundViewFactory(object):
""" There can only be one :term:`Not Found view` in any
diff --git a/tests/test_view.py b/tests/test_view.py
index de40df1d5..e182c28ad 100644
--- a/tests/test_view.py
+++ b/tests/test_view.py
@@ -507,7 +507,14 @@ class TestViewConfigDecorator(unittest.TestCase):
def test_create_defaults(self):
decorator = self._makeOne()
- self.assertEqual(decorator.__dict__, {})
+ self.assertEqual(list(decorator.__dict__.keys()), ['_info'])
+
+ def test_create_info(self):
+ target = self._getTargetClass()
+ decorator = target()
+ info = decorator._info
+ self.assertEqual(info[2], 'test_create_info')
+ self.assertEqual(info[3], 'decorator = target()')
def test_create_context_trumps_for(self):
decorator = self._makeOne(context='123', for_='456')
@@ -560,7 +567,6 @@ class TestViewConfigDecorator(unittest.TestCase):
self.assertEqual(len(settings[0]), 3)
self.assertEqual(settings[0]['venusian'], venusian)
self.assertEqual(settings[0]['view'], None) # comes from call_venusian
- self.assertEqual(settings[0]['_info'], 'codeinfo')
def test_call_class(self):
decorator = self._makeOne()
@@ -580,7 +586,6 @@ class TestViewConfigDecorator(unittest.TestCase):
self.assertEqual(settings[0]['venusian'], venusian)
self.assertEqual(settings[0]['view'], None) # comes from call_venusian
self.assertEqual(settings[0]['attr'], 'foo')
- self.assertEqual(settings[0]['_info'], 'codeinfo')
def test_call_class_attr_already_set(self):
decorator = self._makeOne(attr='abc')
@@ -600,7 +605,6 @@ class TestViewConfigDecorator(unittest.TestCase):
self.assertEqual(settings[0]['venusian'], venusian)
self.assertEqual(settings[0]['view'], None) # comes from call_venusian
self.assertEqual(settings[0]['attr'], 'abc')
- self.assertEqual(settings[0]['_info'], 'codeinfo')
def test_stacking(self):
decorator1 = self._makeOne(name='1')