[Python-Dev] Rationale behind removing kwdict from keyword.py? (original) (raw)

Tim Peters tim.peters at gmail.com
Wed Jul 28 04:13:24 CEST 2004


[Fernando Perez]

I recently got a report from a user of a project of mine breaking under 2.4a1. The reason is that keyword stopped having a kwdict variable in it. Is there any rationale behind this change?

Looking at the code, because keyword.py no longer uses a dictionary (Raymond changed it to use a set), and kwdict wasn't part of keyword's public API so there was no reason to avoid changing this.

I know I can always work around it, but this honestly feels, to me, like gratuitous breakage.

It would be nice if things like public members (it wasn't called kwdict, so I had no reason to assume it was off-limits) ...

You actually had two reasons, and strong ones. As you noted later, it wasn't part of keyword's documented interface, and you always act at your own risk when you go beyond the docs.

The second reason is that 'kwdict' didn't appear in the keyword.all list. As the docs for Python's import statement say:

The public names defined by a module are determined by checking the
module's namespace for a variable named __all__; if defined, it must be a
sequence of strings which are names defined or imported by that module.
The names given in __all__ are all considered public and are

required to exist. If all is not defined, the set of public names includes all names found in the module's namespace which do not begin with an underscore character ("_"). all should contain the entire public API. It is intended to avoid accidentally exporting items that are not part of the API (such as library modules which were imported and used within the module).

Note that it's very common in older modules (which keyword.py is) to define the newer all rather than risk breaking code by massive renaming of variables to stick an underscore in front of them.

... While the html docs for keyword don't mention kwdict, I often simply use help(module) to look for what I need, and I saw kwdict happily listed there, without any leading to indicate any sense of it being private.

You should stop doing that, then -- this is the kind of trouble it leads to, and you'll only get more of it. help(keyword) did advertise the keyword.all value in 2.3.4:

... DATA all = ['iskeyword', 'kwlist'] keyword = 'yield' kwdict = {'and': 1, 'assert': 1, 'break': 1, 'class': 1, 'continue': 1... kwlist = ['and', 'assert', 'break', 'class', 'continue', 'def', 'del',...

Since 'keyword' and 'kwdict' weren't in all, you couldn't rely on either of them; and, indeed, they're both gone in 2.4, while keyword.all hasn't changed.

The changes were made, according to viewCVS, in revision 1.13. I know I can use iskeyword() for my purposes, and patch accordingly. But I'd like to remind the core developers that when things go into the stdlib, people start using them. Removing stuff will always break code.

The developers were careful to keep the public API in this case exactly the same.

I'll gladly file a SF bug report against this, but I'd like not to waste anyone's time if it won't be considered.

Sorry, no, I would not consider this one.



More information about the Python-Dev mailing list