<div dir="ltr">I don't really understand what you're doing when you take a fragment of my sentence where I explain a wrong understanding of WHATWG encodings, and say "that's wrong, as you explain". I know it's wrong. That's what I was saying.<div><br></div><div>You quoted the part where I said "Filling in all the gaps with Latin-1", cut out the part where I said "is wrong", and replied with "that's wrong". I guess I'm glad we're in agreement, but this has been a strange bit of discourse.<br><div><br></div><div>In this pseudocode that implements a "whatwg_error_mode", can you describe what the Python code to call it would look like? Does every call to .encode and .decode now have a "whatwg_error_mode" parameter, in addition to the "errors" parameter? Or are there twice as many possible strings you could pass as the "errors" parameter, so you can have "replace", "replace-whatwg", "surrogateescape", "surrogateescape-whatwg", etc?</div><div><br></div><div>My objection here isn't efficiency, it's adding confusing extra options to .encode() and .decode() that aren't relevant in most cases.</div><div><br></div><div>I'd like to limit this proposal to single-byte encodings, addressing the discrepancies in the C1 characters and possibly that Hebrew vowel point. If there are differences in the JIS encodings, that is a can of worms I'd like to not open at the moment.</div><div><br></div><div>-- Rob Speer</div><div><br></div><div><div class="gmail_quote"><div dir="ltr">On Mon, 22 Jan 2018 at 01:43 Stephen J. Turnbull <<a href="mailto:turnbull.stephen.fw@u.tsukuba.ac.jp">turnbull.stephen.fw@u.tsukuba.ac.jp</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I don't expect to change your mind about the "right" way to deal with<br>
this, but this is a more explicit description of what those of us who<br>
advocate error handlers are thinking about.  It may be useful in<br>
writing your PEP (PEPs describe rejected counterproposals and<br>
amendments along with adopted proposals and rationale in either case).<br>
<br>
Rob Speer writes:<br>
<br>
 > > The question to my mind is whether or not this "latin1replace" handler,<br>
 > > in conjunction with existing codecs, will do the same thing as the<br>
 > > WHATWG codecs. If I have understood you correctly, I think it will. Have<br>
 > > I missed something?<br>
 ><br>
 > It won't do the same thing, and neither will the "chaining coders"<br>
 > proposal.<br>
<br>
The "chaining coders" proposal isn't well-enough specified to be sure.<br>
<br>
However, for practical purposes you may think of a Python *codec* as a<br>
"whole array" decoder/encoder, and an *error handler* as a "token-by-<br>
token" decoder/encoder.  The distinction in type is for efficiency, of<br>
course.  Codecs can't be "chained" (I think, but I didn't think very<br>
hard), but handlers can, in the sense that each handler can handle<br>
some input values and delegate anything it can't deal with to the next<br>
handler in the chain (under the hood handler implementationss are just<br>
Python functions with a particular signature, so this is just "loop<br>
until non-None").<br>
<br>
 > It's easy to miss details like this in all the counterproposals.<br>
<br>
I see no reason why a 'whatwgreplace' error handler with the logic<br>
<br>
    # I am assuming decoding, and single-byte encodings.  Encoding<br>
    # with 'html' error mode would insert format("&#%d;", ord(unicode)).<br>
    # Multibyte is a little harder.<br>
<br>
    # ASCII bytes never error except maybe in UTF16, UTF32, Shift JIS<br>
    # and Big5.<br>
    assert the_byte >= 0x80<br>
    # Handle C1 control characters.<br>
    if the_byte < 0xA0:<br>
        append_to_output(chr(the_byte))<br>
    # Handle extended repertoire with a dict.<br>
    # This condition will depend on the particular codec.<br>
    elif the_byte in additional_code_points:<br>
        append_to_output(additional_code_points[the_byte])<br>
    # Implement WHATWG error modes.<br>
    elif whatwg_error_mode is replacement:<br>
        append_to_output("\uFFFD")<br>
    else:<br>
        raise<br>
<br>
doesn't have the effect you want.  This can be done in pure Python.<br>
(Note: The actions in the pseudocode are not accurate.  IIRC real<br>
handlers take a UnicodeError as argument, and return a tuple of the<br>
text to append to output and number of input tokens to skip, or<br>
return None to indicate an unhandled error, rather than doing the<br>
appending and raising themselves.)<br>
<br>
The main objection to doing it this way would be efficiency.  To be<br>
honest, I personally don't think that's an important objection since<br>
this handler is frequently invoked only if the source text is badly<br>
broken.  (Remember, you'll already be greatly expanding the repertoire<br>
of at least ASCII and ISO 8859/1 by promoting to windows-1252.)  And<br>
it would surely be "fast enough" if written in C.<br>
<br>
Caveat: I'm not sure I agree with MAL about windows-1255.  I think<br>
it's arguable that the WHAT-WG index is a better approximation to<br>
reality, and I'd like to hear Hebrew speakers argue about that (I'm<br>
not one).<br>
<br>
 > The difference between WHATWG encodings and the ones in Python is,<br>
 > in all but one case, *only* in the C1 control character range (0x80<br>
 > to 0x9F),<br>
<br>
Also in Japanese, where "corporate characters" have been added<br>
(frequently twice, preventing round-tripping ... yuck) to the JIS<br>
standard.  I haven't checked the Chinese and Korean tables for similar<br>
damage, but they're not quite as wacky about this stuff as the JISC<br>
is, so they're probably OK (and of course Big5 was "corporate" from<br>
the get-go).<br>
<br>
 > a range of Unicode characters that has historically evaded<br>
 > standardization because they never had a clear purpose even before<br>
 > Unicode.  Filling in all the gaps with Latin-1<br>
<br>
That's wrong, as you explain:<br>
<br>
 > [Eg, in Greek, some code points] are simply unassigned. Other<br>
 > software sometimes maps them to the Private Use Area, but this is<br>
 > not standardized at all, and it seems clear that Python should<br>
 > handle them with its usual error handler for unassigned<br>
 > bytes. (Which is one of the reasons not to replace the error<br>
 > handler with something different: we still need the error handler.)<br>
<br>
The logic above handles all this.  As mentioned, a stdlib error<br>
handler ('strict', 'replace', or 'xmlcharrefreplace' for WHAT-WG<br>
conformance, or 'surrogatereplace' for the Pythonic equivalent of<br>
mapping to the private area) could be chained if desired, and the<br>
defaults could be changed and the names aliased to the WHAT-WG terms.<br>
<br>
This could be automated with a factory function that takes a list of<br>
predefined handlers and composes them, although that would add another<br>
layer of inefficiency (the composition would presumably be done in a<br>
loop, and possibly using try although I think the error handler<br>
convention is to return the text to insert if handled, and None if the<br>
error can't be handled).<br>
<br>
Steve<br>
<br>
</blockquote></div></div></div></div>