Repository: cool-RR/PySnooper

Issue:
Problem with passing in a single tuple in custom_repr= ()
I was trying it on a toy example and just wanted to pass in one tuple like 
(list, print_list_size) to custom_repr= () with print_list_size being the example used in the readme file:
`
def print_list_size(l):
    return 'list(size={})'.format(len(l))
`

There was an exception:" TypeError: cannot unpack non-iterable function object." 
I think the problem lies in that custom_repr is a tuple of tuples thus when it has only one element it won't be unpacked successfully. 
I changed custom_repr = [ ] and then put in the tuple (list, print_list_size) and it worked. Or, put an extra , in the tuple such like this:
`
@pysnooper.snoop(custom_repr = ( (list, print_list_size), ))
`

Just a small issue but hopefully this would be beneficial for other people. 



Discussion:

Patch:
diff --git a/pysnooper/tracer.py b/pysnooper/tracer.py
index 5d91aeb..fb6eddc 100644
--- a/pysnooper/tracer.py
+++ b/pysnooper/tracer.py
@@ -214,6 +214,9 @@ class Tracer:
         self.target_codes = set()
         self.target_frames = set()
         self.thread_local = threading.local()
+        if len(custom_repr) == 2 and not all(isinstance(x,
+                      pycompat.collections_abc.Iterable) for x in custom_repr):
+            custom_repr = (custom_repr,)
         self.custom_repr = custom_repr
 
     def __call__(self, function):


Test patch:
diff --git a/tests/test_pysnooper.py b/tests/test_pysnooper.py
index 0b93845..930dd5d 100644
--- a/tests/test_pysnooper.py
+++ b/tests/test_pysnooper.py
@@ -1174,6 +1174,30 @@ def test_custom_repr():
         )
     )
 
+def test_custom_repr_single():
+    string_io = io.StringIO()
+
+    @pysnooper.snoop(string_io, custom_repr=(list, lambda l: 'foofoo!'))
+    def sum_to_x(x):
+        l = list(range(x))
+        return 7
+
+    result = sum_to_x(10000)
+
+    output = string_io.getvalue()
+    assert_output(
+        output,
+        (
+            VariableEntry('x', '10000'),
+            CallEntry(),
+            LineEntry(),
+            VariableEntry('l', 'foofoo!'),
+            LineEntry(),
+            ReturnEntry(),
+            ReturnValueEntry('7'),
+        )
+    )
+
 
 def test_disable():
     string_io = io.StringIO()