Question

I have some Python code that works as expected if I type the commands one-at-a-time using Python's interactive mode. The same code crashes if saved as myscript.py and run as 'C:\Python27\python.exe myscript.py'.

In what ways could running Python code as a script cause it to crash, if the same code works in interactive mode?

This question asks for ways to tell if python is in interactive mode. However, the asker just wants a single, reliable fingerprint of interactive mode. I'd like a list of ways that interactive mode is different, with particular attention to problems this can cause.

For example:

  • sys.path could be different
  • os.getcwd() could be different
  • os.environ could be different
  • All the answers to this question
  • This warning at the beginning of the multiprocessing module documentation

What else could be different between Python's interactive and script mode?

Was it helpful?

Solution

It looks like you're interacting with hardware, which brings up the most glaring difference between the REPL and a script:

Commands in a script run immediately as soon as possible, whereas the REPL waits for human input.

That is to say, you are probably having a timing issue where the hardware isn't ready for the next command so soon after executing the previous.

OTHER TIPS

Threads and Greenlets have different behavior in an interactive environment. The main event loop has to be hacked in some instances.

Greenlet is from the gevent module which is a concurrent task in python. It has an internal context switching separate from Python's (pthread) and the concurrency works really well (in my experience). Some of the issues with Greenlets is that they block on blocking C-system calls and socket interactions if they're not monkey-patched (module in gevent).

The main event-loop needs to be patched in order for the greenlets to work correctly... If you spawn a greenlet in an interactive environment it will not switch contexts and execute, I forgot how off the top of my head how to patch the main event loop (will add later).

Example of failure:

In [1]: from gevent.greenlet import Greenlet

In [2]: def print_hi():
   ...:     print 'hi'
   ...:     

In [3]: print_hi()
hi

In [4]: g = Greenlet(print_hi)

In [5]: g.start()

Edit:

After looking at some of the code on this project here's how we hacked the ipython input hook to use gevent

import sys
import select
import gevent

def stdin_ready():
    infds, outfds, erfds = select.select([sys.stdin], [], [], 0)
    if infds:
        return True
    else:
        return False

def inputhook_gevent():
    try:
        while not stdin_ready():
            gevent.sleep(0.001)
    except KeyboardInterrupt:
        pass

    return 0

# install the gevent inputhook
from IPython.lib.inputhook import inputhook_manager
inputhook_manager.set_inputhook(inputhook_gevent)
inputhook_manager._current_gui = 'gevent'

# First import the embeddable shell class
from IPython.frontend.terminal.embed import InteractiveShellEmbed

Patched Example:

In [6]: def say_hi():
   ...:     print "hi"
   ...:     

In [7]: g = gevent.greenlet.Greenlet(say_hi)

In [8]: g.start()

In [9]: hi  <-- Cursor is here so it printed hi

Take a look at this line

PCO_api = ctypes.oledll.LoadLibrary("SC2_Cam")

If you can use the COMPLETE path for LoadLibrary

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top