[MERGE] Repository.iter_files_bytes()

John Arbash Meinel john at arbash-meinel.com
Thu Mar 26 22:37:20 GMT 2009


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andrew Bennetts wrote:
> John Arbash Meinel wrote:
> [...]
>> I'm pretty sure that the issue is that gettext sets the "_"
>> function/operator/variable in "__builtins__". The wanted to do that so
>> it would be available everywhere, without having to do "from gettext
>> import gettext as _" at the top of every module (bringing it into your
>> globals).
>>
>> However, as a builtin, it then has a single binding, and assigning to it
>> *modifies the builtin*.
> 
> Huh?  That's not what builtins mean.
> 
>> So try:
>>
>> # foo.py
>> import __builtins__
>> __builtins__.x = 1
>>
>> def func():
>>   x = 2
>> func()
>> print x
> 
> That prints 1 (once you fix it to s/__builtins__/__builtin__, or paste it in the
> interactive interpreter rather than a separate file, same result either way).
> 

Sorry I didn't look close enough. But this is what gettext does:

__builtin__.__dict__['_'] = unicode and self.ugettext or self.gettext

> Assignment inside a function *always* only changes a local, unless:
> 
>   * the LHS is not just plain identifier, e.g. “foo.bar” obviously doesn't
>     assign to a local; or
>   * there is “global” declaration for that variable in the function.
> 
> (Python 3 adds a “nonlocal” declaration, but that's the same sort of thing as
> “global”.)
> 
> You may be thinking of the case when a variable is used but not assigned in a
> function, *then* Python will search through the outer scopes (cells if there is
> a nested function, then module globals, then builtins) to try find it.  But
> assignment to an identifier in a function always makes that identifier a local
> (even in lines before the assignment in that function, which tends to cause
> UnboundLocalErrors), unless you've explicitly told Python otherwise with global.
> 
> So my confusion about what's wrong with using “_” still stands.
> 
> -Andrew.

Maybe it is just stuff like pdb and the python interpreter which do
weird things with "_", but if you do:

>>> import __builtin__
>>> x = 1
>>> x
1
>>> __builtin__.__dict__['_']
1

At that point, pdb and the python interpreter have overridden the value
of '_' in the __builtin__ dict. And in doing so, they have stepped on
the one that gettext() wanted to use.
And so if you didn't do:

from gettext import gettext as _

At the top of all your modules, and just used "_()" as a builtin, then
it has gotten hosed, and things start breaking everywhere.

Now I *thought* that assigning to "_" was enough to trigger this. I
can't seem to reproduce it.

So I'm *sure* that breaking into a debugger would cause bzr-gtk to
crash, because it would try to internationalize() a string, and "_" had
been overwritten. So at the very least, pdb and the general python
interpreter write to the __builtin__.__dict__['_'] variable.

I *thought* that things were breaking anyway, which is why people were
dropping into the debugger to try and fix it. But it is certainly
possible that it was something else that was broken, and then the
debugger broke their _ (or maybe they did so in some other part of the
function without realizing it).

John
=:->

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAknMA6AACgkQJdeBCYSNAAOhJwCgw98i2b7uwMt1GpMxzIc4MJqZ
ooMAniLZBTAzPIV1xUGJLxBzjnX1pOw/
=Q3N/
-----END PGP SIGNATURE-----



More information about the bazaar mailing list