代码之家  ›  专栏  ›  技术社区  ›  Jeet

如何避免PIP在可编辑模式下安装脚本,生成“resourcewarning:unclosed file”消息?

  •  2
  • Jeet  · 技术社区  · 7 年前

    当使用“pip”在可编辑模式下安装包(使用“-e”)标志时,任何可执行脚本在调用时都将生成令人讨厌的“resourcewarning:unclosed file”消息。

    要复制,请考虑以下最小包:

    foo/
        bin/foo.py
        setup.py
    

    其中“setup.py”具有:

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from setuptools import setup
    
    setup(
        name='foo',
        version='0.1',
        scripts=["bin/foo.py"],
        zip_safe=False)
    

    和“bin/foo.py”有,例如

    #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    
    print("hello, world")
    

    然后,在运行时:

    python3 -m pip install -e foo
    

    调用可执行文件会导致:

    $ foo.py 
    /.../bin/foo.py:6: ResourceWarning: unclosed file <_io.TextIOWrapper name='/.../foo/bin/foo.py' mode='r' encoding='UTF-8'>
    hello, world
    

    这个问题是由“pip”在可编辑模式下自动生成并安装在用户二进制目录中的伪脚本存根,它使用以下语句调用源脚本:

    exec(compile(open(__file__).read(), __file__, 'exec'))
    

    文件确实是在未关闭的情况下打开的。手动修复很简单。但是我们如何才能让“pip”自己正确地完成它呢?

    (请注意,如果不使用“可编辑”模式,则不会出现此问题,因为这里直接复制可执行脚本,而不是由包装脚本调用)。

    1 回复  |  直到 7 年前
        1
  •  1
  •   wim    7 年前

    尝试:

    您将在site packages目录中找到模板,其中包含文件名 script (dev).tmpl 以下内容:

    $ cat ".venv/lib/python3.6/site-packages/setuptools/script (dev).tmpl"
    # EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r
    __requires__ = %(spec)r
    __import__('pkg_resources').require(%(spec)r)
    __file__ = %(dev_path)r
    exec(compile(open(__file__).read(), __file__, 'exec'))
    

    根据需要编辑,例如:

    # EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r
    __requires__ = %(spec)r
    __import__('pkg_resources').require(%(spec)r)
    __file__ = %(dev_path)r
    try:
        f = open(__file__)
        exec(compile(f.read(), __file__, 'exec'))
    finally:
        f.close()
    

    最后:

    投票请求: https://github.com/pypa/setuptools/pull/1398 这几乎是立即合并的,因此模板应该在下一个SETUPTOOLS版本中修复。这里唯一需要做的似乎就是有人能关心到,真正抱怨这件事。