Fix to preserve argspec
The positional wrapper is fixed so that the argspec of the wrapped function is preserved.
This commit is contained in:
		| @@ -10,11 +10,11 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
| import functools |  | ||||||
| import inspect | import inspect | ||||||
| import warnings | import warnings | ||||||
|  |  | ||||||
| import pbr.version | import pbr.version | ||||||
|  | import wrapt | ||||||
|  |  | ||||||
| __version__ = pbr.version.VersionInfo('positional').version_string() | __version__ = pbr.version.VersionInfo('positional').version_string() | ||||||
|  |  | ||||||
| @@ -76,14 +76,21 @@ class positional(object): | |||||||
|  |  | ||||||
|         plural = '' if self._max_positional_args == 1 else 's' |         plural = '' if self._max_positional_args == 1 else 's' | ||||||
|  |  | ||||||
|         @functools.wraps(func) |         @wrapt.decorator | ||||||
|         def inner(*args, **kwargs): |         def inner(wrapped, instance, args, kwargs): | ||||||
|             if len(args) > self._max_positional_args: |  | ||||||
|  |             # If called on an instance, adjust args len for the 'self' | ||||||
|  |             # parameter. | ||||||
|  |             args_len = len(args) | ||||||
|  |             if instance: | ||||||
|  |                 args_len += 1 | ||||||
|  |  | ||||||
|  |             if args_len > self._max_positional_args: | ||||||
|                 message = ('%(name)s takes at most %(max)d positional ' |                 message = ('%(name)s takes at most %(max)d positional ' | ||||||
|                            'argument%(plural)s (%(given)d given)' % |                            'argument%(plural)s (%(given)d given)' % | ||||||
|                            {'name': func.__name__, |                            {'name': wrapped.__name__, | ||||||
|                             'max': self._max_positional_args, |                             'max': self._max_positional_args, | ||||||
|                             'given': len(args), |                             'given': args_len, | ||||||
|                             'plural': plural}) |                             'plural': plural}) | ||||||
|  |  | ||||||
|                 if self._enforcement == self.EXCEPT: |                 if self._enforcement == self.EXCEPT: | ||||||
| @@ -91,6 +98,6 @@ class positional(object): | |||||||
|                 elif self._enforcement == self.WARN: |                 elif self._enforcement == self.WARN: | ||||||
|                     warnings.warn(message, DeprecationWarning, stacklevel=2) |                     warnings.warn(message, DeprecationWarning, stacklevel=2) | ||||||
|  |  | ||||||
|             return func(*args, **kwargs) |             return wrapped(*args, **kwargs) | ||||||
|  |  | ||||||
|         return inner |         return inner(func) | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
| #    License for the specific language governing permissions and limitations | #    License for the specific language governing permissions and limitations | ||||||
| #    under the License. | #    under the License. | ||||||
|  |  | ||||||
|  | import inspect | ||||||
| import warnings | import warnings | ||||||
|  |  | ||||||
| import testtools | import testtools | ||||||
| @@ -81,3 +82,15 @@ class TestPositional(testtools.TestCase): | |||||||
|     def test_normal_method(self): |     def test_normal_method(self): | ||||||
|         self.assertEqual((self, 1, 2), self.normal_method(1, b=2)) |         self.assertEqual((self, 1, 2), self.normal_method(1, b=2)) | ||||||
|         self.assertRaises(TypeError, self.normal_method, 1, 2) |         self.assertRaises(TypeError, self.normal_method, 1, 2) | ||||||
|  |  | ||||||
|  |     def test_argspec_preserved(self): | ||||||
|  |  | ||||||
|  |         @positional() | ||||||
|  |         def f_wrapped(my_arg=False): | ||||||
|  |             return my_arg | ||||||
|  |  | ||||||
|  |         def f_not_wrapped(my_arg=False): | ||||||
|  |             return my_arg | ||||||
|  |  | ||||||
|  |         self.assertEqual(inspect.getargspec(f_not_wrapped), | ||||||
|  |                          inspect.getargspec(f_wrapped)) | ||||||
|   | |||||||
| @@ -2,3 +2,4 @@ | |||||||
| # of appearance. | # of appearance. | ||||||
|  |  | ||||||
| pbr>=1.6 | pbr>=1.6 | ||||||
|  | wrapt | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Brant Knudson
					Brant Knudson