Repository: vispy/vispy

Issue:
Bug with text demo
Ubuntu 14.04, Python 3.4, Intel GPU

```
cyrille@Cyrille-ASUS:~$ python git/vispy/examples/basics/scene/text.py 
Downloading data from https://github.com/vispy/demo-data/raw/master/fonts/OpenSans-Regular.ttf (212 kB)
[........................................] 100.00000 \ downloading   
File saved as /home/cyrille/.vispy/data/fonts/OpenSans-Regular.ttf.
#f006
WARNING: Traceback (most recent call last):
  File "git/vispy/examples/basics/scene/text.py", line 43, in <module>
    canvas.app.run()
  File "/home/cyrille/git/vispy/vispy/app/application.py", line 88, in run
    return self._backend._vispy_run()
  File "/home/cyrille/git/vispy/vispy/app/backends/_qt.py", line 175, in _vispy_run
    return app.exec_()
  File "/home/cyrille/git/vispy/vispy/app/backends/_qt.py", line 334, in paintGL
    self._vispy_canvas.events.draw(region=None)
  File "/home/cyrille/git/vispy/vispy/util/event.py", line 418, in __call__
    self._invoke_callback(cb, event)
  File "/home/cyrille/git/vispy/vispy/util/event.py", line 446, in _invoke_callback
    self, cb_event=(cb, event))
  << caught exception here: >>
  File "/home/cyrille/git/vispy/vispy/scene/shaders/function.py", line 464, in signature
    self._signature = parsing.parse_function_signature(self._code)
  File "/home/cyrille/git/vispy/vispy/scene/shaders/parsing.py", line 62, in parse_function_signature
    raise Exception("Failed to parse function signature. "
Exception: Failed to parse function signature. Full code is printed above.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/cyrille/git/vispy/vispy/util/event.py", line 435, in _invoke_callback
    cb(event)
  File "/home/cyrille/git/vispy/vispy/scene/canvas.py", line 148, in on_draw
    self.draw_visual(self.scene)
  File "/home/cyrille/git/vispy/vispy/scene/canvas.py", line 181, in draw_visual
    visual.draw(scene_event)
  File "/home/cyrille/git/vispy/vispy/scene/subscene.py", line 41, in draw
    self.process_system(event, 'draw')
  File "/home/cyrille/git/vispy/vispy/scene/subscene.py", line 49, in process_system
    self._systems[system_name].process(event, self)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 22, in process
    self._process_entity(event, subscene, force_recurse=True)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 47, in _process_entity
    self._process_entity(event, sub_entity)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 33, in _process_entity
    _handle_exception(False, 'reminders', self, entity=entity)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 29, in _process_entity
    entity.draw(event)
  File "/home/cyrille/git/vispy/vispy/scene/widgets/viewbox.py", line 212, in draw
    self.scene.draw(event)
  File "/home/cyrille/git/vispy/vispy/scene/subscene.py", line 41, in draw
    self.process_system(event, 'draw')
  File "/home/cyrille/git/vispy/vispy/scene/subscene.py", line 49, in process_system
    self._systems[system_name].process(event, self)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 22, in process
    self._process_entity(event, subscene, force_recurse=True)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 47, in _process_entity
    self._process_entity(event, sub_entity)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 33, in _process_entity
    _handle_exception(False, 'reminders', self, entity=entity)
  File "/home/cyrille/git/vispy/vispy/scene/systems.py", line 29, in _process_entity
    entity.draw(event)
  File "/home/cyrille/git/vispy/vispy/scene/visuals/line/line.py", line 372, in draw
    self._gl_draw(event)
  File "/home/cyrille/git/vispy/vispy/scene/visuals/line/line.py", line 385, in _gl_draw
    '(gl_Position.x + 1.0) / 2.0')
  File "/home/cyrille/git/vispy/vispy/scene/shaders/function.py", line 456, in __call__
    return FunctionCall(self, args)
  File "/home/cyrille/git/vispy/vispy/scene/shaders/function.py", line 926, in __init__
    sig_len = len(function.args)
  File "/home/cyrille/git/vispy/vispy/scene/shaders/function.py", line 483, in args
    return self.signature[1]
  File "/home/cyrille/git/vispy/vispy/scene/shaders/function.py", line 466, in signature
    raise ValueError('Invalid code: ' + str(err))
ValueError: Invalid code: Failed to parse function signature. Full code is printed above.
WARNING: Error invoking callback <bound method SceneCanvas.on_draw of <Vispy canvas (PyQt4 (qt) backend) at 0x7f2bd935ce48>> for event: <DrawEvent blocked=False handled=False native=None region=None source=<Vispy canvas (PyQt4 (qt) backend) at 0x7f2bd935ce48> sources=[<Vispy canvas (PyQt4 (qt) backend) at 0x7f2bd935ce48>] type=draw>
#f006
WARNING: Error invoking callback <bound method SceneCanvas.on_draw of <Vispy canvas (PyQt4 (qt) backend) at 0x7f2bd935ce48>> repeat 2
#f006
WARNING: Error invoking callback <bound method SceneCanvas.on_draw of <Vispy canvas (PyQt4 (qt) backend) at 0x7f2bd935ce48>> repeat 3
```



