"UnboundLocalError: local variable 'os' referenced before assignment"

OS: macOS Sonoma 14.0 (on an M2 chip)
PsychoPy version: 2023.2.3
Standard Standalone? (y/n) y
What are you trying to achieve?: Upgrade an experiment from 2021.1.4 to 2023.2.3

Context: Our lab computers were updated and 2021.1.4 was no longer working (tasks would not start). I think it had something to do with losing support for python 2.X, but I decided to just move forward and upgrade versions. Note: I didn’t go straight to 2023.2.3, but tried some other versions along the way.

What did you try to make it work?: Installed v2023.2.3, updated “use version” to 2023.2.3
Other details: window backend = pyglet, audio library = ptb (but experiment has no sound anyway), keyboard backend = PsychToolbox

What specifically went wrong when you tried that?:
I got an:
"UnboundLocalError: local variable 'os' referenced before assignment"
…referring to line 301 in the generated python script which uses os.chdir(_thisDir) early on in the “run” fuction.
According to posts on this forum, an UnboundLocalError is usually due to a problematic conditions file. However, an error with the os package in the run function seems to be a deeper problem. Have I totally corrupted the experiment by changing versions?

(somewhat redacted) error output:

Generating PsychoPy script...

## Running: /Path/to/experiment/soptCAT_lastrun.py ##
71.5452     INFO     Loaded monitor calibration from ['2023_03_03 10:32']
2023-10-18 21:22:06.452 … ApplePersistenceIgnoreState: Existing state will not be touched. New state will be written to /var/folders/ … org.opensciencetools.psychopy.savedState
Traceback (most recent call last):
7.4781     INFO     Loaded monitor calibration from ['2023_03_03 10:32']
7.6434     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6443     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6453     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6469     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6483     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6488     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6498     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6513     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6515     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6517     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6527     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6537     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6546     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6556     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6564     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6575     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6585     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6588     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6593     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6608     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6611     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6612     DEBUG     Uploading Texture Font fontname to graphics card
7.6641     DEBUG     Upload of Texture Font fontname complete
7.6704     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6719     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6734     DEBUG     TextBox2 loaded 1 chars with 0 blanks and 1 valid
7.6735     DEBUG     Uploading Texture Font fontname to graphics card
7.6754     DEBUG     Upload of Texture Font fontname complete
8.6851     WARNING     Couldn't measure a consistent frame rate!
  - Is your graphics card set to sync to vertical blank?
  - Are you running other processes on your computer?

8.6857     EXP     Created window1 = Window(allowGUI=True, allowStencil=False, autoLog=True, backendConf=UNKNOWN, backgroundFit=<method-wrapper '__getattribute__' of attributeSetter object at 0x7f9e1c523850>, backgroundImage=<method-wrapper '__getattribute__' of attributeSetter object at 0x7f9e1c5237f0>, bitsMode=UNKNOWN, blendMode='avg', bpc=(8, 8, 8), color=array([-1, -1, -1]), colorSpace='rgb', depthBits=8, fullscr=<method-wrapper '__getattribute__' of attributeSetter object at 0x7f9e1c523670>, gamma=None, gammaErrorPolicy='raise', lms=UNKNOWN, monitor=<psychopy.monitors.calibTools.Monitor object at 0x7f9e1c740340>, multiSample=False, name='window1', numSamples=2, pos=[367.5, 239.0], screen=0, size=array([2940, 1912]), stencilBits=0, stereo=False, title='PsychoPy', units='height', useFBO=True, useRetina=True, viewOri=0.0, viewPos=None, viewScale=None, waitBlanking=True, winType='pyglet')
8.6858     EXP     window1: mouseVisible = True
8.6859     EXP     window1: backgroundImage = ''
8.6859     EXP     window1: backgroundFit = 'none'
8.6891     EXP     window1: Attempting to measure frame rate of screen (0) ...
8.6892     EXP     window1: recordFrameIntervals = False
8.7696     EXP     window1: recordFrameIntervals = True
9.6029     WARNING     Couldn't measure a consistent frame rate!
  - Is your graphics card set to sync to vertical blank?
  - Are you running other processes on your computer?

9.6039     EXP     window1: mouseVisible = False
10.4768     INFO     keyboard.Keyboard is using ptb backend.
10.4769     EXP     soptCAT: status = STARTED
10.4896     EXP     window1: mouseVisible = True
10.4900     DEBUG     Saving data for soptCAT ExperimentHandler
10.4911     INFO     saved data to /Path/to/experiment/data/datafile.psydat
10.4913     INFO     saved data to '/Path/to/experiment/data/datafile.csv'
  File "/Path/to/experiment/soptCAT_lastrun.py", line 4390, in <module>
    run(
  File "/Path/to/experiment/soptCAT_lastrun.py", line 302, in run
    os.chdir(_thisDir)
UnboundLocalError: local variable 'os' referenced before assignment
################# Experiment ended with exit code 1 [pid:8817] #################

Seems like it could be something like this scoping issue, but I have no idea how the py code got this way.

1 Like

What happens if use version is blank?

Same error, unfortunately! :frowning:

Update: if I set useVersion back to v2022.1.0 (one of the previous versions this experiment passed through), the error does not occur and I am able to run the experiment normally. However, this version is on the list of versions to avoid… so I’d rather avoid it if possible.

Hi, I came into the same problem today. And I’m completely new with Psychopy, so you may not find my solution useful given that you may have already tried it. But for other users as new as me, we should put code component before the other stimuli component (e.g., text, image). Psychopy needs to run the code before it runs the stimuli.

I think this will depend on whether you need the results of that code component to display other components in that routine. There are other situations where a code component would need to come at the end of a routine.

My friend was having the same issue as you. We have been able to solve it. The problem is exactly the scoping issue you were referring to.

The problem is this:
In the version 2023.2.3, when you build the project, generated code already imports os in global scope. However, unlike some of the older versions (2021, 2022) all the code related to the routines are under a function run(). At the beginning of this run() function, os module is used with the function os.chdir(). Crucial part is that, this call is being made before any other routine. The problem arises when in one of your routines, you write the statement “import os”. When that happens, the scope issue arises because os is already defined globally, and you are defining it locally, but you already tried to access it before you define it locally. So the exact situation in stackoverflow post happens.

Why wasn’t it happening in older versions?
Because in those versions, when you build the project, all the code related to your routines are still under the global scope, unlike newer versions where its under the local scope of run() function.

1 Like