"WinError 32" 在执行 run_setup 之后找出包元数据

"WinError 32" after doing run_setup to find out package metadata

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

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

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

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

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

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

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.

共享数据

无论哪种方式,我都不明白为什么“另一个进程”会保持 file/directory 锁定,因为 exec() 应该发生在当前进程中!?请注意,在脚本退出后 tempdir 是空的,我可以毫无问题地删除它。

好吧,我想我只需要输入这个问题就可以立即得到答案。在删除树之前,我打印出当前工作目录:

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

我意识到这是我要删除的目录,我认为这是 run_setup 的副作用。解决办法就是直接改目录再删除!

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