internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: psychopy/psychopy

Issue:
Providing a hex value for the Window's color parameter results in `ValueError: invalid value 'rgb' for Window.colorSpace`
Platforms: all
Versions: 1.85.6, 1.90

If you try to open a window and specify a background color in hex, a ValueError is thrown.
~~~python
import psychopy.visual
win = psychopy.visual.Window(color="#FF0000")

ValueError: invalid value 'rgb' for Window.colorSpace
~~~

It works correctly if you do:
~~~python
win = psychopy.visual.Window(color="red")
~~~
so it seems that this problem only occurs with hex values?



Discussion:

Resolving patch:
diff --git a/psychopy/visual/helpers.py b/psychopy/visual/helpers.py
--- a/psychopy/visual/helpers.py
+++ b/psychopy/visual/helpers.py
@@ -211,7 +211,7 @@ def setColor(obj, color, colorSpace=None, operation='',
             return
         elif color[0] == '#' or color[0:2] == '0x':
             # e.g. obj.rgb=[0,0,0]
-            setattr(obj, rgbAttrib, np.array(colors.hex2rgb255(color)))
+            setattr(obj, rgbAttrib, np.array(colors.hex2rgb255(color))- [1,1,1])
             obj.__dict__[colorSpaceAttrib] = 'hex'  # eg obj.colorSpace='hex'
             obj.__dict__[colorAttrib] = color  # eg Qr='#000000'
             setTexIfNoShaders(obj)
diff --git a/psychopy/visual/window.py b/psychopy/visual/window.py
--- a/psychopy/visual/window.py
+++ b/psychopy/visual/window.py
@@ -1209,7 +1209,7 @@ def setColor(self, color, colorSpace=None, operation='', log=None):
                  colorAttrib='color')
 
         # These spaces are 0-centred
-        if self.colorSpace in ['rgb', 'dkl', 'lms', 'hsv']:
+        if self.colorSpace in ['rgb', 'dkl', 'lms', 'hsv', 'hex']:
             # RGB in range 0:1 and scaled for contrast
             desiredRGB = (self.rgb + 1) / 2.0
         # rgb255 and named are not...


Test patch:
Repository: psychopy/psychopy

