[Pyrex] Shadowing of C globals
Sam Rushing
sam-pyrex at rushing.nightmare.com
Thu Jan 26 21:13:42 CET 2006
Several times I've been bitten by this problem:
----------
cdef int counter
def fun1():
counter = counter + 1
def fun2():
global counter
counter = counter + 1
----------
fun1() will fail with "you can't add 1 to None", whereas in Python it
you would get UnboundLocalError...
fun2() tells Pyrex that it's a global value, and does the expected
thing.
The usual pattern for this is to write a function that reads a global
variable, and then at some much later time change it to also update that
variable. Surprise!
Now, reasonable people could argue for hours about what is the 'right'
thing to do here. The current behavior is correct, because it's what
Python does (or close, anyway). And I would never be surprised by it in
Python code. However, once I've defined a global C variable my brain
somehow expects it to behave more like a C variable than a Python one.
I've found the following warning to be helpful - it actually found
*another* instance of this bug in my project the first time I used it.
--- d1/Pyrex/Compiler/ExprNodes.py Mon Jun 13 17:39:17 2005
+++ d2/Pyrex/Compiler/ExprNodes.py Wed Jan 25 17:43:37 2006
@@ -659,6 +659,12 @@
def analyse_target_declaration(self, env):
self.entry = env.lookup_here(self.name)
+ maybe_shadowed = env.lookup (self.name)
+ if maybe_shadowed is not None:
+ if maybe_shadowed != self.entry and maybe_shadowed.is_cglobal:
+ print "Warning: local '%s' shadows C global: %s:%d:%d" % (
+ self.name, self.pos[0], self.pos[1], self.pos[2]
+ )
if not self.entry:
self.entry = env.declare_var(self.name,
PyrexTypes.py_object_type, self.pos)
-Sam
More information about the Pyrex
mailing list