Locate source code from pip install packages in Ubuntu
site-packages
is the target directory of manually built python packages. When you build and install python packages from source (using distutils, probably by executing python setup.py install
), you will find the installed modules in site-pacakges by default.
>>> import site; site.getsitepackages()
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']
If you really doubt default location then,
>>> import django
>>> print django.__path__
['/Library/Python/2.7/site-packages/django']
Generally speaking, modules and packages have a __file__
attribute that you can use to find out where they were loaded from:
>>> import jinja2
>>> jinja2.__file__
'/usr/local/anaconda3/envs/felix_backend/lib/python3.6/site-packages/jinja2/__init__.py'
EDIT Nov 20 '20 The original answer might have been more helpful had it mentioned that pip
normally installs packages in the (sometimes virtual) environment's site-packages
directory, but that the -e
option can be used to install a module or package in so-called editable mode from a directory or URL. From pip install --help
:
-e, --editable <path/url> Install a project in editable mode (i.e.
setuptools "develop mode") from a local project
path or a VCS url.
This is commonly used by cloning a git repository (most open source software can be accessed in this way from Github or similar sources) and then installing it with pip install -e
. The environment's interpreter will use the code from the given directory, which are linked in rather than being copied into the environment's site-packages
directory.
The import system is quite complex, but if a module's __file__
attribute doesn't answer your questions, consult the documentation on import-related module attributes.
EDIT Mar 27 '22 For packages, the issue is somewhat more complex. If an imported object has a __path__
attribute then it is a package, and __path__
is a (possible empty) iterable of strings. This allows for namespace packages, whose contents can be installed incrementally and from different directories.
To assist in understanding all this, you can create a simple package by creating a directory and, in that, creating an empty module.py
file and a package
subdirectory containing only an empty __init__.py
. I did that, and ran the following script.
sholden@fathead-2 pkgtest % python
Python 3.9.10 (main, Jan 15 2022, 11:48:00)
[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import module, package
>>> module.__file__
'/private/tmp/pkgtest/module.py'
>>> package.__path__
['/private/tmp/pkgtest/package']
Here's what the filestore looked like after execution - also showing how the interpreter has created .pyc
files for both the module and the package.
sholden@fathead-2 pkgtest % tree $(pwd)
/tmp/pkgtest
├── __pycache__
│ └── module.cpython-39.pyc
├── module.py
└── package
├── __init__.py
└── __pycache__
└── __init__.cpython-39.pyc
3 directories, 4 files