Sort of hard to explain, but if you put another: list = configuration.items("core") print list
at the end of the script, you will find that the original config hasn't been changed. It is a quirk of how the items() method is implemented using 'yield' that means that you see what you do. In particular to use 'yield' it it necessary to create a temporary dictionary which contains the key/value pairs from that section of the config and then overlay it with the user supplied vars. Ie., the items() code has: . d = self._defaults.copy() . try: . d.update(self._sections[section]) . except KeyError: . if section != DEFAULTSECT: . raise NoSectionError(section) . # Update with the entry specific variables . if vars: . d.update(vars) See the last line, that will replace the value of 'xyzzy' with that passed in as argument to items(). To avoid this, you need to write something like: . list = [] . for key in configuration.options("core"): . list.append((key,configuration.get("core",substitution)) . print list This cause me problems for a different reason, ie., that user vars keys appear in what items() returns. I avoid using items() for this reason. -- http://mail.python.org/mailman/listinfo/python-list