0

So I'm trying to create a setup.py file do deploy a test framework in python. The library has dependencies in pexpect and easy_install. So, after installing easy_install, I need to install s3cmd which is a tool to work with Amazon's S3. However, to configure s3cmd I use pexpect, but if you want to run setup.py from a fresh VM, so we run into an ImportError:

import subprocess
import sys
import pexpect # pexpect is not installed ... it will be

def install_s3cmd():
    subprocess.call(['sudo easy_install s3cmd'])
    # now use pexpect to configure s3cdm
    child = pexpect.spawn('s3cmd --configure')
    child.expect ('(?i)Access Key')
    # ... more code down there

def main():
    subprocess.call(['sudo apt-get install python-setuptools']) # installs easy_install
    subprocess.call(['sudo easy_install pexpect']) # installs pexpect
    install_s3cmd()
    # ... more code down here

if __name__ == "__main__":
    main()

I know of course I could create a another file, initial_setup.py to have easy_install and pexpect installed, before using setup.py, but my question is: Is there a way to import pexpect before having it installed? The library will be installed before using it, but does the Python interpreter will accept the import pexpect command?

cybertextron
  • 10,547
  • 28
  • 104
  • 208

1 Answers1

7

It won't accept it like that, but Python allows you to import things everywhere, not only in the global scope. So you can postpone the import until the time when you really need it:

def install_s3cmd():
    subprocess.call(['easy_install', 's3cmd'])

    # assuming that by now it's already been installed
    import pexpect

    # now use pexpect to configure s3cdm
    child = pexpect.spawn('s3cmd --configure')
    child.expect ('(?i)Access Key')
    # ... more code down there

EDIT: there is a peculiarity with using setuptools this way, since the .pth file will not be reloaded until Python relaunches. You can enforce reloading though (found here):

import subprocess, pkg_resources
subprocess.call(['easy_install', 'pexpect'])
pkg_resources.get_distribution('pexpect').activate()
import pexpect  # Now works

(Unrelated: I'd rather assume that the script itself is called with the needed privileges, not use sudo in it. That will be useful with virtualenv.)

Community
  • 1
  • 1
bereal
  • 32,519
  • 6
  • 58
  • 104