# Buggy code
def can_init():
    """This function returns True iff stderr is a TTY and we are not inside a
    REPL.  Iff this function returns `True`, a call to :meth:`init` will let
    ``pwnlib`` manage the terminal.
    """

    if sys.platform == "win32":
        return False

    if not sys.stdout.isatty():
        return False

    # Check for python -i
    if sys.flags.interactive:
        return False

    # Check fancy REPLs
    mods = sys.modules.keys()
    for repl in ["IPython", "bpython", "dreampielib"]:
        if repl in mods:
            return False

    # The standard python REPL will have co_filename == '<stdin>' for some
    # frame. We raise an exception to set sys.exc_info so we can unwind the call
    # stack.
    try:
        raise BaseException
    except BaseException:
        frame = sys.exc_info()[2].tb_frame

    while frame:
        if frame.f_code.co_filename == "<stdin>":
            return False
        frame = frame.f_back

    return True


# Traceback (ImportError)
In 1: from pwn import *
Out 1:
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-1-d810d1e70089> in <module>()
----> 1 from pwn import *

/usr/local/lib/python2.7/dist-packages/pwn/__init__.py in <module>()
1 # Promote useful stuff to toplevel
----> 2 from .toplevel import *
3
4 pwnlib.args.initialize()
5 pwnlib.log.install_default_handler()

/usr/local/lib/python2.7/dist-packages/pwn/toplevel.py in <module>()
18 from pprint import pprint
19
---> 20 import pwnlib
21 from pwnlib import *
22 from pwnlib.asm import *

/usr/local/lib/python2.7/dist-packages/pwnlib/__init__.py in <module>()
38
39 for module in __all__:
---> 40     importlib.import_module('.%s' % module, 'pwnlib')

/usr/lib/python2.7/importlib/__init__.pyc in import_module(name, package)
35             level += 1
36         name = _resolve_name(name[level:], package, level)
---> 37     __import__(name)
38     return sys.modules[name]

/usr/local/lib/python2.7/dist-packages/pwnlib/args.py in <module>()
46 import sys
47
---> 48 from . import term
49 from .context import context
50

/usr/local/lib/python2.7/dist-packages/pwnlib/term/__init__.py in <module>()
1 import sys
2
----> 3 from . import completer
4 from . import key
5 from . import keymap

/usr/local/lib/python2.7/dist-packages/pwnlib/term/completer.py in <module>()
2 import re
3
----> 4 from . import readline
5
6

/usr/local/lib/python2.7/dist-packages/pwnlib/term/readline.py in <module>()
2 from . import keymap as km
3 from . import term
----> 4 from . import text
5
6 cursor = text.reverse

/usr/local/lib/python2.7/dist-packages/pwnlib/term/text.pyc in <module>()
113
114 tether = sys.modules[__name__]
--> 115 sys.modules[__name__] = Module()

/usr/local/lib/python2.7/dist-packages/pwnlib/term/text.pyc in __init__(self)
24         self.__file__ = __file__
25         self.__name__ = __name__
---> 26         self.num_colors = termcap.get('colors', default = 8)
27         self.has_bright = self.num_colors >= 16
28         self.has_gray = self.has_bright

/usr/local/lib/python2.7/dist-packages/pwnlib/term/termcap.pyc in get(cap, *args, **kwargs)
23     s = cache.get(cap)
24     if not s:
---> 25         s = curses.tigetstr(cap)
26         if s == None:
27             s = curses.tigetnum(cap)

error: must call (at least) setupterm() first

​

In 2: import curses

In 3: curses.setupterm()
Out 2:
---------------------------------------------------------------------------
UnsupportedOperation                      Traceback (most recent call last)
<ipython-input-5-82805162dd9f> in <module>()
----> 1 curses.setupterm()

/usr/local/lib/python2.7/dist-packages/ipykernel/iostream.pyc in fileno(self)
304
305     def fileno(self):
--> 306         raise UnsupportedOperation("IOStream has no fileno.")
307
308     def write(self, string):

UnsupportedOperation: IOStream has no fileno.

print (curses.initscr(), curses.endwin())

(<_curses.curses window object at 0x7fef5c891a98>, None)

In 4: from pwnlib import *

Out 3:
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-2-5eb1d9485f4c> in <module>()
----> 1 from pwnlib import *

/usr/local/lib/python2.7/dist-packages/pwnlib/__init__.py in <module>()
38
39 for module in __all__:
---> 40     importlib.import_module('.%s' % module, 'pwnlib')

/usr/lib/python2.7/importlib/__init__.pyc in import_module(name, package)
35             level += 1
36         name = _resolve_name(name[level:], package, level)
---> 37     __import__(name)
38     return sys.modules[name]

/usr/local/lib/python2.7/dist-packages/pwnlib/args.py in <module>()
46 import sys
47
---> 48 from . import term
49 from .context import context
50

/usr/local/lib/python2.7/dist-packages/pwnlib/term/__init__.py in <module>()
1 import sys
2
----> 3 from . import completer
4 from . import key
5 from . import keymap

/usr/local/lib/python2.7/dist-packages/pwnlib/term/completer.py in <module>()
2 import re
3
----> 4 from . import readline
5
6

/usr/local/lib/python2.7/dist-packages/pwnlib/term/readline.py in <module>()
----> 1 from . import keyconsts as kc
2 from . import keymap as km
3 from . import term
4 from . import text
5

ImportError: cannot import name keyconsts

​```

# Fixed code
def can_init():
    """This function returns True iff stderr is a TTY and we are not inside a
    REPL.  Iff this function returns `True`, a call to :meth:`init` will let
    ``pwnlib`` manage the terminal.
    """

    if sys.platform == "win32":
        return False

    if not sys.stdout.isatty():
        return False

    # Check for python -i
    if sys.flags.interactive:
        return False

    # Check fancy REPLs
    mods = sys.modules.keys()
    for repl in ["IPython", "bpython", "dreampielib", "jupyter_client._version"]:
        if repl in mods:
            return False

    # The standard python REPL will have co_filename == '<stdin>' for some
    # frame. We raise an exception to set sys.exc_info so we can unwind the call
    # stack.
    try:
        raise BaseException
    except BaseException:
        frame = sys.exc_info()[2].tb_frame

    while frame:
        if frame.f_code.co_filename == "<stdin>":
            return False
        frame = frame.f_back

    return True