[Tutor] String Encoding problem

spir denis.spir at free.fr
Mon Apr 20 19:22:59 CEST 2009


Le Mon, 20 Apr 2009 10:46:47 -0400,
Matt <HellZFury+Python at gmail.com> s'exprima ainsi:

> Hey everyone,
> 
> I'm hoping someone here can help me solve an odd problem (bug?). I'm having
> trouble with string encoding, object deletion, and the xml.etree library. If
> this isn't the right list to be posting this question, please let me know.
> I'm new to Python and don't know of any other "help me" Python mailing
> lists. I have tried debugging this ad-infinitem. Anyway, at the bottom of
> this e-mail you will find the code of a python file. This is a gross
> over-simplification of my code, with little exception handling so that the
> errors are obvious.
> 
> Running this interactively, if you finish off with 'del db', it exits fine
> and creates a skeleton xml file called 'db.xml' with text '<root />'.
> However, if you instead CTRL-D, it throws at exception while quitting and
> then leaves an empty 'db.xml' which won't work. Can anyone here help me
> figure out why this is?
> 
> Stuff I've done:
> I've traced this down to the self.commit() call in __del__. The stacktrace
> and a few print statements injected into xml.etree leads me to the call
> 'root'.encode('us-ascii') throwing a LookupError on line 751 of
> xml.etree.ElementTree. This makes no sense to me, since it works fine
> normally.
> 
> Thank you very much. Any and all help or pointers are appreciated.
> 
> ~Matt
> 
> #### db.py ###
> from xml.etree import ElementTree as ET
> import os
> 
> class Database(object):
>     def __init__(self, path):
>         self.__dbpath = path    ## Path to the database
>         self.load()
>     def __del__(self):
>         ## FIXME: Known bug:
>         ##  del db at command line works properly
>         ##  Ctrl-D, when there is no db file present, results in a
> LookupError
>         ##    and empty xml file
>         from StringIO import StringIO
>         from traceback import print_exc
>         trace = StringIO()
>         try:
>             print 5
>             self.commit()
>             print 7
>         except Exception:
>             print_exc(100, trace)
>             print trace.getvalue()
>     def load(self):
>         if os.path.exists(self.__dbpath):
>             self.root = ET.parse(self.__dbpath).getroot()
>         else:
>             self.root = ET.Element("root")
>     def commit(self):
>         ET.ElementTree(self.root).write(self.__dbpath)
> db = Database('db.xml')

Actually, it all runs well for me -- after the following modification:

    def __del__(self):
        ## FIXME: Known bug:
        ##  del db at command line works properly
        ##  Ctrl-D, when there is no db file present, results in a LookupError
        ##    and empty xml file
        try:
            print 5
            self.commit()
            print 7
        except Exception:
            raise

Notes:
* I don't know for what reason you needed such a complicated traceback construct.
* Before I did this modif, I indeed had a weird exception about stringIO.
* __del__() seems to do the contrary: it writes back to file through commit()???
* "del db" works fine, anyway
* When I run without any bd.xml, it properly creates one with text "<root />".
* When I run with an ampty db.xml, I have the following exception message:

Traceback (most recent call last):
  File "xmlTree.py", line 29, in <module>
    db = Database('db.xml')
  File "xmlTree.py", line 10, in __init__
    self.load()
  File "xmlTree.py", line 24, in load
    self.root = ET.parse(self.__dbpath).getroot()
  File "/usr/lib/python2.5/xml/etree/ElementTree.py", line 862, in parse
    tree.parse(source, parser)
  File "/usr/lib/python2.5/xml/etree/ElementTree.py", line 587, in parse
    self._root = parser.close()
  File "/usr/lib/python2.5/xml/etree/ElementTree.py", line 1254, in close
    self._parser.Parse("", 1) # end of data
xml.parsers.expat.ExpatError: no element found: line 2, column 0
5
Exception exceptions.AttributeError: AttributeError("'Database' object has no attribute 'root'",) in <bound method Database.__del__ of <__main__.Database object at 0xb7e78fec>> ignored

------
la vita e estrany


More information about the Tutor mailing list