Re:Python bug: Can assign [] = (), but not () = []
by ronbeltran on Wednesday May 27, 2015 @02:50AM
(#9609718)
I can also do this, which is harmful.
[ Parent
| on HN ]
Re:Python bug: Can assign [] = (), but not () = []
by teddyh on Wednesday May 27, 2015 @03:04AM
(#9609782)
Only in Python 2, since that is a backward-compatibility feature. (“False” and “True” used to be variables containing 0 and 1 before Python had true booleans, many ages ago.) Python 3 makes “True” and “False” be constant values, like “1” or “2”, like they should be.
Re:Python bug: Can assign [] = (), but not () = []
by Jach on Wednesday May 27, 2015 @04:36AM
(#9610070)
Only constant for certain values of "constant". ;)
(https://gist.github.com/Jach/1208215 works in Python 3 too.)
Re:Python bug: Can assign [] = (), but not () = []
by teddyh on Wednesday May 27, 2015 @04:46AM
(#9610092)
After “import ctypes”, all bets are off.
Re:Python bug: Can assign [] = (), but not () = []
by IsTom on Wednesday May 27, 2015 @06:20AM
(#9610385)
There are ways to mark memory pages as read-only. It's not even difficult.
Re:Python bug: Can assign [] = (), but not () = []
by rjaco31 on Wednesday May 27, 2015 @08:03AM
(#9610725)
Why would you do that? That code is working perfectly as intended, the user is allowed to do that
Re:Python bug: Can assign [] = (), but not () = []
by netheril96 on Wednesday May 27, 2015 @06:36AM
(#9610432)
Are there any codes dependent on True and False being assignable? Don't those codes deserve to die?
Re:Python bug: Can assign [] = (), but not () = []
by dalke on Wednesday May 27, 2015 @03:46PM
(#9613842)
Yes. There are codes written with backwards compatibility to versions of Python pre-2.3, which did not have True/False. They typically looked like this:
try:
True
except NameError:
True = 1==1
False = not True
Such code would likely be at least 10 years old. Given the transition to Python 3, it seems the general answer is "yes, they deserve to die."
Re:Python bug: Can assign [] = (), but not () = []
by TheLoneWolfling on Wednesday May 27, 2015 @04:30PM
(#9614108)
Couldn't that be kept compatible by allowing tautological assignments to True/False (True = (1==1), that sort of thing) but throwing an error on all other assignments?
Also, I don't see how that wouldn't be compatible with forbidding assignments to True/False. It'd never execute the except block.
Re:Python bug: Can assign [] = (), but not () = []
by dalke on Wednesday May 27, 2015 @05:48PM
(#9614608)
Yes, that specific case is possible with some sort of AST rewriting. But it's only one of several ways to introduce a True into the module or local namespace. Another might be:
from _compat import True, False, next, enumerate
This is allowed under Python 2, but not under Python 3. As you suggest, it could be made possible to allow an import like this so long as the actual imported value is indeed the True or False singleton. But it's a lot of work with little gain.While on the other hand, even in Python 2 it was a SyntaxError to say "None = None" or to import None. Extending that check to include True and False is much easier, and consistent with existing use.
Re:Python bug: Can assign [] = (), but not () = []
by masklinn on Wednesday May 27, 2015 @02:57AM
(#9609753)
The second line doesn't do anything though, since you already reassigned True to False it's like assigning False to False.
You could write (False, True) = (True, False) though.
Re:Python bug: Can assign [] = (), but not () = []
by rectangletangle on Wednesday May 27, 2015 @02:52AM
(#9609721)
Python 3 removed this feature unfortunately.
Re:Python bug: Can assign [] = (), but not () = []
by tdicola on Wednesday May 27, 2015 @03:05AM
(#9609787)
Unfortunately? I'd love to know when changing false to mean true and vice-versa would make sense in any codebase.
Re:Python bug: Can assign [] = (), but not () = []
by rectangletangle on Wednesday May 27, 2015 @03:08AM
(#9609798)
>>> (False, True) = (True, False)
>>> 1 if False else 0
1
>>> bool(0) == False
False
Re:Python bug: Can assign [] = (), but not () = []
by janzer on Wednesday May 27, 2015 @03:27AM
(#9609858)
Not entirely sure of your point but...
Python 3.4.0 (default, Apr 11 2014, 13:05:11)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> (True, False) = (False, True)
File "<stdin>", line 1
SyntaxError: can't assign to keyword
Re:Python bug: Can assign [] = (), but not () = []
by exogen on Wednesday May 27, 2015 @03:28AM
(#9609863)
But, like the parent said, in Python 3:
>>> (False, True) = (True, False)
File "<stdin>", line 1
SyntaxError: can't assign to keyword
Re:Python bug: Can assign [] = (), but not () = []
by thaumasiotes on Wednesday May 27, 2015 @06:00AM
(#9610319)
In[2]: (True, False) = (False, True)
In[3]: True
Out[3]: False
In[4]: 1 if False else 0
Out[4]: 1
In[5]: 'yes' if bool(0) == False else 'no'
Out[5]: 'no'
In[6]: bool(0) == False
Out[6]: False
What bothers me here is that when the interpreter says "False", it clearly means the opposite of (the new) False. So by reassigning True and False, I've actually caused inconsistent behavior in python, not just really-confusingly-named behavior. Suddenly False sometimes means one thing and sometimes means something else.
Re:Python bug: Can assign [] = (), but not () = []
by masklinn on Wednesday May 27, 2015 @06:44AM
(#9610452)
There's no inconsistency, the "False" printed in your console is just the repr of the object, you can give that repr to your own object if you have nothing better to do with your life:
>>> A()
False
>>> bool(A())
True
>>> type(A())
<class '__main__.A'>
A repr is just a representation in development context, nothing more and nothing less, there is no requirement that it be sensible or of any use, though that's certainly recommended (contrary to __str__/__unicode__ which should be silly): >>> B()
A gray parrot
The only "inconsistency" you've created is that False in the console's local namespace does not match __builtins__.False or the interpreter's internal False object. You can still access the former by the way: >>> False
True
>>> __builtins__.False
False
unless you also override it: >>> __builtins__.False = True
>>> __builtins__.False
True
the interpreter still does not care though, you've just broken any Python code relying on the builtin (you can actually alter the "true" False object via ctypes)