Adding modules in atom in python - python

I have the module pygame and tkinter installed on my computer, but I cannot find out how to access them in the text editor atom. I can use them in IDLE by using
import pygame
but when I try to import it in atom it doesn't recognize the module. Anybody know why? All of my other imports work by the way (time, random, etc.) but I think that they work because they come installed with python (right?).

Firstly, atom is a text editor, it does not run python code by itself. So when you say you're trying to "import it in atom", I have to assume you're using an atom plugin that can interpret code. One common plugin for this is "script".
You need to head to the atom settings to check which python install is being used. Do this by first entering atom settings with control+,, then click on "packages" on the navagator, and click on "script" (or whatever plugin you're using to run your code, e.g. script, Hydrogen, atom-runner etc.). In the script settings, click on "view code", which will open the source code of script. On the tree nagivator on the left, navigate to script-->lib-->grammars-->python.coffee
In this coffeescript file, you should find the python interpreter that atom-script is using. For example, since I use anaconda, mine reads:
exports.Python =
'Selection Based':
command: '/home/username/.miniconda3/envs/local35/bin/python'
args: (context) -> ['-u', '-c', context.getCode()]
If you run linux or mac, now you can open a terminal and run
which python
import pygame should theoretically work if the system python matches the one atom is using, so these will probably be different. Just replace the python path in the coffeescript file with the result of which python. If these are already the same, this process should at least give you some clues to further diagnose the issue.
Personally, I recommend the use of Anaconda to keep track of your python environments and modules, it can really help with issues like this.
Also do make sure that python -c "import pygame" works, because if it doesn't, this isn't an atom issue at all.

I'm a new user. John Kealy's answer is what helped solve my Atom 1.40.1 (using Script 3.18.1,) "..module not found" issue. From the Python 3.7 interpreter:
Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32
My pip list:
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\erica> pip list
Package Version
--------------- -----------
bleak 0.5.0
bricknil-bleak 0.3.1
cycler 0.10.0
kiwisolver 1.1.0
matplotlib 3.1.1
mpmath 1.1.0
numpy 1.16.4
pip 19.2.3
pybluez 0.22
pyparsing 2.4.0
python-dateutil 2.8.0
pythonnet 2.4.0
pyVIP 1.3.0
scipy 1.3.0
setuptools 41.2.0
six 1.12.0
sympy 1.4
virtualenv 16.7.4
wheel 0.33.4
winrt 1.0.19128.1
I right-clicked on the Python interpreter icon and copied the target string from the properties dialog box:
C:\Users\erica\AppData\Local\Programs\Python\Python37\python.exe
From the python.coffee script John mentioned, where "command:" originally read:
exports.Python =
'Selection Based':
command: 'python'
args: (context) -> ['-u', '-c', context.getCode()]
'File Based':
command: 'python'
args: ({filepath}) -> ['-u', filepath]
I then modified to:
exports.Python =
'Selection Based':
command: 'C:/Users/erica/AppData/Local/Programs/Python/Python37/python'
args: (context) -> ['-u', '-c', context.getCode()]
'File Based':
command: 'C:/Users/erica/AppData/Local/Programs/Python/Python37/python'
args: ({filepath}) -> ['-u', filepath]
So now I can have this code in my test.py file:
import bluetooth as bt
for e in bt.__dict__:
print(e)
...and cntrl-shift-b to the results in the Script output window at the bottom of my Atom screen:
[Command: C:/Users/erica/AppData/Local/Programs/Python/Python37/python -u C:\Users\erica\AppData\Local\Programs\Python\Python37\test.py]
__name__
__doc__
__package__
__loader__
__spec__
__path__
__builtins__
__file__
__cached__
sys
os
btcommon
struct
binascii
L2CAP
RFCOMM
PORT_ANY
SDP_SERVER_CLASS
BROWSE_GRP_DESC_CLASS
PUBLIC_BROWSE_GROUP
SERIAL_PORT_CLASS
LAN_ACCESS_CLASS
DIALUP_NET_CLASS
IRMC_SYNC_CLASS
OBEX_OBJPUSH_CLASS
OBEX_FILETRANS_CLASS
IRMC_SYNC_CMD_CLASS
HEADSET_CLASS
CORDLESS_TELEPHONY_CLASS
AUDIO_SOURCE_CLASS
AUDIO_SINK_CLASS
AV_REMOTE_TARGET_CLASS
ADVANCED_AUDIO_CLASS
AV_REMOTE_CLASS
VIDEO_CONF_CLASS
INTERCOM_CLASS
FAX_CLASS
HEADSET_AGW_CLASS
WAP_CLASS
WAP_CLIENT_CLASS
PANU_CLASS
NAP_CLASS
GN_CLASS
DIRECT_PRINTING_CLASS
REFERENCE_PRINTING_CLASS
IMAGING_CLASS
IMAGING_RESPONDER_CLASS
IMAGING_ARCHIVE_CLASS
IMAGING_REFOBJS_CLASS
HANDSFREE_CLASS
HANDSFREE_AGW_CLASS
DIRECT_PRT_REFOBJS_CLASS
REFLECTED_UI_CLASS
BASIC_PRINTING_CLASS
PRINTING_STATUS_CLASS
HID_CLASS
HCR_CLASS
HCR_PRINT_CLASS
HCR_SCAN_CLASS
CIP_CLASS
VIDEO_CONF_GW_CLASS
UDI_MT_CLASS
UDI_TA_CLASS
AV_CLASS
SAP_CLASS
PNP_INFO_CLASS
GENERIC_NETWORKING_CLASS
GENERIC_FILETRANS_CLASS
GENERIC_AUDIO_CLASS
GENERIC_TELEPHONY_CLASS
UPNP_CLASS
UPNP_IP_CLASS
UPNP_PAN_CLASS
UPNP_LAP_CLASS
UPNP_L2CAP_CLASS
VIDEO_SOURCE_CLASS
VIDEO_SINK_CLASS
SDP_SERVER_PROFILE
BROWSE_GRP_DESC_PROFILE
SERIAL_PORT_PROFILE
LAN_ACCESS_PROFILE
DIALUP_NET_PROFILE
IRMC_SYNC_PROFILE
OBEX_OBJPUSH_PROFILE
OBEX_FILETRANS_PROFILE
IRMC_SYNC_CMD_PROFILE
HEADSET_PROFILE
CORDLESS_TELEPHONY_PROFILE
AUDIO_SOURCE_PROFILE
AUDIO_SINK_PROFILE
AV_REMOTE_TARGET_PROFILE
ADVANCED_AUDIO_PROFILE
AV_REMOTE_PROFILE
VIDEO_CONF_PROFILE
INTERCOM_PROFILE
FAX_PROFILE
HEADSET_AGW_PROFILE
WAP_PROFILE
WAP_CLIENT_PROFILE
PANU_PROFILE
NAP_PROFILE
GN_PROFILE
DIRECT_PRINTING_PROFILE
REFERENCE_PRINTING_PROFILE
IMAGING_PROFILE
IMAGING_RESPONDER_PROFILE
IMAGING_ARCHIVE_PROFILE
IMAGING_REFOBJS_PROFILE
HANDSFREE_PROFILE
HANDSFREE_AGW_PROFILE
DIRECT_PRT_REFOBJS_PROFILE
REFLECTED_UI_PROFILE
BASIC_PRINTING_PROFILE
PRINTING_STATUS_PROFILE
HID_PROFILE
HCR_PROFILE
HCR_PRINT_PROFILE
HCR_SCAN_PROFILE
CIP_PROFILE
VIDEO_CONF_GW_PROFILE
UDI_MT_PROFILE
UDI_TA_PROFILE
AV_PROFILE
SAP_PROFILE
PNP_INFO_PROFILE
GENERIC_NETWORKING_PROFILE
GENERIC_FILETRANS_PROFILE
GENERIC_AUDIO_PROFILE
GENERIC_TELEPHONY_PROFILE
UPNP_PROFILE
UPNP_IP_PROFILE
UPNP_PAN_PROFILE
UPNP_LAP_PROFILE
UPNP_L2CAP_PROFILE
VIDEO_SOURCE_PROFILE
VIDEO_SINK_PROFILE
SERVICE_RECORD_HANDLE_ATTRID
SERVICE_CLASS_ID_LIST_ATTRID
SERVICE_RECORD_STATE_ATTRID
SERVICE_ID_ATTRID
PROTOCOL_DESCRIPTOR_LIST_ATTRID
BROWSE_GROUP_LIST_ATTRID
LANGUAGE_BASE_ATTRID_LIST_ATTRID
SERVICE_INFO_TIME_TO_LIVE_ATTRID
SERVICE_AVAILABILITY_ATTRID
BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRID
DOCUMENTATION_URL_ATTRID
CLIENT_EXECUTABLE_URL_ATTRID
ICON_URL_ATTRID
SERVICE_NAME_ATTRID
SERVICE_DESCRIPTION_ATTRID
PROVIDER_NAME_ATTRID
SDP_UUID
UDP_UUID
RFCOMM_UUID
TCP_UUID
TCS_BIN_UUID
TCS_AT_UUID
OBEX_UUID
IP_UUID
FTP_UUID
HTTP_UUID
WSP_UUID
BNEP_UUID
UPNP_UUID
HIDP_UUID
HCRP_CTRL_UUID
HCRP_DATA_UUID
HCRP_NOTE_UUID
AVCTP_UUID
AVDTP_UUID
CMTP_UUID
UDI_UUID
L2CAP_UUID
IAC_GIAC
IAC_LIAC
BluetoothError
is_valid_address
is_valid_uuid
to_full_uuid
sdp_parse_size_desc
sdp_parse_uuid
sdp_parse_int
sdp_parse_data_elementSequence
sdp_parse_data_element
sdp_parse_raw_record
sdp_make_data_element
__version__
_dbg
have_widcomm
dll
sysroot
_msbt
msbt
bt
discover_devices
read_local_bdaddr
lookup_name
BluetoothSocket
advertise_service
stop_advertising
find_service
DeviceDiscoverer
[Finished in 0.417s]
Additionally, from inquiry.py:
import bluetooth
print("performing inquiry...")
nearby_devices = bluetooth.discover_devices(
duration=8, lookup_names=True, flush_cache=True, lookup_class=False)
print("found %d device(s)" % len(nearby_devices))
for addr, name in nearby_devices:
try:
print(" %s - %s" % (addr, name))
except UnicodeEncodeError:
print(" %s - %s" % (addr, name.encode('utf-8', 'replace')))
...and again cntrl-shift-b to the results in the Script output window at the bottom of my Atom screen:
performing inquiry...
found 1 device(s)
98:FD:B4:47:0D:14 - HP Bluetooth Mouse X4000b
[Finished in 10.601s]
Seems that my access to my Python modules is working now.

Related

failed to create executable with pyinstaller and cefpython on Linux (Invalid file descriptor to ICU data)

I have some simple cefpython code opening a url and am trying to create a stand alone executable with pyinstaller:
I copied files from https://github.com/cztomczak/cefpython/tree/master/examples/pyinstaller to a a directry named pyinstaller
I made following minor changes to pyinstaller.spec
+SECRET_CIPHER = ""
...
- ["../wxpython.py"],
+ ["../hello.py"],
...
- icon="../resources/wxpython.ico")
+ )
I can successfully compile my application on windows with python
On the same machine with python 3.5.4 64 bit and following virtualenv:
cefpython3==66.0
future==0.18.2
PyInstaller==3.2.1
pypiwin32==223
pywin32==228
I can also compile windows with python 3.6.4 64 and following virtualenv:
altgraph==0.17
cefpython3==66.0
future==0.18.2
macholib==1.14
pefile==2019.4.18
PyInstaller==3.3.1
pyinstaller-hooks-contrib==2020.9
pypiwin32==223
pywin32==228
pywin32-ctypes==0.2.0
On Linux compilation works as well, but the executable is not operational.
I get following output and error:
CEF Python 66.0
Chromium 66.0.3359.181
CEF 3.3359.1774.gd49d25f
Python 3.5.2 64bit
[1013/180954.001980:ERROR:icu_util.cc(133)] Invalid file descriptor to ICU data received.
Trace/breakpoint trap (core dumped)
version is python 3.5.2 64bit and the virtualenv is:
cefpython3==66.0
pkg-resources==0.0.0
PyInstaller==3.2.1
What could be the cause?
The code, that I try to compile is below:
import platform
import sys
from cefpython3 import cefpython as cef
def check_versions():
ver = cef.GetVersion()
print("CEF Python {ver}".format(ver=ver["version"]))
print("Chromium {ver}".format(ver=ver["chrome_version"]))
print("CEF {ver}".format(ver=ver["cef_version"]))
print("Python {ver} {arch}".format(
ver=platform.python_version(),
arch=platform.architecture()[0]))
assert cef.__version__ >= "57.0", "CEF Python v57.0+ required to run this"
def main(url="https://www.stackoverflow.com"):
sys.excepthook = cef.ExceptHook
check_versions()
settings = {}
switches = {}
browser_settings = {}
cef.Initialize(settings=settings, switches=switches)
cef.CreateBrowserSync(
url=url,
window_title="CEF_HELLO: ",
settings=browser_settings,
)
cef.MessageLoop()
cef.Shutdown()
if __name__ == "__main__":
main()
Addendum: 2020-10-14:
same error on linux with other versions:
so far I tried python 3.5 and 3.7
Is there anybody who successfully created an executable?
I could be, that this just an issue with the example project and its configuration?
As alternative, a solution could be found in PyInstaller bug 5400
Here the steps:
1- download the PyInstaller helper in CEFpython named hook-cefpython3.py from:
https://github.com/cztomczak/cefpython/tree/master/examples/pyinstaller and put in the root directory of your project
2- In that file, replace the line:
from PyInstaller.compat import is_win, is_darwin, is_linux, is_py2
with:
from PyInstaller.compat import is_win, is_darwin, is_linux
is_py2 = False
3- in your PyInstaller .spec file, add the '.' to the hookspath, e.g. hookspath=['.']. I think it is also possible to add it as PyInstaller command line option.
These steps should solve the problem, until CEFPython deliver a correct version of the hook file.
This is not really the answer I would like to accept, but it is at least one solution and contains information, that might lead to a better fix, a better answer.
After debugging with strace I found out, that the executable searches many files like for example icudtl.dat, v8_context_snapshot.bin, locales/* were searched in
'dist/cefapp/cefpython3but were copied todist/cefapp/`
An ugly work around is to do following after compilation
cd dist/cefapp/cefpython3
ln -s ../* .
and the executable works.
I'm sure there is also a nicer non-brute-force solution, but for the time being I wanted to answer in case others are stuck as well
Probably this can be fixed in the spec file but would we need one spec file for linux and one for windows then?
Perhaps there's also an option to tell the excutable to search for these files one level higer?
To solve this, you need to set this in your spec file:
hookspath=[r'YOUR_ENV_SITE_PACKAGES\cefpython3\examples\pyinstaller\']
And then rebuild, you will have things in the right place.
The following steps solved the issue for me on Windows 10, Python 3.9.5 32-bit, PyInstaller 4.3, and CEFPython 66.1:
Download the hook-cefpython3.py file from here and put it into your project root directory.
Run the pyinstaller command as usual but add the --additional-hooks-dir . command line option, so the command will look like this:
pyinstaller --additional-hooks-dir . <main-file.py>
As opposed to other answers here, this anser neither requires changes of hookspath directive in pyinstaller's spec file and, as of now, nor any changes to the downloaded hook-cefpython3.py file.

How can I create the minimum size executable with pyinstaller?

I am on Windows 10, I have anaconda installed but I want to create an executable independently in a new, clean minimal environment using python 3.5. So I did some tests:
TEST1:
I created a python script test1.py in the folder testenv with only:
print('Hello World')
Then I created the environment, installed pyinstaller and created the executable
D:\testenv> python -m venv venv_test
...
D:\testenv\venv_test\Scripts>activate.bat
...
(venv_test) D:\testenv>pip install pyinstaller
(venv_test) D:\testenv>pyinstaller --clean -F test1.py
And it creates my test1.exe of about 6 Mb
TEST 2: I modified test1.py as follows:
import pandas as pd
print('Hello World')
I installed pandas in the environment and created the new executable:
(venv_test) D:\testenv>pip install pandas
(venv_test) D:\testenv>pyinstaller --clean -F test1.py
Ant it creates my test1.exe which is now of 230 Mb!!!
if I run the command
(venv_test) D:\testenv>python -V
Python 3.5.2 :: Anaconda custom (64-bit)
when I am running pyinstaller I get some messages I do not understand, for example:
INFO: site: retargeting to fake-dir 'c:\\users\\username\\appdata\\local\\continuum\\anaconda3\\lib\\site-packages\\PyInstaller\\fake-modules'
Also I am getting messages about matplotlib and other modules that have nothing to do with my code, for example:
INFO: Matplotlib backend "pdf": added
INFO: Matplotlib backend "pgf": added
INFO: Matplotlib backend "ps": added
INFO: Matplotlib backend "svg": added
I know there are some related questions:
Reducing size of pyinstaller exe, size of executable using pyinstaller and numpy
but I could not solve the problem and I am afraid I am doing something wrong with respect to anaconda.
So my questions are:
what am I doing wrong? can I reduce the size of my executable?
I accepted the answer above but I post here what I did step by step for complete beginners like me who easily get lost.
Before I begin I post my complete test1.py example script with all the modules I actually need. My apologies if it is a bit more complex than the original question but maybe this can help someone.
test1.py looks like this:
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.image as image
import numpy as np
import os.path
import pandas as pd
import re
from matplotlib.ticker import AutoMinorLocator
from netCDF4 import Dataset
from time import time
from scipy.spatial import distance
from simpledbf import Dbf5
from sys import argv
print('Hello World')
I added matplotlib.use('Agg') (as my actual code is creating figures)
Generating a PNG with matplotlib when DISPLAY is undefined
1) Install a new version of python independently from anaconda.
downloaded python from:
https://www.python.org/downloads/
installed selecting 'add python to path' and deselecting install launcher for all users (I don't have admin rights)
check that I am using the same version from CMD, just writing python I get:
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017,
06:04:45) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
2) Create and activate the environment, from CMD
D:\> mkdir py36envtest
...
D:\py36envtest>python -m venv venv_py36
...
D:\py36envtest\venv_py36\Scripts>activate.bat
3) Install in the environment all the modules needed in the script
Making sure they are compatible to the python version with the command:
(from Matplotlib not recognized as a module when importing in Python)
(venv_py36) D:\py36envtest> python -m pip install nameofmodule
NB: in my case I also had to add the option --proxy https://00.000.000.00:0000
for the example I used development version of py installer:
(venv_py36) D:\py36envtest> python -m pip install https://github.com/pyinstaller/pyinstaller/archive/develop.tar.gz
and the modules: pandas, matplolib, simpledbf, scipy, netCDF4. At the end my environment looks like this.
(venv_py36) D:\py36envtest> pip freeze
altgraph==0.15
cycler==0.10.0
future==0.16.0
macholib==1.9
matplotlib==2.1.2
netCDF4==1.3.1
numpy==1.14.0
pandas==0.22.0
pefile==2017.11.5
PyInstaller==3.4.dev0+5f9190544
pyparsing==2.2.0
pypiwin32==220
python-dateutil==2.6.1
pytz==2017.3
scipy==1.0.0
simpledbf==0.2.6
six==1.11.0
style==1.1.0
update==0.0.1
4) Create/modify the .spec file (when you run pyinstaller it creates a .spec file, you can rename).
Initially I got a lot of ImportError: DLL load failed (especially for scipy) and missing module error which I solved thanks to these posts:
What is the recommended way to persist (pickle) custom sklearn pipelines?
and the comment to this answer:
Pyinstaller with scipy.signal ImportError: DLL load failed
My inputtest1.spec finally looks like this:
# -*- mode: python -*-
options = [ ('v', None, 'OPTION')]
block_cipher = None
a = Analysis(['test1.py'],
pathex=['D:\\py36envtest', 'D:\\py36envtest\\venv_py36\\Lib\\site-packages\\scipy\\extra-dll' ],
binaries=[],
datas=[],
hiddenimports=['scipy._lib.messagestream',
'pandas._libs.tslibs.timedeltas'],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='test1',
debug=False,
strip=False,
upx=True,
runtime_tmpdir=None,
console=True )
5) Finally make the executable with the command
(venv_py36) D:\py36envtest>pyinstaller -F --clean inputtest1.spec
my test1.exe is 47.6 Mb, the .exe of the same script created from an anaconda virtual environment is 229 Mb.
I am happy (and if there are more suggestions they are welcome)
The problem is that you should not be using a virtual environment and especially not anaconda. Please download default python 32 bit and use only necessary modules. Then follow the steps provided in the links, this should definitely fix it.
Although you created a virtual env, are you sure your spec file is not linking to old Anaconda entries?
If all this fails, then submit a bug as this is very strange.
I had a similar problem and found a solution.
I used Windows terminal preview. This program allows creation of various virtual environments like Windows Power Shell (btw. Linux Ubuntu too. Also, worth noting: you can have many terminals in this program installed and, even, open a few at once. Very cool stuff).
Inside Windows Power Shell in Windows terminal preview I installed all the necessary libraries (like numpy, pandas,re, etc.), then I opened the path to my file and tried to use this command:
pyinstaller --onefile -w 'filename.py'
...but, the output exe didn't work. For some reason, the console said that there is a lack of one library (which I had installed earlier). I've found the solution in mimic the auto-py-to-exe library. The command used by this GUI is:
pyinstaller --noconfirm --onedir --console "C:/Users/something/filename.py"
And this one works well. I reduced the size of my output exe program from 911MB to 82,9MB !!!
BTW. 911MB was the size of output made by auto-py-to-exe.
I wonder how is it possible that no one yet has created a compressor that reads the code, checks what libraries are part of the code, then putting only them inside the compression. In my case, auto-py-to-exe probably loaded all libraries that I ever installed. That would explain the size of this compressed folder.
Some suggest using https://virtualenv.pypa.io/en/stable/ but in my opinion, this library is very difficult, at least for me.

py2app Error OSX El Capitan

In Alias mode, this fails.
Here's what I'm running:
OSX 10.11.1 (El Capitan)
Python 3.5 via Anaconda (with the Jupyter 4.1.0 Notebook)
py2app is the newest version (0.9)
Here's what I'm doing:
Create script and save as APP_OSX.py
Enter the following commands in terminal:
py2applet --make-setup APP_OSX.py
rm -rf build dist
python setup.py py2app -A
This is after I installed a regular version of Python 3.5.1 from python.org (because there was an issue with using py2app and my Anaconda Python 3.5.1 version).
Then I find the bundled app under the 'dist' folder and open it and a box pops up with the name of my app and "error".
From the console, I get this:
3/30/16 7:37:18.972 PM APP_OSX[5819]: 2016-03-30 19:37:18.971 APP_OSX[5819:746261] APP_OSX Error
3/30/16 7:37:21.511 PM sharedfilelistd[242]: SecTaskLoadEntitlements failed error=22
3/30/16 7:37:21.585 PM Console[5822]: Failed to connect (_consoleX) outlet from (NSApplication) to (ConsoleX): missing setter or instance variable
3/30/16 7:37:25.893 PM WindowServer[161]: send_datagram_available_ping: pid 349 failed to act on a ping it dequeued before timing out.
3/30/16 7:37:51.601 PM Console[5822]: Persistent UI failed to open file file:///Users/mi/Library/Saved%20Application%20State/com.apple.Console.savedState/window_3.data: Permission denied (13)
Not sure if this helps, but the script uses the following libraries:
Numpy
Pandas
Easygui
Thanks in advance!

Can't import the cx_Oracle module unless I'm using an interactive shell

When using Python on an interactive shell I'm able to import the cx_Oracle file with no problem. Ex:
me#server~/ $ python
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cx_Oracle
>>>
As you can see, importing works without a hitch. However, when I try to run a Python script doing the same thing, I get an error:
me#server~/ $ sudo script.py
Traceback (most recent call last):
File "/usr/local/bin/script.py", line 19, in <module>
import cx_Oracle
ImportError: No module named "cx_Oracle'
Here is the important section from script.py:
# 16 other lines above here
# Imports
import sys
import cx_Oracle
import psycopg2
...
I'm befuddled here. Other pertinent information is the server I'm running is Ubuntu 14.04.1 LTS (upgraded from 12.04) 64bit. which python and sudo which python both point to the same location. Also, doing this as root via sudo su - gets the same results; import OK from interactive but error from script.
Nothing other than the OS upgrade happened between when this worked and when it stopped working.
Sorry, all. This was a silly on my part. Turns out the script in question was using Python3, and when the server upgraded, Python3 went from being 3.2 version to being 3.4 version.
Once the cx_Oracle module was set up in the 3.4 version, everything worked as expected.
Phil, your final note talking about the shebang was what lead me to discover this, so kudos to you! The reason I didn't mark your response as the answer was because technically it wasn't but led me on the right path.
Cheers!
sudo starts a new bash environment which is then pointing to a different python executable (different installed modules).
You can verify this with which python and sudo which python
EDIT: so if they point to the same executable, then you should look at sys.path to find differences. In both environemnts you can:
python -c "import sys; print('\n'.join(sys.path))"
sudo python -c "import sys; print('\n'.join(sys.path))"
Look for differences. If there are none:
A common error in import situations like this is that python will first look at the local dir. So if you happen to be running python and importing something what is found locally (i.e. cx_Oracle is a subdir of your current location), you will get an import error if you change directories.
Final note: I have assumed here that the shbang of the script.py points to the same executable as which python. That is, that python script.py and script.py return the same error.

How do I find the location of my Python site-packages directory?

How do I find the location of my site-packages directory?
There are two types of site-packages directories, global and per user.
Global site-packages ("dist-packages") directories are listed in sys.path when you run:
python -m site
For a more concise list run getsitepackages from the site module in Python code:
python -c 'import site; print(site.getsitepackages())'
Caution: In virtual environments getsitepackages is not available with older versions of virtualenv, sys.path from above will list the virtualenv's site-packages directory correctly, though. In Python 3, you may use the sysconfig module instead:
python3 -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])'
The per user site-packages directory (PEP 370) is where Python installs your local packages:
python -m site --user-site
If this points to a non-existing directory check the exit status of Python and see python -m site --help for explanations.
Hint: Running pip list --user or pip freeze --user gives you a list of all installed per user site-packages.
Practical Tips
<package>.__path__ lets you identify the location(s) of a specific package: (details)
$ python -c "import setuptools as _; print(_.__path__)"
['/usr/lib/python2.7/dist-packages/setuptools']
<module>.__file__ lets you identify the location of a specific module: (difference)
$ python3 -c "import os as _; print(_.__file__)"
/usr/lib/python3.6/os.py
Run pip show <package> to show Debian-style package information:
$ pip show pytest
Name: pytest
Version: 3.8.2
Summary: pytest: simple powerful testing with Python
Home-page: https://docs.pytest.org/en/latest/
Author: Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna Laugher, Florian Bruhin and others
Author-email: None
License: MIT license
Location: /home/peter/.local/lib/python3.4/site-packages
Requires: more-itertools, atomicwrites, setuptools, attrs, pathlib2, six, py, pluggy
>>> import site; site.getsitepackages()
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']
(or just first item with site.getsitepackages()[0])
A solution that:
outside of virtualenv - provides the path of global site-packages,
insidue a virtualenv - provides the virtualenv's site-packages
...is this one-liner:
python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
Formatted for readability (rather than use as a one-liner), that looks like the following:
from distutils.sysconfig import get_python_lib
print(get_python_lib())
Source: an very old version of "How to Install Django" documentation (though this is useful to more than just Django installation)
For Ubuntu,
python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
...is not correct.
It will point you to /usr/lib/pythonX.X/dist-packages
This folder only contains packages your operating system has automatically installed for programs to run.
On ubuntu, the site-packages folder that contains packages installed via setup_tools\easy_install\pip will be in /usr/local/lib/pythonX.X/dist-packages
The second folder is probably the more useful one if the use case is related to installation or reading source code.
If you do not use Ubuntu, you are probably safe copy-pasting the first code box into the terminal.
This is what worked for me:
python -m site --user-site
A modern stdlib way is using sysconfig module, available in version 2.7 and 3.2+. Unlike the current accepted answer, this method still works regardless of whether or not you have a virtual environment active.
Note: sysconfig (source) is not to be confused with the distutils.sysconfig submodule (source) mentioned in several other answers here. The latter is an entirely different module and it's lacking the get_paths function discussed below. Additionally, distutils is deprecated in 3.10 and will be unavailable soon.
Python currently uses eight paths (docs):
stdlib: directory containing the standard Python library files that are not platform-specific.
platstdlib: directory containing the standard Python library files that are platform-specific.
platlib: directory for site-specific, platform-specific files.
purelib: directory for site-specific, non-platform-specific files.
include: directory for non-platform-specific header files.
platinclude: directory for platform-specific header files.
scripts: directory for script files.
data: directory for data files.
In most cases, users finding this question would be interested in the 'purelib' path (in some cases, you might be interested in 'platlib' too). The purelib path is where ordinary Python packages will be installed by tools like pip.
At system level, you'll see something like this:
# Linux
$ python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))"
/usr/local/lib/python3.8/site-packages
# macOS (brew installed python3.8)
$ python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))"
/usr/local/Cellar/python#3.8/3.8.3/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages
# Windows
C:\> py -c "import sysconfig; print(sysconfig.get_path('purelib'))"
C:\Users\wim\AppData\Local\Programs\Python\Python38\Lib\site-packages
With a venv, you'll get something like this
# Linux
/tmp/.venv/lib/python3.8/site-packages
# macOS
/private/tmp/.venv/lib/python3.8/site-packages
# Windows
C:\Users\wim\AppData\Local\Temp\.venv\Lib\site-packages
The function sysconfig.get_paths() returns a dict of all of the relevant installation paths, example on Linux:
>>> import sysconfig
>>> sysconfig.get_paths()
{'stdlib': '/usr/local/lib/python3.8',
'platstdlib': '/usr/local/lib/python3.8',
'purelib': '/usr/local/lib/python3.8/site-packages',
'platlib': '/usr/local/lib/python3.8/site-packages',
'include': '/usr/local/include/python3.8',
'platinclude': '/usr/local/include/python3.8',
'scripts': '/usr/local/bin',
'data': '/usr/local'}
A shell script is also available to display these details, which you can invoke by executing sysconfig as a module:
python -m sysconfig
Addendum: What about Debian / Ubuntu?
As some commenters point out, the sysconfig results for Debian systems (and Ubuntu, as a derivative) are not accurate. When a user pip installs a package it will go into dist-packages not site-packages, as per Debian policies on Python packaging.
The root cause of the discrepancy is because Debian patch the distutils install layout, to correctly reflect their changes to the site, but they fail to patch the sysconfig module.
For example, on Ubuntu 20.04.4 LTS (Focal Fossa):
root#cb5e85f17c7f:/# python3 -m sysconfig | grep packages
platlib = "/usr/lib/python3.8/site-packages"
purelib = "/usr/lib/python3.8/site-packages"
root#cb5e85f17c7f:/# python3 -m site | grep packages
'/usr/local/lib/python3.8/dist-packages',
'/usr/lib/python3/dist-packages',
USER_SITE: '/root/.local/lib/python3.8/site-packages' (doesn't exist)
It looks like the patched Python installation that Debian/Ubuntu are distributing is a bit hacked up, and they will need to figure out a new plan for 3.12+ when distutils is completely unavailable. Probably, they will have to start patching sysconfig as well, since this is what pip will be using for install locations.
Let's say you have installed the package 'django'. import it and type in dir(django). It will show you, all the functions and attributes with that module. Type in the python interpreter -
>>> import django
>>> dir(django)
['VERSION', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'get_version']
>>> print django.__path__
['/Library/Python/2.6/site-packages/django']
You can do the same thing if you have installed mercurial.
This is for Snow Leopard. But I think it should work in general as well.
As others have noted, distutils.sysconfig has the relevant settings:
import distutils.sysconfig
print distutils.sysconfig.get_python_lib()
...though the default site.py does something a bit more crude, paraphrased below:
import sys, os
print os.sep.join([sys.prefix, 'lib', 'python' + sys.version[:3], 'site-packages'])
(it also adds ${sys.prefix}/lib/site-python and adds both paths for sys.exec_prefix as well, should that constant be different).
That said, what's the context? You shouldn't be messing with your site-packages directly; setuptools/distutils will work for installation, and your program may be running in a virtualenv where your pythonpath is completely user-local, so it shouldn't assume use of the system site-packages directly either.
The native system packages installed with python installation in Debian based systems can be found at :
/usr/lib/python2.7/dist-packages/
In OSX - /Library/Python/2.7/site-packages
by using this small code :
from distutils.sysconfig import get_python_lib
print get_python_lib()
However, the list of packages installed via pip can be found at :
/usr/local/bin/
Or one can simply write the following command to list all paths where python packages are.
>>> import site; site.getsitepackages()
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']
Note: the location might vary based on your OS, like in OSX
>>> import site; site.getsitepackages()
['/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/site-python', '/Library/Python/2.7/site-packages']
pip show will give all the details about a package:
https://pip.pypa.io/en/stable/reference/pip_show/ [pip show][1]
To get the location:
pip show <package_name>| grep Location
In Linux, you can go to site-packages folder by:
cd $(python -c "import site; print(site.getsitepackages()[0])")
All the answers (or: the same answer repeated over and over) are inadequate. What you want to do is this:
from setuptools.command.easy_install import easy_install
class easy_install_default(easy_install):
""" class easy_install had problems with the fist parameter not being
an instance of Distribution, even though it was. This is due to
some import-related mess.
"""
def __init__(self):
from distutils.dist import Distribution
dist = Distribution()
self.distribution = dist
self.initialize_options()
self._dry_run = None
self.verbose = dist.verbose
self.force = None
self.help = 0
self.finalized = 0
e = easy_install_default()
import distutils.errors
try:
e.finalize_options()
except distutils.errors.DistutilsError:
pass
print e.install_dir
The final line shows you the installation dir. Works on Ubuntu, whereas the above ones don't. Don't ask me about windows or other dists, but since it's the exact same dir that easy_install uses by default, it's probably correct everywhere where easy_install works (so, everywhere, even macs). Have fun. Note: original code has many swearwords in it.
An additional note to the get_python_lib function mentioned already: on some platforms different directories are used for platform specific modules (eg: modules that require compilation). If you pass plat_specific=True to the function you get the site packages for platform specific packages.
This works for me.
It will get you both dist-packages and site-packages folders.
If the folder is not on Python's path, it won't be
doing you much good anyway.
import sys;
print [f for f in sys.path if f.endswith('packages')]
Output (Ubuntu installation):
['/home/username/.local/lib/python2.7/site-packages',
'/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages']
This should work on all distributions in and out of virtual environment due to it's "low-tech" nature. The os module always resides in the parent directory of 'site-packages'
import os; print(os.path.dirname(os.__file__) + '/site-packages')
To change dir to the site-packages dir I use the following alias (on *nix systems):
alias cdsp='cd $(python -c "import os; print(os.path.dirname(os.__file__))"); cd site-packages'
A side-note: The proposed solution (distutils.sysconfig.get_python_lib()) does not work when there is more than one site-packages directory (as recommended by this article). It will only return the main site-packages directory.
Alas, I have no better solution either. Python doesn't seem to keep track of site-packages directories, just the packages within them.
from distutils.sysconfig import get_python_lib
print get_python_lib()
You should try this command to determine pip's install location
Python 2
pip show six | grep "Location:" | cut -d " " -f2
Python 3
pip3 show six | grep "Location:" | cut -d " " -f2
Answer to old question. But use ipython for this.
pip install ipython
ipython
import imaplib
imaplib?
This will give the following output about imaplib package -
Type: module
String form: <module 'imaplib' from '/usr/lib/python2.7/imaplib.py'>
File: /usr/lib/python2.7/imaplib.py
Docstring:
IMAP4 client.
Based on RFC 2060.
Public class: IMAP4
Public variable: Debug
Public functions: Internaldate2tuple
Int2AP
ParseFlags
Time2Internaldate
For those who are using poetry, you can find your virtual environment path with poetry debug:
$ poetry debug
Poetry
Version: 1.1.4
Python: 3.8.2
Virtualenv
Python: 3.8.2
Implementation: CPython
Path: /Users/cglacet/.pyenv/versions/3.8.2/envs/my-virtualenv
Valid: True
System
Platform: darwin
OS: posix
Python: /Users/cglacet/.pyenv/versions/3.8.2
Using this information you can list site packages:
ls /Users/cglacet/.pyenv/versions/3.8.2/envs/my-virtualenv/lib/python3.8/site-packages/
I made a really simple function that gets the job done
import site
def get_site_packages_dir():
return [p for p in site.getsitepackages()
if p.endswith(("site-packages", "dist-packages"))][0]
get_site_packages_dir()
# '/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages'
If you want to retrieve the results using the terminal:
python3 -c "import site;print([p for p in site.getsitepackages() if p.endswith(('site-packages', 'dist-packages')) ][0])"
/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages
I had to do something slightly different for a project I was working on: find the relative site-packages directory relative to the base install prefix. If the site-packages folder was in /usr/lib/python2.7/site-packages, I wanted the /lib/python2.7/site-packages part. I have, in fact, encountered systems where site-packages was in /usr/lib64, and the accepted answer did NOT work on those systems.
Similar to cheater's answer, my solution peeks deep into the guts of Distutils, to find the path that actually gets passed around inside setup.py. It was such a pain to figure out that I don't want anyone to ever have to figure this out again.
import sys
import os
from distutils.command.install import INSTALL_SCHEMES
if os.name == 'nt':
scheme_key = 'nt'
else:
scheme_key = 'unix_prefix'
print(INSTALL_SCHEMES[scheme_key]['purelib'].replace('$py_version_short', (str.split(sys.version))[0][0:3]).replace('$base', ''))
That should print something like /Lib/site-packages or /lib/python3.6/site-packages.
Something that has not been mentioned which I believe is useful, if you have two versions of Python installed e.g. both 3.8 and 3.5 there might be two folders called site-packages on your machine. In that case you can specify the python version by using the following:
py -3.5 -c "import site; print(site.getsitepackages()[1])

Categories