Repository: psychopy/psychopy

Issue:
PsychoPy 2023.1.2 still crashes with $ in text component
I downloaded and installed PsychoPy- 2023.1.2.zip on Ubuntu 22.04 in a venv.  Same issue as #4207 #5514.  For this version, no error dialog, PsychoPy just crashes and closes when an attempt is made to edit a text component to use $var.  The zip file did indeed launch the correct version of PsychoPy this time (unlike PsychoPy-2023.1.1.zip), but the $var issue remains a bug.

![image](https://user-images.githubusercontent.com/26172078/231774415-2cda9d5b-f371-4b95-a017-c9622b1e9e43.png)

![image](https://user-images.githubusercontent.com/26172078/231773337-5def94cc-7185-4c8a-9b7e-442ea1a1a1b2.png)

![image](https://user-images.githubusercontent.com/26172078/231772529-f221c5ec-9fc4-47a4-899e-b772158d8f78.png)


Possible bug - Builder crashes when typing a dollar sign into a text component
**OS:** Ubuntu 20.04
**PsychoPy version:** 2021.2.2
**Standard Standalone**

**What happens:**
When I type a dollar sign ($) at the beginning of a text component, Builder gives an error and crashes.
If I type the $ at a different position in the box, nothing happens (please, see the gif below):

![Builder_crash_with_dollar_sign](https://user-images.githubusercontent.com/23731464/128643192-cf7e7fef-080e-42d4-8391-eb728c6e0efa.gif)

**Error message:**
> Traceback (most recent call last):
File “/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py”, line 29, in validate
validate(self, self.valType)
File “/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py”, line 442, in validate
val = str(obj.GetValue())
RecursionError: maximum recursion depth exceeded while calling a Python object

It happens in a new file - I just have to start Builder and insert a text component.
The same was not happening with the previous version of Psychopy (same OS and machine).

I’m available to run diagnostics.

Cheers!
Flavio





Discussion:
A bit more info.  If an earlier version script is opened, just selecting the text component in a routine will crash PsychoPy-2023.1.2
Is the only contents of the text field in question `$var`? Or is it `$var + "something"`? From looking at the code the only thing I can think which would cause a recursion error is the code to substitute curly quotes for regular quotes, but that's only hit if the value has either of the following unicode characters in:
```
\u201c\u201d
```

Next time I'm at a Linux machine I'll try to recreate this!
Just need to type "$" in the text box for it to crash - I'm actually running PsychoPy 2-23.1.2 under Wine on Ubuntu 22.04 and that seems to work, but I noticed that PsychoPy Win version is much slower to launch, and the dialogs (e.g., participant) are also slower to launch than linux versions.
Any progress on this issue?  I did do extensive testing on various releases and found that this issue exists for **all releases** post 2022.1.2.  Release 2022.1.2 works with both python 3.8 and 3.9 with a small caveat.  In the text component, the $var needs to be entered anywhere below the first line, then moved up to the top manually using the return key.  Pasting won't work.  So, something changed after this release.
Thank you for reporting this. We'll be looking into it.
I haven't been able to replicate this on macOS, although I'm not sure what aspect would make it a platform-specific bug 🤔 
I'll make a fresh install of Ubuntu and Psychopy to check if I can still see it. I'll report it here as soon as I can.
With a fresh install (and after installing all the updates) I still get the error, but now PsychoPy does not crash (please, see the gif below).

![Psychopy_error_text](https://user-images.githubusercontent.com/23731464/129118077-69213b33-e054-4ee1-915e-2d772fbdb553.gif)

**Error message**

> Traceback (most recent call last):
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 29, in validate
    validate(self, self.valType)
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 442, in validate
    val = str(obj.GetValue())
RecursionError: maximum recursion depth exceeded while calling a Python object

PS: Sadly, in this installation I don't get my buttons on the right panel anymore...

![No_buttons](https://user-images.githubusercontent.com/23731464/129118468-9a03a4e4-79f9-406b-9744-e4ad72103c36.gif)



The way I install PsychoPy changes the behavior of the error:

- No icons, but also no crash: above installation following [this instructions](https://discourse.psychopy.org/t/unable-to-properly-install-psychopy-on-ubuntu-20-04/12760/8)
- Icons showing nicely, but PsychoPy crashes: the method I describe below

> **Install outdated psychopy from Ubuntu's repository**
> sudo apt install psychopy
> 
> **Install pip3**
> sudo apt install python3-pip
> 
> **Download the lastest wxPython-4 from**
> https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-20.04/
> 
> **Install the downloaded wxPython-4 file**
> pip3 install <path_to_wxPython4_downloaded_file>
> _In my case: pip3 install /home/flavio/Downloads/wxPython-4.1.1-cp38-cp38-linux_x86_64.whl_
> 
> **Install Psychtoolbox bindings**
> sudo apt install libusb-1.0-0-dev portaudio19-dev libasound2-dev
> 
> **Update psychopy using pip3**
> pip3 install -U psychopy
> 
> **Upgrade cryptography - only incompatibility I spotted during the installation**
> pip3 install --upgrade cryptography

This time, I started PsychoPy from the terminal so I could (hopefully) get more information on the error. 
**This is the message I got:**

> RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd pygame 1.9.6
> Hello from the pygame community. https://www.pygame.org/contribute.html
> RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
> PTB-INFO: Using modified PortAudio V19.6.0-devel, revision unknown
> 03:10:50 PM: Debug: "Shift+Tab" is not supported as a keyboard accelerator with GTK

> (psychopy:15982): Gtk-WARNING **: 15:11:26.114: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
> You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
> You can apply tags and insert marks without invalidating your iterators,
> but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
> will invalidate all outstanding iterators
> Segmentation fault (core dumped)

I hope this helps :)

Please, let me know if I can help testing anything.
@peircej I think we need a tool to check whether package versions installed to the system/current interpreter differ from those we ship with standalone. Since we require specific package versions to get things like movies/audio working, other apps within the environment can break or be broken by installing PsychoPy. At the very least we should enumerate over the packages installed to the environment PsychoPy is running on and display warnings if things differ from what's we bundle with standalone. At least that will give a clue to the user that the weird stuff going on is due to API incompatibility and they should adjust their setup accordingly (e.g., use a virtual python environment).
Getting exactly the same behaviour on Centos 7.  I do use separate virtual Python environments for each version of PsychoPy.
This issue does not happen with previous versions of PsychoPy (eg, 2021.1.4) on the same machine, so not sure if it's a simple dependency issue...

As a temporary workaround, I made the following edit to [python-package-directory]/psychopy/app/builder/dialogs/paramCtrls.py.org:
```
@@ -51,7 +51,8 @@
             valType = "str"
         if valType == "code" or hasattr(self, "dollarLbl"):
             # Set font
-            self.SetFont(self.GetTopLevelParent().app._codeFont.Bold())
+            #self.SetFont(self.GetTopLevelParent().app._codeFont.Bold())
+            self.SetFont(self.GetTopLevelParent().app._mainFont)
         else:
             self.SetFont(self.GetTopLevelParent().app._mainFont)

```
PsychoPy no longer crashes and buttons still working on right panel.
Thank you very much for reporting this, @arnon-weinberg!
The workaround you proposed also fixes the problem in my install of PsychoPy 2021.2.3 (no more errors or crashes) :1st_place_medal: 
@arnon-weinberg Thanks for tracking down the issue and fixing it. Perhaps you could submit a PR with the patch to get credit for your contribution and help others out. 😃 
I can, but it didn't seem like a fix so much as a temporary workaround.  It looks like the intended functionality was to set a different font for code than text in the UI; which this patch effectively disables.  A real fix would get that functionality working under Linux, which I am not sure how to do.
I am glad it helps others for now.
Okay I'll sort it out.
Well done everyone on the detective work. My guess is that this is a change between wxPython versions on that Bold() method. Are we certain the fix is sufficient? ie. does the IsOK trick in Matthew's fix catch the broken font? Also, I guess we could at least revert to `app._codeFont` rather than `app._mainFont` if the Bold() call doesn't work?
I've replaced my paramCtrls.py with [this version](https://github.com/mdcutone/psychopy/blob/dev-code-validation-bf/psychopy/app/builder/dialogs/paramCtrls.py) and PsychoPy v2021.2.3 crashed after giving this error:

> Traceback (most recent call last):
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 31, in validate
    validate(self, self.valType)
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 450, in validate
    val = str(obj.GetValue())
RecursionError: maximum recursion depth exceeded while calling a Python object

[This version](https://github.com/psychopy/psychopy/blob/cf71a48ef36c0ac186256782919c392626b6b428/psychopy/app/builder/dialogs/paramCtrls.py) gives the same error:

> Traceback (most recent call last):
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 31, in validate
    validate(self, self.valType)
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 450, in validate
    val = str(obj.GetValue())
RecursionError: maximum recursion depth exceeded while calling a Python object

I just mentioned them both because in the first one "Some checks were not successful" and in the second one "All checks have passed"


This might be a wxPython on Linux issue. We could just detect the platform and use the workaround for now. Longshot but try removing the `str()` around `obj.GetValue()` and see if that clears up the issue.
Removing the `str()` - living just `val = obj.GetValue()` - still gives the error and crash :(
Hi @mdcutone,

I've tried [this version of paramCtrls.py](https://github.com/psychopy/psychopy/blob/943ac736deda52e4cb38ee6a745536d6a84feb60/psychopy/app/builder/dialogs/paramCtrls.py) and it gives this error:

> Traceback (most recent call last):
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 31, in validate
    validate(self, self.valType)
  File "/home/flavio/.local/lib/python3.8/site-packages/psychopy/app/builder/dialogs/paramCtrls.py", line 449, in validate
    val = str(obj.GetValue())
RecursionError: maximum recursion depth exceeded while calling a Python object

I am here to report that this bug is still present.
Tested on the latest Arch installation and the latest Fedora.
I suggest implementing a workaround because now it is unusable on Linux which is unacceptable.
A fix by @bastosfh works but I feel dirty modyfing the source code in such a way...
Thank you for bringing this issue to github, @PanBartosz!

The mentioned workaround is [this one](https://discourse.psychopy.org/t/possible-bug-builder-crashes-when-typing-a-dollar-sign-into-a-text-component/24451/20?u=bastosfh). 

As can be seen, the lines of paramCtrls.py I commented changed (compared to the [workaround](https://github.com/psychopy/psychopy/issues/4207#issuecomment-903049304) proposed by @arnon-weinberg), but the problem is still related to the same function.

Resolving patch:
diff --git a/psychopy/app/builder/dialogs/paramCtrls.py b/psychopy/app/builder/dialogs/paramCtrls.py
--- a/psychopy/app/builder/dialogs/paramCtrls.py
+++ b/psychopy/app/builder/dialogs/paramCtrls.py
@@ -72,18 +72,20 @@ def updateCodeFont(self, valType):
             # Name is never code
             valType = "str"
 
-        fontNormal = self.GetTopLevelParent().app._mainFont
+        # get font
         if valType == "code" or hasattr(self, "dollarLbl"):
-            # Set font
-            fontCode = self.GetTopLevelParent().app._codeFont
-            fontCodeBold = fontCode.Bold()
-            if fontCodeBold.IsOk():
-                self.SetFont(fontCodeBold)
-            else:
-                # use normal font if the bold version is invalid on the system
-                self.SetFont(fontCode)
+            font = self.GetTopLevelParent().app._codeFont.Bold()
+        else:
+            font = self.GetTopLevelParent().app._mainFont
+
+        # set font
+        if sys.platform == "linux":
+            # have to go via SetStyle on Linux
+            style = wx.TextAttr(self.GetForegroundColour(), font=font)
+            self.SetStyle(0, len(self.GetValue()), style)
         else:
-            self.SetFont(fontNormal)
+            # otherwise SetFont is fine
+            self.SetFont(font)
 
 
 class _FileMixin(_FrameMixin):


Test patch: