Q:

Python NameError when attempting to use a user-defined class

I'm getting a weird instance of a NameError when attempting to use a class I wrote.  In a directory, I have the following file structure:

dir/    

ReutersParser.py
test.py
reut-xxx.sgm

Where my custom class is defined in ReutersParser.py and I have a test script defined in test.py.
The ReutersParser looks something like this:
from sgmllib import SGMLParser

class ReutersParser(SGMLParser):

    def __init__(self, verbose=0):
        SGMLParser.__init__(self, verbose)

    ... rest of parser

if __name__ == '__main__':

    f = open('reut2-short.sgm')
    s = f.read()

    p = ReutersParser()
    p.parse(s)

It's a parser to deal with SGML files of Reuters articles.  The test works perfectly.  Anyway, I'm going to use it in test.py, which looks like this:
from ReutersParser import ReutersParser

def main():
    parser = ReutersParser()

if __name__ == '__main__':
    main()

When it gets to that parser line, I'm getting this error:
Traceback (most recent call last):
  File "D:\Projects\Reuters\test.py", line 34, in <module>
    main()
  File "D:\Projects\Reuters\test.py", line 19, in main
    parser = ReutersParser()
  File "D:\Projects\Reuters\ReutersParser.py", line 38, in __init__
    SGMLParser.__init__(self, verbose)
NameError: global name 'sgmllib' is not defined

For some reason, when I try to use my ReutersParser in test.py, it throws an error that says it cannot find sgmllib, which is a built-in module.  I'm at my wits' end trying to figure out why the import won't work.
What's causing this NameError? I've tried importing sgmllib in my test.py and that works, so I don't understand why it can't find it when trying to run the constructor for my ReutersParser.

A:

Your problem is not your code, but what you run it in. If you read the error and the code it displays closely:
  File "D:\Projects\Reuters\ReutersParser.py", line 38, in __init__
    SGMLParser.__init__(self, verbose)
NameError: global name 'sgmllib' is not defined

you'll notice there's no reference to 'sgmllib' on the line that Python thinks produced this error. That means one of two things: either the error didn't originate there (and Python is quite confused), or the code that's being displayed is not the code that is being executed. The latter is quite common when you, for example, run your code in an IDE that doesn't restart the Python interpreter between code executions. It will execute your old code, but when displaying the traceback will show the new code. I'm guessing you did sgmllib.SGMLParser.__init__(self, verbose) on that line at some point in the past.
The reason it was fixed by renaming the class is probably that you did something -- like editing the code -- that caused the IDE to either restart the interpreter, properly clean it up or (by accident) reloaded the right module the right way for it to see the new code. Since you name your module after your class (which is bad style, by the way) I assume you renamed your module when you renamed your class, and so your IDE picked up the new code this time. Until the next time the same thing happens, of course.

