Why no warnings when re-assigning builtin names?
usenet-nospam at seebs.net
Tue Aug 16 23:17:23 EDT 2011
On 2011-08-17, Steven D'Aprano <steve+comp.lang.python at pearwood.info> wrote:
> Seebs wrote:
>> On 2011-08-16, Steven D'Aprano <steve+comp.lang.python at pearwood.info>
>>> *My* objects certainly are, because I write documentation for my code. My
>>> docs are no less official than Python's docs.
>> Sure they are. I can't get yours from python.org.
> And what makes that unofficial?
> python.org is not the sole arbiter of official documentation in the world.
But it is the sole arbiter of official *Python* documentation. If I am
looking at code in Python, I reasonably expect the Python docs to be
correct about that code. Incomplete, sure, but *correct*.
>> I think code which shadows a built-in has a pretty real risk of being
>> harmful at some unspecified future point when some maintainer who hasn't
>> memorized every last line of the code makes the totally reasonable
>> assumption that basic language features are still working and available.
> Am I the only person who writes functions and methods any more? *wink*
Yes. Everyone else converted to single giant blocks of code because they
are easier to develop. :P
> Modern languages, and by modern I mean most languages more than, oh, about
> fifty years old, provide ways to limit the scope of variables. You don't
> need to memorise "every last line of the code" to safely edit a function.
Only the parts that are in scope, but...
I seem to recall (and I'm pretty Python newbiesh, so I could be wrong)
that Python classes create a scope in which bits of the class become
visible, and some classes are sorta biggish.
> def process(list, arg):
> cheese(list, arg)
> The scope of parameter "list" is limited to within the function process
> itself. Inside, it shadows the built-in list. Outside, it doesn't do squat.
Yes. But what about the built-in spam? :)
> Define the "entire language". Does that include the names of all the
> plethora of exceptions? How about the standard library?
I'd think "standard library" or close to it.
> For what it's worth, I don't care about memorising all the built-ins. I
> delegate that job to my editor, which has a syntax highlighter for Python.
> It never forgets built-ins. (In fact, sometimes this is a nuisance. When
> I'm editing Python 3 code, it still insists that apply and reduce are
I mostly don't use syntax highlighters; at best, they distract me, at worst,
they distract me a lot. I also don't use one in English, although I am
sure some people would love to have nouns in blue and punctuation in green.
> Yes, and Python also encourages the use of scopes, so that the clear,
> obvious name for something in one scope does not clash with the clear,
> obvious, identical name for something completely different in another
"Another" scope is normally a horizontal thing -- you're talking about
a different scope such that you are *either* in this one *or* in that
Built-ins are not in a scope you are never not in.
> Oh there's no doubt that shadowing *can* be unsafe. But then, very few
> things can't be abused.
> As I see it, there are (at least) four stages related to shadowing.
> (1) At first, you don't even know enough to be concerned by shadowing. You
> blithely call variables "list" and "str" without a care in the world...
> until something goes wrong.
> (2) Second stage, you know enough to realise that shadowing can be bad. You
> avoid shadowing everything. Your code is full of variables called "my_list"
> and "astr" and "some_tuple". You call your functions things like "izip"
> even though it is designed as a replacement for zip, because the caller
> might use from itertools import * and accidentally replace the built-in zip
> with my zip.
> You even avoid using "string" as a variable name because it might shadow the
> string module -- even though you haven't actually imported or used the
> string module in the last four years.
Heh. (I got advised by pylint not to grab something from it, but I no
longer remember why; I seem to recall being totally unable to find a way
to avoid that warning and still have the string processing I needed.)
> (3) Eventually, you get frustrated writing doc strings like this:
> def function(astr, myint=0):
> """function(astr [, myint]) -> list
> astr - string
> myint - integer
> Do something tool-like to a string and optional integer...
> and begin writing them like this:
> def function(astr, myint):
> """function(str [, int]) -> list
> Do something tool-like to a string and optional integer...
That seems safe enough to me. :)
> (4) And then, after a while, you decide that perhaps shadowing is not always
> so bad. (It helps if the Effbot tells you off for objecting to shadowing in
> a two-line function.) At first, you limit yourself to using parameter names
> that shadow built-ins in small tool-like functions. Then when the world
> doesn't implode, you rethink the use of top-level function names
> like "izip" and realise that namespaces exist so that you don't need to
> care about shadowing functions you don't use, and if people call import *
> they have nobody to blame but themselves if things break.
Hmm. See, I've never reached that, in Python or any other language. I
figure it creates a new potential for confusion, and that I would rather
avoid any ambiguity. I don't *like* ambiguity in code.
So I don't shadow stuff that's part of the language, because doing that
makes it possible for a line of code to have a clear and obvious meaning to
someone who looks at that line out of context, and a *completely different*
clear and obvious meaning to someone who looks at it with a bit more
context. I don't like that! It means that someone reading my code can
never, ever, assume that a standard language feature is actually itself
and not a local shadow which does something different unless they go
walking back up the scope chain checking. And that's a pretty big cost
to attach to stuff that is, by design, basic and universally available.
I might feel differently about names which were only visible after you
imported some specific thing, but if we're talking built-ins that are
Hmm. No, actually, even then, I just think it's Bad Mojo to overlap
names that were taken by the language itself. If a name is in a different
scope which I'm not in, I don't care about it, but if the name would already
be in scope if I didn't declare it, then I am creating a nasty ambiguity
if I use it.
Copyright 2011, all wrongs reversed. Peter Seebach / usenet-nospam at seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
More information about the Python-list