My Python application can be install the normal way, or in development/editable mode with pip
, like this:
virtualenv my_app
source my_app/bin/activate
pip install -e my_app
How can I make a function to introspect my virtualenv and check if my application runs in development/editable mode?
Is there any "flag" in sys
module for that?
Motivation: have different configuration in development mode, and in production.
EDIT: I compare the virtualenv and the package directories.
import os
import sys
import pkg_resources
main_pkg = 'my_app'
package_dir = pkg_resources.resource_filename(main_pkg, '__init__.py')
virtualenv_dir = os.path.dirname(os.path.dirname(sys.executable))
common_path = os.path.commonprefix([package_dir, virtualenv_dir])
is_dev_mode = not common_path.startswith(virtualenv_dir)
I test if the package_dir is a subdirectory of the virtualenv_dir: if it is not a subdirectory, then I am on development mode.
EDIT2:
Is there a more reliable solution?
I want to know if there isn’t a data/a flag in the environment that would clearly indicate to me that my application is running in development mode.
What will happen if another dependency is in development mode too?
Using code from pip
we can determine this:
import pip
import pkg_resources
# I've done `pip install -e .` for a git repo I'm working in inside
# a virtualenv
distributions = {v.key: v for v in pkg_resources.working_set}
# >>> distribution
# pre-commit 0.9.3 (/home/asottile/workspace/pre-commit)
distribution = distributions['pre-commit']
# Below is approximately how `pip freeze` works, see the end of
# the answer for a simpler approach, still using pip
# Turn into a pip FrozenRequirement (I'm using pip 9.0.1, it may
# be different for your version)
# I've passed an empty list for the second argument (dependency_links)
# I don't think it's necessary?
frozen_requirement = pip.FrozenRequirement.from_dist(distribution, [])
# Query whether the requirement is installed editably:
print(frozen_requirement.editable)
The magic of this comes from a little function inside pip (pip.utils
):
def dist_is_editable(dist):
"""Is distribution an editable install?"""
for path_item in sys.path:
egg_link = os.path.join(path_item, dist.project_name + '.egg-link')
if os.path.isfile(egg_link):
return True
return False
The dist
in this is a pkg_resources
distribution (as we acquired above). You of course can use the dist_is_editable
function directly instead of going through FrozenRequirement
:
# With `distribution` as above:
from pip.utils import dist_is_editable
print(dist_is_editable(distribution)) # True in my case ;)
The top solution needs updating for a more recent version of pip, where the FrozenRequirement class is no longer accessible in pip's namespace.
I used this workaround in the relevant lines.
from pip._internal.operations.freeze import FrozenRequirement
frozen_requirement = FrozenRequirement.from_dist(distribution)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With