You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If you look at the file, you'll find that the data is in utf-8 (at least if your locale is a utf-8 locale). However, html is by default interpreted as latin-1, so that's what the webrowser displays when you pass the file on disk to it. If you add "encoding='latin-1'" to your open call, your script will work. What you do if you need to display non-latin1 characters, I don't know. (See https://bugzil.la/760050, for example).
Note: the above is for python3. I don't remember how you do the equivalent in python2...a naive codecs.open call just got me a UnicodeDecodeError.
If you cannot offer a solution for arbitrary unicode, you have no solution at all. Afer all, that is what unicode is about: support ALL languages, not only your own.
I do not quite understand why you think this is not a bug.
For Python3, the fix is actually very simple: Do not write doc but str(doc.encode('ascii', 'xmlcharrefreplace')), like in the attached patch. This patch works for me but there might be yet uncovered code paths. And my source file is encoded in utf-8, other source file encodings should be tested too. I do not know if cgitb correctly honors the source file header like # -- coding: utf-8 --
Fixing this for Python2 is certainly doable too but perhaps more difficult because a Python2 str() may have an unknown encoding.
What about
open(..., encoding='latin-1', errors='xmlcharrefreplace')
wrohdewald commented on Oct 28, 2014
wrohdewaldmannequin
MannequinAuthor
More actions
What about
open(..., encoding='latin-1', errors='xmlcharrefreplace')
That works fine. I tested with a chinese character 与
But I do not think the application should work around something that cgitb is supposed to handle. More so since the documentation is dead silent about this. You need to use codecs.open instead of open and add those kw arguments. As long as this is not explained in the documentation, I guess it is a bug for everyone not using latin-1.
wrohdewald commented on Oct 28, 2014
wrohdewaldmannequin
MannequinAuthor
More actions
correction: A bug for everyone using non-ascii characters.
In normal HTML utf-8 works fine, doesn't it?. It's only when reading from a file (where the browser doesn't know the encoding) that it fails. Do you have a use case for xmlcharrefreplace in the HTML context (which is what cgitb is primarily targeted at). Some place where the web page can't be declared as utf-8, perhaps?
I suppose it might be a not-unreasonable enhancement request to have a parameter to Hook that says "do xmlcharrefreplace", but since the workaround is actually simpler than that, I don't know if that is worthwhile or not. Or do people feel like doing the replacement all the time (it's only in tracebacks, after all) be the right thing to do?
wrohdewald commented on Oct 28, 2014
wrohdewaldmannequin
MannequinAuthor
More actions
> You need to use codecs.open instead of open
No, why? in python3 open() supports the errors handler.
right, but not in python2 which has the same problem. I need my code to run with both.
Do you have a use case for xmlcharrefreplace in the HTML context?
It does, in fact as long as the encoding used by the browser matches the one used in the file, no charrefs needs to be used (except > < and "). Of course, if non-Unicode encodings are used, the range of available characters that can go directly in the HTML will be more limited, but this can be solved by using charrefs -- the browser will display the corresponding character no matter what is the encoding. This also means that if charrefs are used for all non-ASCII characters, then the browser will be able to display the page no matter what encoding is being used (as long as it's ASCII-compatible, and most encoding are). The downside is that it will make the source less readable and possible longer, especially if there are lot of non-ASCII characters, but if most of the characters are expected to be ASCII, using charrefs might be ok.
We can convert cgitb.hook to produce ASCII-compatible output with charrefs in 3.x. But there is a problem with str in 2.7. 8-bit string can contain non-ASCII data and the encoding is not known in general case.
Activity
wrohdewald commentedon Oct 27, 2014
The attached script shows the non-ascii characters wrong wherever they occur, including the exception message and the comment in the source code.
Looking at the produced .html, I can say that cgitb simply passes the single byte utf-8 codes without encoding them as needed.
Same happens with Python3.4 (after applying some quick and dirty changes to cgitb.py, see bug bpo-22745).
bitdancer commentedon Oct 27, 2014
If you look at the file, you'll find that the data is in utf-8 (at least if your locale is a utf-8 locale). However, html is by default interpreted as latin-1, so that's what the webrowser displays when you pass the file on disk to it. If you add "encoding='latin-1'" to your open call, your script will work. What you do if you need to display non-latin1 characters, I don't know. (See https://bugzil.la/760050, for example).
Note: the above is for python3. I don't remember how you do the equivalent in python2...a naive codecs.open call just got me a UnicodeDecodeError.
wrohdewald commentedon Oct 28, 2014
If you cannot offer a solution for arbitrary unicode, you have no solution at all. Afer all, that is what unicode is about: support ALL languages, not only your own.
I do not quite understand why you think this is not a bug.
If cgitb encodes unicode like & x e 4 ; (remove spaces), the browser does not have to guess the encoding, it will always show the correct character. This works for all of unicode. See https://en.wikipedia.org/wiki/Unicode_and_HTML#Numeric_character_references
So this bug is fixable, I am reopening it.
For Python3, the fix is actually very simple: Do not write doc but str(doc.encode('ascii', 'xmlcharrefreplace')), like in the attached patch. This patch works for me but there might be yet uncovered code paths. And my source file is encoded in utf-8, other source file encodings should be tested too. I do not know if cgitb correctly honors the source file header like # -- coding: utf-8 --
Fixing this for Python2 is certainly doable too but perhaps more difficult because a Python2 str() may have an unknown encoding.
amauryfa commentedon Oct 28, 2014
What about
open(..., encoding='latin-1', errors='xmlcharrefreplace')
wrohdewald commentedon Oct 28, 2014
That works fine. I tested with a chinese character 与
But I do not think the application should work around something that cgitb is supposed to handle. More so since the documentation is dead silent about this. You need to use codecs.open instead of open and add those kw arguments. As long as this is not explained in the documentation, I guess it is a bug for everyone not using latin-1.
wrohdewald commentedon Oct 28, 2014
correction: A bug for everyone using non-ascii characters.
amauryfa commentedon Oct 28, 2014
bitdancer commentedon Oct 28, 2014
In normal HTML utf-8 works fine, doesn't it?. It's only when reading from a file (where the browser doesn't know the encoding) that it fails. Do you have a use case for xmlcharrefreplace in the HTML context (which is what cgitb is primarily targeted at). Some place where the web page can't be declared as utf-8, perhaps?
I suppose it might be a not-unreasonable enhancement request to have a parameter to Hook that says "do xmlcharrefreplace", but since the workaround is actually simpler than that, I don't know if that is worthwhile or not. Or do people feel like doing the replacement all the time (it's only in tracebacks, after all) be the right thing to do?
wrohdewald commentedon Oct 28, 2014
right, but not in python2 which has the same problem. I need my code to run with both.
No, my only use case is the local file.
ezio-melotti commentedon Oct 31, 2014
It does, in fact as long as the encoding used by the browser matches the one used in the file, no charrefs needs to be used (except > < and "). Of course, if non-Unicode encodings are used, the range of available characters that can go directly in the HTML will be more limited, but this can be solved by using charrefs -- the browser will display the corresponding character no matter what is the encoding. This also means that if charrefs are used for all non-ASCII characters, then the browser will be able to display the page no matter what encoding is being used (as long as it's ASCII-compatible, and most encoding are). The downside is that it will make the source less readable and possible longer, especially if there are lot of non-ASCII characters, but if most of the characters are expected to be ASCII, using charrefs might be ok.
serhiy-storchaka commentedon Dec 3, 2014
We can convert cgitb.hook to produce ASCII-compatible output with charrefs in 3.x. But there is a problem with str in 2.7. 8-bit string can contain non-ASCII data and the encoding is not known in general case.
hugovk commentedon Apr 11, 2022
I think we can close this? The cgitb module is deprecated in 3.11 and set for removal in 3.13.
See PEP 594 – Removing dead batteries from the standard library, #91217 and #32410.
AlexWaygood commentedon Apr 12, 2022
Cc. @amauryfa, @wrohdewald