Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute an installed Python package as a script?

Tags:

python

Is there a way to enable a package to be executed as a script? For example:

[~]# easy_install /path/to/foo.egg ... [~]# python -m foo --name World Hello World 

I've tried creating a __main__.py file inside my package but it's not being executed (I'm using Python 2.6). The following error is raised:

foo is a package and cannot be directly executed 

The structure of my package is as follows:

foo/   setup.py   foo/     __init__.py     __main__.py 

Running python -m foo.__main__ --name World works as expected, but I would prefer the former way of execution. Is this possible?

like image 928
Phillip B Oldham Avatar asked Oct 29 '10 08:10

Phillip B Oldham


People also ask

How do I run a Python module from a script?

The most basic and easy way to run a Python script is by using the python command. You need to open a command line and type the word python followed by the path to your script file, like this: python first_script.py Hello World! Then you hit the ENTER button from the keyboard and that's it.

How do I run a Python package from command line?

To run Python scripts with the python command, you need to open a command-line and type in the word python , or python3 if you have both versions, followed by the path to your script, just like this: $ python3 hello.py Hello World!

Can you run pip from Python?

PIP is automatically installed with Python 2.7.9+ and Python 3.4+ and it comes with the virtualenv and pyvenv virtual environments. Before you install PIP on Windows, check if PIP is already installed.


2 Answers

This is a regression in Python 2.6. See issue2571:

The ability to execute packages was never intended, since doing so breaks imports in a variety of subtle ways. It was actually a bug in 2.5 that it was permitted at all, so 2.6 not only disabled it again, but also added a test to make sure it stays disabled (2.4 correctly rejected it with an ImportError, just as 2.6 does).

You have a few options, you can either always run it specifying main:

$ python -m module.__main__ 

Or you can write a shell script wrapper that detects the python version and then executes it in the different style.

Or you can execute code on the command line that will import and then run the module, and then perhaps place that in a shell script:

$ python -c "import module; module.main()" 

In my own command-line projects I have both the shell script that catches errors (python not being installed, etc.) but the shell script will also execute the import code and detect if the necessary modules have been installed and prompt an error (with a helpful link or install text).

like image 86
nikcub Avatar answered Sep 25 '22 12:09

nikcub


I think this may be a limitation of Python 2.6. I've tested it, and executing a package (either in . or installed from an egg with easy_install) with the -m option works fine in 2.7, but not in 2.6. For example, on my system (Ubuntu) with a test package called pkg_exec in the current directory, and where __main__.py simply prints sys.argv:

xx@xx:~/tmp/pkg_exec$ python2.6 -m pkg_exec /usr/bin/python2.6: pkg_exec is a package and cannot be directly executed xx@xx:~/tmp/pkg_exec$ python2.7 -m pkg_exec ['/home/xx/tmp/pkg_exec/pkg_exec/__main__.py'] 

Also, according to the 2.7 docs:

Changed in version 2.7: Supply the package name to run a __main__ submodule.

like image 23
nfirvine Avatar answered Sep 24 '22 12:09

nfirvine