Can no longer feed a file to gpxpy.parse() in Python 3 / Django 2.2
Closed this issue · 5 comments
Hi,
In a site we built using Django 1.11 and Python 2.7 the following would work:
try:
gpx_data = gpxpy.parse(gpx_file)
except GPXException:
raise ValidationError(_('Invalid GPX file.'))
(where gpx_file is from a django FileField)
After upgrading to Python 3 and Django 2 the above does not work anymore, resulting in a gpxpy.gpx.GPXXMLSyntaxException: Error parsing XML: Start tag expected, '<' not found, line 1, column 1
A workaround is:
try:
gpx_string = str(gpx_file.read().decode())
gpx_data = gpxpy.parse(gpx_string)
except GPXException:
raise ValidationError(_('Invalid GPX file.'))
That's an error from an underlying XML parses. Can you provide the GPX file, and is it possible that(as the error says) <
isn't found on line 1 column 1?
Update: Ignore ^. Somehow I overlooked your workaround. Anyway, yes, that workaround should probably be part of the parse()
function. If somebody is willing to implement it I'll merge the PR.
I thought a bit more about this, and I think I'll close this issue for now. Because, from inside gpxpy
it's totally not clear why (and when) should I call .decode()
if it's available after .read()
. I understand it fixes a problem for FileField
s from Django. But it works for normal file IO objects.
I agree with you that it's an issue, but I'm not 100% sure it should be fixed inside gpxpy. The argument in parse()
must be a string or a file (the arg is named xml_or_file
). If there is a way to reproduce it with GPX files and normal file-like objects, I'll add this fix.
This bug bit me on Pyramid's file upload. The fix is very simple though, run decode()
if the type is bytes
, but not when it is string
.
I don't know how to make it compatible with 2.7, but in py3 this would be a straightforward fix.
@hyperknot fixed now in 1672f15 (still in dev
but I'll merge/release it after more testing)