Pip freeze命令不能显示requirements文件中的存储库路径。

21

我创建了一个环境,并通过Git添加了django-paramfield包:

$ pip install git+https://bitbucket.org/DataGreed/django-paramfield.git
Downloading/unpacking git+https://bitbucket.org/DataGreed/django-paramfield.git
  Cloning https://bitbucket.org/DataGreed/django-paramfield.git to /var/folders/9Z/9ZQZ1Q3WGMOW+JguzcBKNU+++TI/-Tmp-/pip-49Eokm-build
Unpacking objects: 100% (29/29), done.
  Running setup.py egg_info for package from git+https://bitbucket.org/DataGreed/django-paramfield.git
Installing collected packages: paramfield
  Running setup.py install for paramfield
Successfully installed paramfield
Cleaning up...

但是当我想创建一个需求文件时,我只能看到包名称:

$ pip freeze
paramfield==0.1
wsgiref==0.1.2

我该如何使其输出整个字符串git+https://bitbucket.org/DataGreed/django-paramfield.git而不仅仅是软件包名称?该软件包不在PyPi中。
更新:也许与setup.py有关?我应该如何更改它以反映repo url?
更新2:我在stackoverflow中找到了一个非常相似的question,但作者不确定他是如何解决问题的,而且接受的答案没有给出好的提示,尽管从作者的评论来看,它与setup.py文件有关。
更新3:我尝试在setup.py中传递download_url并使用此url通过pip安装软件包,但问题仍然存在。

听起来这似乎是pip中的一个bug或者是他们文档中的遗漏。告诉他们https://github.com/pypa/pip/issues。 - Colonel Panic
1
谢谢,我已经提交了一个问题 - https://github.com/pypa/pip/issues/609 - DataGreed
3个回答

19
一个简单但有效的解决方法是使用-e标志安装软件包,例如:pip install -e git+https://bitbucket.org/DataGreed/django-paramfield.git#egg=django-paramfield
然后,pip freeze会显示软件包的完整源路径。这不是最好的解决办法,应该在pip中进行修复,但它能够正常工作。-e(编辑标志)的权衡是,pip将git / hg仓库克隆到/path/to/venv/src/packagename,并运行python setup.py deploy而不是将其克隆到临时目录并运行python setup.py install,并在软件包设置完成后删除临时目录。

谢谢,那确实是一种可行的解决方法,但我认为这个正确的语法应该是pip install -e git+https://bitbucket.org/DataGreed/django-paramfield.git#egg=paramfield。但-e标志具体是做什么用的呢?是指定要安装包的目录吗? - DataGreed

3
这里有一份可以实现该功能的脚本:
```

以下是可用的脚本:

```
#!/usr/bin/env python

from subprocess import check_output
from pkg_resources import get_distribution

def download_url(package):
    dist = get_distribution(package)
    for line in dist._get_metadata('PKG-INFO'):
        if line.startswith('Download-URL:'):
            return line.split(':', 1)[1]


def main(argv=None):
    import sys
    from argparse import ArgumentParser

    argv = argv or sys.argv

    parser = ArgumentParser(
        description='show download urls for installed packages')
    parser.parse_args(argv[1:])

    for package in check_output(['pip', 'freeze']).splitlines():
        print('{}: {}'.format(package, download_url(package) or 'UNKNOWN'))


if __name__ == '__main__':
    main()

但是为什么pip freeze不这样做呢?通常它会显示存储库的URL。 - DataGreed

1
这是一个老问题,但我刚刚解决了同样的问题,方法很简单:将仓库路径(在我的情况下是git)添加到要求文件中,而不是包名。
例如:
...
celery==3.0.19
# chunkdata isn't available on PyPi
https://github.com/aaronmccall/chunkdata/zipball/master
distribute==0.6.34
... 

部署到Heroku上工作得很好。


当然,它基本上与被接受的答案相同 - pip freeze将生成类似的行 ;) - DataGreed
pip freeze > requirements.txt 会覆盖此行 - Amaimersion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接