summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Socol <me@jamessocol.com>2017-11-07 09:27:51 -0500
committerGitHub <noreply@github.com>2017-11-07 09:27:51 -0500
commitc934453f8d5709f7075b845e03ba31e228d31bca (patch)
treeca9105f712f354b7baa249ae90f362bd8b1c571b
parent883f2c3818521174a8f32c3200324f4a75b19bc1 (diff)
parent353e54ae49cc86b47fef9f7b7464785497ebf3d4 (diff)
downloadpystatsd-c934453f8d5709f7075b845e03ba31e228d31bca.tar.gz
Merge pull request #98 from leplatrem/master
Bug: Fix timer decorator with partial functions (#85)
-rw-r--r--AUTHORS1
-rw-r--r--CHANGES5
-rw-r--r--statsd/client.py11
-rw-r--r--statsd/tests.py13
4 files changed, 28 insertions, 2 deletions
diff --git a/AUTHORS b/AUTHORS
index a37070b..bedfa5f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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>
diff --git a/CHANGES b/CHANGES
index ddca03f..00c28c1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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):