summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2024-01-27 17:33:26 -0700
committerMichael Merickel <michael@merickel.org>2024-01-27 17:33:26 -0700
commit19ae96b97ea055c2e36c8fb86819c426b37ab6af (patch)
tree437540b467bd1a2af90409145935742537b3699e
parent8a9d78106fd3b6d6dc44fabd205ee2c58fffef08 (diff)
downloadpyramid-19ae96b97ea055c2e36c8fb86819c426b37ab6af.tar.gz
pyramid-19ae96b97ea055c2e36c8fb86819c426b37ab6af.tar.bz2
pyramid-19ae96b97ea055c2e36c8fb86819c426b37ab6af.zip
revert restriction to eventonly predicates, allow a predicate to receive all args
-rw-r--r--src/pyramid/config/adapters.py26
-rw-r--r--src/pyramid/util.py5
-rw-r--r--tests/pkgs/eventonly/__init__.py19
-rw-r--r--tests/test_integration.py8
4 files changed, 53 insertions, 5 deletions
diff --git a/src/pyramid/config/adapters.py b/src/pyramid/config/adapters.py
index 08bfff142..8a043cf56 100644
--- a/src/pyramid/config/adapters.py
+++ b/src/pyramid/config/adapters.py
@@ -45,13 +45,17 @@ class AdaptersConfiguratorMixin:
predlist = self.get_predlist('subscriber')
order, preds, phash = predlist.make(self, **predicates)
- derived_subscriber = self._derive_subscriber(subscriber, preds)
+ derived_predicates = [self._derive_predicate(p) for p in preds]
+ derived_subscriber = self._derive_subscriber(
+ subscriber, derived_predicates
+ )
intr.update(
{
'phash': phash,
'order': order,
'predicates': preds,
+ 'derived_predicates': derived_predicates,
'derived_subscriber': derived_subscriber,
}
)
@@ -71,6 +75,19 @@ class AdaptersConfiguratorMixin:
self.action(None, register, introspectables=(intr,))
return subscriber
+ def _derive_predicate(self, predicate):
+ if eventonly(predicate):
+
+ def derived_predicate(*arg):
+ return predicate(arg[0])
+
+ # seems pointless to try to fix __doc__, __module__, etc as
+ # predicate will invariably be an instance
+ else:
+ derived_predicate = predicate
+
+ return derived_predicate
+
def _derive_subscriber(self, subscriber, predicates):
if eventonly(subscriber):
@@ -104,7 +121,7 @@ class AdaptersConfiguratorMixin:
# with all args, the eventonly hack would not have been required.
# At this point, though, using .subscriptions and manual execution
# is not possible without badly breaking backwards compatibility.
- if all(predicate(arg[0]) for predicate in predicates):
+ if all(predicate(*arg) for predicate in predicates):
return derived_subscriber(*arg)
if hasattr(subscriber, '__name__'):
@@ -309,4 +326,7 @@ class AdaptersConfiguratorMixin:
def eventonly(callee):
- return takes_one_arg(callee, argname='event')
+ # we do not count a function as eventonly if it accepts *args
+ # which will open up the possibility for the function to receive
+ # all of the args
+ return takes_one_arg(callee, argname='event', allow_varargs=False)
diff --git a/src/pyramid/util.py b/src/pyramid/util.py
index f396712f3..c71528a49 100644
--- a/src/pyramid/util.py
+++ b/src/pyramid/util.py
@@ -652,7 +652,7 @@ def make_contextmanager(fn):
return wrapper
-def takes_one_arg(callee, attr=None, argname=None):
+def takes_one_arg(callee, attr=None, argname=None, allow_varargs=True):
ismethod = False
if attr is None:
attr = '__call__'
@@ -679,6 +679,9 @@ def takes_one_arg(callee, attr=None, argname=None):
if not args:
return False
+ if not allow_varargs and argspec.varargs:
+ return False
+
if len(args) == 1:
return True
diff --git a/tests/pkgs/eventonly/__init__.py b/tests/pkgs/eventonly/__init__.py
index e45a5691f..f7a9270dc 100644
--- a/tests/pkgs/eventonly/__init__.py
+++ b/tests/pkgs/eventonly/__init__.py
@@ -15,6 +15,19 @@ class Yup:
return getattr(event.response, 'yup', False)
+class YupWithAllArgs:
+ def __init__(self, val, config):
+ self.val = val
+
+ def text(self):
+ return f'yup_with_extra_args = {self.val}'
+
+ phash = text
+
+ def __call__(self, event, *args):
+ return getattr(event.response, 'yup', False)
+
+
class Foo:
def __init__(self, response):
self.response = response
@@ -54,6 +67,11 @@ def foobaryup2(event, context):
event.response.text += 'foobaryup2 '
+@subscriber([Foo, Bar], yup=True, yup_with_all_args=True)
+def foobaryup3(event, context):
+ event.response.text += 'foobaryup3 '
+
+
@view_config(name='sendfoo')
def sendfoo(request):
response = request.response
@@ -72,4 +90,5 @@ def sendfoobar(request):
def includeme(config):
config.add_subscriber_predicate('yup', Yup)
+ config.add_subscriber_predicate('yup_with_all_args', YupWithAllArgs)
config.scan('tests.pkgs.eventonly')
diff --git a/tests/test_integration.py b/tests/test_integration.py
index 63a7088e9..7ca11e81e 100644
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -213,7 +213,13 @@ class TestEventOnlySubscribers(IntegrationBase, unittest.TestCase):
res = self.testapp.get('/sendfoobar', status=200)
self.assertEqual(
sorted(res.body.split()),
- [b'foobar', b'foobar2', b'foobaryup', b'foobaryup2'],
+ [
+ b'foobar',
+ b'foobar2',
+ b'foobaryup',
+ b'foobaryup2',
+ b'foobaryup3',
+ ],
)