I have a small test page for Brython related tests and recently added xml.etree.Elementree module there, but it doesn't work for some reason.
I've following code (actually there is more stuff but I removed the irrelevant parts):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" href="/js/jquery-ui-1.12.1/jquery-ui.min.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/js/jquery-ui-1.12.1/jquery-ui.structure.min.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/layout.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/visual.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/js/jquery-ui-1.12.1/jquery-ui.theme.min.css" media="screen" />
<script rel="script" type="text/javascript" src="/js/jquery-3.1.1.min.js"></script>
<script rel="script" type="text/javascript" src="/js/jquery-ui-1.12.1/jquery-ui.min.js"></script>
<script rel="script" type="text/javascript" src="/js/brython/brython.js"></script>
<script rel="script" type="text/javascript" src="/js/brython/brython_stdlib.js"></script>
</head>
<body onload='brython()'>
<script type="text/python" charset="utf-8">
import sys
from browser import alert, document as docu
from browser import ajax
from xml.etree import ElementTree as ET
def ajaxReceive(req):
alert("Input value: " + docu["numinput"].value)
alert('Ajax response: \n %s' % req.text )
if req.status == 200 or req.status == 0:
d = docu['messagebox']
d.clear()
r = ET.fromstring(req.text)
#n = r.findall('./person/name')
#a = r.findall('./person/age')
#d.text = 'Dude %s is %s old.' % (n,a)
else:
docu['messagebox'] <= 'error: ' + req.text
def ajaxSend():
req = ajax.ajax()
url = '/bryt/'
x = 1
y = 2
z = docu['numinput']
req.open('POST', url, True)
req.bind('complete', ajaxReceive)
req.set_header('content-type', 'application/x-www-form-urlencoded' )
req.send( {
'action': 'calc',
'x': x,
'y': y,
'z': z.value
})
docu['ajaxbutton'].bind('click', ajaxSend )
d = docu['messagebox']
d.clear()
d.text = 'ready'
</script>
<div id='messagebox' style='width: 20%; border: 1px solid gray; padding: 2em;' >
</div>
<br/>
<input id="numinput" / >
<br/>
<br/>
<button id='ajaxbutton' >Ajax run</button>
</body>
</html>
And at server side it only adds up 3 to given number. The problem is XML-formatted Ajax-response that is being received. It comes in in clear XML, but even building a etree root-element by calling .fromstring() funtion, it tracebacks as follows:
Error 500 means that Python module pyexpat was not found at url http://example.com/bryt/pyexpat.py
brython.js:7171:1
Error 500 means that Python module pyexpat was not found at url http://example.com/bryt/pyexpat/__init__.py
brython.js:7171:1
Error 500 means that Python module pyexpat was not found at url http://example.com/js/brython/Lib/site-packages/pyexpat.py
brython.js:7171:1
Error 500 means that Python module pyexpat was not found at url http://example.com/js/brython/Lib/site-packages/pyexpat/__init__.py
brython.js:7171:1
Error for module xml.parsers.expat
brython.js:7242:21
Error:
Stack trace:
_b_.ImportError.$factory@http://example.com/js/brython/brython.js line 6466 > eval:49:371
import_hooks@http://example.com/js/brython/brython.js:11605:7
$B.$__import__@http://example.com/js/brython/brython.js:7430:33
$B.$import@http://example.com/js/brython/brython.js:7460:43
$module<@http://example.com/js/brython/brython.js line 7242 > eval:14:9
@http://example.com/js/brython/brython.js line 7242 > eval:1:16
run_py@http://example.com/js/brython/brython.js:7242:1
exec_module@http://example.com/js/brython/brython.js:7276:1
cl_method@http://example.com/js/brython/brython.js:4729:43
import_hooks@http://example.com/js/brython/brython.js:11629:5
$B.$__import__@http://example.com/js/brython/brython.js:7430:33
$B.$import@http://example.com/js/brython/brython.js:7473:5
__init__205@http://example.com/js/brython/brython.js line 7242 > eval:5653:25
type.__call__@http://example.com/js/brython/brython.js:4674:20
factory@http://example.com/js/brython/brython.js:4741:47
XML194@http://example.com/js/brython/brython.js line 7242 > eval:5190:41
ajaxReceive3@http://example.com/js/brython/brython.js line 4294 > eval:176:32
@http://example.com/js/brython/brython.js line 7188 > eval:69:24
ajax.$factory/xmlhttp.onreadystatechange@http://example.com/js/brython/brython.js line 7188 > eval:161:13
brython.js:7243:1
16:21:17.002 args
Array [ "No module named pyexpat" ]
And there has been something similar in the past brython issue 613 where Pierre states that there is no such thing as pure python pyexpat (July 2017). However Brython standard distribution lists Lib/xml/etree and expat.py - does it mean that it's still not available?
Brython Lib/xml/etreeElementTree.py lines 1511 and onwards starts with:
class XMLParser:
def __init__(self, html=0, target=None, encoding=None):
try:
from xml.parsers import expat
except ImportError:
try:
import pyexpat as expat
except ImportError:
raise ImportError(
"No module named expat; use SimpleXMLTreeBuilder instead"
)
In my understanding it should succeed in first import from xml.parsers import expat but apparently it doesn't when it tries to pyexpat version that does not exist.
So, the question is, has anyone else stumbled into same problem and/or does anyone have a solution for this?
Some addtional (next day) observations:
Cloning and checking out a tag, building from the git repository does not really work as you would expect (no pun intentended).
% git clone https://github.com/brython-dev/brython.git brython.git
% cd brython.git/scripts
brython.git/scripts% python3 ./make_dist.py
/usr/bin
Traceback (most recent call last):
File "./make_dist.py", line 207, in <module>
run()
File "./make_dist.py", line 88, in run
import make_stdlib_list
File "brython.git/scripts/make_stdlib_list.py", line 53, in <module>
with open(os.path.join(static_doc_folder,lang,'stdlib.html'), 'w', encoding="utf-8") as out:
FileNotFoundError: [Errno 2] No such file or directory: 'brython.git/www/static_doc/en/stdlib.html'
brython.git%
That is caused by missing directories:
brython.git/scripts% mkdir -p ../www/static_doc/{en,es,fr}
brython.git/scripts% python3 ./make_dist.py
Very last build lines were:
adding xml.etree
adding xml.etree.cElementTree
adding xml.parsers
adding xml.parsers.expat
adding xml.sax
So maybe those are included.
Once targets are created, they (apparently, not really sure) appear into brython.git/setup/data directory, release zip files and naked .js files for live website. So I link into that directory in my Apache httpd webroot. But that building did not solve the traceback problem.
As side note, for an old OpenSource fart as myself, I feel very alien in this source tree, this project is done in Mouse camp (Microsoft Windows) and even one rare Makefile I managed to find, does not work with GNU Make because conflicting use of whitespace. Let alone there would be regular INSTALL, README, setup, Makefile etc files with expected content. I'm literally reading sources and guessing how all this is supposed to work. But I guess that only tells that Python is truely a cross platform language.
As being an "Open Source project", it's funny that its discussion is not for everyone: Your application to join the Google group brython has been refused
Well, digging deeper and it appears that Lib/xml/parses/expat.py contains:
"""Interface to the Expat non-validating XML parser."""
import sys
from pyexpat import *
# provide pyexpat submodules as xml.parsers.expat submodules
sys.modules['xml.parsers.expat.model'] = model
sys.modules['xml.parsers.expat.errors'] = errors
I tried to comment that pyexpat part and rebuild the pkgs, the traceback is now different. So there is no expat, no pyexpat and no ElementTree then. No XML in Ajax responses then.