diff options
author | James Socol <me@jamessocol.com> | 2017-11-07 09:27:51 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-07 09:27:51 -0500 |
commit | c934453f8d5709f7075b845e03ba31e228d31bca (patch) | |
tree | ca9105f712f354b7baa249ae90f362bd8b1c571b | |
parent | 883f2c3818521174a8f32c3200324f4a75b19bc1 (diff) | |
parent | 353e54ae49cc86b47fef9f7b7464785497ebf3d4 (diff) | |
download | pystatsd-c934453f8d5709f7075b845e03ba31e228d31bca.tar.gz |
Merge pull request #98 from leplatrem/master
Bug: Fix timer decorator with partial functions (#85)
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | statsd/client.py | 11 | ||||
-rw-r--r-- | statsd/tests.py | 13 |
4 files changed, 28 insertions, 2 deletions
@@ -6,3 +6,4 @@ Contributors: - Andy McKay <amckay@mozilla.com> - Daniel Holz <dgholz@gmail.com> - Kyle Conroy <kyle@kyleconroy.com> +- Mathieu Leplatre <mathieu@mozilla.com> @@ -1,6 +1,11 @@ Statsd Changelog ================ +Unreleased +---------- + +- Fix timer decorator with partial functions (#85) + Version 3.2.2 ------------- diff --git a/statsd/client.py b/statsd/client.py index 54f62e7..6d8a921 100644 --- a/statsd/client.py +++ b/statsd/client.py @@ -1,6 +1,6 @@ from __future__ import with_statement from collections import deque -from functools import wraps +import functools import random import socket import abc @@ -17,6 +17,13 @@ except ImportError: __all__ = ['StatsClient', 'TCPStatsClient'] +def safe_wraps(wrapper, *args, **kwargs): + """Safely wraps partial functions.""" + while isinstance(wrapper, functools.partial): + wrapper = wrapper.func + return functools.wraps(wrapper, *args, **kwargs) + + class Timer(object): """A context manager/decorator for statsd.timing().""" @@ -30,7 +37,7 @@ class Timer(object): def __call__(self, f): """Thread-safe timing function decorator.""" - @wraps(f) + @safe_wraps(f) def _wrapped(*args, **kwargs): start_time = time_now() try: diff --git a/statsd/tests.py b/statsd/tests.py index 2e388a7..b82c835 100644 --- a/statsd/tests.py +++ b/statsd/tests.py @@ -1,4 +1,5 @@ from __future__ import with_statement +import functools import random import re import socket @@ -517,6 +518,18 @@ def test_timer_context_rate_tcp(): _test_timer_context_rate(cl, 'tcp') +def test_timer_decorator_partial_function(): + """TCPStatsClient.timer can be used as decorator on a partial function.""" + cl = _tcp_client() + + foo = functools.partial(lambda x: x * x, 2) + func = cl.timer('foo')(foo) + + eq_(4, func()) + + _timer_check(cl._sock, 1, 'tcp', 'foo', 'ms|@0.1') + + def _test_timer_decorator_rate(cl, proto): @cl.timer('foo', rate=0.1) def foo(a, b): |