Repository: NeuralEnsemble/python-neo

Issue:
segments[0].filter recursion if String key not found.
example:script  (taken from doc except for last line)
```python
from neo.core import (Block, Segment, ChannelIndex, AnalogSignal)
from quantities import nA, kHz
import numpy as np

blk = Block()
for ind in range(3):
     seg = Segment(name='segment %d' % ind, index=ind)
     blk.segments.append(seg)

for ind in range(2):
     chx = ChannelIndex(name='Array probe %d' % ind,
                        index=np.arange(64))
     blk.channel_indexes.append(chx)

for seg in blk.segments:
     for chx in blk.channel_indexes:
         a = AnalogSignal(np.random.randn(10000, 64)*nA,
                          sampling_rate=10*kHz)
         chx.analogsignals.append(a)
         seg.analogsignals.append(a)

print(blk)
blk.segments[0].filter("foo")
```
-
Clearly the filter("foo") should fail but NOT with the error 
RecursionError: maximum recursion depth exceeded while calling a Python object

-
We suspect this is called because the filter checks if the key is an iterable and then check each element separately.  Which is a great idea until you remember that a string is an iterable so on not finding "foo" it tries "f"  which is still and iterable with one element "f" ............

Discussion:

Patch:
diff --git a/neo/core/container.py b/neo/core/container.py
index 5e7084cf..f990f0b4 100644
--- a/neo/core/container.py
+++ b/neo/core/container.py
@@ -8,6 +8,10 @@ object inherit from.  It provides shared methods for all container types.
 
 # needed for python 3 compatibility
 from __future__ import absolute_import, division, print_function
+try:
+    basestring
+except NameError:
+    basestring = str
 
 from neo.core.baseneo import BaseNeo, _reference_name, _container_name
 
@@ -404,6 +408,11 @@ class Container(BaseNeo):
             >>> obj.filter(objects=neo.SpikeTrain)
             >>> obj.filter(targdict={'myannotation':3})
         """
+
+        if isinstance(targdict, basestring):
+            raise TypeError("filtering is based on key-value pairs."
+                            " Only a single string was provided.")
+
         # if objects are specified, get the classes
         if objects:
             data = True


Test patch:
diff --git a/neo/test/coretest/test_container.py b/neo/test/coretest/test_container.py
index ab197eeb..90f13a23 100644
--- a/neo/test/coretest/test_container.py
+++ b/neo/test/coretest/test_container.py
@@ -101,6 +101,10 @@ class TestContainerNeo(unittest.TestCase):
         container.create_many_to_many_relationship()
         container.create_relationship()
 
+    def test_filter(self):
+        container = Container()
+        self.assertRaises(TypeError, container.filter, "foo")
+
 
 class Test_Container_merge(unittest.TestCase):
     '''