Setuptools:如何确保由pip删除由压缩代码生成的文件

问题描述 投票:9回答:2

我有一个名为main.py的简单代码,它在其中生成一个文件夹和一个文件:

import os
def main():
    path = os.path.join(os.path.dirname(__file__), 'folder')

    if not os.path.isdir(path):
        os.mkdir(path)

    with open(os.path.join(path, 'file.txt'), 'w+') as f:
        f.write('something')


if __name__ == '__main__':
    main()

如果此脚本在文件夹中运行,则结构应如下所示:

.
├── main.py
└── folder
    └── file.txt

我使用setup.py文件打包代码,我在其中分配了一个名为foo的入口点。 setup.py看起来像:

from setuptools import setup  
setup(
    name='mypack',
    entry_points={
        'console_scripts': ['foo=mypack.main:main'],
    },
    packages=['mypack'],
    package_data={'': '*.txt'},
    include_package_data=True
)

我用以下结构打包代码:

.
├── mypack
│   └── main.py
└── setup.py

我在pip install .的根目录下安装它。然后我运行foo,它确实生成了一个文件夹和一个文件。然后我通过pip uninstall mypack卸载它,终端输出显示:

Uninstalling mypack-0.0.0:
  Would remove:
    d:\programdata\envs\testsetup\lib\site-packages\mypack-0.0.0-py3.6.egg-info
    d:\programdata\envs\testsetup\lib\site-packages\mypack\main.py
    d:\programdata\envs\testsetup\scripts\foo-script.py
    d:\programdata\envs\testsetup\scripts\foo.exe
Proceed (y/n)? y
  Successfully uninstalled mypack-0.0.0

folder\file.txt没有删除pip uninstall,它的输出也没有提及有关folder\file.txt的任何内容


然后我用下面的结构打包代码:

.
├── mypack
│   ├── __init__.py
│   └── main.py
└── setup.py

__init__.py是一个空文件。我做了同样的程序,即:pip install . - > foo - > pip uninstall mypack,然后终端的输出是:

Uninstalling mypack-0.0.0:
  Would remove:
    d:\programdata\envs\testsetup\lib\site-packages\mypack-0.0.0-py3.6.egg-info
    d:\programdata\envs\testsetup\lib\site-packages\mypack\*
    d:\programdata\envs\testsetup\scripts\foo-script.py
    d:\programdata\envs\testsetup\scripts\foo.exe
  Would not remove (might be manually added):
    d:\programdata\envs\testsetup\lib\site-packages\mypack\folder\file.txt
Proceed (y/n)? y
  Successfully uninstalled mypack-0.0.0

这一次,在folder\file.txt的输出中提到了pip uninstall,但pip没有自动删除。


所以我的问题:

  • 为什么有和没有__init__.py有区别
  • 有没有什么方法可以让pip在我的例子中自动删除folder\file.txt
python python-3.x python-2.7 pip
2个回答
1
投票

__init__.py文件告诉python它所在的目录是一个模块,并查看位于其中的所有子模块。这使得pip认为它是一个模块,因此提到它内部的一切。

从文档:

需要init.py文件才能使Python将目录视为包含包;这样做是为了防止具有通用名称的目录(例如字符串)无意中隐藏在模块搜索路径上稍后(更深)发生的有效模块。在最简单的情况下,init.py可以只是一个空文件

对于你的第二个问题,我的回答可能是。我这样说是因为,我无法确定这是可能的。

P.S:我不确定(因为我没有测试过),但也许你可以改变file.txt.py的延伸,也许可以愚弄pip去除它。


1
投票

pip/blob/master/src/pip/_internal/req/req_uninstall.py的第381行:

if not verbose:
            will_remove, will_skip = compress_for_output_listing(self.paths)
        else:
            # In verbose mode, display all the files that are going to be
            # deleted.
            will_remove = list(self.paths)
            will_skip = set()

        _display('Would remove:', will_remove)
        _display('Would not remove (might be manually added):', will_skip)
        _display('Would not remove (outside of prefix):', self._refuse)

您可以看到要从文件中删除的compress_for_output_listing分隔文件以保留,除非verboseTrue,它似乎将它们全部删除。但是这很糟糕,因为verbose似乎是一个内部函数参数,并且没有命令行参数来设置它,并且需要更改源代码才能删除所有文件。

© www.soinside.com 2019 - 2024. All rights reserved.