pyinfra-dev / pyinfra

pyinfra turns Python code into shell commands and runs them on your servers. Execute ad-hoc commands and write declarative operations. Target SSH servers, local machine and Docker containers. Fast and scales from one server to thousands.
https://pyinfra.com
MIT License
3.78k stars 371 forks source link

Cannot run in PyCharm/IntelliJ runner due to `This operation would block forever` #1143

Closed nazarewk closed 1 month ago

nazarewk commented 1 month ago

Describe the bug

I am trying to run the following IntelliJ Run configuration (in both debugger and just "run" mode) after enabling gevent compatibility mentioned in #450 .

image

This results in gevent.exceptions.LoopExit: This operation would block forever:

run console output ``` /home/kdn/XXXXXXXXXXXXXXXX/mysql-users/.bin/python -m pyinfra @local mysql-users.py /nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/pyinfra_cli/__init__.py:6: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016. Modules that had direct imports (NOT patched): ['urllib3.util (/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/urllib3/util/__init__.py)', 'urllib3.util.ssl_ (/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/urllib3/util/ssl_.py)']. monkey.patch_all() # noqa --> Loading config... --> Loading inventory... --> Connecting to hosts... [@local] Connected --> An internal exception occurred: File "src/gevent/_gevent_c_greenlet_primitives.pxd", line 35, in gevent._gevent_c_greenlet_primitives._greenlet_switch gevent.exceptions.LoopExit: This operation would block forever Hub: Handles: [] --> The full traceback has been written to pyinfra-debug.log --> If this is unexpected please consider submitting a bug report on GitHub, for more information run `pyinfra --support`. ```

To Reproduce

Steps to reproduce the behavior, please include where possible:

Expected behavior

I would (probably mistakenly) expect to be able to run mysql-users.py line-by-line, but at least to execute at all.

Meta

when executed through Run ``` /home/kdn/dev/gitlab.com/XXXXXXXXXX/mysql-users/.bin/python -m pyinfra --support /nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/pyinfra_cli/__init__.py:6: MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016. Modules that had direct imports (NOT patched): ['urllib3.util.ssl_ (/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/urllib3/util/ssl_.py)', 'urllib3.util (/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/urllib3/util/__init__.py)']. monkey.patch_all() # noqa If you are having issues with pyinfra or wish to make feature requests, please check out the GitHub issues at https://github.com/Fizzadar/pyinfra/issues . When adding an issue, be sure to include the following: --> Support information: System: Linux Platform: Linux-6.8.12-x86_64-with-glibc2.39 Release: 6.8.12 Machine: x86_64 pyinfra: v2.9.2 Executable: /nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/pyinfra/__main__.py Python: 3.11.9 (CPython, GCC 13.3.0) ```
pyinfra-debug.log ``` File "/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/pyinfra_cli/main.py", line 218, in cli _main(*args, **kwargs) File "/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/pyinfra_cli/main.py", line 356, in _main connect_all(state) File "/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/pyinfra/api/connect.py", line 27, in connect_all with progress_spinner(greenlet_to_host.values()) as progress: File "/nix/store/6b1fqdwb3g56j5pazv8zkx9qd0mv3wiz-python3-3.11.9/lib/python3.11/contextlib.py", line 144, in __exit__ next(self.gen) File "/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/pyinfra/progress.py", line 146, in progress_spinner spinner_thread.join() File "/nix/store/6b1fqdwb3g56j5pazv8zkx9qd0mv3wiz-python3-3.11.9/lib/python3.11/threading.py", line 1119, in join self._wait_for_tstate_lock() File "/nix/store/6b1fqdwb3g56j5pazv8zkx9qd0mv3wiz-python3-3.11.9/lib/python3.11/threading.py", line 1139, in _wait_for_tstate_lock if lock.acquire(block, timeout): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/nix/store/26r5fywjsrgfk832hia1rp9qwsl48r3r-python3-3.11.9-env/lib/python3.11/site-packages/gevent/thread.py", line 112, in acquire acquired = BoundedSemaphore.acquire(self, blocking, timeout) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "src/gevent/_semaphore.py", line 184, in gevent._gevent_c_semaphore.Semaphore.acquire File "src/gevent/_semaphore.py", line 263, in gevent._gevent_c_semaphore.Semaphore.acquire File "src/gevent/_semaphore.py", line 253, in gevent._gevent_c_semaphore.Semaphore.acquire File "src/gevent/_abstract_linkable.py", line 521, in gevent._gevent_c_abstract_linkable.AbstractLinkable._wait File "src/gevent/_abstract_linkable.py", line 487, in gevent._gevent_c_abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 490, in gevent._gevent_c_abstract_linkable.AbstractLinkable._wait_core File "src/gevent/_abstract_linkable.py", line 442, in gevent._gevent_c_abstract_linkable.AbstractLinkable._AbstractLinkable__wait_to_be_notified File "src/gevent/_abstract_linkable.py", line 451, in gevent._gevent_c_abstract_linkable.AbstractLinkable._switch_to_hub File "src/gevent/_greenlet_primitives.py", line 61, in gevent._gevent_c_greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_greenlet_primitives.py", line 65, in gevent._gevent_c_greenlet_primitives.SwitchOutGreenletWithLoop.switch File "src/gevent/_gevent_c_greenlet_primitives.pxd", line 35, in gevent._gevent_c_greenlet_primitives._greenlet_switch gevent.exceptions.LoopExit: This operation would block forever Hub: Handles: [] ```
xvello commented 1 month ago

Not a bug in pyinfra, but a limitation of pycharm. pycharm heavily monkey-patches stuff in the python context to hook their UI and this breaks gevent. Setting GEVENT_SUPPORT=True in the launch config helps somewhat, but the experience is still pretty janky.

Running pyinfra ... as a standard command (not as a python run config) works fine though.

nazarewk commented 1 month ago

Running pyinfra ... as a standard command (not as a python run config) works fine though.

I was mostly thinking about using step-by-step debugger when developing code. Is there any debugger (pdb or whatever else) that actually works with pyinfra?

nazarewk commented 1 month ago

I've learned on Matrix chatroom that pyinfra doesn't really support any kind of step-by-step debugging, so closing this issue.