简体   繁体   English

从 setup.py 中检测 python 包安装路径

[英]Detect python package installation path from within setup.py

After installation, I would like to make soft-links to some of the configuration & data files created by installation.安装后,我想对安装时创建的一些配置和数据文件进行软链接。

How can I determine the location of a new package's files installed from within the package's setup.py?如何确定从包的 setup.py 中安装的新包文件的位置?

I initially hard-coded the path "/usr/local/lib/python2.7/dist-packages", but that broke when I tried using a virtual environment.我最初对路径“/usr/local/lib/python2.7/dist-packages”进行了硬编码,但是当我尝试使用虚拟环境时,它坏了。 (Created by virtualenv.) (由 virtualenv 创建。)

I tried distutils.sysconfig.get_python_lib(), and that works inside the virtualenv.我试过 distutils.sysconfig.get_python_lib(),它在 virtualenv 中工作。 When installed on the real system, however, it returns "/usr/lib/python2.7/dist-packages" (Note the "local" directory isn't present.)然而,当安装在真实系统上时,它返回“/usr/lib/python2.7/dist-packages”(注意“local”目录不存在。)

I've also tried site.getsitepackages():我也试过 site.getsitepackages():

Running a Python shell from the base environment:从基本环境运行 Python shell:

import site进口网站

site.getusersitepackages() site.getusersitepackages()

'/home/sarah/.local/lib/python2.7/site-packages' '/home/sarah/.local/lib/python2.7/site-packages'

site.getsitepackages() site.getsitepackages()

['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages'] ['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']

Running a Python shell from a virtual environment "testenv":从虚拟环境“testenv”运行 Python shell:

import site进口网站

site.getsitepackages() site.getsitepackages()

Traceback (most recent call last):回溯(最近一次调用最后一次):

File "", line 1, in文件“”,第 1 行,在

AttributeError: 'module' object has no attribute 'getsitepackages' AttributeError: 'module' 对象没有属性 'getsitepackages'

I'm running "Python 2.7.3 (default, Aug 1 2012, 05:14:39)" with "[GCC 4.6.3] on linux2" on Ubuntu.我在 Ubuntu 上运行“Python 2.7.3(默认,2012 年 8 月 1 日,05:14:39)”和“[GCC 4.6.3] on linux2”。 I can probably cobble something together with try-except blocks, but it seems like there should be some variable set / returned by distutils / setuptools.我可能可以用 try-except 块拼凑一些东西,但似乎应该有一些变量设置/由 distutils/setuptools 返回。 (I'm agnostic about which branch to use, as long as it works.) (我不知道使用哪个分支,只要它有效。)

Thanks.谢谢。

I haven't found the "correct" way of doing this, but I have found a couple tricks that seem almost-correct.我还没有找到这样做的“正确”方法,但我发现了一些看起来几乎正确的技巧。 One method only works on install;一种方法仅适用于安装; the other only works if the package is already installed.另一个仅在软件包已安装时才有效。

For install, I use the object returned by setuptools.setup() :对于安装,我使用setuptools.setup()返回的对象:

from setuptools import setup
s = setup([...])
installation_path = s.command_obj['install'].install_lib

(This only works during install since you need a valid Distribution object for those attributes to exist. AFAIK, the only way to get such an object is to run setup() .) (这仅在安装期间有效,因为您需要一个有效的Distribution对象才能存在这些属性。AFAIK,获取此类对象的唯一方法是运行setup() 。)

On uninstall, I use the file attribute of the package, as suggested by @Zhenya above.卸载时,我使用包的文件属性,如上面@Zhenya 所建议的。 The only catch is that when I run ./setup.py uninstall to get rid of package , I usually have directories ./package/ , ./build , ./dist , and ./package.egg-info/ .唯一的问题是,当我运行./setup.py uninstall来删除package ,我通常有目录./package/./build./dist./package.egg-info/ (The "uninstall" option is caught by my code without calling setup(). It runs a manually-created script to delete the package files.) These can redirect the python interpreter to some place other than the globally-accessible repository I'm trying to get rid of. (“卸载”选项被我的代码捕获而不调用 setup()。它运行一个手动创建的脚本来删除包文件。)这些可以将 python 解释器重定向到某个地方,而不是我的全局可访问存储库试图摆脱。 Here's my hack to handle that:这是我处理这个问题的技巧:

import imp
import sys
from subprocess import Popen
from os import getcwd
Popen('rm -r build dist *.egg-info', shell=True).wait()
oldpath = sys.path
rundir = getcwd()
sys.path.remove(rundir)
mod = imp.find_module(PACKAGE)
p = imp.load_module(PACKAGE, mod[0], mod[1], mod[2])
sys.path = oldpath
installation_path = p.__file__

(This doesn't work during install since - I think - Python only inventories modules when it starts, so find_module() won't find the just-installed package unless you exit python and come back in.) (这在安装过程中不起作用,因为 - 我认为 - Python 仅在启动时清点模块,因此 find_module() 不会找到刚刚安装的包,除非您退出 python 并返回。)

I've tested both install and uninstall on a bare environment and a virtual environment (from virtualenv 1.9.1).我已经在裸环境和虚拟环境(来自 virtualenv 1.9.1)上测试了安装和卸载。 I'm running Ubuntu 12.04 LTS, Python 2.7.3, setuptools 0.6c11 (in the bare environment) and setuptools 0.7.4 (in virtualenv).我正在运行 Ubuntu 12.04 LTS、Python 2.7.3、setuptools 0.6c11(在裸机环境中)和 setuptools 0.7.4(在 virtualenv 中)。

This will probably not answer your question, but if you need to access the source code of a package you have installed, or any other file within this package, the best way to do it is to install this package in develop mode (by downloading the sources, putting it wherever you want and then running python setup.py develop in the base directory of the package sources).这可能不会回答您的问题,但是如果您需要访问您已安装的软件包的源代码或该软件包中的任何其他文件,最好的方法是在开发模式下安装该软件包(通过下载源,把它放在任何你想要的地方,然后在包源的基本目录中运行 python setup.py develop )。 This way you know where the package is found.这样你就知道包在哪里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM