当pip install
具有自定义build_py
命令的项目在构建目录中生成其他文件时,由pip在安装上生成的installed-files.txt文件不会列出生成的文件。因此,当我卸载发行版时,它会留下我生成的文件。
我想我无法以某种方式注册生成的文件,但我找不到任何关于如何执行此操作的文档。
我必须更改哪些内容,以便pip的installed-files.txt列出我生成的文件?
创建以下文件系统条目。
installed-files-missing-project ├── install-entry-missing │ └── __init__.py └── setup.py
将以下内容放入setup.py。
import os
from setuptools import setup
from setuptools.command.build_py import build_py
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
class my_build_py(build_py):
def run(self):
if not self.dry_run:
target_dir = os.path.join(self.build_lib, "install-entry-missing")
self.mkpath(target_dir)
touch(os.path.join(target_dir, "my_file.txt"))
# TODO: missing registration of "my_file.txt"?
build_py.run(self)
setup_args = dict(
name='install-entry-missing',
version='1.0.0',
description='',
author='author',
author_email='author@example.com',
packages = ["install-entry-missing"],
cmdclass={'build_py': my_build_py}
)
if __name__ == '__main__':
setup(**setup_args)
在install-entry-missing-project
目录中,运行pip install .
。
安装的目录将包含my_file.txt和__init__.py。但是,检查egg-info目录的installed-files.txt将显示未列出my_file.txt。因此,pip uninstall install-entry-missing
将删除__init__.py但不会删除my_file.txt。
答案 0 :(得分:2)
通过覆盖get_outputs
的{{1}}方法而非使用build_py
,可以获得比Eric's answer中建议的更清晰的代码:
install_egg_info
虽然Eric's answer中使用的方法有效,但为了更新 installed-files.txt ,覆盖import os
from setuptools import setup
from setuptools.command.build_py import build_py
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
class my_build_py(build_py):
def run(self):
self.my_outputs = []
if not self.dry_run:
target_dir = os.path.join(self.build_lib, "install-entry-missing")
self.mkpath(target_dir)
output = os.path.join(target_dir, "my_file.txt")
touch(output)
self.my_outputs.append(output)
build_py.run(self)
def get_outputs(self):
outputs = build_py.get_outputs(self)
outputs.extend(self.my_outputs)
return outputs
setup_args = dict(
name='install-entry-missing',
version='1.0.0',
description='',
author='author',
author_email='author@example.com',
packages = ["install-entry-missing"],
cmdclass={'build_py': my_build_py}
)
if __name__ == '__main__':
setup(**setup_args)
在语义上可疑,因为您正在更新相关文件列表到 egg-info 目录中安装的内容。在install_egg_info
中覆盖get_outputs
可以使更改的文件列表更接近于生成它们的位置,并且可以更轻松地处理生成的文件仅在运行时确定的情况。
答案 1 :(得分:1)
必须覆盖install_egg_info
命令并在其self.outputs
列表中附加一个条目。 self.outputs
列表中的每个条目都将在最终的installed-files.txt中生成一个条目。
修改上面的代码,正确的解决方案是:
import os
from setuptools import setup
from setuptools.command.build_py import build_py
from setuptools.command.install_egg_info import install_egg_info
def touch(fname, times=None):
with open(fname, 'a'):
os.utime(fname, times)
class my_build_py(build_py):
def run(self):
if not self.dry_run:
target_dir = os.path.join(self.build_lib, "install-entry-missing")
self.mkpath(target_dir)
touch(os.path.join(target_dir, "my_file.txt"))
# this file will be registered in my_install_egg_info
build_py.run(self)
class my_install_egg_info(install_egg_info):
def run(self):
install_egg_info.run(self)
target_path = os.path.join(self.install_dir, "my_file.txt")
self.outputs.append(target_path)
setup_args = dict(
name='install-entry-missing',
version='1.0.0',
description='',
author='author',
author_email='author@example.com',
packages = ["install-entry-missing"],
cmdclass={'build_py': my_build_py,
'install_egg_info': my_install_egg_info}
)
if __name__ == '__main__':
setup(**setup_args)
答案 2 :(得分:0)
我遇到的问题与此帖所描述的类似。上述解决方案无效。我创建了一个符号链接作为我的setup.py。
的安装后步骤我按照pip源代码中的代码来查看installed-files.txt
的内容,看看发生了什么。事实证明,由于我的文件是一个符号链接,它被忽略了。在pip / req / req_uninstall.py的第50行,对normalise_path
的调用遵循符号链接,只是将链接文件添加到要删除的路径列表中。链接本身不会添加到要删除的文件列表中,因此会被丢弃并由安装程序保留。
作为一项解决方法,我将符号链接更改为硬链接,然后pip完全卸载了我的包。