4

Built-in constants True and False are unmodifiable in Python 3 since at least 3.3:

The false value of the bool type. Assignments to False are illegal and raise a SyntaxError.

The true value of the bool type. Assignments to True are illegal and raise a SyntaxError.

However, in python 2.7, the code True = 0 executes without any exceptions. It seems these restrictions should have been ported to 2.x long ago, but they haven't.

The only reason I can think of is compatibility with existing code base. Do you know any case when the existing software is deliberately modifying True or False? If not, what other reasons might there be?

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
  • The duplicate doesn't seem to answer why it *wasn't backported*. Granted, the title doesn't actually mirror the question body. – Dimitris Fasarakis Hilliard Sep 18 '17 at 20:32
  • "Do you know any case when the existing software is deliberately modifying True or False?" - people used to assign `True=1` and `False=0` (or `true=1`, or `TRUE=1`...) back when Python didn't actually have bools, and they needed to maintain backward compatibility. – user2357112 Sep 18 '17 at 20:33
  • I see your point. Correct me if I'm wrong but python 2.2 introduced a whole new keyword `yield` (PEP 255), which broke compatibility for those who had used `yield` as a variable. Don't see any difference here. –  Sep 18 '17 at 20:49
  • 1
    @Free I'm pretty sure that instances of people using `yield` are way less than people defining a pretty universal constant like `True` and `False`. – Dimitris Fasarakis Hilliard Sep 18 '17 at 20:51
  • I'm sure it was when `True` and `False` were introduced in the language (which version was it, by the way?). Is it still actual today, in 2017? –  Sep 18 '17 at 20:56
  • 1
    If Python 2 only had to be compatible with code written in 2017, we could change a lot of things. – user2357112 Sep 18 '17 at 20:57

2 Answers2

6

As Guido states in the story of None, True and False, context matters in the case of not making True and False keywords in the first place. When bool was introduced (with PEP 285 in Python 2.3) it couldn't of been made a keyword because a lot of code in existence already defined it in one way or another:

The situation for True/False is a little different. They weren't always part of the language, and many people had invented their own convention. People would define constants named true and false, True and False, or TRUE and FALSE, and use those consistently throughout their code. I don't recall which spelling was most popular, but when we introduced True and False into the language, we definitely did not want to break any packages that were defining their own True and False constants.

and continues to state in a later paragraph:

So, essentially our hand was forced in this case, and we had to introduce True and False as built-in constants, not as keywords. But over time, code defining its own versions of True and False (by whichever name) became more and more frowned upon, and by the time Python 3 came around, when we looked at opportunities for cleaning up the language, we found that it was logical to make True and False keywords, by analogy to None.

You correctly assume that:

The only reason I can think of is compatibility with existing code base.

And, indeed, this is the case. The need to keep backwards-compatibility between versions of Python 2 is why True and False aren't keywords there.

Python 3 is different in that it introduced a number of backwards incompatible changes in an effort to clean the language up, the awkward re-assigning to True and False can no longer be done, thankfully.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
2

It's not really that True and False can be modified, so much as that True and False can be names, and if they are names, those names will shadow the names in builtin. That is True and False are not handled by the parser as special symbols, but appear to be looked up in the current local and global binding scope:

>>> True = 'mumble'
>>> True
'mumble'
>>> bool(True)
True
>>> bool(True) == True # "mumble" == True
False
>>> bool(True) == bool(True)
True

So, it's a language design choice about how to interact with the symbols.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
Sam Hartman
  • 6,210
  • 3
  • 23
  • 40