Issue 13633: Automatically convert character references in HTMLParser (original) (raw)
Created on 2011-12-19 06:55 by ezio.melotti, last changed 2022-04-11 14:57 by admin. This issue is now closed.
Messages (8)
Author: Ezio Melotti (ezio.melotti) *
Date: 2011-12-19 06:55
The doc for handle_charref and handle_entityref say: """ HTMLParser.handle_charref(name) This method is called to process a character reference of the form "&#ref;". It is intended to be overridden by a derived class; the base class implementation does nothing.
HTMLParser.handle_entityref(name) This method is called to process a general entity reference of the form "&name;" where name is an general entity reference. It is intended to be overridden by a derived class; the base class implementation does nothing. """
The doc doesn't mention hex references, like ">", and apparently they are passed to handle_charref without the '&#' but with the leading 'x':
from HTMLParser import HTMLParser class MyParser(HTMLParser): ... def handle_charref(self, data): ... print data ... MyParser().feed('> > >') 62 x3E
I've seen code in the wild doing unichr(int(data)) in handle_charref (once they figured out that '62' is passed) and then fail when an hex entity is found. Passing 'x3E' doesn't seem too useful because the user has to first check if there's a leading 'x', if there is remove it, then convert the hex string to int, and finally use unichr() to get the char, otherwise just convert to int and use unichr().
There 3 different possible solutions:
- just document the behavior;
- normalize the hex value before passing them to handle_charref and document it;
- add a new handle_entity method that is called with the character represented by the entity (named, decimal, or hex);
The first solution alone doesn't solve much, but the doc should be clearer regardless of the decision we take. The second one is better, but if it's implemented there won't be any way to know if the entity had a decimal or hex value anymore (does anyone care?). The normalization should also convert the hex string to int and then convert it back to str to be consistent with decimal entities. The third one might be better, but doesn't solve the issue on 2.7/3.2. People don't care about entities and just want the equivalent char, so having a method that converts them already sounds like a useful feature to me.
Author: Ezio Melotti (ezio.melotti) *
Date: 2012-02-23 02:38
This behavior is now documented, but the situation could still be improved. Adding a new method that receives the converted entity seems a good way to handle this. The parser can call both, and users can pick either one.
One problem with the current methods (handle_charref and handle_entityref) is that they don't do any processing on the entity and let invalid character references like � or &#iamnotanentity; go through.
There are at least 3 changes that should be done in order to follow the HTML5 standard 0:
- the parser should look at html.entities while parsing named character references (see also #11113). This will allow the parser to parse ¬it; as "¬it;" and ∉ as "∉" (see note at the very end of 0);
- invalid character references (e.g. �, &#iamnotanentity;) should not go through;
- the table at 0 with the replacement character should be used by the parser to "correct" those invalid character references (e.g. 0x80 -> U+20AC);
Now, 1) can be done for both the old and new method, but for 2) and 3) the situation is a bit more complicated. The best thing is probably to keep sending them unchanged to the old methods, and implement the correct behavior for the new method only.
Author: Ezio Melotti (ezio.melotti) *
Date: 2013-05-01 13:24
Another option is to add a new "convert_entities" option that, when True, automatically converts character references and doesn't call handle_charref and handle_entityref. (See also #17802.)
Author: Ezio Melotti (ezio.melotti) *
Date: 2013-11-20 18:46
Here is a patch. It might be also be a good idea to add warning when the option is not explicitly set to False, and change the default to True in 3.5/3.6.
Author: Serhiy Storchaka (serhiy.storchaka) *
Date: 2013-11-22 19:01
I have added a couple of nitpicks on Rietveld. You can ignore most of them. ;)
Author: Ezio Melotti (ezio.melotti) *
Date: 2013-11-23 15:44
New patch attached.
Author: Roundup Robot (python-dev)
Date: 2013-11-23 17:52
New changeset 1575f2dd08c4 by Ezio Melotti in branch 'default': #13633: Added a new convert_charrefs keyword arg to HTMLParser that, when True, automatically converts all character references. http://hg.python.org/cpython/rev/1575f2dd08c4
Author: Ezio Melotti (ezio.melotti) *
Date: 2013-11-23 18:17
Fixed, thanks for the reviews!
History
Date
User
Action
Args
2022-04-11 14:57:24
admin
set
github: 57842
2013-11-23 18:17:29
ezio.melotti
set
status: open -> closed
resolution: fixed
messages: +
stage: commit review -> resolved
2013-11-23 17:52:19
python-dev
set
nosy: + python-dev
messages: +
2013-11-23 15:44:25
ezio.melotti
set
files: + issue13633-2.diff
messages: +
stage: patch review -> commit review
2013-11-22 19:01:38
serhiy.storchaka
set
messages: +
2013-11-20 21:44:03
eli.bendersky
set
nosy: - eli.bendersky
2013-11-20 19:17:37
ezio.melotti
set
title: Handling of hex character references in HTMLParser.handle_charref -> Automatically convert character references in HTMLParser
2013-11-20 18:46:21
ezio.melotti
set
files: + issue13633.diff
nosy: + serhiy.storchaka
messages: +
keywords: + patch
stage: test needed -> patch review
2013-11-18 10:40:10
ezio.melotti
set
dependencies: + expose html.parser.unescape
2013-11-17 02:37:38
ezio.melotti
set
nosy: + r.david.murray, eli.bendersky
2013-05-01 13:24:37
ezio.melotti
set
messages: +
2012-10-06 03:38:58
ezio.melotti
set
versions: + Python 3.4, - Python 2.7, Python 3.2, Python 3.3
2012-02-23 02:38:49
ezio.melotti
set
dependencies: + html.entities mapping dicts need updating?
messages: +
2011-12-19 06:55:56
ezio.melotti
create