TypeError:TypeError: decoding Unicode is not supported

Hi all,

I am new to PsychoPy and creating a simple lexical decision task using Builder in PsychoPy 2 (1.84.2). This a very preliminary version of my experiment works without any problems on Mac (OSX 10.11.6) but when I tried to replicate it on a stimulus presentation computer (Windows 8) it only loads a grey screen and than gives an error: **File “C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\visual\text.py”, line 274, in text**
**
_ self.dict[‘text’] = unicode(text,“utf-8”)_**
**
TypeError: decoding Unicode is not supported_**

(see attachments)

I have also re-created the same condition files (.xlsx) on this PC, so that I don’t need to transfer any files from Mac but this did not work. I’ve tried a couple of things in the script (replace u’text object’ with unicode (“text”, ‘utf-8’) but this also did not work. I don’t really know enough about Python to have more ideas about this error, rather than that it is related to coding text objects.

Does any of you have more thoughts on this error? Any thoughts will be appreciated!

Many thanks,

Alena

Hi Alena,

Please post all of the error message: most of that huge screen shot wasn’t relevant code, and I think the bulk of the error message was hidden. Just copy and paste it into a message.

But the problem seems to be related to updating the contents of a text stimulus. Can you also show us how you are doing that?

Thanks, Michael. I’ve attached another screenshot with the full error message, but also pasting it below. I’ll using lexical decision task . Participants need to press button to indicate one of two choices - whether they see a word or non-word. This is randomised between the blocks and within the blocks. A word/non-word is preceded by a fixation cross and a blank inter-trial. When I tried to run it now, it actually runs until the fixation and then doesn’t load a word with the following message. Exactly the same program runs on another mac and a PC, but I need to use this PC for stimulus presentation in an EEG study.

 Running: C:\Users\NCIL User\Desktop\alena exp\from mac\Kid_LDT_ERP_V2_lastrun.py 
pyo version 0.8.0 (uses single precision)
Traceback (most recent call last):
  File "C:\Users\NCIL User\Desktop\alena exp\from mac\Kid_LDT_ERP_V2_lastrun.py", line 343, in <module>
    target.setText(word)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\visual\text.py", line 285, in setText
    setAttribute(self, 'text', text, log)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\tools\attributetools.py", line 137, in setAttribute
    setattr(self, attrib, value)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\tools\attributetools.py", line 27, in __set__
    newValue = self.func(obj, value)
  File "C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\visual\text.py", line 274, in text
    self.__dict__['text'] = unicode(text,"utf-8")
TypeError: decoding Unicode is not supported

We still need to know this. It would be useful to know what the source of your words is ( a .csv file. .xlsx file, etc) and perhaps post it so we can check for special characters, formatting, etc.

Also, things are a bit confusing here, as your screenshots are changing. Previously, target was the name of a routine, and now (from the code in the latest error message), it seems to be the name of a text component. Having multiple objects with the same name can definitely cause problems.

Sorry, Michael. It’s a bit confusing because in this main program which runs on two other computers “target” is always a name of the text component. (In another/newer version however of which I initially made a screenshot of, the routine was called “target” but I did not check if the same program runs on other computers). Here is the exact screenshot of this main version and as well as stimulus .xlsx files for two conditions (one with words one with non-words).

Thanks again,

Alena

conditionsB1.xlsx (8.3 KB)
conditionsB2.xlsx (8.3 KB)

Hi Alena,

Please attach a screenshot showing the settings in your target routine. Also, it is not clear how the two spreadsheets are used. Which one is connected to which loop?

Hi Michael,

Here are the screenshots for target routine: target as a text, and response key press. Two excel sheets attached previously are for the inner loop (block 1= B1, blocks 2= B2). for the outer loop, I am using .xlsx sheet: condition _file.xlsx which only containts the names of excel sheets (B1,B2) with the trial lists. I’ve done it this way, because I will have up to 6-7 blocks and the blocks need to be selected randomly for each subject (see the third screenshot and attached .xlsx file)

condition_file.xlsx (8.0 KB)

Thanks again,

Alena

The third screenshot is here :slight_smile:

Thank you!

OK, it seems like you are doing everything properly. What seems strange is the the actual code that generates the error (i.e. the source code for the PsychoPy application itself):

Looking at the PsychoPy source code, that line should read:

self.__dict__['text'] = unicode(text)

rather than:

self.dict['text'] = unicode(text,"utf-8")

Can you examine the file “C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\visual\text.py” and see what is in line 274?

Would someone have edited it for some reason? It could be changed back if needed, to see if that might fix the problem.

Hi Michael,

I’ve checked it - it is self.dict[‘text’] = unicode (text) in line 274, exactly the same line as in Python libraries on a PC, on which the same program is running.

I’m really confused now what to do, because I can’t swap these two PCs over, due to other people in the Lab who already set up their experiments on this stim PC in the EEG booth.

Also, I don’t think that anyone would have changed anything in Python libraries. And it does look like the line is the same as it should be.

As it doesn’t look promising to solve this soon, I should probably give up with Psychopy and switch to another program we have in the Lab :frowning: It’s a pity because I do like the builder.

Thank you anyway for your responses!

Alena

sorry I meant it is self._dict[‘text’] = unicode(text).
(and I tried to change it to the one with “utf-8” in it, just in case, and it did not change anything).

In fact, that’s exactly the output she got. It just appeared as self.dict['text'] here in the forum because the pasted text was not formatted properly (neither wrapped in triple-backticks nor indented by 4 spaces). I have corrected the quotes in this posting, but not in the other ones, to not destroy context of your reply.

The error message indicates that the strings you/we try to convert to unicode are in fact already unicode strings. I believe it shouldn’t be too hard to track this issue down, but I won’t have time before the weekend. I can look into it then if that would help you.

1 Like

Thanks both for replying and sorry that I completely forgot to reply to your last comment! In fact, for some reason I did not get any email notification of Richard’s reply.

The program is working now and yes, I actually needed to delete utf-8 in text (unicode,“utf-8”) which actually WAS there in the line 274. Another post-doc in the Lab has changed this line in the library, because her French task with Psychopy wasn’t working otherwise. Now, I have a dilemma, which is how to make our both tasks work, which now requires making changing in text.py file, since we both present stimuli on the same computer.

Is it possible to modify my script so that it refers to another text.py file, which say textEng.py in which I can delete “utf-8”? In other words, can we have two similar text.py files, but with only difference in line 274? If so, where do I need to put changes in my script?

I hope this makes sense.

Many thanks again and Happy New Year to all,

Alena

One of the beauties of Python is that everything is an object, so one can easily replace a function with an another function, in code at run time. One doesn’t need to edit the actual source code file (in part for precisely the reasons you are seeing here: it can break things for other people). So ideally that line 274 should be edited back to it’s original:

self.__dict__['text'] = unicode(text)

Then your postdoc colleague could insert a code component in her experiment which creates an alternative version of that function in code, and swaps it out for the original one. This is known as ‘monkey patching’: the effect is only temporary, as it lasts only for the duration of the experiment (i.e. the actual source code file in text.py isn’t being modified on disk, the change occurs in memory only).

i.e. in the Begin experiment tab of the code component, she should create her alternative version of the function:

def my_text_function(self, text):
    """The text to be rendered. Use \\\\n to make new lines.
    THIS IS AN ALTERNATIVE MONKEY PATCH VERSION TO DEAL WITH
    SOME UNICODE STUFF.

    Issues: May be slow, and pyglet has a memory leak when setting text.
    For these reasons, check and only update the text if it has changed.
    So scripts can safely set the text on every frame, no need to check.
    """
    if text == self.text:
        return
    if text != None:  # make sure we have unicode object to render
        self.__dict__['text'] = unicode(text, "utf-8") # *** THE ALTERED LINE ***
    if self.useShaders:
        self._setTextShaders(text)
    else:
        self._setTextNoShaders(text)
    self._needSetText = False

# now replace the standard version of the function with the amended version.
# This should be *something* like this:
visual.text.TextStim.text = my_text_function

Of course, you might not be able to persuade your colleague to do the right thing, so you might need to do this process yourself, using the line without “utf-8” to temporarily undo the change she has made in the source code.

Hi Michael,

Thank you for your responses. I’ve tried it and it gives the following error (see below). I’m trying to change my code because my colleague is actually on mat leave and she wouldn’t come to the Lab to figure out such things. I’ve attached the function which I pasted in the screenshot, the only difference I think it should be the following (based on functions call in the routines below)

visual.TextStim.text = my_text_function

If I’m wrong I’ve tried also to put
visual.text.TextStim.text = my_text_function

as you suggested but it gives the same error. What do you think the error might be related to?

Thanks again,

Alena

File “C:\Users\NCIL User\Desktop\alena exp\from mac\Kid_LDT_ERP_V2.py”, line 200, in
win.flip()
File “C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\visual\window.py”, line 568, in flip
thisStim.draw()
File “C:\Program Files (x86)\PsychoPy2\lib\site-packages\psychopy-1.84.2-py2.7.egg\psychopy\visual\text.py”, line 728, in draw
GL.glTranslatef(-self.width / 2, 0, 0)
AttributeError: ‘TextStim’ object has no attribute 'width’

Hi all,

Does anyone else have more thoughts on how can I write a function, to solve the unicode issue on my PC?
See the link with original posts and replies from Michael here:

Thanks

Alena

@michael , I think I know why this isn’t working, but I don’t know a solution. The issue is since .text is an “@attributeSetter”, the method can’t be overridden in the normal way. It turns out this is something I’ve been meaning to ask about, but the decorator syntax has me a bit lost, I’m really not sure what goes on with those things. If you don’t know, Michael, maybe @jon knows a quick way of overriding them?

Here’s a very simple experiment demonstrating how the .text method can’t be overridden the normal way. If you uncomment the last line of the code component, you’ll see that the text stim will just display “default text”.

conditions.xlsx (4.7 KB)
customTextFun.psyexp (5.9 KB)

Ok, after reading up a little on decorators I think I figured out a fix (but I don’t fully understand how the attributeSetter works in psychopy).

So in your Begin experiment tab of the code component, simply add this to the top of the function Michael gave you:

from psychopy.tools.attributetools import attributeSetter

@attributeSetter
def my_text_function(self, text):
    # etc. 

Your new .text method should now be successfully monkey patched.

P.S. Looking at one of your questions @Alena_Galilee , the correct line should be this:

 visual.text.TextStim.text = my_text_function
1 Like