在开发模式下无法从 windows 上的 pypy virtualenv 卸载 python 包
Failure to uninstall a python package from a pypy virtualenv on windows in develop mode
TL;DR: 运行ning python setup.py develop --uninstall
来自使用 tox
创建的 pypy
环境导致异常: error: [Error 32] The process cannot access the file because it is being used by another process: c:\users\shach\code\pydocstyle\.tox\pypy\site-packages\funniest.egg-link
.
大家好,
我的 python 包有一组集成测试,它们执行以下操作:
- 呼叫
python setup.py develop
(使用subprocess.check_call
)
- 运行 包的所有测试
- 调用
python setup.py develop --uninstall
(再次使用 subprocess.check_call
)
tox
正在 运行 进行测试。在 python 版本 27
、33
、34
、35
和 36
上一切正常,但代码在 pypy
上失败.
我不会在此处包含 setup.py
和项目文件,您可以假设它们没问题。我使用显示的最小包复制了这个 here 并且它仍然有效(失败?)。
为了重现,我创建了一个 python 脚本,其中 运行 如下:
import shlex
import subprocess
subprocess.check_call(shlex.split('python setup.py develop'))
print('----------')
subprocess.check_call(shlex.split('python setup.py develop --uninstall'))
运行使用系统上安装的常规 pypy
来处理文件就可以了:
C:\Users\shach\code\bla\funniest>pypy test.py
running develop
running egg_info
writing funniest.egg-info\PKG-INFO
writing dependency_links to funniest.egg-info\dependency_links.txt
writing top-level names to funniest.egg-info\top_level.txt
reading manifest file 'funniest.egg-info\SOURCES.txt'
writing manifest file 'funniest.egg-info\SOURCES.txt'
running build_ext
Creating c:\python\pypy\site-packages\funniest.egg-link (link to .)
Adding funniest 0.1 to easy-install.pth file
Installed c:\users\shach\code\bla\funniest
Processing dependencies for funniest==0.1
Finished processing dependencies for funniest==0.1
----------
running develop
Removing c:\python\pypy\site-packages\funniest.egg-link (link to .)
Removing funniest 0.1 from easy-install.pth file
C:\Users\shach\code\bla\funniest>
但是当我 运行 它来自 pypy
的 tox
环境时:
C:\Users\shach\code\bla\funniest>tox
GLOB sdist-make: C:\Users\shach\code\bla\funniest\setup.py
pypy inst-nodeps: C:\Users\shach\code\bla\funniest\.tox\dist\funniest-0.1.zip
pypy installed: cffi==1.10.1,funniest==0.1,greenlet==0.4.12,readline==6.2.4.1
pypy runtests: PYTHONHASHSEED='122'
pypy runtests: commands[0] | python test.py
running develop
running egg_info
writing funniest.egg-info\PKG-INFO
writing dependency_links to funniest.egg-info\dependency_links.txt
writing top-level names to funniest.egg-info\top_level.txt
reading manifest file 'funniest.egg-info\SOURCES.txt'
writing manifest file 'funniest.egg-info\SOURCES.txt'
running build_ext
Creating c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
funniest 0.1 is already the active version in easy-install.pth
Installed c:\users\shach\code\bla\funniest
Processing dependencies for funniest==0.1
Finished processing dependencies for funniest==0.1
----------
running develop
Removing c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
error: [Error 32] The process cannot access the file because it is being used by another process: c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link
Traceback (most recent call last):
File "test.py", line 6, in <module>
subprocess.check_call(shlex.split('python setup.py develop --uninstall'))
File "C:\Python\pypy\lib-python.7\subprocess.py", line 186, in check_call
raise CalledProcessError(retcode, cmd)
CalledProcessError: Command '['python', 'setup.py', 'develop', '--uninstall']' returned non-zero exit status 1
ERROR: InvocationError: 'C:\Users\shach\code\bla\funniest\.tox\pypy\bin\python.EXE test.py'
___________________________________ summary ___________________________________
ERROR: pypy: commands failed
C:\Users\shach\code\bla\funniest>
这是我用来复制的tox.ini
:
[tox]
envlist = pypy
[testenv]
commands=python test.py
我确定我对该目录有 read/write 权限,现在我有点失去理智了。
它在 linux 上工作得很好。可能是因为您可以删除正在使用的文件(inodes
,等等):^)
更新 1:
我认为问题可能在于 develop
和 develop --uninstall
都是来自同一个 python 文件的 运行,并且某些资源没有被清理正确(可能是一个锁定 egg-link
的打开文件),所以我手动 运行 它:
C:\Users\shach\code\bla\funniest>.tox\pypy\bin\activate.bat
(pypy) C:\Users\shach\code\bla\funniest>pypy setup.py develop
running develop
running egg_info
writing funniest.egg-info\PKG-INFO
writing dependency_links to funniest.egg-info\dependency_links.txt
writing top-level names to funniest.egg-info\top_level.txt
reading manifest file 'funniest.egg-info\SOURCES.txt'
writing manifest file 'funniest.egg-info\SOURCES.txt'
running build_ext
Creating c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
funniest 0.1 is already the active version in easy-install.pth
Installed c:\users\shach\code\bla\funniest
Processing dependencies for funniest==0.1
Finished processing dependencies for funniest==0.1
(pypy) C:\Users\shach\code\bla\funniest>pypy setup.py develop --uninstall
running develop
Removing c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
error: [Error 32] The process cannot access the file because it is being used by another process: c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link
(pypy) C:\Users\shach\code\bla\funniest>
仍然失败:(
请指教!
沙查尔。
更新 2:
我尝试使用 Sysinternal 的 Process Explorer
和 nada 检查是否有一个进程持有该文件。我手动 运行 pypy setup.py develop
,然后检查 Process Explorer
并确保文件没有在任何进程中打开,然后 运行 pypy setup.py develop --uninstall
和同样的错误是提出。
更新 3:
关闭CMD再打开CMD后仍然出现
更新 4:
重启机器不能解决这个问题!什么-----?
根据描述,似乎在 pypy setup.py develop --uninstall
的 运行 中的某处,一个文件或目录被保持打开状态,这阻止了它在 windows 上被删除。您可以尝试使用“-X track-resources”参数(pypy -X track-resources setup.py develop --uninstall
)运行 pypy,如果在资源关闭之前释放持有资源的对象,它应该会通知您。有时扫描像 s - open(path).read()
这样的代码可能足以发现问题,该代码会泄漏文件描述符,直到垃圾收集器 运行 注意到幽灵对象并将其删除。代码应该使用上下文管理器; with open(path) as fid: s = fid.read()
TL;DR: 不要直接使用 setup.py
,使用 pip install -e .
.
看来问题出在windows上的setuptools
。发生的情况是 egg-link
文件在被删除之前仅打开和关闭了几行 - windows 无法处理。
不知何故 pip
确实处理了这种情况,我会在有更多信息时更新。
我在 setuptools 中打开了一个 issue。
TL;DR: 运行ning python setup.py develop --uninstall
来自使用 tox
创建的 pypy
环境导致异常: error: [Error 32] The process cannot access the file because it is being used by another process: c:\users\shach\code\pydocstyle\.tox\pypy\site-packages\funniest.egg-link
.
大家好,
我的 python 包有一组集成测试,它们执行以下操作:
- 呼叫
python setup.py develop
(使用subprocess.check_call
) - 运行 包的所有测试
- 调用
python setup.py develop --uninstall
(再次使用subprocess.check_call
)
tox
正在 运行 进行测试。在 python 版本 27
、33
、34
、35
和 36
上一切正常,但代码在 pypy
上失败.
我不会在此处包含 setup.py
和项目文件,您可以假设它们没问题。我使用显示的最小包复制了这个 here 并且它仍然有效(失败?)。
为了重现,我创建了一个 python 脚本,其中 运行 如下:
import shlex
import subprocess
subprocess.check_call(shlex.split('python setup.py develop'))
print('----------')
subprocess.check_call(shlex.split('python setup.py develop --uninstall'))
运行使用系统上安装的常规 pypy
来处理文件就可以了:
C:\Users\shach\code\bla\funniest>pypy test.py
running develop
running egg_info
writing funniest.egg-info\PKG-INFO
writing dependency_links to funniest.egg-info\dependency_links.txt
writing top-level names to funniest.egg-info\top_level.txt
reading manifest file 'funniest.egg-info\SOURCES.txt'
writing manifest file 'funniest.egg-info\SOURCES.txt'
running build_ext
Creating c:\python\pypy\site-packages\funniest.egg-link (link to .)
Adding funniest 0.1 to easy-install.pth file
Installed c:\users\shach\code\bla\funniest
Processing dependencies for funniest==0.1
Finished processing dependencies for funniest==0.1
----------
running develop
Removing c:\python\pypy\site-packages\funniest.egg-link (link to .)
Removing funniest 0.1 from easy-install.pth file
C:\Users\shach\code\bla\funniest>
但是当我 运行 它来自 pypy
的 tox
环境时:
C:\Users\shach\code\bla\funniest>tox
GLOB sdist-make: C:\Users\shach\code\bla\funniest\setup.py
pypy inst-nodeps: C:\Users\shach\code\bla\funniest\.tox\dist\funniest-0.1.zip
pypy installed: cffi==1.10.1,funniest==0.1,greenlet==0.4.12,readline==6.2.4.1
pypy runtests: PYTHONHASHSEED='122'
pypy runtests: commands[0] | python test.py
running develop
running egg_info
writing funniest.egg-info\PKG-INFO
writing dependency_links to funniest.egg-info\dependency_links.txt
writing top-level names to funniest.egg-info\top_level.txt
reading manifest file 'funniest.egg-info\SOURCES.txt'
writing manifest file 'funniest.egg-info\SOURCES.txt'
running build_ext
Creating c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
funniest 0.1 is already the active version in easy-install.pth
Installed c:\users\shach\code\bla\funniest
Processing dependencies for funniest==0.1
Finished processing dependencies for funniest==0.1
----------
running develop
Removing c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
error: [Error 32] The process cannot access the file because it is being used by another process: c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link
Traceback (most recent call last):
File "test.py", line 6, in <module>
subprocess.check_call(shlex.split('python setup.py develop --uninstall'))
File "C:\Python\pypy\lib-python.7\subprocess.py", line 186, in check_call
raise CalledProcessError(retcode, cmd)
CalledProcessError: Command '['python', 'setup.py', 'develop', '--uninstall']' returned non-zero exit status 1
ERROR: InvocationError: 'C:\Users\shach\code\bla\funniest\.tox\pypy\bin\python.EXE test.py'
___________________________________ summary ___________________________________
ERROR: pypy: commands failed
C:\Users\shach\code\bla\funniest>
这是我用来复制的tox.ini
:
[tox]
envlist = pypy
[testenv]
commands=python test.py
我确定我对该目录有 read/write 权限,现在我有点失去理智了。
它在 linux 上工作得很好。可能是因为您可以删除正在使用的文件(inodes
,等等):^)
更新 1:
我认为问题可能在于 develop
和 develop --uninstall
都是来自同一个 python 文件的 运行,并且某些资源没有被清理正确(可能是一个锁定 egg-link
的打开文件),所以我手动 运行 它:
C:\Users\shach\code\bla\funniest>.tox\pypy\bin\activate.bat
(pypy) C:\Users\shach\code\bla\funniest>pypy setup.py develop
running develop
running egg_info
writing funniest.egg-info\PKG-INFO
writing dependency_links to funniest.egg-info\dependency_links.txt
writing top-level names to funniest.egg-info\top_level.txt
reading manifest file 'funniest.egg-info\SOURCES.txt'
writing manifest file 'funniest.egg-info\SOURCES.txt'
running build_ext
Creating c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
funniest 0.1 is already the active version in easy-install.pth
Installed c:\users\shach\code\bla\funniest
Processing dependencies for funniest==0.1
Finished processing dependencies for funniest==0.1
(pypy) C:\Users\shach\code\bla\funniest>pypy setup.py develop --uninstall
running develop
Removing c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link (link to .)
error: [Error 32] The process cannot access the file because it is being used by another process: c:\users\shach\code\bla\funniest\.tox\pypy\site-packages\funniest.egg-link
(pypy) C:\Users\shach\code\bla\funniest>
仍然失败:(
请指教!
沙查尔。
更新 2:
我尝试使用 Sysinternal 的 Process Explorer
和 nada 检查是否有一个进程持有该文件。我手动 运行 pypy setup.py develop
,然后检查 Process Explorer
并确保文件没有在任何进程中打开,然后 运行 pypy setup.py develop --uninstall
和同样的错误是提出。
更新 3:
关闭CMD再打开CMD后仍然出现
更新 4:
重启机器不能解决这个问题!什么-----?
根据描述,似乎在 pypy setup.py develop --uninstall
的 运行 中的某处,一个文件或目录被保持打开状态,这阻止了它在 windows 上被删除。您可以尝试使用“-X track-resources”参数(pypy -X track-resources setup.py develop --uninstall
)运行 pypy,如果在资源关闭之前释放持有资源的对象,它应该会通知您。有时扫描像 s - open(path).read()
这样的代码可能足以发现问题,该代码会泄漏文件描述符,直到垃圾收集器 运行 注意到幽灵对象并将其删除。代码应该使用上下文管理器; with open(path) as fid: s = fid.read()
TL;DR: 不要直接使用 setup.py
,使用 pip install -e .
.
看来问题出在windows上的setuptools
。发生的情况是 egg-link
文件在被删除之前仅打开和关闭了几行 - windows 无法处理。
不知何故 pip
确实处理了这种情况,我会在有更多信息时更新。
我在 setuptools 中打开了一个 issue。