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?
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).
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.
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.
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
Related
I made a python (3) package and I have been trying to upload it on Github. I also know how to push and install a git using pip. To test if it works as anticipated, I made a virtual environment on my local computer (linux) and pip installed my already pushed private package in there without a problem.
The issue is that I don't know how to access it!!! (I know how to activate and use virtualenvs; I don't know how to call my package) My package has a main interface that one would need to call it in terminal as follows:
python3 myui.py some_args *.data
and it's supposed to create some files where it's called. In other words, it's not exactly a module like numpy to be imported. I have watched/read many tutorials and documentations on the web and tbh I'm lost here.
You are looking for the -m flag. If you installed everything correctly, then the following command should allow you to run your script (based on your example). Note that you shouldn't add the file extension '.py'.
python3 -m myui some args *.data
If you have an actual package (directory with __init__.py file and more) instead of a module (a single .py file), then you can add a __main__.py file to that package. Python will execute this script when you use the -m flag with the package's name, in the same way as shown above.
python3 -m mypackage some args *.data
If you want to run a different script that is nested somewhere inside of that package, you can still run it by specifying its module name:
python3 -m mypackage.subpackage.myscript some args *.data
Another common way to make your script available uses the setup script (setup.py) or setup configuration file (setup.cfg) that is used to install the module or package. In that case, you can add an entry point to map a command to a specific module/function/etc. (as described in this Python packaging tutorial) so that you can run that command instead of having to use the -m flag with Python.
$ mycommand some args *.data
I'm having trouble running a script downloaded from an Android repository. Based on related questions and on my own testing, I'm pretty sure that the problem is that it's being interpreted by Python2, when it was written for Python3.
Here's my attempt at reproducing the problem in a script of my own:
#!/usr/bin/env python3
# test.py
import sys
print('hello', file=sys.stderr)
And here are the test steps:
$ alias python=python3
$ python --version
Python 3.6.9
$ python test.py
hello
$ unalias python
$ python --version
Python 2.7.17
$ python test.py
File "test.py", line 5
print('hello', file=sys.stderr)
^
SyntaxError: invalid syntax
What's confusing is that, while this test executes as expected, when I use repo to attempt to install Android Open Source Project, I get the SyntaxError (from essentially an identical line of script), despite running alias python=python3. (The shebang doesn't seem to affect the test or the main script.)
What am I missing? How can I run this script using the correct version of python3? And assuming there is a workaround, how do I clean up afterwards so that the rest of my system can still access python2 when it wants to?
alias only changes the interpretation of commands you directly type into your shell. repo is therefore unaffected, because it doesn't type the python command into your shell.
Usually the best way to run a different Python configuration from the system's is to use virtualenvs.
What is -m stands for in python -m unittest? The unittest unit testing framework has other command line options like -v -b -c -t but wondering what does -m stands for? Is it part of unittest or other python command line option?
if you run python --help you will see that:
-m mod : run library module as a script (terminates option list)
An explanation as to what that means and -m flage does can be found here, I have copied the important parts below:
Properly designed modules usually do nothing except set up stuff (e.g. functions and types you could import), but they usually won’t have any visible side effect. That’s why you can do import sys and nothing happens.
However, some modules may offer useful stuff when they are run from the command line. Examples for that include venv but also http.server or idlelib: All of those are regular modules that can be imported from other modules without side effects.
But when executed directly, they all do things (e.g. venv sets up a virtual environment, http.server runs a simple HTTP server, and idlelib runs IDLE). This is usually done with the following check:
I'm using Python 3.3 on Win7, and I'm fairly new to testing and py.test.
I have a simple test to run, and although I can run it from the command line by calling
$ python -m pytest testing.py
when trying to call it with the simpler line
$ py.test testing.py
it returns:
'py.test' is not recognized as an internal or external command,
operable program, or batch file
Do I need to have the py.test source folder in the same location as my program, or am I doing something incorrectly?
The system is telling you:
py.test is not installed in a standard location. If you installed using pip or easy-install, it should be in /usr/local/bin or possibly /opt/bin depending on your flavour of Linux, and these should be on your path.
py.test has not been marked as executable.
You installed from source using setup.py and the directory containing py.test is not on your path, probably in or below your home directory.
Check for these possibilities, correct them if necessary and post the results of your efforts.
Above one is true.
Try to create a new virtual environment and do a new py.test
And check your python installation and path if the executable is accessible by terminal
pip install pytest==6.2.1
It worked for me.
pip install pytest== (any pytest version number)
Is it possible to run Python egg files directly as you can run jar files with Java?
For example, with Java you might dos something like:
$ java -jar jar-file
A python egg is a "a single-file importable distribution format". Which is typically a python package.
You can import the package in the egg as long as you know it's name and it's in your path.
You can execute a package using the "-m" option and the package name.
However, python packages generally do not do anything when executed, and you may get an error. The -c option can be used to run code. (See http://docs.python.org/using/cmdline.html for details on command line options)
> python -m sphinx
sphinx is a package and cannot be directly executed
> python -c "import <package in an egg>; <function>();"
> python -c "import sphinx; print sphinx.package_dir"
C:\Python26\lib\site-packages\sphinx-0.6.1-py2.6.egg\sphinx
As of Python 2.6, you can use python some.egg and it will be executed if it includes a module named __main__.
For earlier versions of Python, you can use PYTHONPATH=some.egg python -m some module, and somemodule from the egg will be run as the main module. (Note: if you're on Windows, you'd need to do a separate SET PYTHONPATH=some.egg.)
For example, if you want to import the suds module which is available as .egg file:
egg_path='/home/shahid/suds_2.4.egg'
sys.path.append(egg_path)
import suds
#... rest of code
Python Egg file direct execution steps
Suppose if you have egg file and driver file to run through below command.
PYTHONPATH=eggfilename.egg python driverfile.py
above command for without install egg file with python code.