10

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?

fredrik
  • 8,747
  • 13
  • 64
  • 117
  • Related? http://stackoverflow.com/questions/30306099/pip-install-editable-vs-python-setup-py-develop – Warren P Apr 11 '17 at 14:36
  • @WarrenP no, that explains how to install a module in editable mode. I'm looking to a nice way of then detecting that (vs regular install). – fredrik Apr 11 '17 at 14:38
  • Sounds like a pretty ugly detail. Since that could change in any minor release of setuptools, how would you ever know when your hack broke? – Warren P Apr 11 '17 at 14:50
  • This seems to be related to a [similar post](https://stackoverflow.com/questions/40530000/check-if-my-application-runs-in-development-editable-mode/66480035#66480035). – jenclark Mar 04 '21 at 17:32

2 Answers2

2

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
betontalpfa
  • 3,006
  • 1
  • 29
  • 54
0

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.

florisla
  • 10,965
  • 5
  • 35
  • 46