执行 run_setup 以找出包元数据后出现“WinError 32”

问题描述

我在没有任何管理员权限的 Windows 开发环境中使用 Python 3.6.1。我有一个 Python 程序,它执行以下操作:

  1. 使用 tempfile.mkdtemp() 创建临时目录
  2. 将 Git 存储库克隆到其中
  3. 将 Git 存储库中的代码构建到 Python 轮子中
  4. 将轮子安装到目标 Python venv 中
  5. 使用 shutil.rmtree() 删除临时目录

在第 5 步(删除 tempdir)中,我不断收到错误消息:

PermissionError: [WinError 32] The process cannot access the file 
    because it is being used by another process: <path of tmpdir>

请注意,此错误消息似乎删除目录有关,而不是其中的任何特定文件

经过许多吃力不讨好的调试时间,我认为脚本在第三步中必须执行的以下行似乎是导致它的原因:

def get_Metadata(path_to_setup_py):
    return distutils.core.run_setup(path_to_setup_py,stop_after='init').Metadata

我正在使用 run_setup() 获取模拟应用设置的包元数据,但我认为该函数无法关闭文件句柄或其他内容,从而导致上述错误

我阅读了 run_setup 的源代码,但我不太明白。我认为发生的事情是 exec() 实际上运行了完整的 setup.py,但是对 setup()调用被重新路由到当前进程中,因此可以使用全局变量 _setup_stop_after_setup_distribution

无论哪种方式,我都不明白为什么“另一个进程”会保留文件/目录锁,因为 exec() 应该在当前进程内发生!?请注意,脚本退出tempdir 为空,我可以毫无问题地将其删除

解决方法

好吧,我想我只需要输入这个问题即可立即获得答案。在移除树之前,我打印了当前的工作目录:

print(os.getcwd())
shutil.rmtree(tmpdir)

然后我意识到这是我想要删除的目录,我认为这是 run_setup 的副作用。解决方案是在删除之前简单地更改目录!

os.chdir(r'C:\Temp')
shutil.rmtree(tmpdir)