Repository: psychopy/psychopy

Issue:
Validation routine causes eyetracking experiment to end
Adding a validation routine to the eyetracking feature demo causes the experiment to end with exit code 1 [pid:17616]

Replicated with Pupil Labs and MouseGaze Eyetracker Devices

Branches tested: 
- Current `dev`
- `pupil-labs-pupil-core-eye-tracker`

```
Traceback (most recent call last):
  File "C:\Users\Neil Thomas\Documents\PsychoPy3 Demos\Feature Demos\eyetracking\neil_test_lastrun.py", line 227, in <module>
    validation.run()
  File "c:\users\neil thomas\psychopy\psychopy\iohub\client\eyetracker\validation\procedure.py", line 333, in run
    terminate = not self.targetsequence.display(**self.animation_params)
  File "c:\users\neil thomas\psychopy\psychopy\iohub\client\eyetracker\validation\procedure.py", line 1091, in display
    self.moveTo(pos, prevpos, **kwargs)
  File "c:\users\neil thomas\psychopy\psychopy\iohub\client\eyetracker\validation\procedure.py", line 956, in moveTo
    fliptime = self._animateTarget(topos, frompos, **kwargs)
  File "c:\users\neil thomas\psychopy\psychopy\iohub\client\eyetracker\validation\procedure.py", line 877, in _animateTarget
    self.target.setPos(topos)
AttributeError: 'TargetStim' object has no attribute 'setPos'
```



Discussion:

Resolving patch:
diff --git a/psychopy/experiment/components/settings/__init__.py b/psychopy/experiment/components/settings/__init__.py
--- a/psychopy/experiment/components/settings/__init__.py
+++ b/psychopy/experiment/components/settings/__init__.py
@@ -1007,7 +1007,6 @@ def writeIohubCode(self, buff):
         buff.writeIndentedLines(code % inits)
         # Add eyetracker config
         if self.params['eyetracker'] != "None":
-            print(self.params['eyetracker'])
             # Alert user if window is not fullscreen
             if not self.params['Full-screen window'].val:
                 alert(code=4540)
diff --git a/psychopy/iohub/client/eyetracker/validation/procedure.py b/psychopy/iohub/client/eyetracker/validation/procedure.py
--- a/psychopy/iohub/client/eyetracker/validation/procedure.py
+++ b/psychopy/iohub/client/eyetracker/validation/procedure.py
@@ -76,6 +76,14 @@ def setPos(self, pos):
         for s in self.stim:
             s.setPos(pos)
 
+    @property
+    def pos(self):
+        return self.stim[0].pos
+
+    @pos.setter
+    def pos(self, value):
+        self.setPos(value)
+
     @property
     def radius(self):
         return self._radius
@@ -646,7 +654,7 @@ def drawResultScreen(self):
         results = self.getValidationResults()
 
         for tp in self.positions.getPositions():
-            self.targetsequence.target.setPos(tp)
+            self.targetsequence.target.pos = tp
             self.targetsequence.target.draw()
 
         title_txt = 'Validation Results\nMin: %.4f, Max: %.4f,' \
@@ -699,7 +707,7 @@ def drawResultScreen(self):
                     else:
                         g_pos = toPix(self.win, gaze_x[i], gaze_y[i])
                         g_pos = g_pos[0][0], g_pos[1][0]
-                    sample_gfx.setPos(g_pos)
+                    sample_gfx.pos = g_pos
                     sample_gfx.draw()
                 txt_bold = False
                 position_txt = "Gaze Error:\nMin: %.4f\nMax: %.4f\n" \
@@ -857,7 +865,7 @@ def _animateTarget(self, topos, frompos, **kwargs):
                     v2 = topos
                     t = 60.0 * ((1.0 / 10.0) * t ** 5 - (1.0 / 4.0) * t ** 4 + (1.0 / 6.0) * t ** 3)
                     moveTo = ((1.0 - t) * v1[0] + t * v2[0], (1.0 - t) * v1[1] + t * v2[1])
-                    self.target.setPos(moveTo)
+                    self.target.pos = moveTo
                     self._draw()
                     fliptime = self.win.flip()
                     io.sendMessageEvent('POS_UPDATE %.4f,%.4f' % (moveTo[0], moveTo[1]), self.msgcategory,
@@ -874,7 +882,7 @@ def _animateTarget(self, topos, frompos, **kwargs):
                     if self._terminate_requested:
                         return 0
 
-        self.target.setPos(topos)
+        self.target.pos = topos
         self._draw()
         fliptime = self.win.flip()
         io.sendMessageEvent('TARGET_POS %.4f,%.4f' % (topos[0], topos[1]), self.msgcategory, sec_time=fliptime)
diff --git a/psychopy/visual/target.py b/psychopy/visual/target.py
--- a/psychopy/visual/target.py
+++ b/psychopy/visual/target.py
@@ -87,6 +87,9 @@ def pos(self, value):
         self.outer.pos = value
         self.inner.pos = value
 
+    def setPos(self, value):
+        self.pos = value
+
     @property
     def size(self):
         return self.outer.size


Test patch: