classification
Title: LC_CTYPE=C: pydoc leaves terminal in an unusable state
Type: behavior Stage:
Components: Versions: Python 3.5, Python 3.4
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: haypo, matrixise, python-dev, r.david.murray, skrah
Priority: normal Keywords: patch

Created on 2014-04-30 11:33 by skrah, last changed 2014-05-13 00:08 by haypo. This issue is now closed.

Files
File name Uploaded Description Edit
pydoc_encoding.patch haypo, 2014-05-02 19:39 review
Messages (16)
msg217604 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-04-30 11:33
$ ./python -m pydoc heapq

Traceback (most recent call last):
  File "/home/stefan/hg/cpython/Lib/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/home/stefan/hg/cpython/Lib/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/stefan/hg/cpython/Lib/pydoc.py", line 2615, in <module>
    cli()
  File "/home/stefan/hg/cpython/Lib/pydoc.py", line 2580, in cli
    help.help(arg)
  File "/home/stefan/hg/cpython/Lib/pydoc.py", line 1862, in help
    elif request: doc(request, 'Help on %s:', output=self._output)
  File "/home/stefan/hg/cpython/Lib/pydoc.py", line 1600, in doc
    pager(render_doc(thing, title, forceload))
  File "/home/stefan/hg/cpython/Lib/pydoc.py", line 1408, in pager
    pager(text)
  File "/home/stefan/hg/cpython/Lib/pydoc.py", line 1422, in <lambda>
    return lambda text: pipepager(text, os.environ['PAGER'])
  File "/home/stefan/hg/cpython/Lib/pydoc.py", line 1449, in pipepager
    pipe.write(text)
UnicodeEncodeError: 'ascii' codec can't encode character '\xe7' in position 3574: ordinal not in range(128)

$ stty sane
$ locale      
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=C
msg217607 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-04-30 12:22
Works fine for me.
msg217608 - (view) Author: Stéphane Wirtel (matrixise) * Date: 2014-04-30 12:28
the pydoc module works fine but when I use CTRL-C to quit it, I get this error in the terminal.

I think it's an other bug but the traceback is really similar.

Stephane

Traceback (most recent call last):
  File "/Users/stephane/src/projects/externals/cpython/Lib/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/Users/stephane/src/projects/externals/cpython/Lib/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/stephane/src/projects/externals/cpython/Lib/pydoc.py", line 2615, in <module>
    cli()
  File "/Users/stephane/src/projects/externals/cpython/Lib/pydoc.py", line 2580, in cli
    help.help(arg)
  File "/Users/stephane/src/projects/externals/cpython/Lib/pydoc.py", line 1862, in help
    elif request: doc(request, 'Help on %s:', output=self._output)
  File "/Users/stephane/src/projects/externals/cpython/Lib/pydoc.py", line 1600, in doc
    pager(render_doc(thing, title, forceload))
  File "/Users/stephane/src/projects/externals/cpython/Lib/pydoc.py", line 1408, in pager
    pager(text)
  File "/Users/stephane/src/projects/externals/cpython/Lib/pydoc.py", line 1428, in <lambda>
    return lambda text: pipepager(text, 'less')
  File "/Users/stephane/src/projects/externals/cpython/Lib/pydoc.py", line 1450, in pipepager
    pipe.close()
  File "/Users/stephane/src/projects/externals/cpython/Lib/os.py", line 957, in close
    returncode = self._proc.wait()
  File "/Users/stephane/src/projects/externals/cpython/Lib/subprocess.py", line 1581, in wait
    (pid, sts) = self._try_wait(0)
  File "/Users/stephane/src/projects/externals/cpython/Lib/subprocess.py", line 1529, in _try_wait
    (pid, sts) = _eintr_retry_call(os.waitpid, self.pid, wait_flags)
  File "/Users/stephane/src/projects/externals/cpython/Lib/subprocess.py", line 502, in _eintr_retry_call
    return func(*args)
KeyboardInterrupt
msg217609 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-04-30 12:30
Did you use the same locale settings?
msg217611 - (view) Author: Stéphane Wirtel (matrixise) * Date: 2014-04-30 12:32
> locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
msg217612 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-04-30 12:37
Sorry, then I should have been more explicit:  The failure only occurs
with LC_CTYPE=C.
msg217613 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-04-30 12:39
Ah, yes, my lc_ctype was en_US.utf-8.  I can reproduce it if I change that.
msg217614 - (view) Author: Stéphane Wirtel (matrixise) * Date: 2014-04-30 12:43
I use OSX 10.9 on my laptop, Python 3.5 and I get this error in one case. If I use CTRL-C to quit the application and if LC_CTYPE=C.

with the 'q' key, I don't get this problem.

Just LC_CTYPE=C and CTRL-C and I have to reset my terminal.
msg217615 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-04-30 12:53
I can also confirm the need to reset the terminal when using
a working locale and Ctrl-C.

