Execute an installed Python package as a script?

Python

Python Problem Overview


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?

Python Solutions


Solution 1 - Python

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).

Solution 2 - Python

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.

Solution 3 - Python

Yes, you can do that if the script has the __main__ section.

Of course, you can't execute a package if it is a directory. But if you can run the script itself (say it starts with #!/usr/bin/python3 and you run it with ./script), you can choose another interpreter this way:

/bin/python2 -v ../path/to/my/script status

where -v is for the interpreter (if needed), and status is an argument for your script.

Solution 4 - Python

as long as the package is on the python path, add at the end of the script.

if __name__ == "__main__":
     call_script()

$ python -m module_name  

will run the module e.g

python -m random

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPhillip B OldhamView Question on Stackoverflow
Solution 1 - PythonnikcubView Answer on Stackoverflow
Solution 2 - PythonnfirvineView Answer on Stackoverflow
Solution 3 - PythonYaroslav NikitenkoView Answer on Stackoverflow
Solution 4 - PythonmossplixView Answer on Stackoverflow