Numbers and truth values

Alex Martelli aleax at mac.com
Sat Apr 28 14:19:22 EDT 2007


Szabolcs <szhorvat at gmail.com> wrote:
   ...
> >>>> True = 2  # DON'T DO THIS!!!
> >>>> 2 == True
> > True
> 
> But shouldn't Python forbid this? Is it possible to get a warning when
> unintentionally redefining built-in thing?

Python can be changed to make some non-reserved builtin identifiers into
reserved words, going through a stage where this is allowed but gives a
warning.  This happened in recent years for assignments to None, which
were legal back in 2.2 and earlier:

$ python2.3 -c'None=23'   
<string>:1: SyntaxWarning: assignment to None
$ python2.4 -c'None=23'
  File "<string>", line 1
SyntaxError: assignment to None

...and, as you can see, gave syntax warnings in 2.3, becoming syntax
errors in 2.4 and later versions.

However, Python has a somewhat large and growing number of builtin
identifiers:

$ python2.3 -c'print len(__builtins__.__dict__)'
124
$ python2.4 -c'print len(__builtins__.__dict__)'
128
$ python2.5 -c'print len(__builtins__.__dict__)'
133

while keywords (reserved words) are far fewer, and more constrained in
their growth:

$ python2.3 -c'import keyword; print len(keyword.kwlist)'
29
$ python2.4 -c'import keyword; print len(keyword.kwlist)'
29
$ python2.5 -c'import keyword; print len(keyword.kwlist)'
31

so, making all builtins into keywords is unlikely to happen: it would
break a lot of existing code in exchange for a minor benefit.

It _would_ surely be possible to make Python behave this way only when a
certain commandline flag or environment variable is present, e.g. by
tweaking the implementation of the relevant bytecodes:

>>> def f():
...   global aglobal
...   aglobal = 23
...   alocal = 45
... 
>>> dis.dis(f)
  3           0 LOAD_CONST               1 (23)
              3 STORE_GLOBAL             0 (aglobal)

  4           6 LOAD_CONST               2 (45)
              9 STORE_FAST               0 (alocal)
             12 LOAD_CONST               0 (None)
             15 RETURN_VALUE        

STORE_GLOBAL and STORE_FAST.  However, this might slow down normal
operation (by needing to check some flag at each STORE_...).

Perhaps a better approach is to perform your checking with a tool that
is _separate_ from "Python proper".  Wouldn't it be great to have a tool
to check Python sources, one which we could name, for example,
pychecker, that we could run as follows...:

$ cat >ba.py
False = 23

$ pychecker ba.py 
Processing ba...

Warnings...

ba.py:1: (False) shadows builtin
ba.py:1: Should not assign to False, it is (or will be) a builtin


Rejoyce!  <http://pychecker.sourceforge.net/> ...

There are other tools to perform such checks, such as pylint,
<http://www.logilab.org/857>, which is quite a bit more complicated but
can perform many more checks (and can be integrated into PyDev, an
Eclipse add-on which some people like to use as a Python IDE), and, I
believe, a few other with slightly different slants (such as pyflakes,
<http://www.divmod.org/projects/pyflakes>, which does fewer checks but
does them faster and in a way that's safe against potentially-evil
code).

By the way, both of these tools (and many other tools, and a lot of
other useful tips) are mentioned at
<http://www.python.org/doc/faq/programming/> , the Python Programming
FAQ (it's a bit dated, but if you find any problem with it, just like
with any other piece of official Python docs, bugs and suggested patches
are welcome at the usual location,
<http://sourceforge.net/projects/python> ).

Perhaps one day some variant of pychecker and/or pylint can be
integrated in Python itself, and executed (for example at each import)
if that's indicated by some appropriate flag or environment variable;
however, for us command-line dinosaurs, the people who prefer running
python at a shell prompt (rather than more advanced things such as
ipython, or IDEs such as PyDev, IDLE, etc, etc) this doesn't really tend
to be that high a priority, as we're quite used to "not necessarily
auto-integrated" tools; it's probably a higher priority to get pychecker
or something like that integrated with other IDEs such as IDLE (I don't
know, besides PyDev's ability to use pylint, which other such
integrations currently exist -- anybody?).


Alex



More information about the Python-list mailing list