【发布时间】:2019-09-17 22:28:03
【问题描述】:
用户应该通过 pip 安装我们的 python 包,或者它可以从 github repo 克隆并从源代码安装。出于多种原因,用户不应在源代码树目录中运行import Foo,例如缺少 C 扩展(numpy 有同样的问题:read here)。因此,我们想检查用户是否在源代码树中运行import Foo,但是如何在支持 Python 3 和 2 的情况下干净、高效、稳健地执行此操作?
编辑:注意这里的源代码树也被定义为下载代码的位置(例如,通过 git 或从源存档),它与安装代码的安装目录形成对比。
我们考虑了以下几点:
- 检查
setup.py或其他文件,如PKG-INFO,它们应该只存在于源中。它不是那么优雅,并且检查文件的存在也不是很便宜,因为每次有人import Foo时都会进行此检查。此外,没有什么可以阻止某人将setup.py放在其lib/python3.X/site-packages/目录或类似目录中的源代码树之外。 - 解析
setup.py的内容作为包名,但这也增加了开销,而且解析起来也不是很干净。 - 创建一个仅存在于源代码树中的虚拟标志文件。
- 一些聪明但可能过于复杂且容易出错的想法,例如在安装过程中修改
Foo/__init__.py以注意我们现在位于源代码树之外。
【问题讨论】:
-
那么您希望向用户展示什么。如果用户从源代码树运行 import Foo,他会看到某种异常或警告吗? @Chris_Rands
-
@DeveshKumarSingh 是的,要么是
numpy之类的异常引发,要么更可能是if in_source_tree: warnings.warn(msg, CustomWarning)之类的自定义警告消息 -
我有一个包结构,其中
import Foo; Foo.__file__将根据它的安装位置显示不同的路径,并且可以通过执行os.getcwd()将其与源树路径进行比较,这样的方法为你工作@Chris_Rands! -
@DeveshKumarSingh 注意——如果用户在安装目录中,例如
lib/python3.X/site-packages/,然后Foo.__file__将匹配os.getcwd();如果用户实际上在源代码树中,它也会匹配。注意这里的源代码树也是下载代码的目录(通常通过 git clone)与安装代码的安装目录 -
啊,为了解决这个问题,我总是可以做类似
git rev-parse --git-dir的事情,如果它是一个git repo,它将返回.git,否则它会抛出一个错误!而且这个命令只适用于通过 git 克隆的源目录,而不适用于其他任何地方!这会解决问题@Chris_Rands
标签: python package python-import