lordmauve / chopsticks

Chopsticks is an orchestration library: it lets you execute Python code on remote hosts over SSH.
https://chopsticks.readthedocs.io/
Apache License 2.0
158 stars 16 forks source link

Jupyter notebook import doesn't work recursively #38

Open lordmauve opened 7 years ago

lordmauve commented 7 years ago

I wrote this code in a Jupyter Notebook cell:

import os
from chopsticks.tunnel import SSHTunnel, Docker, Local

tun = Docker('docker')

class DockerLocal(Local):
    """A Python subprocess on a docker container"""
    python2 = python3 = 'python'

def num_procs():
    return sum(fname.isdigit() for fname in os.listdir('/proc'))

def local_tun():
    with DockerLocal() as tun:
        tun.call(num_procs)

tun.call(local_tun)

This crashes with this exception:

...snip...
/home/mauve/dev/chopsticks/chopsticks/tunnel.py in handle_imp(self, mod)
    162             # Special-case main to find real main module
    163             main = sys.modules['__main__']
--> 164             path = main.__file__
    165             self.write_msg(
    166                 OP_IMP,

AttributeError: module '__main__' has no attribute '__file__'
lordmauve commented 7 years ago

This is occurring for two reasons:

  1. We don't special case __chopmain__ - which is the module where imported __main__ functions are created - in the same way we special-case __main__

  2. I believe imp.find_source() will not work on objects created from source in __chopmain__. We could work around this by storing the source for the object - perhaps in a WeakKeyDictionary. We could consult this dictionary and then fall back to imp.find_source().