I'm running a python CGI script on my localhost that needs to import and use another python module that I wrote. I placed the CGI script in the Apache cgi-bin directory (I'm running this on windows). I've tried placing my custom module in the same directory, but it doesn't seem to be able to import that module. I would prefer to not have the custom module be another CGI script that is called via exec().
You need to put your Python module somewhere that Python's import can see it. The easy ways to do that are:
Make a directory for the module, and add that directory to your PYTHONPATH environment variable.
Copy the module into your Python site-packages directory, which is under your Python installation directory.
In either case, you will need to make sure your module's name is not the same as the name of some other module that might be imported by Python in your CGI script.
Related
The Python Tutorial chapter 6 (Modules) says:
The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended.
Why is this an error? In other terms, what is the meaning of the sentence "This is an error unless the replacement is intended"?
After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended. See section Standard Modules for more information.
Assuming you have a package (= module) installed called fooo. This is the package you want to use for e script.
Now, if you import it using fooo, everything works as intended.
Now, if there's a module in the directory mentioned above, with the same name (fooo), this one will replace your intended package.
The error is, that you now got imported the wrong package.
Resource: https://docs.python.org/3/tutorial/modules.html#the-module-search-path
It basically says: If you overwrite something already specified by python and this is not your intention, then it is an error. If it is intended to overwrite it, it is not an error.
The search path is a list of paths under which the python interpreter searches for any imported modules. You can view its contents in the interactive python shell by running python3, then import sys; print(sys.path) in the terminal. For me it looks like this:
['', '/usr/lib/python311.zip', '/usr/lib/python3.11', '/usr/lib/python3.11/lib-dynload', '/usr/local/lib/python3.11/dist-packages', '/usr/lib/python3/dist-packages']
Make a python script containing import sys; print(sys.path), run the script and see the first entry change from an empty string to the path your python file resides in (aka your working directory):
['/home/thomas/Downloads', '/usr/lib/python310.zip', '/usr/lib/python3.10', '/usr/lib/python3.10/lib-dynload', '/home/thomas/.local/lib/python3.10/site-packages', '/usr/lib/python3.10/site-packages']
If your python script also contained import my_module, upon execution the python interpreter would first search in your working directory for a file called my_module.py and only if it doesn't find one there will it continue searching for the module in all the usual places where third-party libraries may be installed.
This may cause unexpected errors if you accidentally import one of your own modules instead of a third-party module you installed via pip with the same name.
I have installed Eclipse IDE with Python, I'm trying to setup an environment for writing some python scripts to automate Libre Office, I have made a script with just one line of code for now ("import libpyuno"), when i run this line of code i get an error:
ImportError: dynamic module does not define init function (initlibpyuno)
I have added "usr/lib/libreoffice/program" as external library path.
Can anyone tell me why I'm getting this error?
The supported way of using pyuno is to invoke the python interpreter bundled with LibreOffice itself. If you want to use an existing interpreter, then you need to make sure you manually do the same setup as the python shell script does inside the LibreOffice installation set (/usr/lib/libreoffice) in your case. This involves not only setting PYTHONPATH but at least specifying URE_BOOTSTRAP as well (both are environment variables.)
Now to your actual question: you probably don't want to import libpyuno. If you want to import a single LibreOffice-specific Python module for testing, then import just uno.
See https://cgit.freedesktop.org/libreoffice/core/tree/scripting/examples/python/NamedRanges.py for a real-world pyuno script, you can see even that only needs the uno module.
Eclipse can run a python project rather than just one .py file. Is it possible to run an entire project from Python 3.x shell. I looked into it a little, but I didn't really find a way. I tried just running the .py file with the main using exec(open('bla/blah/projMain.py')) like you would any python file. All of my modules (including the main) is in one package, but when I ran the main I got a no module named 'blah' (the package it is in). Also, as a side note there is in fact aninit.pyand even apycache' directory.
Maybe I didn't structure it correctly with Eclipse (or rather maybe Eclipse didn't structure it properly), but Eclipse can run it, so how can I with a Python 3.4.1 shell? Do I have to put something in __init__.py, perhaps, and then run that file?
It depends on what your file looks like -- if you have an if __name__ == "__main__": do_whatever(), then an import will not do_whatever() because the name of the imported module will not be "__main__". (It will be whatever the name of the module is).
However, if it is just a script without the conditional, you can just import the module and it will be run. Python needs to know where the module is though, so if it is not in your path, you will have to use relative imports, as documented here.
Based on current information, I would suggest you to run it this way in OSX
1) Bring up the Terminal app
2) cd to the location where bla lives
3) run python bla/blah/projMain.py
Show us stacktrace if the above failed.
When you write a python library, and want to import one module in it from another, what is the correct way to do it, so that imports work both when the library is imported from outside and when some unit tests are run from the library directory?
If you do
import some_module
from some_module import something
it works when run from the library directoy, but when imported from outside, produces ImportError: No module named 'some_module'.
You can do
from . import some_module
import my_library.some_other_module
from .some_module import something
but it will not work if you import the library from the unittest placed in the same directory.
Finally, you can play with sys.path and/or move unit tests to some other directory.
What's the best solution?
Edit: Just to make it clear, I'd like to run the unittests using python -m unittest in the top directory of the library. So far I made it work by adding
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
to the beginning of the unit test files. As an alternative it's possible to write a short shell script that will add the parent directory to PYTHONPATH and then run unittests. I wonder if there are better ways to deal with it?
Take a look at the docs on Module Search Path
When a module named spam is imported, the interpreter first searches
for a built-in module with that name. If not found, it then searches
for a file named spam.py in a list of directories given by the
variable sys.path. sys.path is initialized from these locations:
the directory containing the input script (or the current directory).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
the installation-dependent default.
If you write a library, the test code should usually interface with the library in the same manner that a user of the library would. This might mean adding the module to the the search path either by setting the PYTHONPATH environment variable, or by installing the module in the default 3rd party module location.
I would suggest running your tests from the base directory which holds your modules using the automated test discovery option
python -m unittest discover (python >= 2.7)
This will recursively find files matching test_*.py (i.e. within module dirs), but should set the python path relative to the parent dir.
I am tinkering with some pet projects with Python in Linux (Mint 13) and I plan to do the following:
Create a Dropbox subfolder named "pybin" where I put all my home-made python modules;
Put a symlink to this folder somewhere in the system (first candidate: /usr/lib/python2.7/dist-packages, which is in sys.path, or some similar path);
Then I just do import mymodule from any python session, and the module is imported.
I tried it and it didn't work. I suspect this has to do with differences between modules and packages, and __init__.py files, but I confess that everytime I read something about this stuff I get pretty confused. Besides learning a bit more about this, all I really want to do is find a way to import my modules the described way. It is crucial that the actual folder is inside Dropbox (or any other file-syncing folder), not in a system folder.
Thanks for any help!
Why not simply set the PYTHONPATH envvar in your .bash_profile. That way every time you execute a bash shell (normally happens upon login), this environment variable will be set the wherever you place your user defined modules. The python interpreter uses this variable to determine where to search for module imports:
PYTHONPATH="${PYTHONPATH}:/path/to/some/cool/python/package/:/path/to/another/cool/python/package/"
export PYTHONPATH