Cascade_button.menu.choices = Menu(Cascade_button.menu)
# ...and this is a menu that cascades from that.
- Cascade_button.menu.choices.wierdones = Menu(Cascade_button.menu.choices)
+ Cascade_button.menu.choices.weirdones = Menu(Cascade_button.menu.choices)
# then you define the menus from the deepest level on up.
- Cascade_button.menu.choices.wierdones.add_command(label='avacado')
- Cascade_button.menu.choices.wierdones.add_command(label='belgian endive')
- Cascade_button.menu.choices.wierdones.add_command(label='beefaroni')
+ Cascade_button.menu.choices.weirdones.add_command(label='avacado')
+ Cascade_button.menu.choices.weirdones.add_command(label='belgian endive')
+ Cascade_button.menu.choices.weirdones.add_command(label='beefaroni')
# definition of the menu one level up...
Cascade_button.menu.choices.add_command(label='Chocolate')
Cascade_button.menu.choices.add_command(label='Rocky Road')
Cascade_button.menu.choices.add_command(label='BubbleGum')
Cascade_button.menu.choices.add_cascade(
- label='Wierd Flavors',
- menu=Cascade_button.menu.choices.wierdones)
+ label='Weird Flavors',
+ menu=Cascade_button.menu.choices.weirdones)
# and finally, the definition for the top level
Cascade_button.menu.add_cascade(label='more choices',
File_button.menu = Menu(File_button)
# add an item. The first param is a menu entry type,
- # must be one of: "cascade", "checkbutton", "command", "radiobutton", "seperator"
+ # must be one of: "cascade", "checkbutton", "command", "radiobutton", "separator"
# see menu-demo-2.py for examples of use
File_button.menu.add_command(label='New...', underline=0,
command=new_file)
user. Typically this component is represented by the templates.
* The *controller*. This is the layer between the user and the model. The
controller reacts on user actions (like opening some specific URL) and tells
- the model to modify the data if neccessary.
+ the model to modify the data if necessary.
While one might think that MVC is a complex design pattern, in fact it is not.
It is used in Python because it has turned out to be useful for creating clean,
.. note::
While not all Python frameworks explicitly support MVC, it is often trivial
- to create a web site which uses the MVC pattern by seperating the data logic
+ to create a web site which uses the MVC pattern by separating the data logic
(the model) from the user interaction logic (the controller) and the
- templates (the view). That's why it is important not to write unneccessary
+ templates (the view). That's why it is important not to write unnecessary
Python code in the templates -- it is against MVC and creates more chaos.
.. seealso::
-----------------------
There is an incredible number of frameworks, so there is no way to describe them
-all. It is not even neccessary, as most of these frameworks are nothing special
+all. It is not even necessary, as most of these frameworks are nothing special
and everything that can be done with these can also be done with one of the
popular ones.
Another framework that's already been mentioned is `Pylons`_. Pylons is much
like TurboGears with ab even stronger emphasis on flexibility, which is bought
at the cost of being more difficult to use. Nearly every component can be
-exchanged, which makes it neccessary to use the documentation of every single
+exchanged, which makes it necessary to use the documentation of every single
component, because there are so many Pylons combinations possible that can
satisfy every requirement. Pylons builds upon `Paste
<http://pythonpaste.org/>`_, an extensive set of tools which are handy for WSGI.
At the top of the I/O hierarchy is the abstract base class :class:`IOBase`. It
defines the basic interface to a stream. Note, however, that there is no
-seperation between reading and writing to streams; implementations are allowed
+separation between reading and writing to streams; implementations are allowed
to throw an :exc:`IOError` if they do not support a given operation.
Extending :class:`IOBase` is :class:`RawIOBase` which deals simply with the
is enabled. With this enabled, on input, the lines endings ``'\n'``,
``'\r'``, or ``'\r\n'`` are translated to ``'\n'`` before being returned to
the caller. Conversely, on output, ``'\n'`` is translated to the system
- default line seperator, :data:`os.linesep`. If *newline* is any other of its
+ default line separator, :data:`os.linesep`. If *newline* is any other of its
legal values, that newline becomes the newline when the file is read and it
is returned untranslated. On output, ``'\n'`` is converted to the *newline*.
concept: starting another process and being able to write to and read from its
controlling terminal programmatically.
-Because pseudo-terminal handling is highly platform dependant, there is code to
+Because pseudo-terminal handling is highly platform dependent, there is code to
do it only for SGI and Linux. (The Linux code is supposed to work on other
platforms, but hasn't been tested yet.)
only works if the base class is defined or imported directly in the global
scope.)
-Python has two builtin functions that work with inheritance:
+Python has two built-in functions that work with inheritance:
* Use :func:`isinstance` to check an object's type: ``isinstance(obj, int)``
will be ``True`` only if ``obj.__class__`` is :class:`int` or some class
print row[i],
print
-In real world, you should prefer builtin functions to complex flow statements.
+In real world, you should prefer built-in functions to complex flow statements.
The :func:`zip` function would do a great job for this use case::
>>> zip(*mat)
>>> 0.1
0.1000000000000000055511151231257827021181583404541015625
-instead! The Python prompt uses the builtin :func:`repr` function to obtain a
+instead! The Python prompt uses the built-in :func:`repr` function to obtain a
string version of everything it displays. For floats, ``repr(float)`` rounds
the true decimal value to 17 significant digits, giving ::
(although some languages may not *display* the difference by default, or in all
output modes).
-Python's builtin :func:`str` function produces only 12 significant digits, and
+Python's built-in :func:`str` function produces only 12 significant digits, and
you may wish to use that instead. It's unusual for ``eval(str(x))`` to
reproduce *x*, but the output may be more pleasant to look at::
This is particularly useful in combination with the new built-in :func:`vars`
function, which returns a dictionary containing all local variables.
-For a complete overview of string formating with :meth:`str.format`, see
+For a complete overview of string formatting with :meth:`str.format`, see
:ref:`formatstrings`.
>>> os.chdir('/server/accesslogs')
Be sure to use the ``import os`` style instead of ``from os import *``. This
-will keep :func:`os.open` from shadowing the builtin :func:`open` function which
+will keep :func:`os.open` from shadowing the built-in :func:`open` function which
operates much differently.
.. index:: builtin: help
-The builtin :func:`dir` and :func:`help` functions are useful as interactive
+The built-in :func:`dir` and :func:`help` functions are useful as interactive
aids for working with large modules like :mod:`os`::
>>> import os
self.assertEqual(d.get('0321'), '0321-0321-0321-0321-0321')
- # By default non-existant keys return None...
+ # By default non-existent keys return None...
self.assertEqual(d.get('abcd'), None)
# ...but they raise exceptions in other situations. Call
except KeyError:
pass
else:
- self.fail("set_location on non-existant key did not raise KeyError")
+ self.fail("set_location on non-existent key did not raise KeyError")
f.sync()
f.close()
if verbose:
print rec
- # test that non-existant key lookups work (and that
+ # test that non-existent key lookups work (and that
# DBC_set_range doesn't have a memleak under valgrind)
rec = c.set_range(999999)
self.assertEqual(rec, None)
(from line tuple, to line tuple, boolean flag)
from/to line tuple -- (line num, line text)
- line num -- integer or None (to indicate a context seperation)
+ line num -- integer or None (to indicate a context separation)
line text -- original line text with following markers inserted:
'\0+' -- marks start of added text
'\0-' -- marks start of deleted text
def test_run_setup_uses_current_dir(self):
# This tests that the setup script is run with the current directory
- # as it's own current directory; this was temporarily broken by a
+ # as its own current directory; this was temporarily broken by a
# previous patch when TESTFN did not use the current directory.
sys.stdout = StringIO.StringIO()
cwd = os.getcwd()
SEMISPACE = '; '
# Regular expression that matches `special' characters in parameters, the
-# existance of which force quoting of the parameter value.
+# existence of which force quoting of the parameter value.
tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')
def try_open_completions_event(self, event):
"""Happens when it would be nice to open a completion list, but not
- really neccesary, for example after an dot, so function
+ really necessary, for example after an dot, so function
calls won't be made.
"""
lastchar = self.text.get("insert-1c")
COMPLETE_FILES)
def autocomplete_event(self, event):
- """Happens when the user wants to complete his word, and if neccesary,
+ """Happens when the user wants to complete his word, and if necessary,
open a completion list after that (if there is more than one
completion)
"""
def try_open_calltip_event(self, event):
"""Happens when it would be nice to open a CallTip, but not really
- neccesary, for example after an opening bracket, so function calls
+ necessary, for example after an opening bracket, so function calls
won't be made.
"""
self.open_calltip(False)
window raising, especially in the Windows menu and in the debugger.
IDLEfork 763524.
-- If user passes a non-existant filename on the commandline, just
+- If user passes a non-existent filename on the commandline, just
open a new file, don't raise a dialog. IDLEfork 854928.
At the top of the I/O hierarchy is the abstract base class IOBase. It
defines the basic interface to a stream. Note, however, that there is no
-seperation between reading and writing to streams; implementations are
+separation between reading and writing to streams; implementations are
allowed to throw an IOError if they do not support a given operation.
Extending IOBase is RawIOBase which deals simply with the reading and
enabled. With this enabled, on input, the lines endings '\n', '\r',
or '\r\n' are translated to '\n' before being returned to the
caller. Conversely, on output, '\n' is translated to the system
- default line seperator, os.linesep. If newline is any other of its
+ default line separator, os.linesep. If newline is any other of its
legal values, that newline becomes the newline when the file is read
and it is returned untranslated. On output, '\n' is converted to the
newline.
"""Return the color (red, green, blue) of the pixel at X,Y."""
return self.tk.call(self.name, 'get', x, y)
def put(self, data, to=None):
- """Put row formated colors to image starting from
+ """Put row formatted colors to image starting from
position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))"""
args = (self.name, 'put', data)
if to:
def _drawturtle(self):
"""Manages the correct rendering of the turtle with respect to
- its shape, resizemode, strech and tilt etc."""
+ its shape, resizemode, stretch and tilt etc."""
screen = self.screen
shape = screen._shapes[self.turtle.shapeIndex]
ttype = shape._type
"""print_usage(file : file = stdout)
Print the usage message for the current program (self.usage) to
- 'file' (default stdout). Any occurence of the string "%prog" in
+ 'file' (default stdout). Any occurrence of the string "%prog" in
self.usage is replaced with the name of the current program
(basename of sys.argv[0]). Does nothing if self.usage is empty
or not defined.
"""print_version(file : file = stdout)
Print the version message for this program (self.version) to
- 'file' (default stdout). As with print_usage(), any occurence
+ 'file' (default stdout). As with print_usage(), any occurrence
of "%prog" in self.version is replaced by the current program's
name. Does nothing if self.version is empty or undefined.
"""
if USE_ZIPIMPORT:
if name != "zlib":
# neatly pack all extension modules in a subdirectory,
- # except zlib, since it's neccesary for bootstrapping.
+ # except zlib, since it's necessary for bootstrapping.
dstpath = pathjoin("ExtensionModules", dstpath)
# Python modules are stored in a Zip archive, but put
# extensions in Contents/Resources/. Add a tiny "loader"
s = StringIO(data)
msg = Message.Message(s)
# These headers are required for the proper execution of Mailman. All
- # MTAs in existance seem to add these if the original message doesn't
+ # MTAs in existence seem to add these if the original message doesn't
# have them.
if not msg.getheader('from'):
msg['From'] = mailfrom
def getmember(self, name):
"""Return a TarInfo object for member `name'. If `name' can not be
found in the archive, KeyError is raised. If a member occurs more
- than once in the archive, its last occurence is assumed to be the
+ than once in the archive, its last occurrence is assumed to be the
most up-to-date version.
"""
tarinfo = self._getmember(name)
class OutputTestCase(unittest.TestCase):
def normalize_calendar(self, s):
- # Filters out locale dependant strings
+ # Filters out locale dependent strings
def neitherspacenordigit(c):
return not c.isspace() and not c.isdigit()
# Make sure the right things happen for remove_option();
# added to include check for SourceForge bug #123324:
self.failUnless(cf.remove_option('Foo Bar', 'foo'),
- "remove_option() failed to report existance of option")
+ "remove_option() failed to report existence of option")
self.failIf(cf.has_option('Foo Bar', 'foo'),
"remove_option() failed to remove option")
self.failIf(cf.remove_option('Foo Bar', 'foo'),
- "remove_option() failed to report non-existance of option"
+ "remove_option() failed to report non-existence of option"
" that was removed")
self.assertRaises(ConfigParser.NoSectionError,
file1 = test_support.findfile("cfgparser.1")
# check when we pass a mix of readable and non-readable files:
cf = self.newconfig()
- parsed_files = cf.read([file1, "nonexistant-file"])
+ parsed_files = cf.read([file1, "nonexistent-file"])
self.assertEqual(parsed_files, [file1])
self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
# check when we pass only a filename:
self.assertEqual(cf.get("Foo Bar", "foo"), "newbar")
# check when we pass only missing files:
cf = self.newconfig()
- parsed_files = cf.read(["nonexistant-file"])
+ parsed_files = cf.read(["nonexistent-file"])
self.assertEqual(parsed_files, [])
# check when we pass no files:
cf = self.newconfig()
# useful that the error handler is not called for every single
# unencodable character, but for a complete sequence of
# unencodable characters, otherwise we would output many
- # unneccessary escape sequences.
+ # unnecessary escape sequences.
def uninamereplace(exc):
if not isinstance(exc, UnicodeEncodeError):
counter[key] = counter[key] + 1
self.assert_(not (
- # a permanent cookie got lost accidently
+ # a permanent cookie got lost accidentally
counter["perm_after"] != counter["perm_before"] or
# a session cookie hasn't been cleared
counter["session_after"] != 0 or
{1: 3.25}
>>> print a[1] # show the new item
3.25
- >>> print a[0] # a non-existant item
+ >>> print a[0] # a non-existent item
0.0
>>> a.merge({1:100, 2:200}) # use a dict method
>>> print sortdict(a) # show the result
def test_unset_attr(self):
for func in [self.b, self.f.a, self.fi.a]:
- try: func.non_existant_attr
+ try: func.non_existent_attr
except AttributeError: pass
else: self.fail("using unknown attributes should raise "
"AttributeError")
def test_ftp(self):
urls = [
'ftp://ftp.kernel.org/pub/linux/kernel/README',
- 'ftp://ftp.kernel.org/pub/linux/kernel/non-existant-file',
+ 'ftp://ftp.kernel.org/pub/linux/kernel/non-existent-file',
#'ftp://ftp.kernel.org/pub/leenox/kernel/test',
'ftp://gatekeeper.research.compaq.com/pub/DEC/SRC'
'/research-reports/00README-Legal-Rules-Regs',
from types import ListType, TupleType
# Regular expression that matches `special' characters in parameters, the
-# existance of which force quoting of the parameter value.
+# existence of which force quoting of the parameter value.
import re
tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]')
(2) Stefan Esser (se@MI.Uni-Koeln.DE), in work done to compile Python
1.0.0 on AIX 3.2.4, reports that AIX compilers don't like the LANG
environment varaiable set to European locales. This makes the compiler
- generate floating point constants using "," as the decimal seperator,
+ generate floating point constants using "," as the decimal separator,
which the assembler doesn't understand (or perhaps it is the other way
around, with the assembler expecting, but not getting "," in float
numbers). "LANG=C; export LANG" solves the problem, as does
Also (quite separately, but strangely related to the philosophical
issue above) fix abspath() so that if win32api exists, it doesn't fail
when the path doesn't actually exist -- if GetFullPathName() fails,
- fall back on the old strategy (join with getcwd() if neccessary, and
+ fall back on the old strategy (join with getcwd() if necessary, and
then use normpath()).
* configure.in, configure, config.h.in, acconfig.h:
- Issue #3575: Incremental decoder's decode function now takes bytearray
by using 's*' instead of 't#'.
-- Issue #2222: Fixed reference leak when occured os.rename()
+- Issue #2222: Fixed reference leak when occurred os.rename()
fails unicode conversion on 2nd parameter. (windows only)
- Issue 2464. urllib2 now supports a malformation in the URL received
s.isupper() return True if all characters in s are uppercase, False (6)
otherwise.
s.join(seq) return a concatenation of the strings in the sequence
- seq, seperated by 's's.
+ seq, separated by 's's.
s.ljust(width) return s left justified in a string of length width. (1),
(8)
s.lower() return a copy of s converted to lowercase.
asctime(
timeTuple),
strftime(
-format, return a formated string representing time.
+format, return a formatted string representing time.
timeTuple)
mktime(tuple) inverse of localtime(). Return a float.
-strptime( parse a formated string representing time, return tuple as in
+strptime( parse a formatted string representing time, return tuple as in
string[, gmtime().
format])
sleep(secs) Suspend execution for <secs> seconds. <secs> can be a float.
test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \
test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
- # We can hardcode non-existant directories.
+ # We can hardcode non-existent directories.
if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
test -n "$runpath_var" || \
test "X$hardcode_automatic" = "Xyes" ; then
- # We can hardcode non-existant directories.
+ # We can hardcode non-existent directories.
if test "$hardcode_direct" != no &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
test -n "$runpath_var_CXX" || \
test "X$hardcode_automatic_CXX" = "Xyes" ; then
- # We can hardcode non-existant directories.
+ # We can hardcode non-existent directories.
if test "$hardcode_direct_CXX" != no &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
test -n "$runpath_var_F77" || \
test "X$hardcode_automatic_F77" = "Xyes" ; then
- # We can hardcode non-existant directories.
+ # We can hardcode non-existent directories.
if test "$hardcode_direct_F77" != no &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
test -n "$runpath_var_GCJ" || \
test "X$hardcode_automatic_GCJ" = "Xyes" ; then
- # We can hardcode non-existant directories.
+ # We can hardcode non-existent directories.
if test "$hardcode_direct_GCJ" != no &&
# If the only mechanism to avoid hardcoding is shlibpath_var, we
# have to relink, otherwise we might link with an installed library
/* Register class used for passing given 64bit part of the argument.
These represent classes as documented by the PS ABI, with the exception
of SSESF, SSEDF classes, that are basically SSE class, just gcc will
- use SF or DFmode move instead of DImode to avoid reformating penalties.
+ use SF or DFmode move instead of DImode to avoid reformatting penalties.
Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
whenever possible (upper half does contain padding). */
/* Register class used for passing given 64bit part of the argument.
These represent classes as documented by the PS ABI, with the exception
of SSESF, SSEDF classes, that are basically SSE class, just gcc will
- use SF or DFmode move instead of DImode to avoid reformating penalties.
+ use SF or DFmode move instead of DImode to avoid reformatting penalties.
Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
whenever possible (upper half does contain padding). */
PyErr_Clear();
}
- /* abort query if error occured */
+ /* abort query if error occurred */
rc = 1;
} else {
rc = (int)PyObject_IsTrue(ret);
PyDoc_STRVAR(count_doc,
"count(x)\n\
\n\
-Return number of occurences of x in the array.");
+Return number of occurrences of x in the array.");
static PyObject *
array_index(arrayobject *self, PyObject *v)
PyDoc_STRVAR(index_doc,
"index(x)\n\
\n\
-Return index of first occurence of x in the array.");
+Return index of first occurrence of x in the array.");
static int
array_contains(arrayobject *self, PyObject *v)
PyDoc_STRVAR(remove_doc,
"remove(x)\n\
\n\
-Remove the first occurence of x in the array.");
+Remove the first occurrence of x in the array.");
static PyObject *
array_pop(arrayobject *self, PyObject *args)
append() -- append a new item to the end of the array\n\
buffer_info() -- return information giving the current memory info\n\
byteswap() -- byteswap all the items of the array\n\
-count() -- return number of occurences of an object\n\
+count() -- return number of occurrences of an object\n\
extend() -- extend array by appending multiple elements from an iterable\n\
fromfile() -- read items from a file object\n\
fromlist() -- append items from the list\n\
fromstring() -- append items from the string\n\
-index() -- return index of first occurence of an object\n\
+index() -- return index of first occurrence of an object\n\
insert() -- insert a new item into the array at a provided position\n\
pop() -- remove and return item (default last)\n\
read() -- DEPRECATED, use fromfile()\n\
-remove() -- remove first occurence of an object\n\
+remove() -- remove first occurrence of an object\n\
reverse() -- reverse the order of the items in the array\n\
tofile() -- write all items to a file object\n\
tolist() -- return the array converted to an ordinary list\n\
static PyObject *
posix__getfullpathname(PyObject *self, PyObject *args)
{
- /* assume encoded strings wont more than double no of chars */
+ /* assume encoded strings won't more than double no of chars */
char inbuf[MAX_PATH*2];
char *inbufp = inbuf;
Py_ssize_t insize = sizeof(inbuf);
"Your program accessed mem currently in use at xxx"
and a hopeful warning about the stability of your
system.
- Cost is Ctrl+C wont kill children, but anyone
+ Cost is Ctrl+C won't kill children, but anyone
who cares can have a go!
*/
dwProcessFlags |= CREATE_NEW_CONSOLE;
/* Iterate over seq. Result depends on the operation:
PY_ITERSEARCH_COUNT: -1 if error, else # of times obj appears in seq.
- PY_ITERSEARCH_INDEX: 0-based index of first occurence of obj in seq;
+ PY_ITERSEARCH_INDEX: 0-based index of first occurrence of obj in seq;
set ValueError and return -1 if none found; also return -1 on error.
Py_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on error.
*/
A:10000 B:20000 C:10000
we dare not merge A with C first, because if A, B and C happen to contain
-a common element, it would get out of order wrt its occurence(s) in B. The
+a common element, it would get out of order wrt its occurrence(s) in B. The
merging must be done as (A+B)+C or A+(B+C) instead.
So merging is always done on two consecutive runs at a time, and in-place,
none_dealloc(PyObject* ignore)
{
/* This should never get called, but we also don't want to SEGV if
- * we accidently decref None out of existance.
+ * we accidentally decref None out of existence.
*/
Py_FatalError("deallocating None");
}
charsleft = (charsleft << 16) | ch;
/* out, charsleft, bitsleft = */ ENCODE(out, charsleft, bitsleft);
- /* If the next character is special then we dont' need to terminate
+ /* If the next character is special then we don't need to terminate
the shift sequence. If the next character is not a BASE64 character
or '-' then the shift sequence will be terminated implicitly and we
don't have to insert a '-'. */
/* The win32api module reports the function name that failed,
but this concept is not in the Python core.
- Hopefully it will one day, and in the meantime I dont
+ Hopefully it will one day, and in the meantime I don't
want to lose this info...
*/
#define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \
** Note that fixupMultiSZ and countString have both had changes
** made to support "incorrect strings". The registry specification
** calls for strings to be terminated with 2 null bytes. It seems
-** some commercial packages install strings which dont conform,
+** some commercial packages install strings which don't conform,
** causing this code to fail - however, "regedit" etc still work
-** with these strings (ie only we dont!).
+** with these strings (ie only we don't!).
*/
static void
fixupMultiSZ(char **str, char *data, int len)
# zlibmodule.c -- Wrapper of ZLib Compression API (GZip Format)
# puremodule.c -- Wrapper of Purify Debugging API (Probably Non-OS/2)
- # dlmodule.c -- Some Wierd Form of Data Processing Module
+ # dlmodule.c -- Some Weird Form of Data Processing Module
# xxmodule.c -- Template to Create Your Own Module
#
# rpyron 2002-05-07
# Robert Pyron <rpyron@alum.mit.edu>
# 1. BUGFIX: In function makefile(), strip blanks from the nodename.
-# This is necesary to match the behavior of parser.makeref() and
+# This is necessary to match the behavior of parser.makeref() and
# parser.do_node().
# 2. BUGFIX fixed KeyError in end_ifset (well, I may have just made
# it go away, rather than fix it)