Search code examples
python-2.7ubuntupippackage

Locate source code from pip install packages in Ubuntu


I have installed some packages with pip in Ubuntu. However, I want to change some part of the installed code from those packages. In windows is easy to do so, from Pycharm using provided links. How can I locate the source code from the packages and make changes? My import code:

from metric_learn import LSML_Supervised

Solution

  • 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