6

I am writing a script to automate the packaging of a 'home-made' python module and distributing it on a remote machine.

i am using Pip and have created a setup.py file but i then have to call the subprocess module to call the "python setup.py sdist" command.

i have looked at the "run_setup" method in distutils.core but i am trying to avoid using the subprocess module alltogether. (i see no point in opening a shell to run a python command if i am already in python...)

is there a way to import the distutils module into my script and pass the setup information directly to one of its methods and avoid using the shell command entirely? or any other suggestions that may help me

thanks

Ben
  • 300
  • 2
  • 11
  • related: [Run a python script from another python script, passing in args](http://stackoverflow.com/q/3781851/4279) – jfs Feb 19 '16 at 14:18

2 Answers2

5

Just for the sake of completeness, I wanted to answer this since I came across it trying to find out how to do this myself. In my case, I wanted to be sure that the same python version was being used to execute the command, which is why using subprocess was not a good option. (Edit: as pointed out in comment, I could use sys.executable with subprocess, though programmatic execution is IMO still a cleaner approah -- and obviously pretty straightforward.)

(Using distutils.core.run_setup does not call subprocess, but uses exec in a controlled scope/environment.)

from distutils.core import run_setup

run_setup('setup.py', script_args=['sdist'])

Another option, may be to use the setuptools commands, though I have not explored this to completion. Obviously, you still have to figure out how to avoid duplicating your proj metadata.

from setuptools.dist import Distribution
from setuptools.command.sdist import sdist

dist = Distribution({'name': 'my-project', 'version': '1.0.0'}) # etc.
dist.script_name = 'setup.py'
cmd = sdist(dist)
cmd.ensure_finalized()
cmd.run()  # TODO: error handling

Anyway, hopefully that will help someone in the right direction. There are plenty of valid reasons to want to perform packaging operations programmatically, after all.

Hans L
  • 5,845
  • 4
  • 22
  • 21
  • you could use the exact same version using `sys.executable` and `subprocess`. – jfs Feb 19 '16 at 14:18
  • Thanks, that is useful for the future; although in this case it is still convenient to run the command from my build framework context. Anyway, running programmatically is trivial and produces richer errors than using subprocess. – Hans L Feb 21 '16 at 01:47
  • The isolation is worse. You may get incorrect results if you run multiple `setup.py` in the same process. It is not uncommon to patch `setuptools`, `distutils` in `setup.py` that may interfere with other scripts. `pip` runs `setup.py` files using `subprocess`. – jfs Feb 22 '16 at 16:03
  • Perhaps in the abstract, but the question asked how to do this w/o subprocess and this is obviously perfectly possible and there are many scenarios when this makes sense. – Hans L Feb 23 '16 at 21:40
  • You may provide a way to run it without `subprocess` but you should not say that it is a "cleaner" approach. – jfs Feb 23 '16 at 21:42
0

If you don’t have a real reason to avoid subprocesses (i.e. lack of platform support, not just aesthetics (“I see no point”)), then I suggest you should just not care and run in a subprocess. There are a few ways to achieve what you request, but they have their downsides (like having to catch exceptions and reporting errors).

merwok
  • 6,779
  • 1
  • 28
  • 42
  • 1
    In any case, i would like it very much if you could outline what those ways are and allow me to make an informed decision by weighing up the pros and cons. – Ben Mar 29 '12 at 09:54