Discussion:
Ahh, this is because of the recent changes where `str` is interpreted as a colormap... argh.

Generally a good idea to run through all of the examples before merging, it only takes a minute. Maybe we could add a unit test that just runs the examples and checks for exceptions..


Resolving patch:
diff --git a/examples/basics/visuals/colored_line.py b/examples/basics/visuals/colored_line.py
--- a/examples/basics/visuals/colored_line.py
+++ b/examples/basics/visuals/colored_line.py
@@ -15,6 +15,7 @@
 from vispy.color import colormaps
 from vispy.scene import visuals
 from vispy.scene.transforms import STTransform
+from vispy.ext.six import next
 
 colormaps = itertools.cycle(colormaps)
 
@@ -30,7 +31,7 @@ def __init__(self):
         vispy.scene.SceneCanvas.__init__(self, keys='interactive',
                                          size=(400, 200), show=True)
         # Create a visual that updates the line with different colormaps
-        color = colormaps.next()
+        color = next(colormaps)
         self.line = visuals.Line(pos=pos, color=color, mode='gl')
         self.line.transform = STTransform(translate=[0, 140])
         # redraw the canvas if the visual requests an update
diff --git a/vispy/scene/visuals/line/line.py b/vispy/scene/visuals/line/line.py
--- a/vispy/scene/visuals/line/line.py
+++ b/vispy/scene/visuals/line/line.py
@@ -169,6 +169,7 @@ class Line(Visual):
     color : Color, tuple, or array
         The color to use when drawing the line. If an array is given, it
         must be of shape (..., 4) and provide one rgba color per vertex.
+        Can also be a colormap name, or appropriate `Function`.
     width:
         The width of the line in px. Line widths > 1px are only
         guaranteed to work when using 'agg' mode.
@@ -187,7 +188,7 @@ class Line(Visual):
             * "gl" uses OpenGL's built-in line rendering. This is much faster,
               but produces much lower-quality results and is not guaranteed to
               obey the requested line width or join/endcap styles.
-    antialias : bool 
+    antialias : bool
         For mode='gl', specifies whether to use line smoothing or not.
     """
     def __init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1,
@@ -201,7 +202,7 @@ def __init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1,
             try:
                 self._color = Function(get_colormap(color))
             except KeyError:
-                self._color = Function(color)
+                self._color = ColorArray(color)
         elif isinstance(color, Function):
             self._color = Function(color)
         else:
@@ -224,7 +225,7 @@ def __init__(self, pos=None, color=(0.5, 0.5, 0.5, 1), width=1,
         self._da = None
         self._U = None
         self._dash_atlas = None
-        
+
         # now actually set the mode, which will call set_data
         self.mode = mode
 


Test patch: