fab-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fab-user] A lesson in python scope resolution


From: Wes Winham
Subject: [Fab-user] A lesson in python scope resolution
Date: Wed, 24 Jun 2009 13:27:28 -0400

I have what I would consider a very complex fab setup for:
 * Build amazon EC2 ami's
 * Launching and configuring new ec2 instances
 * Deploying new versions of our application to a new instance
 * Updating an instance with a newer version of the application

It's pretty sweet what fabric enables me to do by running:
fab test new deploy
- or -
fab customer1 update deploy

I say that in attempt to save some face in that I'm not *always* useless.

I spent part of the last 2 days debugging what was supposed to be a
simple bug in my deploy task. I had made a ton of changes converting
from fab 0.1 to fab 0.9 and was working through everything.

I would run fab test new deploy and get an error in the first
reference to 'env' in deploy with the line:
sudo('add2virtualenv /some/path/%(variable)s' % env)

and exception:
UnboundLocalError: local variable 'env' referenced before assignment

This was boggling to me because before that command I had lines like
run('echo "foobar"') that were doing just fine.

Long story shortish, here's the 5-line reproduction:

from fabric.api import env

def failure():
    print env
    env = 'blah'

The error was being caused by a line of code within a nested if
statement (that wouldn't have been executed) 100 lines away. I
committed an obvious error by re-assigning env (I just converted from
0.1 where env wasn't meaningful) and instead of failing on that line
when it was evaluated, I get an error about an UnboundLocal way up
top. I eventually found it by slowing stripping away every other line
of code until I couldn't reproduce the error.

So the lesson is, if you ever potentially re-assign a module-level
variable anywhere in the current function, the python interpreter
doesn't let you use the module-level variant ANYWHERE in that function
(even before it's re-assigned).

Hopefully this helps someone else avoid my own little personal hell of
resorting to randomly removing lines of code with no rhyme or reason
to find a bug caused by code that didn't execute :)

-Wes




reply via email to

[Prev in Thread] Current Thread [Next in Thread]