The following code works in Python 2.7, but raises this exception in Python 3.4:
File "/home/sean/dev/ving/meridian/venv/src/django-testmigrate/django_testmigrate/base.py", line 70, in __getattr__
if e:
UnboundLocalError: local variable 'e' referenced before assignment
e
is assigned at the top of the same function though. I assume there's some new scoping rules in Python 3, but I can't find any reference to them.
Here's the code:
def __getattr__(self, name):
e = None
if not self._store:
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
for state, scope in reversed(list(self._store.items())):
try:
val = getattr(scope, name)
except AttributeError as e:
continue
else:
e = None
# get fresh instance
if state != self._current_state and isinstance(val, models.Model):
model_meta = val.__class__._meta
model_class = self._current_state.get_model(model_meta.app_label, model_meta.model_name)
val = model_class.objects.get(pk=val.pk)
# add this value to the current scope
setattr(self, name, val)
break
if e: # error raised here
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
return val
Update:
I got it to work by modifying my code as follows:
except AttributeError as ex:
# needed for Python 3 compatibility
e = ex
continue
Somehow except...as
was actually removing the variable e
from the local scope. Seems like it might be a bug in Python to me.