How to detect if module is installed in "editable mode"?

Question:

I’m pip-installing my module like so:

cd my_working_dir
pip install -e .

When I later import the module from within Python, can I somehow detect if the module is installed in this editable mode?

Right now, I’m just checking if there’s a .git folder in os.path.dirname(mymodule.__file__)) which, well, only works if there’s actually a .git folder there. Is there a more reliable way?

Asked By: fredrik

||

Answers:

I don’t know of a way to detect this directly (e.g. ask setuptools).

You could try to detect that you package can not be reached through the paths in sys.path. But that’s tedious. It’s also not bullet proof — what if it can be reached through sys.path but it’s also installed as en editable package?

The best option is to look at the artifacts an editable install leaves in your site-packages folder. There’s a file called my_package.egg-link there.

from pathlib import Path

# get site packages folder through some other magic

# assuming this current file is located in the root of your package
current_package_root = str(Path(__file__).parent.parent)

installed_as_editable  = False
egg_link_file = Path(site_packages_folder) / "my_package.egg-link"
try:
    linked_folder = egg_link_file.read_text()
    installed_as_editable = current_package_root in linked_folder
except FileNotFoundError:
    installed_as_editable = False

Note: to make this a bit more bullet-proof, read only the first line of the egg-link file and parse it using Path() as well to account for proper slashes etc.

Answered By: florisla

Another workaround:

Place an "not to install" file into your package. This can be a README.md, or a not_to_install.txt file. Use any non-pythonic extension, to prevent that file installation. Then check if that file exists in your package.

The suggested source structure:

my_repo
|-- setup.py
`-- awesome_package
    |-- __init__.py
    |-- not_to_install.txt
    `-- awesome_module.py

setup.py:

# setup.py
from setuptools import setup, find_packages

setup(
    name='awesome_package',
    version='1.0.0',

    # find_packages() will ignore non-python files.
    packages=find_packages(),
)

The __init__.py or the awesome_module.py:

import os

# The current directory
__here__ = os.path.dirname(os.path.realpath(__file__))

# Place the following function into __init__.py or into awesome_module.py

def check_editable_installation():
    '''
        Returns true if the package was installed with the editable flag.
    '''
    not_to_install_exists = os.path.isfile(os.path.join(__here__, 'not_to_install.txt'))
    return not_to_install_exists
Answered By: betontalpfa

Recently I had to test if various packages were installed in editable mode across different machines. Running pip show <package name> reveals not only the version, but other information about it, which includes the location of the source code. If the package was not installed in editable mode, this location will point to site-packages, so for my case it was sufficient with checking the output of such command:

import subprocess

def check_if_editable(name_of_the_package:str) -> bool:
    out = subprocess.check_output(["pip", "show", f"{name_of_the_package}"]).decode()
    return "site-packages" in out
Answered By: egeres

Haven’t found a definite source for this, but if the output of

$ pip show my-package -f

is something like this:

..
..
Files:
  __editable__.my-package-0.0.5.pth
  my-package-0.0.5.dist-info/INSTALLER
  my-package-0.0.5.dist-info/METADATA
  my-package-0.0.5.dist-info/RECORD
  my-package-0.0.5.dist-info/REQUESTED
  my-package-0.0.5.dist-info/WHEEL
  my-package-0.0.5.dist-info/direct_url.json
  my-package-0.0.5.dist-info/top_level.txt

then it’s probably editable.

Answered By: Eyal Levin

Run pip list, and there is a column called "Editable project location". If that column has a value, specifically the directory from which you installed it, then the package is pip installed in editable mode.

Answered By: Thomas Dietert
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.