News for hackers. Stuff that matters.
Re:Moving Away from Python 2 by vetinari on Friday May 20, 2016 @03:05PM (#11740545)
> Python2 supports unicode. Chávez and Çelik are covered.

Most python2 code doesn't. It has a nice property of exploding spectacularly when the string you are writing out to console or file contains Chávez or Çelik.

Re:Moving Away from Python 2 by the_mitsuhiko on Friday May 20, 2016 @03:24PM (#11740691)
> Most python2 code doesn't.

Citation needed. I can't say I ever had practical issues with not being able to handle unicode on Python if I needed. No matter which library. Please give practical examples of where you cannot deal with unicode on Python 2.

Re:Moving Away from Python 2 by vetinari on Friday May 20, 2016 @04:16PM (#11741125)
just plain

    for line in yourfile:
        print line
with yourfile containing non-ascii characters and running it in windows console.
Re:Moving Away from Python 2 by colejohnson66 on Friday May 20, 2016 @06:28PM (#11742032)
That sounds like a limitation of the Windows console, not the programming language.
Re:Moving Away from Python 2 by comex on Friday May 20, 2016 @07:23PM (#11742308)
It's a limitation of how the programming language interacts with the Windows console, and it's a mistake. If you are writing potentially-garbled strings directly to the console, there is already no guarantee that the output will properly reflect the string or e.g. copying and pasting will work correctly, because the string could include backspace characters, or a ton of newlines. Therefore it doesn't make sense to do anything other than make a 'best effort' attempt when rendering strings to the console, including with Unicode handling. If it works, great, but if the string is invalid Unicode, that's only one of multiple problematic cases, so what exactly is throwing an exception supposed to accomplish? Python should use replacement characters by default in this case.
Re:Moving Away from Python 2 by rjurney on Friday May 20, 2016 @09:36PM (#11742741)
Stop using the Windows console. Or fix it. More rational than a breaking upgrade to Python 3.
Re:Moving Away from Python 2 by paulddraper on Friday May 20, 2016 @10:47PM (#11742954)
Fixing the Windows console rather than upgrading to Python 3 is the only sensible choice.

</s>

Re:Moving Away from Python 2 by Animats on Friday May 20, 2016 @10:46PM (#11742948)
It is, and Java has similar problems on Windows. The Windows console can be switched to Unicode, but by default, it emulates the IBM 5150 PC character set, circa 1980. It's not even ISO LATIN-1.

Works fine on Linux.

Re:Moving Away from Python 2 by the_mitsuhiko on Saturday May 21, 2016 @04:56AM (#11743876)
Windows console shpport is broken on python 3 too on many versions. Click the library can print unicode to the console on windows however. No python 3 needed.
Re:Moving Away from Python 2 by takeda on Saturday May 21, 2016 @01:20AM (#11743328)
> Citation needed.

I'm sorry to say, but your code for example. While I love your click library it has many small issues. Which annoy the heck out of me.

I would submit a patch but this is not a simple change and requires a bit of effort. Perhaps I'll find some time to work on it, but I'm afraid it might possibly break compatibility.

Re:Moving Away from Python 2 by the_mitsuhiko on Saturday May 21, 2016 @04:55AM (#11743867)
Can you talk specifics about what does not work? Because if there is an actual unicode problem in click i want to fix it.
Re:Moving Away from Python 2 by takeda on Monday May 23, 2016 @03:39AM (#11752455)
Would have to go over the rest of code, but the code in ClickException is broken:

    class ClickException(Exception):
        """An exception that Click can handle and show to the user."""

        #: The exit code for this exception
        exit_code = 1

        def __init__(self, message):
            ctor_msg = message
            if PY2:
                if ctor_msg is not None:
                    ctor_msg = ctor_msg.encode('utf-8')
            Exception.__init__(self, ctor_msg)
            self.message = message

        def format_message(self):
            return self.message

        def __unicode__(self):
            return self.message

        def __str__(self):
            return self.message.encode('utf-8')

        def show(self, file=None):
            if file is None:
                file = get_text_stderr()
            echo('Error: %s' % self.format_message(), file=file)
This code is arguably wrong. I think I understand what you were trying to do, but I'm not certain. There is a possibility to use it correctly in python 2 though, but many people might be not aware of it.

In python 3 you pass the message as is (it might cause another issue, but about that later).

In python 2 you immediately encode the passed variable using utf-8. This means that you're expecting argument to be of unicode type, but at the same time you're discouraging users to use unicode_literals, and in most situations users will pass a regular string.

In python 3 __str__ is trying to convert text to bytes, while the message would already be text. This most of the times will look correct, but it might spew garbage when there are non ascii characters.

Here's corrected code (did not test it though):

    if PY2:
      unicode = str

    class ClickException(Exception):
        """An exception that Click can handle and show to the user."""

        #: The exit code for this exception
        exit_code = 1

        def __init__(self, message):
            if PY2 and isinstance(self, unicode):
                message = message.encode()
            Exception.__init__(self, message)
            self.message = message

        def format_message(self):
            return self.message

        def __unicode__(self):
            return str(self).decode()

        def __str__(self):
            return str(self.message)

        def show(self, file=None):
            if file is None:
                file = get_text_stderr()
            echo('Error: %s' % self.format_message(), file=file)
There are few other things that gives headaches (not necessarily python 2 only).

In python 3 for example click refuses to run if LANG and LC_CTYPE are not defined. Why doesn't it simply do what all other applications are doing and simply fall back to latin-1 (ISO-8859-1) instead of printing the error.

Also, another issue (and my above code is also is affected by this). Click is checking for environmental variables before continuing, yet encode and decode have hardcoded utf-8. It probably should use whatever locale.getdefaultlocale() returns.

Re:Moving Away from Python 2 by mark-r on Friday May 20, 2016 @03:42PM (#11740850)
Yes, it will explode if you try to write a Unicode string to something that doesn't have UTF-8 encoding by default. But it won't explode if you write byte strings, or if your default encoding is UTF-8.
Re:Moving Away from Python 2 by vetinari on Friday May 20, 2016 @04:20PM (#11741150)
Windows console is that case which doesn't default to UTF-8. At the time when I was working with it, py2 defaulted to ascii.

For some locales Windows has additional bonus, the Ansi (GUI) encoding is different than OEM (console) and it was heroic undertaking to make your program work correctly for both.

Python3 works out of the box.

Re:Moving Away from Python 2 by mark-r on Friday May 20, 2016 @04:57PM (#11741459)
I can sympathize, Windows is my environment too. But I'm not blind to other environments where some simplifying assumptions can be made.

For true insanity try adding IDLE to the mix. IDLE under Windows in Python 2 will let you output UTF-8, but won't accept it as input. Python 3 is more consistent.