minghua minghua - 2 months ago 34
Python Question

python curses remote debugging pdevd error in setupterm

Is it possible to debug a curse program remotely in PyCharm? How to set it up?

I followed the PyCharm 4.0.8 instruction, added this to the "

EXAMPLE.py
" from "
npyscreen-4.8.7
".

import pydevd
pydevd.settrace('localhost', port=8899, stdoutToServer=False, stderrToServer=True)


And always it runs into an error in "
setupterm
":

$ PYTHONPATH=~/bin/pycharm-debug.egg python EXAMPLE.py
Traceback (most recent call last):
File "EXAMPLE.py", line 34, in <module>
App.run()
File "/home/.../npyscreen-4.8.7/npyscreen/apNPSApplication.py", line 30, in run
return npyssafewrapper.wrapper(self.__remove_argument_call_main)
File "/home/.../npyscreen-4.8.7/npyscreen/npyssafewrapper.py", line 41, in wrapper
wrapper_no_fork(call_function)
File "/home/.../npyscreen-4.8.7/npyscreen/npyssafewrapper.py", line 83, in wrapper_no_fork
_SCREEN = curses.initscr()
File "/usr/lib64/python2.6/curses/__init__.py", line 33, in initscr
fd=_sys.__stdout__.fileno())
_curses.error: setupterm: could not find terminal





The problem is that pydevd changed environment "TERM" from "xterm" to "emacs". This can be verified by a little test program.

import pydevd
pydevd.settrace('localhost', port=8899, stdoutToServer=False, stderrToServer=True)
import os as _os
import sys as _sys
import curses
print " my term: ", _os.environ.get("TERM", "unknown"), "\n"
print " my fd: ", _sys.__stdout__.fileno(), "\n"
print "\n ok 1 \n"
curses.setupterm(term=_os.environ.get("TERM", "unknown"),
#curses.setupterm(term='xterm',
fd=_sys.__stdout__.fileno())
print "\n ok 2 \n"



  • If removing the two lines with "
    pdevd
    ", the program succeeds. The "
    TERM
    " it prints out is "
    xterm
    ".

  • If change the 1st argument to "
    setupterm
    " into "
    term='xterm'
    ", even with "
    pydevd
    " it succeeds.



I guess the question is how to have "
pydevd
" setup the correct "
TERM
"?

Answer

While one of the answer could be this: Change /usr/lib/python2.6/curses/__init__.py to force TERM like:

def initscr():
    import _curses, curses
    # we call setupterm() here because it raises an error
    # instead of calling exit() in error cases.
    _os.environ['TERM'] = 'xterm' ##hack force 'xterm' for pydevd debugging.
    setupterm(term=_os.environ.get("TERM", "unknown"),
              fd=_sys.__stdout__.fileno())
    stdscr = _curses.initscr()
    for key, value in _curses.__dict__.items():
        if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'):
            setattr(curses, key, value)

    return stdscr

The original source that changed "TERM" is here:

$ head plugins/org.python.pydev_4.0.0.201504132356/pysrc/pydev_ipython_console.py 
import sys
from pydev_console_utils import BaseInterpreterInterface

import os

os.environ['TERM'] = 'emacs' #to use proper page_more() for paging


# Uncomment to force PyDev standard shell.
# raise ImportError()