So we have two issues then:

   1) The UnicodeDecodeError should not happen.

   2) pydoc behaves erratically after various exceptions.


In Python2.7 neither of the issues is present.
msg217618 - (view) Author: Stéphane Wirtel (matrixise) * Date: 2014-04-30 12:59
In python 2.7, If I use my working locales (utf-8) and I use CTRL-C, pydoc does not quit but leave a message when the screen is cleaned.

same result with LC_CTYPE=C

bash-4.3$ python -m pydoc heapq
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.py", line 2359, in <module>
    if __name__ == '__main__': cli()
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.py", line 2328, in cli
    help.help(arg)
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.py", line 1793, in help
    elif request: doc(request, 'Help on %s:')
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.py", line 1532, in doc
    pager(render_doc(thing, title, forceload))
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.py", line 1337, in pager
    pager(text)
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.py", line 1357, in <lambda>
    return lambda text: pipepager(text, 'less')
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pydoc.py", line 1379, in pipepager
    pipe.close()
KeyboardInterrupt
bash-4.3$
msg217779 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-05-02 19:39
heapq documentation contains "François" which is not encodable to ASCII. When using LC_ALL=C, the locale encoding is ASCII (at least on Linux). It's not easy to specify a different error handler globally in pydoc, different functions are used and child processes are spawned. The subprocess module doesn't allow to specify an error handler different than strict (see #6135).

I propose pydoc_encoding.patch which escapes manually non-encodable characters. I chose sys.getfilesystemencoding(), I'm not sure that it's the encoding used for all cases of getpager() on all platforms. For example, on Windows, sys.getfilesystemencoding() is the ANSI code page, whereas sys.stdout.encoding is the OEM code page.
msg217780 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-05-02 19:46
"LC_CTYPE=C:  pydoc leaves terminal in an unusable state"

In the use case, pydoc doesn't touch the terminal, it's the pager: the program "less". I don't see how to ensure that the terminal state is restored, even on error.
msg217784 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-05-02 20:10
STINNER Victor <report@bugs.python.org> wrote:
> I don't see how to ensure that the terminal state is restored, even on error.

Python2 suppresses the exception until after normal exit (pressing 'q').
I think that behavior is better.

In Python3 you can also get the unusable terminal by pressing Ctrl-C,
i.e. without any UnicodeError.
msg217803 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2014-05-02 21:59
The patch works well BTW.  We can create another issue for the
general misbehavior of pydoc with other exceptions.
msg218388 - (view) Author: Roundup Robot (python-dev) Date: 2014-05-13 00:06
New changeset 89a29e92416f by Victor Stinner in branch '3.4':
Issue #21398: Fix an unicode error in the pydoc pager when the documentation
http://hg.python.org/cpython/rev/89a29e92416f

New changeset 3424d65ad5ce by Victor Stinner in branch 'default':
(Merge 3.4) Issue #21398: Fix an unicode error in the pydoc pager when the
http://hg.python.org/cpython/rev/3424d65ad5ce
msg218389 - (view) Author: STINNER Victor (haypo) * (Python committer) Date: 2014-05-13 00:08
I fixed the initial bug and so I close the issue.

Open a new issue if you have an idea to restore the terminal state when the pager breaks the terminal. I don't think that it's possible to save/restore the terminal state in a portable way.
History
Date User Action Args
2014-05-13 00:08:11hayposetstatus: open -> closed
resolution: fixed
messages: + msg218389

versions: + Python 3.4
2014-05-13 00:06:43python-devsetnosy: + python-dev
messages: + msg218388
2014-05-02 21:59:47skrahsetmessages: + msg217803
2014-05-02 20:10:48skrahsetmessages: + msg217784
2014-05-02 19:46:04hayposetmessages: + msg217780
2014-05-02 19:39:18hayposetfiles: + pydoc_encoding.patch
keywords: + patch
messages: + msg217779
2014-05-02 17:57:37eric.araujosetnosy: + haypo
2014-04-30 12:59:59matrixisesetmessages: + msg217618
2014-04-30 12:53:53skrahsetmessages: + msg217615
2014-04-30 12:43:21matrixisesetmessages: + msg217614
2014-04-30 12:39:59r.david.murraysetmessages: + msg217613
2014-04-30 12:37:47skrahsetmessages: + msg217612
title: pydoc heapq leaves terminal in an unusable state -> LC_CTYPE=C: pydoc leaves terminal in an unusable state
2014-04-30 12:32:54matrixisesetmessages: + msg217611
2014-04-30 12:30:14skrahsetmessages: + msg217609
2014-04-30 12:28:36matrixisesetnosy: + matrixise
messages: + msg217608
2014-04-30 12:22:25r.david.murraysetnosy: + r.david.murray
messages: + msg217607
2014-04-30 11:48:17skrahsettype: behavior
2014-04-30 11:33:21skrahcreate