Issue:
Psychopy.info partially broken?
When I call ```runInfo = psychopy.info.RunTimeInfo() ```
and then ```print(runInfo)```, I get a bug internal to Psychopy, [here is a minimal program](https://github.com/alexholcombe/Humby3streams/blob/master/tests/lowerPsychopyBug.py) that reproduces the error for me , which is

```
Traceback (most recent call last):
  File "/Users/alexh 1/Documents/attention_tempresltn/temp res of attn, binding/Mednick_Martini_collabs/pythonProgrammingABtask/Humby3streams/tests/lowerPsychopyBug.py", line 19, in <module>
    print(runInfo)
  File "/Applications/PsychoPy2_1.90.1.app/Contents/Resources/lib/python2.7/psychopy/info.py", line 618, in __str__
    infoLines = self.__repr__()
  File "/Applications/PsychoPy2_1.90.1.app/Contents/Resources/lib/python2.7/psychopy/info.py", line 583, in __repr__
    sectKeys.sort(key=str.lower, reverse=bool(sect in revSet))
TypeError: descriptor 'lower' requires a 'unicode' object but received a 'str'
```


Discussion:

Resolving patch:
diff --git a/psychopy/info.py b/psychopy/info.py
--- a/psychopy/info.py
+++ b/psychopy/info.py
@@ -580,7 +580,7 @@ def __repr__(self):
             # get keys for items matching this section label;
             #  use reverse-alpha order if easier to read:
             revSet = ('PsychoPy', 'Window', 'Python', 'OpenGL')
-            sectKeys.sort(key=str.lower, reverse=bool(sect in revSet))
+            sectKeys.sort(reverse=bool(sect in revSet))
             for k in sectKeys:
                 selfk = self[k]  # alter a copy for display purposes
                 try:


Test patch:
Repository: psychopy/psychopy

Issue:
Error raised closing Monitor Center
The following SystemError is raised when closing Monitor Center in version 1.90.1 PY3:
```
wx._core.wxAssertionError: C++ assertion "m_count > 0" failed at ..\..\src\common\object.cpp(352) in wxRefCounter::DecRef(): invalid ref data count

The above exception was the direct cause of the following exception:

SystemError: <class 'wx._core.IdleEvent'> returned a result with an error set
```


Discussion:

Resolving patch:
diff --git a/psychopy/monitors/MonitorCenter.py b/psychopy/monitors/MonitorCenter.py
--- a/psychopy/monitors/MonitorCenter.py
+++ b/psychopy/monitors/MonitorCenter.py
@@ -90,6 +90,7 @@ def __init__(self, parent, id=-1, rows=(), cols=(), data=None):
         for nRow in range(self.nRows):
             for nCol in range(self.nCols):
                 self.SetCellEditor(nRow, nCol, self.numEditor)
+                self.numEditor.IncRef()
         self.setData(data)
         # self.SetMargins(-5,-5)
         self.Bind(wx.EVT_IDLE, self.OnIdle)


Test patch:
Repository: psychopy/psychopy

Issue:
IDE Mirrored for Right-to-Left Locales
Reproduction:
Search in windows for "locale" and click "date, time, and number format" (May be different if not on Windows 7).
Change the format to any RTL language (ex. Hebrew).
Open Psychopy IDE
Text and buttons are on the wrong side of the window. Input is backward as well.
![capture](https://user-images.githubusercontent.com/1297252/39575845-b2f3756c-4ee4-11e8-98d2-91621b721104.PNG)



Discussion:
I guess when we set the locale of the wx app (which we do so that dialogs can change their language) we should watch out for the RTL languages and force the locale back to eng_us in these cases?

Resolving patch:
diff --git a/psychopy/localization/__init__.py b/psychopy/localization/__init__.py
--- a/psychopy/localization/__init__.py
+++ b/psychopy/localization/__init__.py
@@ -35,6 +35,9 @@ def setLocaleWX():
         wxlocale = wx.Locale(languageID)
     else:
         wxlocale = wx.Locale(wx.LANGUAGE_DEFAULT)
+    # Check language layout, and reset to default if RTL
+    if wxlocale.GetCanonicalName()[:2] in ['ar', 'dv', 'fa', 'ha', 'he', 'ps', 'ur', 'yi']:
+        wxlocale = wx.Locale(wx.LANGUAGE_DEFAULT)
     # wx.Locale on Py2.7/wx3.0 seems to delete the preferred encoding (utf-8)
     # Check if that happened and reinstate if needed.
     if locale_pkg.getpreferredencoding(do_setlocale=False) == '':


Test patch:
Repository: psychopy/psychopy

Issue:
ColorPicker returns RGBA rather than RGB as expected 
The `ColorPicker` class (available from both the Builder and Coder interfaces) returns a list of 4 values (R, G, B, A) whereas generally an RGB triplet is expected. Hence, right-clicking in a colour field in Builder returns a value that will cause an error when trying to run the experiment (`ValueError: Invalid parameter. Should be length 3 but got length 4.`)

https://github.com/psychopy/psychopy/blob/e6d804a487d02daefd2d5c84ca317b531c9a052a/psychopy/app/_psychopyApp.py#L582


Discussion:

Resolving patch:
diff --git a/psychopy/app/_psychopyApp.py b/psychopy/app/_psychopyApp.py
--- a/psychopy/app/_psychopyApp.py
+++ b/psychopy/app/_psychopyApp.py
@@ -588,7 +588,7 @@ def __init__(self, parent):
                 dlg.GetColourData().SetChooseFull(True)
                 if dlg.ShowModal() == wx.ID_OK:
                     data = dlg.GetColourData()
-                    rgb = data.GetColour().Get()
+                    rgb = data.GetColour().Get(includeAlpha=False)
                     rgb = map(lambda x: "%.3f" %
                               ((x - 127.5) / 127.5), list(rgb))
                     rgb = '[' + ','.join(rgb) + ']'


Test patch:
Repository: psychopy/psychopy

Issue:
PIL.Image fail in combineImageEmblem
When launching 3.0.0.b in Windows

```
Traceback (most recent call last):
  File "C:\a\Python\Scripts\psychopyApp.py", line 96, in <module>
    start_app()
  File "C:\a\Python\Scripts\psychopyApp.py", line 28, in start_app
    app = PsychoPyApp(0, showSplash=showSplash)
  File "C:\a\Python\lib\site-packages\psychopy\app\_psychopyApp.py", line 181, in __init__
    self.onInit(testMode=testMode, **kwargs)
  File "C:\a\Python\lib\site-packages\psychopy\app\_psychopyApp.py", line 307, in onInit
    self.showCoder(fileList=scripts)
  File "C:\a\Python\lib\site-packages\psychopy\app\_psychopyApp.py", line 499, in showCoder
    files=fileList, app=self)
  File "C:\a\Python\lib\site-packages\psychopy\app\coder\coder.py", line 1426, in __init__
    self.makeToolbar()  # must be before the paneManager for some reason
  File "C:\a\Python\lib\site-packages\psychopy\app\coder\coder.py", line 2000, in makeToolbar
    pavButtons.addPavloviaTools(buttons=['pavloviaSync', 'pavloviaSearch', 'pavloviaUser', ])
  File "C:\a\Python\lib\site-packages\psychopy\app\pavlovia_ui\toolbar.py", line 33, in addPavloviaT
ools
    emblem=join(rc, emblem), pos='bottom_right'))
  File "C:\a\Python\lib\site-packages\psychopy\app\icons.py", line 69, in combineImageEmblem
    main.paste(emblem, [x, y], mask=emblem)
  File "C:\a\Python\lib\site-packages\PIL\Image.py", line 1339, in paste
    box = box + (box[0]+size[0], box[1]+size[1])
TypeError: can only concatenate list (not "tuple") to list
```


Is fixed by change of brackets at psychopy\app\icons.py:69 :
`
main.paste(emblem, [x, y], mask=emblem)`

to 
`
main.paste(emblem, (x, y), mask=emblem)`




Discussion:

Resolving patch:
diff --git a/psychopy/app/icons.py b/psychopy/app/icons.py
--- a/psychopy/app/icons.py
+++ b/psychopy/app/icons.py
@@ -66,7 +66,7 @@ def combineImageEmblem(main, emblem, pos='top_left'):
     elif 'center' in pos:
         x = int(main.size[0]/2-emblem.size[1]/2)
 
-    main.paste(emblem, [x, y], mask=emblem)
+    main.paste(emblem, (x, y), mask=emblem)
     return pilToBitmap(main)
 
 _allIcons = None
@@ -112,7 +112,7 @@ def getIcons(filename=None):
     icons['48'] = pilToBitmap(im)
     # add the plus sign
     add = Image.open(join(resourcesPath, 'add.png'))
-    im.paste(add, [0, 0, add.size[0], add.size[1]], mask=add)
+    im.paste(add, (0, 0, add.size[0], add.size[1]), mask=add)
     # im.paste(add, [im.size[0]-add.size[0], im.size[1]-add.size[1],
     #               im.size[0], im.size[1]], mask=add)
     icons['48add'] = pilToBitmap(im)


Test patch:
Repository: psychopy/psychopy

Issue:
Demos -> Hardware -> testSoundLatency.py not working in v3.0.6
Running Demo -> Hardware -> testSoundLatency.py results in the following error message:
```
##### Running: C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\demos\coder\hardware\testSoundLatency.py #####
pygame 1.9.4
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "C:\Program Files (x86)\PsychoPy3\lib\site-packages\psychopy\demos\coder\hardware\testSoundLatency.py", line 16, in <module>
    from labjack import u3
ModuleNotFoundError: No module named 'labjack'
```
Windows 7, 64 bit, PsychoPy 3.0.6 64 bit standalone


Discussion:
Thanks @peteruhrig , try replacing the import statement with:

```
try:
    from labjack import u3
except ImportError:
    import u3
```
The demos import statements needs updating

Resolving patch:
diff --git a/psychopy/demos/coder/hardware/labjack_u3.py b/psychopy/demos/coder/hardware/labjack_u3.py
--- a/psychopy/demos/coder/hardware/labjack_u3.py
+++ b/psychopy/demos/coder/hardware/labjack_u3.py
@@ -15,7 +15,10 @@
 
 from builtins import range
 from psychopy import visual, core, event, sound
-from labjack import u3
+try:
+    from labjack import u3
+except ImportError:
+    import u3
 
 # sound.setAudioAPI('pyaudio')
 


Test patch:
Repository: psychopy/psychopy

Issue:
iohub.client.keyboard.waitForKeys fails for maxWait=0
The documentation for `iohub.client.keyboard.waitForKeys` states that if `maxWait` is 0, the function should act like `getKeys()`.

 >  :param maxWait: Maximum seconds method waits for >=1 matching event.
 >                  If 0.0, method functions the same as getKeys().
 >                  If None, the methods blocks indefinitely.

In practice, if `maxWait` is 0, `getKeys()` never is called and the function returns an empty list.

The only two checks where `getKeys` can get called are
https://github.com/psychopy/psychopy/blob/4ffc99ec7f2724bf85034cd53f0a69698446c070/psychopy/iohub/client/keyboard.py#L430-L437
and
https://github.com/psychopy/psychopy/blob/4ffc99ec7f2724bf85034cd53f0a69698446c070/psychopy/iohub/client/keyboard.py#L439-L443

I'm thinking the documentation makes more sense here than the current implementation, specifically in the case where `maxWait` is based on a timer that can drop below 0.

Happy to submit a pull request if the documented behavior is intended.


Discussion:

Resolving patch:
diff --git a/psychopy/iohub/client/keyboard.py b/psychopy/iohub/client/keyboard.py
--- a/psychopy/iohub/client/keyboard.py
+++ b/psychopy/iohub/client/keyboard.py
@@ -394,7 +394,7 @@ def waitForKeys(self, maxWait=None, keys=None, chars=None, mods=None,
         Returned events are sorted by time.
 
         :param maxWait: Maximum seconds method waits for >=1 matching event.
-                        If 0.0, method functions the same as getKeys().
+                        If <=0.0, method functions the same as getKeys().
                         If None, the methods blocks indefinitely.
         :param keys: Include events where .key in keys.
         :param chars: Include events where .char in chars.
@@ -427,6 +427,11 @@ def pumpKeys():
             win32MessagePump()
             return key
 
+        # Don't wait if maxWait is <= 0
+        if maxWait <= 0:
+            key = pumpKeys()
+            return key
+
         while getTime() < (timeout - checkInterval * 2):
             # Pump events on pyglet windows if they exist
             ltime = getTime()


Test patch:
Repository: psychopy/psychopy

Issue:
Adding variable to builder causes `AttributeError: 'str' object has no attribute 'tStart'`
To replicate, make a blank Builder experiment, add a variable, try to run it. In my example, it's called `var1`. Run it, and you'll get a crash with `AttributeError: 'str' object has no attribute 'tStart'`.

In the generated python code, I get:

```
# Line 78:
var1 = ''

# ...
# Line 92
trialComponents = [var1]
for thisComponent in trialComponents:
    thisComponent.tStart = None
```

which is indeed not going to work because `var1` is just a string. I both feel like I must be doing something wrong because otherwise this would be broken for a ton of people, but that if so, I have no idea what I'm doing wrong,

Tested in 3.1.2 Standalone on macOS.


Discussion:
Hi @njvack , thanks. You are are using the Variable correctly. This issue has arisen following new changes that the track start and stop times of PsychoPy components. The code is failing because types of data commonly used in a Variable component, such as strings and ints, do not allow attributes to be added to them. I am posting a fix now which should skip this step causing the error for any Variable components in the task.

Resolving patch:
diff --git a/psychopy/experiment/routine.py b/psychopy/experiment/routine.py
--- a/psychopy/experiment/routine.py
+++ b/psychopy/experiment/routine.py
@@ -134,8 +134,9 @@ def writeMainCode(self, buff):
 
         code = '# keep track of which components have finished\n'
         buff.writeIndentedLines(code)
+        # Get list of components, but leave out Variable components, which may not support attributes
         compStr = ', '.join([c.params['name'].val for c in self
-                             if 'startType' in c.params])
+                             if 'startType' in c.params and c.type != 'Variable'])
         buff.writeIndented('%sComponents = [%s]\n' % (self.name, compStr))
         code = ("for thisComponent in %sComponents:\n"
                 "    thisComponent.tStart = None\n"


Test patch:
Repository: psychopy/psychopy

Issue:
[bug] visual.Rect component does not recalculate vertices after change of size, width and height properties
Which results in inability to update width and height of Rect during main loop. I have noticed that Rect class was updated (commit from 14 october), but this update made it unusable. Fix is simple, update vertices after setting size and set self._needVertexUpdate to True to enable redrawing updated shape.
 


Discussion:
This bug was introduced in 3.2.4 update, 3.2.3 works fine.
> Fix is simple, update vertices after setting size and set self._needVertexUpdate to True to enable redrawing updated shape.

Do you fancy making a PR with a fix?

Resolving patch:
diff --git a/psychopy/visual/rect.py b/psychopy/visual/rect.py
--- a/psychopy/visual/rect.py
+++ b/psychopy/visual/rect.py
@@ -120,6 +120,8 @@ def size(self, value):
         self.__dict__['width'] = width
         self.__dict__['height'] = height
 
+        self._needVertexUpdate = True
+
     def setSize(self, size, operation='', log=None):
         """Usually you can use 'stim.attribute = value' syntax instead,
         but use this method if you need to suppress the log message


Test patch:
Repository: psychopy/psychopy

Issue:
Math formulas not rendering in documentation
Math formulas are not rendered in documentation on website, for example on https://www.psychopy.org/general/gamma.html. See image:

<img width="362" alt="gamma" src="https://user-images.githubusercontent.com/489253/78308812-53859500-74fe-11ea-8efc-a832d60a3d16.png">

Math content is not rendered because the MathJax.js is not being loaded from http://mathjax.connectmv.com. It is blocked by Chrome, Firefox and Safari browsers with error message "Mixed Content: The page at 'https://www.psychopy.org/general/gamma.html' was loaded over HTTPS, but requested an insecure script 'http://mathjax.connectmv.com/MathJax.js'. This request has been blocked; the content must be served over HTTPS." in the browser developer console.


Discussion:

Resolving patch:
diff --git a/docs/source/conf.py b/docs/source/conf.py
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -208,5 +208,5 @@
 # If false, no module index is generated.
 #latex_use_modindex = True
 
-# path to mathjax on a public server (or could put on our own in static path?)
-mathjax_path = 'http://mathjax.connectmv.com/MathJax.js'
+# path to mathjax. Use default to load from cdnjs content delivery network.
+#mathjax_path = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.0.0/es5/latest?tex-mml-chtml.js'


Test patch:
Repository: psychopy/psychopy

Issue:
App error dialog Ctrl-C copies entire text even if something is selected
At times I just want to copy a single word (so I can search the code for that) but Ctrl-C in this dialog always copies all the text of the dialog. Should detect if text is selected and just copy that. Copy entire box if nothing selected


Discussion:
That's working as intended, it's suppose to copy the entire text to clipboard oppose to saving it so you can paste it into error reports. I could set it up where if there is a selection, it will only copy that.
 

Resolving patch:
diff --git a/psychopy/app/errorDlg.py b/psychopy/app/errorDlg.py
--- a/psychopy/app/errorDlg.py
+++ b/psychopy/app/errorDlg.py
@@ -133,12 +133,19 @@ def onExit(self, event):
     def onCopyDetails(self, event):
         """Copy the contents of the details text box to the clipboard. This is
         to allow the user to paste the traceback into an email, forum post,
-        issue ticket, etc. to report the error to the developers.
+        issue ticket, etc. to report the error to the developers. If there is a
+        selection range, only that text will be copied.
 
         """
+        # check if we have a selection
+        start, end = self.txtErrorOutput.GetSelection()
+        if start != end:
+            txt = self.txtErrorOutput.GetStringSelection()
+        else:
+            txt = self.txtErrorOutput.GetValue()
+
         if wx.TheClipboard.Open():
-            wx.TheClipboard.SetData(
-                wx.TextDataObject(self.txtErrorOutput.GetValue()))
+            wx.TheClipboard.SetData(wx.TextDataObject(txt))
             wx.TheClipboard.Close()
 
         event.Skip()
diff --git a/psychopy/app/preferencesDlg.py b/psychopy/app/preferencesDlg.py
--- a/psychopy/app/preferencesDlg.py
+++ b/psychopy/app/preferencesDlg.py
@@ -211,6 +211,12 @@ def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
     def __del__(self):
         pass
 
+    def setSelection(self, page):
+        """Select the page."""
+        # set the page
+        self.lstPrefPages.Focus(1)
+        self.lstPrefPages.Select(page)
+
     def addPage(self, label, name, sections=(), bitmap=None):
         """Add a page to the property grid manager."""
 
@@ -367,6 +373,7 @@ def populateGrid(self):
                         pass
 
         self.proPrefs.SetSplitterLeft()
+        self.setSelection(0)
 
     def setPrefVal(self, section, name, value):
         """Set the value of a preference."""


Test patch:
Repository: psychopy/psychopy

Issue:
Error when canceling "Export HTML..." in Builder
Minor bug bug causes a crash. When the file save dialog comes up, clicking "Cancel" results in the following error:

```
Traceback (most recent call last):
  File "C:\Users\matth\PycharmProjects\psychopy\psychopy\app\builder\builder.py", line 707, in fileExport
    exp=self.exp)
  File "C:\Users\matth\PycharmProjects\psychopy\psychopy\app\builder\builder.py", line 2485, in __init__
    if len(filePath) > 70:
TypeError: object of type 'bool' has no len()

```


Discussion:

Resolving patch:
diff --git a/psychopy/app/builder/builder.py b/psychopy/app/builder/builder.py
--- a/psychopy/app/builder/builder.py
+++ b/psychopy/app/builder/builder.py
@@ -698,7 +698,8 @@ def fileExport(self, event=None, htmlPath=None):
         expPath, expName = os.path.split(self.filename)
         if htmlPath is None:
             htmlPath = self._getHtmlPath(self.filename)
-
+        if not htmlPath:
+            return
         dlg = ExportFileDialog(self, wx.ID_ANY,
                                title=_translate("Export HTML file"),
                                filePath=htmlPath,
@@ -1214,7 +1215,11 @@ def _getExportPref(self, pref):
 
     def onPavloviaSync(self, evt=None):
         if self._getExportPref('on sync'):
-            self.fileExport(htmlPath=self._getHtmlPath(self.filename))
+            htmlPath = self._getHtmlPath(self.filename)
+            if htmlPath:
+                self.fileExport(htmlPath=htmlPath)
+            else:
+                return
 
         self.enablePavloviaButton(['pavloviaSync', 'pavloviaRun'], False)
         try:


Test patch:
Repository: psychopy/psychopy

Issue:
In Coder, if the Find dialog is closed, Ctrl-F no longer does anything



Discussion:

Resolving patch:
diff --git a/psychopy/app/coder/coder.py b/psychopy/app/coder/coder.py
--- a/psychopy/app/coder/coder.py
+++ b/psychopy/app/coder/coder.py
@@ -1953,6 +1953,7 @@ def OnFindOpen(self, event):
         win = wx.Window.FindFocus()
         self.findDlg = wx.FindReplaceDialog(win, self.findData, "Find",
                                             wx.FR_NOWHOLEWORD)
+        self.findDlg.Bind(wx.EVT_FIND_CLOSE, self.OnFindClose)
         self.findDlg.Show()
 
     def OnFindNext(self, event):
@@ -1964,9 +1965,8 @@ def OnFindNext(self, event):
         # if self.findDlg is not None:
         #     self.OnFindClose(None)
 
-    # def OnFindClose(self, event):
-    #     self.findDlg.Destroy()
-    #     self.findDlg = None
+    def OnFindClose(self, event):
+        self.findDlg = None
 
     def OnFileHistory(self, evt=None):
         # get the file based on the menu ID


Test patch:
Repository: psychopy/psychopy

Issue:
"Tools" > "csv from psydat" in Coder opens the unit tester.
I think the ID or callback function that menu item points to is incorrect. 


Discussion:

Resolving patch:
diff --git a/psychopy/app/coder/coder.py b/psychopy/app/coder/coder.py
--- a/psychopy/app/coder/coder.py
+++ b/psychopy/app/coder/coder.py
@@ -1638,7 +1638,7 @@ def makeMenus(self):
             item = menu.Append(wx.ID_ANY,
                                _translate("Unit &testing...\tCtrl-T"),
                                _translate("Show dialog to run unit tests"))
-        self.Bind(wx.EVT_MENU, self.onUnitTests, id=item.GetId())
+            self.Bind(wx.EVT_MENU, self.onUnitTests, id=item.GetId())
 
         # ---_demos---#000000#FFFFFF------------------------------------------
         self.demosMenu = wx.Menu()


Test patch: