我试图让setup.py test
使用在Windows上使用多处理的软件包。我有以下情况:
setup.py
。 运行
python -m unittest
顶层目录中的执行我的测试而没有抱怨。但是,在致电
时python setup.py test
我得到了众所周知的freeze_support
问题(请参阅此处的几个问题):
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom
in the main module:
if __name__ == '__main__':
freeze_support()
...
The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
但是,以下 where to put freeze_support() in a Python script?我实际上已经在我的所有文件中都有所描述的警卫,可能太多了。
问题1:我的项目中我需要更改setup.py test
才能使用函数进行多处理?
问题2:我实际需要放置哪个freeze_support()
?据我所知,这通常只在编译冻结的可执行文件时才需要。
project
│ setup.py
│
└─── my_package
│ │ __init__.py
│ │ my_package.py
│
└─── test
│ │ __init__.py
│ │ test_it.py
__init__.py
个文件为空,其他文件为:
import multiprocessing
def say_hi(arg):
print('hi')
def main():
pool = multiprocessing.Pool(1)
pool.map(say_hi, range(1))
if __name__ == '__main__':
multiprocessing.freeze_support()
main()
import multiprocessing
import unittest
from my_package import my_package
class TestIt(unittest.TestCase):
def test_say_hi(self):
my_package.main()
if __name__ == '__main__':
multiprocessing.freeze_support()
#!/usr/bin/env python
import setuptools
import multiprocessing
setuptools.setup(
name = "my_package"
)
if __name__ == '__main__':
multiprocessing.freeze_support()
答案 0 :(得分:2)
我遇到了类似的问题。
我发现当通过 setup.py 执行测试时,多处理创建的新进程会调用setuptools.setup
方法,这会影响某些内容。 (我不清楚根本原因......)
就我而言, setup.py 解决了这个问题。
#!/usr/bin/env python
import setuptools
if __name__ == '__main__':
setuptools.setup(
name = "my_package",
....,
)
答案 1 :(得分:1)
如前所述,我认为只有在__name__ =='main'成立时才执行setuptools.setup,此程序才会运行。
根本原因
当您使用多处理生成流程时,会导入模块,将__name__属性设置为“__mp_main__”,(而不是__main __)。
这是 multiprocessing.spawn.py
中 _fixup_main_from_path 的代码段# If the parent process has sent a path through rather than a module
# name we assume it is an executable script that may contain
# non-main code that needs to be executed
old_main_modules.append(current_main)
main_module = types.ModuleType("__mp_main__")
main_content = runpy.run_path(main_path,
run_name="__mp_main__")
main_module.__dict__.update(main_content)
sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module
因此,如果在模块的顶层执行setuptools.setup,则会发生无限递归。