Embedded Python search modules in a wrong directory - python

I have installed Python 2.6.7 in $HOME/local of a machine which already has a default Python in /usr (I don't have admin access on this machine). The default Python is compiled in 32bits and my local installation is a 64bits. For some unknown reasons my local Python library (which I call as an embedded python interpreter from within a C program) search for the modules in the default (wrong) installation.
This is the result of "import random"
Traceback (most recent call last):
File "test.py", line 3, in <module>
import random
File "/tmp/work/mdorier1/local/lib/python2.6/random.py", line 45, in <module>
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
ImportError: /usr/lib/python2.6/lib-dynload/math.so: wrong ELF class: ELFCLASS32
As you can see, the import statement correctly search "random.py" in the local installation of Python, but the import statement in random.py go search for math.so in the wrong location, which ends in an error since the default location has 32 bits modules.
I guessed there is a problem with an environment variable, and I tried
import sys
sys.path
to get
['/tmp/work/mdorier1/local/lib/python26.zip',
'/tmp/work/mdorier1/local/lib/python2.6',
'/tmp/work/mdorier1/local/lib/python2.6/plat-linux2',
'/tmp/work/mdorier1/local/lib/python2.6/lib-tk',
'/tmp/work/mdorier1/local/lib/python2.6/lib-old',
'/usr/lib/python2.6/lib-dynload',
'/tmp/work/mdorier1/local/lib/python2.6/site-packages']
I noticed that on of the paths indeed points to the default installation of Python. My questions thus are:
- Why this path shows up here, as the local installation has nothing to do with the default one?
- How do I change it (in a clean and permanent way)? This path should be the path to lib-dynload in the local installation instead.
Thanks

You probably don't have your Python's bin directory in the PATH variable before the system Python.
Or perhaps you simply compiled your Python incorrectly and did not use:
./configure --prefix=/tmp/work/mdorier1/local
so now it thinks that its files are somewhere else.

Related

Python3 ModuleNotFoundError when running from command line but works if I enter the shell

I think I'm missing something obvious here. I cloned this repo, and now have this directory structure on my computer:
When I try to run python baby_cry_detection/pc_main/train_set.py, I get a ModuleNotFoundError.
Traceback (most recent call last):
File "baby_cry_detection/pc_main/train_set.py", line 10, in <module>
from baby_cry_detection.pc_methods import Reader
ModuleNotFoundError: No module named 'baby_cry_detection'
However, if I type python and enter the interactive shell and then type the command
from baby_cry_detection.pc_methods import Reader
it imports just fine with no error. I'm completely baffled. I'm using a virtualenv and both instances are using the same python installation, and I haven't changed directories at all.
I think sys.path could be the reason that the module is not found when python command is executed. Here is how we can check if that is indeed the case:
In the train_set.py file, add import sys; print(sys.path). Looking at the error, the path may contain /path/to/baby_cry_detection/baby_cry_detection/pc_main. If that is the case, then we have found the issue which is that baby_cry_detection.pc_methods will not be found in the directory that sys.path is looking into. We'll need to append the parent baby_cry_detection directory to sys.path or use relative imports. See this answer.
The reason that python prompt successfully imports the module could be because the prompt is started in the correct parent directory. Try changing the directory to baby_cry_detection/pc_main/ and try importing the module.

ImportError in Scripts directory

Using windows 7 and python 2.7. I have a package named Regetron in c:\Python27\Lib\site-packages\regetron which contains __init__.py and engine.py. When I try to run this library from the command prompt by typing regetron I get the following error:
Traceback (most recent call last):
File "C:\Python27\Scripts\regetron.py", line 6, in <module>
from regetron.engine import Regetron
File "C:\Python27\Scripts\regetron.py", line 6, in <module>
from regetron.engine import Regetron
ImportError: No module named engine
I added c:\Python27\Lib\site-packages\regetron to %PYTHONPATH% and can successfully import this module from other scripts located in other folders as well as the interactive prompt, but for some reason it refuses to run from the command prompt. What is going on?
You actually have two problems here. Fixing either one of them would actually eliminate your immediate error, but you need to fix both of them.
When I try to run this library from the command prompt by typing regetron
You shouldn't have a script named regetron and also have a module or package named regetron. Fix it by renaming your script. But if you want to understand why it's causing a problem:
The current working directory is always part of sys.path. So, you're in the directory with regetron.py in, and you run it with regetron. That means that regetron.py is on the path. So when you import regetron, it finds your script, not the package. Or, when you from regetron import engine, it finds your script, and tries to import a variable/function/class/whatever named engine from it, rather than finding the package and trying to import a module underneath it.
I added c:\Python27\Lib\site-packages\regetron to %PYTHONPATH%
Never add a package's directory to sys.path.
Since site-packages is already on your sys.path, the code in regetron/engine.py is already available as regetron.engine. You don't want it to also be available as engine. This will cause all kinds of problems.
So, rename you script to something else, remove regetron from %PYTHONPATH%, and everything will be fine.
But you may want to (re-)read the section on Packages in the tutorial.

Why is PYTHONPATH being ignored?

I am setting PYTHONPATH to have a directory that includes a few .py files.
When I go into python and type "import file", the file cannot be find (it says "No module named wsj10").
If, however, I cd to the directory, and repeat the same process, then the file is found.
I am just not sure why PYTHONPATH is being ignored. I followed exact instructions from installation instructions of some software, so I know I am doing the right thing.
Any circumstances under which PYTHONPATH will be ignored, or import won't work?
Thanks.
Following a comment below, here is a transcript:
untar file1.tgz to file1/. file1.tgz contains a library/file called file1.py.
type in the shell:
export PYTHONPATH=`pwd`/file1/:./
echo $PYTHONPATH shows the variable was set.
run python and type "import file1"
I get the error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named file1
If I do first "cd file1" and then to import file1 it identifies the file.
Any circumstances under which PYTHONPATH will be ignored, or import won't work?
Yes. I've set PYTHONPATH in my /home/me/.bashrc and all worked ok from terminal, but when Apache w/ mod_wsgi starts my python scripts, it acts under sysem or dedicated user, which knows nothing of my .bashrc.
For this particular situation, I just used apache config to set python path for apache (WSGIPythonPath option).

Imports working with raw file, but not in IDLE

UPDATE 10 Secs later
Fixed properly now, and thanks to JF and Gauden.
UPDATE
I have found a temporary fix by saving the IDLE file in the directory the other working file is in. (I would still like to know how to fix it entirely if I can.)
That's not a permanant fix, so if you want to try and help make it work wherever the file is saved, feel free.
This is the start of a python file:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import wikipedia
import pagegenerators
import sys
import re
import pywikibot
from pywikibot import *
(You may have noticed it's a pywikipedia script, but I think that's irrelevent)
This file runs fine from the command line.
However, when I try and use IDLE to develop the script, or just use the IDLE interpreter, I get an error:
>>> import wikipedia
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
import wikipedia
ImportError: No module named wikipedia
I don't really have a clue why it isn't working.
I have also tried this:
>>> imp.find_module("wikipedia.py","f:/ake/pa/th/")
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
imp.find_module("wikipedia.py","f:/ake/pa/th/")
ImportError: No frozen submodule named f:/ake/pa/th/.wikipedia.py
The path given in the error log is the correct path to the wikipedia.py file, there's just that . before wikipedia.py.
I then tried adding the path to sys.path, but that didn't work either:
>>> import sys
>>> sys.path.append("c/users/adam/py")
#the same error...
Path to the module: `c:\users\joe_bloggs\py\wikipedia.pyc
Python executable: Command line:C:\Python27\python.exe, IDLE: C:\Python27\pythonw.exe
PYTHONPATH throws, in both:
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
print os.environ['PYTHONPATH'].split(os.pathsep)
File "C:\Python27\lib\os.py", line 423, in __getitem__
return self.data[key.upper()]
KeyError: 'PYTHONPATH'
OS: Windows 7
Python version: 2.7.2
A new PATH: IDLE, and Command Line:
C:\Program Files\Common Files\Microsoft Shared\Windows Live
C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live
C://Python27
C:\Program Files (x86)\IVI Foundation\VISA\WinNT\Bin
C:\Program Files (x86)\QuickTime\QTSystem\
C:\Program Files (x86)\Windows Live\Shared
EDIT The answer to the above question proved to be fairly simple, but I am editing this answer as a possible troubleshooting checklist for future reference, and as a checklist for others who may need to prepare questions of this nature in the future.
CLUE 1: What is the path to the module you are importing?
>>> import wikipedia
>>> print wikipedia.__file__
This will give you the path to the compiled module, and is one clue.
CLUE 2: What is the path to the Python executable?
(See also this question).
>>> import sys
>>> print sys.executable
Try this in the shell and in an IDLE script. If the two results are different, then you are using two Python interpreters and only one of them has a path that points to the wikipedia module.
CLUE 3: What is the sys.path?
Also repeat this in both shell and as a script in IDLE.
>>> print '\n'.join( sys.path )
(You may be able to use sys.path.append("d:/irectory/folder/is/in") to add that location to the sys.path. This should add that directory to the list of places Python looks for modules.)
CLUE 4: What is the PYTHONPATH and does it differ in the two environments?
(See also this answer).
Finally repeat this in both shell and as a script in IDLE.
>>> import os
>>> print '\n'.join( os.environ['PATH'].split(os.pathsep) )
Again note the two results (from shell and from IDLE) and see if there is difference in the PYTHONPATH in the two environments.
If all these tests prove inconclusive, I would add as much of this information as you can to your question as it would help give you specific further leads. Also add what OS you are using and any tracebacks that you get.
I had the same problem when trying to import a newly installed library on my Raspberry Pi. I followed all the instructions to install the library (Adafruit RHT Sensor) and it worked fine from the terminal. However, I couldn't get it to work from within IDLE.
It turned out that the problem was that the Raspberry Pi has both Python 2 and 3 installed. The install I'd done (using the 'python' command) only applied to Python 2. I had to perform another install using the 'python3' command to install it for Python 3. After that, I restarted IDLE and all worked fine.
The suggestion above to print the sys executable path helped point out the discrepancy:
import sys
print sys.executable

ctypes doesn't find fink-installed libraries in /sw/lib

ctypes isn't finding libraries installed via fink, which live under /sw/lib/, unless I explicitly give the full path to the libraries
>>> import ctypes
>>> ctypes.CDLL('libgoffice-0.8.dylib')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/sw/lib/python2.7/ctypes/__init__.py", line 353, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(libgoffice-0.8.dylib, 6): image not found
>>> ctypes.CDLL('/sw/lib/libgoffice-0.8.dylib')
<CDLL '/sw/lib/libgoffice-0.8.dylib', handle 336500 at 2b10b0>
>>>
Compilation against these libraries with gcc, however, works fine; they are always found. Why isn't ctypes locating these libraries, and what can I do to make it locate them?
This is on OS X 10.6.8 with fink-installed Python 2.7 under /sw/bin/python2.7.
The problem seems to be that fink never sets the LD_LIBRARY_PATH variable. ctypes uses dlopen() which will not search in /sw/lib by default. From the dlopen man page:
dlopen() searches for a compatible Mach-O file in the directories speci-
fied by a set of environment variables and the process's current working
directory. When set, the environment variables must contain a colon-sep-
arated list of directory paths, which can be absolute or relative to the
current working directory. The environment variables are LD_LIBRARY_PATH,
DYLD_LIBRARY_PATH, and DYLD_FALLBACK_LIBRARY_PATH. The first two vari-
ables have no default value. The default value of DYLD_FALL-
BACK_LIBRARY_PATH is $HOME/lib;/usr/local/lib;/usr/lib. dlopen()
searches the directories specified in the environment variables in the
order they are listed.
So the solution seems to be to put in your .profile, .bash_profile, or .bashrc
export LD_LIBRARY_PATH=/sw/lib:"${LD_LIBRARY_PATH}"
It also seems that fink installs some libraries in subdirectories under /sw/lib, such as /sw/lib/mysql. In these cases, you will have to explicitly include those, as well, because it seems like the dlopen() does not recursively search the paths in LD_LIBRARY_PATH. In the case of MySQL, you would need to add that in the path:
export LD_LIBRARY_PATH=/sw/lib:/sw/lib/mysql:"${LD_LIBRARY_PATH}"

Categories