diff --git a/CHANGES.rst b/CHANGES.rst index 1a303e9..bc80423 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,8 @@ For changes before version 3.0, see ``HISTORY.rst``. 4.0b6 (unreleased) ------------------ -- Nothing changed yet. +- Fix deprecation warnings for Python 3 and + change visibility of `buildfacade` to public. (#68, #69, #70) 4.0b5 (2018-10-05) diff --git a/src/AccessControl/requestmethod.py b/src/AccessControl/requestmethod.py index 18d063a..f9e537e 100644 --- a/src/AccessControl/requestmethod.py +++ b/src/AccessControl/requestmethod.py @@ -25,7 +25,7 @@ _default = [] -def _buildFacade(name, method, docstring): +def buildfacade(name, method, docstring): """Build a facade function, matching the decorated method in signature. Note that defaults are replaced by _default, and _curried will reconstruct @@ -34,13 +34,14 @@ def _buildFacade(name, method, docstring): """ sig = signature(method) args = [] + callargs = [] for v in sig.parameters.values(): - argstr = str(v) + parts = str(v).split('=') args.append( - argstr if '=' not in argstr else '{}=_default'.format(v.name)) - callargs = ', '.join(sig.parameters.keys()) + parts[0] if len(parts) == 1 else '{}=_default'.format(parts[0])) + callargs.append(parts[0]) return 'def %s(%s):\n """%s"""\n return _curried(%s)' % ( - name, ', '.join(args), docstring, callargs) + name, ', '.join(args), docstring, ', '.join(callargs)) def requestmethod(*methods): @@ -86,7 +87,7 @@ def _curried(*args, **kw): # Build a facade, with a reference to our locally-scoped _curried name = callable.__name__ facade_globs = dict(_curried=_curried, _default=_default) - exec(_buildFacade(name, callable, callable.__doc__), facade_globs) + exec(buildfacade(name, callable, callable.__doc__), facade_globs) return facade_globs[name] return _methodtest diff --git a/src/AccessControl/tests/test_requestmethod.py b/src/AccessControl/tests/test_requestmethod.py index 910b22b..9971065 100644 --- a/src/AccessControl/tests/test_requestmethod.py +++ b/src/AccessControl/tests/test_requestmethod.py @@ -13,6 +13,7 @@ from AccessControl.requestmethod import requestmethod from AccessControl.requestmethod import getfullargspec +from AccessControl.requestmethod import buildfacade from zope.interface import implementer from zope.publisher.interfaces.browser import IBrowserRequest import unittest @@ -84,7 +85,6 @@ def test_preserves_keyword_parameter_defaults(self): # variables against callable signatures, the result of the decorator # must match the original closely, and keyword parameter defaults must # be preserved: - import inspect mutabledefault = dict() @requestmethod('POST') @@ -121,3 +121,16 @@ def foo(bar, REQUEST=None): foo('spam', POST) self.assertEqual('Request must be GET, HEAD or PROPFIND', str(err.exception)) + + def test_facade_render_correct_args_kwargs(self): + """ s. https://github.com/zopefoundation/AccessControl/issues/69 + """ + def foo(bar, baz, *args, **kwargs): + """foo doc""" + return baz + got = buildfacade('foo', foo, foo.__doc__) + expected = '\n'.join([ + 'def foo(bar, baz, *args, **kwargs):', + ' """foo doc"""', + ' return _curried(bar, baz, *args, **kwargs)']) + self.assertEqual(expected, got)