Open boileaum opened 4 years ago
This seems specific to MacOS. No problem inside a python:3
docker container (run from the MacOS environment) :
tmp$ docker run --rm -ti python:3 /bin/bash
root@ea1181c1d2ae:/# pip install doit
Collecting doit
Downloading doit-0.33.1-py3-none-any.whl (84 kB)
|████████████████████████████████| 84 kB 2.3 MB/s
Collecting pyinotify; sys_platform == "linux"
Downloading pyinotify-0.9.6.tar.gz (60 kB)
|████████████████████████████████| 60 kB 4.4 MB/s
Collecting cloudpickle
Downloading cloudpickle-1.6.0-py3-none-any.whl (23 kB)
Building wheels for collected packages: pyinotify
Building wheel for pyinotify (setup.py) ... done
Created wheel for pyinotify: filename=pyinotify-0.9.6-py3-none-any.whl size=25339 sha256=a44970bc035a3a09e43ae6d288d555faa55855e002916cd196dfe4d87ece31ce
Stored in directory: /root/.cache/pip/wheels/9d/a0/4b/1a80814e4ad0b035c07831ea1b06b691046198492bbc5769b6
Successfully built pyinotify
Installing collected packages: pyinotify, cloudpickle, doit
Successfully installed cloudpickle-1.6.0 doit-0.33.1 pyinotify-0.9.6
root@ea1181c1d2ae:/# python --version
Python 3.8.5
root@ea1181c1d2ae:/# cat > dodo.py <<- EOM
def task_hello():
"""hello"""
def python_hello(targets):
with open(targets[0], "a") as output:
output.write("Python says Hello World!!!\n")
return {
'actions': [python_hello],
'targets': ["hello.txt"],
}
EOM
root@ea1181c1d2ae:/# doit
. hello
root@ea1181c1d2ae:/# doit auto
. hello
^Croot@ea1181c1d2ae:/#
Based on #368. It seems multiprocess
package work on better MAC, could you try it?
I dont have a MAC dont expect a fix from me...
Python 3.8 for macOS changed the behavior of multiprocessing, and it now defaults to spawning new processes and communicating with pickles. This looks like doit is trying to run the action with multiprocessing and passes a file object to it, which is not pickleable.
Indeed, replacing multiprocessing
by multiprocess
solves the problem.
great. Now I am curious to know if works because it is better at handling pickled objects, or because it did not change the default to use spawning.
Uhhmmm. It says that using fork
on MAC is not reliable...
So using multiprocess
might be a regression in some cases. right?
Yes, but it can be fixed by manually setting it back to fork
with multiprocess.set_start_method('spawn')
before spawning a Process. I tested with the above snipper and auto
, and it worked in spawn
mode with multiprocess
.
Perhaps unsurprisingly, it appears there are some related issues with python 3.9 on OSX:
=================================== FAILURES ===================================
__________________________ TestAuto.test_invalid_args __________________________
self = <tests.test_cmd_auto.TestAuto object at 0x7fc3a33fd5b0>
cmd = CmdFactory(cmd_auto.Auto, task_loader=task_loader)
# terminates with error number
> assert cmd.parse_execute(['t2']) == 3
tests/test_cmd_auto.py:60:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/site-packages/doit/cmd_base.py:150: in parse_execute
return self.execute(params, args)
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/site-packages/doit/cmd_auto.py:139: in execute
proc.start()
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/multiprocessing/process.py:121: in start
self._popen = self._Popen(self)
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/multiprocessing/context.py:224: in _Popen
return _default_context.get_context().Process._Popen(process_obj)
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/multiprocessing/context.py:284: in _Popen
return Popen(process_obj)
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/multiprocessing/popen_spawn_posix.py:32: in __init__
super().__init__(process_obj)
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/multiprocessing/popen_fork.py:19: in __init__
self._launch(process_obj)
../../_test_env_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold_placehold/lib/python3.9/multiprocessing/popen_spawn_posix.py:47: in _launch
reduction.dump(process_obj, fp)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
obj = <Process name='Process-1' parent=1240 initial>
file = <_io.BytesIO object at 0x7fc3a3b45810>, protocol = None
def dump(obj, file, protocol=None):
'''Replacement for pickle.dump() using ForkingPickler.'''
> ForkingPickler(file, protocol).dump(obj)
E TypeError: cannot pickle 'EncodedFile' object
As discussed on the recent scipy thread, the aging/non-existent libraries that support the auto
feature are increasing the difficulty of keeping doit
packaged.
Proposed over there was moving auto
into an [extra]
, such that e.g. pip check
would be appeased without any os-specific binary packages installed.
At a deeper level: having a generic watcher is useful, and having a robust, yet optional, cross-platform solution is still very attractive.
It looks like watchfiles
, based on rust
, would be a good candidate for this in the future. It has a far simpler API than either macfsevents
or pyinotify
and supports windows (#17).
@bollwyvl moving discussion to #404
Describe the bug
Considering the following
dodo.py
file :doit auto
works with python 3.7 :but crashes with python 3.8 :
Environment