Commit 04be2c1c authored by Martijn Pieters's avatar Martijn Pieters

Merge default value fix from trunk

parent 0dc86d01
...@@ -15,14 +15,16 @@ import inspect ...@@ -15,14 +15,16 @@ import inspect
from zExceptions import Forbidden from zExceptions import Forbidden
from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPRequest import HTTPRequest
_default = []
def _buildFacade(spec, docstring): def _buildFacade(spec, docstring):
"""Build a facade function, matching the decorated method in signature. """Build a facade function, matching the decorated method in signature.
Note that defaults are replaced by None, and _curried will reconstruct Note that defaults are replaced by _default, and _curried will reconstruct
these to preserve mutable defaults. these to preserve mutable defaults.
""" """
args = inspect.formatargspec(formatvalue=lambda v: '=None', *spec) args = inspect.formatargspec(formatvalue=lambda v: '=_default', *spec)
callargs = inspect.formatargspec(formatvalue=lambda v: '', *spec) callargs = inspect.formatargspec(formatvalue=lambda v: '', *spec)
return 'def _facade%s:\n """%s"""\n return _curried%s' % ( return 'def _facade%s:\n """%s"""\n return _curried%s' % (
args, docstring, callargs) args, docstring, callargs)
...@@ -46,7 +48,6 @@ def postonly(callable): ...@@ -46,7 +48,6 @@ def postonly(callable):
if len(args) > r_index: if len(args) > r_index:
request = args[r_index] request = args[r_index]
if isinstance(request, HTTPRequest): if isinstance(request, HTTPRequest):
if request.get('REQUEST_METHOD', 'GET').upper() != 'POST': if request.get('REQUEST_METHOD', 'GET').upper() != 'POST':
raise Forbidden('Request must be POST') raise Forbidden('Request must be POST')
...@@ -55,7 +56,7 @@ def postonly(callable): ...@@ -55,7 +56,7 @@ def postonly(callable):
if defaults is not None: if defaults is not None:
args, kwparams = args[:arglen], args[arglen:] args, kwparams = args[:arglen], args[arglen:]
for positional, (key, default) in zip(kwparams, defaults): for positional, (key, default) in zip(kwparams, defaults):
if positional is None: if positional is _default:
kw[key] = default kw[key] = default
else: else:
kw[key] = positional kw[key] = positional
...@@ -63,7 +64,7 @@ def postonly(callable): ...@@ -63,7 +64,7 @@ def postonly(callable):
return callable(*args, **kw) return callable(*args, **kw)
# Build a facade, with a reference to our locally-scoped _curried # Build a facade, with a reference to our locally-scoped _curried
facade_globs = dict(_curried=_curried) facade_globs = dict(_curried=_curried, _default=_default)
exec _buildFacade(spec, callable.__doc__) in facade_globs exec _buildFacade(spec, callable.__doc__) in facade_globs
return facade_globs['_facade'] return facade_globs['_facade']
......
...@@ -61,9 +61,9 @@ original closely, and keyword parameter defaults must be preserved:: ...@@ -61,9 +61,9 @@ original closely, and keyword parameter defaults must be preserved::
>>> import inspect >>> import inspect
>>> mutabledefault = dict() >>> mutabledefault = dict()
>>> @postonly >>> @postonly
... def foo(bar, baz=mutabledefault, REQUEST=None, **kw): ... def foo(bar, baz=mutabledefault, egg=mutabledefault, REQUEST=None, **kw):
... return bar, baz is mutabledefault, REQUEST ... return bar, baz is mutabledefault, egg is None, REQUEST
>>> inspect.getargspec(foo)[:3] >>> inspect.getargspec(foo)[:3]
(['bar', 'baz', 'REQUEST'], None, 'kw') (['bar', 'baz', 'egg', 'REQUEST'], None, 'kw')
>>> foo('spam') >>> foo('spam', egg=None)
('spam', True, None) ('spam', True, True, None)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment