Unexpected python exception

2009-11-11 Thread Richard Purdie
I've been having problems with an unexpected exception from python which
I can summarise with the following testcase:

def A():
import __builtin__
import os

__builtin__.os = os

def B():
os.stat("/")
import os

A()
B()

which results in:

Traceback (most recent call last):
  File "./test.py", line 12, in 
B()
  File "./test.py", line 8, in B
os.stat("/")
UnboundLocalError: local variable 'os' referenced before assignment

If I remove the "import os" from B(), it works as expected.

>From what I've seen, its very unusual to have something operate
"backwards" in scope in python. Can anyone explain why this happens?

Cheers,

Richard

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Unexpected python exception

2009-11-11 Thread Richard Purdie
On Wed, 2009-11-11 at 12:21 +0100, Diez B. Roggisch wrote:
> As the import-statement in a function/method-scope doesn't leak the 
> imported names into the module scope, python treats them as locals. 
> Which makes your code equivalent to
> 
> 
> x = 1000
> 
> def foo():
>  print x
>  x = 10

Aha, thanks. This makes it clear whats happening.

> Throws the same error. The remedy is to inform python that a specific 
> name belongs to global scope, using the "global"-statement.
> 
> def foo():
>  global x
>  print x
>  x = 10
> 
> 
> Beware though that then of course *assigning* to x is on global level. 
> This shouldn't be of any difference in your case though, because of the 
> import-only-once-mechanics of python.

Is there a way to make the "global x" apply to all functions without
adding it to each one? 

I suspect this equates to intentionally "leaking the imported names into
the module scope"? :)

What I'm trying to do is to avoid having "import X" statements
everywhere by changing __builtin__. It seems my approach doesn't have
quite the same effect as a true import though.

Cheers,

Richard

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Unexpected python exception

2009-11-11 Thread Richard Purdie
On Wed, 2009-11-11 at 05:04 -0800, Chris Rebert wrote:
> On Wed, Nov 11, 2009 at 4:37 AM, Richard Purdie  wrote:
> 
> > Is there a way to make the "global x" apply to all functions without
> > adding it to each one?
> 
> Thankfully, no.

Hmm :(.

> > What I'm trying to do is to avoid having "import X" statements
> > everywhere by changing __builtin__. It seems my approach doesn't have
> > quite the same effect as a true import though.
> 
> And you can't just put all your imports together at the top of the
> file because...?

The application in question is bitbake, the parsing tool for the
OpenEmbedded and Poky projects.

We're talking about python code fragments spread across about 8,000
files which make up the "metadata" some of which is public and some of
which is not. Rightly or wrongly bitbake does some interesting things
with its execution contexts for these code fragments.

Lets just say its not a traditional use case, we know the way bitbake
does some things is evil but it does other things rather well and we
can't break those.

Cheers,

Richard



-- 
http://mail.python.org/mailman/listinfo/python-list