Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElementTree TypeError "write() argument must be str, not bytes" in Python3

Got a Problem with generating a .SVG File with Python3 and ElementTree.

    from xml.etree import ElementTree as et
    doc = et.Element('svg', width='480', height='360', version='1.1', xmlns='http://www.w3.org/2000/svg')

    #Doing things with et and doc

    f = open('sample.svg', 'w')
    f.write('<?xml version=\"1.0\" standalone=\"no\"?>\n')
    f.write('<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n')
    f.write('\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n')
    f.write(et.tostring(doc))
    f.close()

The Function et.tostring(doc) generates the TypeError "write() argument must be str, not bytes". I don't understand that behavior, "et" should convert the ElementTree-Element into a string? It works in python2, but not in python3. What did i do wrong?

like image 535
Benny H. Avatar asked Feb 27 '17 07:02

Benny H.


4 Answers

As it turns out, tostring, despite its name, really does return an object whose type is bytes.

Stranger things have happened. Anyway, here's the proof:

>>> from xml.etree.ElementTree import ElementTree, tostring
>>> import xml.etree.ElementTree as ET
>>> element = ET.fromstring("<a></a>")
>>> type(tostring(element))
<class 'bytes'>

Silly, isn't it?

Fortunately you can do this:

>>> type(tostring(element, encoding="unicode"))
<class 'str'>

Yes, we all thought the ridiculousness of bytes and that ancient, forty-plus-year-old-and-obsolete encoding called ascii was dead.

And don't get me started on the fact that they call "unicode" an encoding!!!!!!!!!!!

like image 152
Ray Toal Avatar answered Oct 23 '22 07:10

Ray Toal


The output file should be in binary mode.

f = open('sample.svg', 'wb')
like image 29
Dominic Bett Avatar answered Oct 23 '22 05:10

Dominic Bett


Try:

f.write(et.tostring(doc).decode(encoding))

Example:

f.write(et.tostring(doc).decode("utf-8"))
like image 5
ShuzZzle Avatar answered Oct 23 '22 05:10

ShuzZzle


Specify encoding of string while writing the xml file.

Like decode(UTF-8) with write(). Example: file.write(etree.tostring(doc).decode(UTF-8))

like image 3
StewieGGriffin Avatar answered Oct 23 '22 05:10

StewieGGriffin