On Wed, Nov 16, 2016 at 8:39 AM, Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info> wrote: > On Wednesday 16 November 2016 16:21, Veek M wrote: > >> Trying to make sense of that article. My understanding of debug was >> simple: >> 1. __debug__ is always True, unless -O or -OO >> 2. 'if' is optimized out when True and the expr is inlined. >> >> So what does he mean by: >> >> 1. 'If you rebind __debug__, it can cause symptoms' > > What he means is, "I didn't test this code before running it, and I am wrong." > > You cannot rebind __debug__. > >>>> __debug__ = False > File "<stdin>", line 1 > SyntaxError: can not assign to __debug__ > > > (That's Python 2.5 or better, and maybe even older than that.)
Andrew didn't assign directly to __debug__. He assigned to sys.modules[__name__].__debug__, which is allowed prior to 2.7. Even in later versions, as he pointed out, you can dynamically assign to '__debug__' in a namespace dict. For an expression containing __debug__, i.e. not simply an `if __debug__` test, the compiler emits a LOAD_NAME operation (or LOAD_GLOBAL in a function) to load the value on the stack and evaluate the expression. Thus the builtins value may be shadowed by a local or global value, or you can just modify builtins directly. This inconsistency could be addressed by making __debug__ a static symbol, which in CPython would always be determined by the value of the C global variable Py_OptimizeFlag. In this case a code block would reference a '__debug__' constant in its co_consts, defined at compile time. For example, this is the current inconsistent compile-time vs run-time behavior, tested in 3.5: >>> import sys >>> sys.flags.optimize 0 >>> vars(sys.modules['builtins'])['__debug__'] = False Compiling a simple `if __debug__` block depends on the value of Py_OptimizeFlag: >>> if __debug__: print('__debug__') ... __debug__ But evaluating an expression requires loading the dynamic value of __debug__: >>> if not __debug__: print('not __debug__') ... not __debug__ >>> vars(sys.modules['builtins'])['__debug__'] = True >>> if not not __debug__: print('__debug__') ... __debug__ For `if __debug__` blocks, the compiler looks at the value of the C global variable Py_OptimizeFlag: >>> import ctypes >>> Py_OptimizeFlag = ctypes.c_int.in_dll( ... ctypes.pythonapi, 'Py_OptimizeFlag') >>> if __debug__: print('__debug__') ... else: print('not __debug__') ... __debug__ >>> Py_OptimizeFlag.value = 1 >>> if __debug__: print('__debug__') ... else: print('not __debug__') ... not __debug__ Off topic: The text after the question ID in a Stack Overflow URL is optional, so I removed it from the message title. -- https://mail.python.org/mailman/listinfo/python-list