RomeoDespres / reapy

A pythonic wrapper for REAPER's ReaScript Python API
MIT License
107 stars 25 forks source link

After the initial `python -c "import reapy; reapy.configure_reaper()` then `import reapy` just hangs the interpreter #130

Open r4dian opened 2 years ago

r4dian commented 2 years ago

Steps to reproduce:

> pip install python-reapy
> python -c "import reapy; reapy.configure_reaper()"

# ( restart REAPER as instructed)

> python
Python 3.10.4 (tags/v3.10.4:9d38120, Mar 23 2022, 23:13:41) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import reapy

Result : at this point the python interpreter hangs. This happens in commandline python, or IDLE. Expected Result : interpreter remains responsive.

If REAPER is not running, I get the error you'd expect: Can't reach distant API. Please start REAPER, or call reapy.config.enable_dist_api() from inside REAPER to enable distant API.

Version under test: package version
cPython 3.10
python-reapy 0.10.0
Reaper 6.53 & also 6.54

All 64 Bit versions, on 64 bit version of Windows 10.

iamtheband commented 2 years ago

Could reproduce both on Windows 10, Python 3.10.4, Reaper 6.53 and Fedora Linux 35, Python 3.10.6, Reaper 6.28. I wonder if this is a Python 3.10 specific bug as the exact same scripts worked fine in Fedora 33 and also on Windows with Python 3.9.

I'll paste a stack trace that I get when ^C after the hang:

>python -c "import reapy"
Traceback (most recent call last):
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 25, in get_reapy_server_port
    port = self.ext_state["server_port"]
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 48, in __getitem__
    raise UndefinedExtStateError(key)
reapy.errors.UndefinedExtStateError: ('Undefined extended state for key server_port.', 'server_port')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 25, in get_reapy_server_port
    port = self.ext_state["server_port"]
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 48, in __getitem__
    raise UndefinedExtStateError(key)
reapy.errors.UndefinedExtStateError: ('Undefined extended state for key server_port.', 'server_port')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 25, in get_reapy_server_port
    port = self.ext_state["server_port"]
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 48, in __getitem__
    raise UndefinedExtStateError(key)
reapy.errors.UndefinedExtStateError: ('Undefined extended state for key server_port.', 'server_port')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files\Python310\lib\socket.py", line 833, in create_connection
    sock.connect(sa)
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "D:\Development\Python\venv\lib\site-packages\reapy\__init__.py", line 25, in <module>
    from .tools import (
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\__init__.py", line 4, in <module>
    from ._inside_reaper import inside_reaper, dist_api_is_enabled
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\_inside_reaper.py", line 8, in <module>
    from .network import machines
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\machines.py", line 139, in <module>
    connect("localhost")
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\machines.py", line 92, in __init__
    register_machine(host)
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\machines.py", line 135, in register_machine
    CLIENTS[host] = client.Client(interface.get_reapy_server_port(), host)
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 30, in get_reapy_server_port
    port = self.get_reapy_server_port()
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 30, in get_reapy_server_port
    port = self.get_reapy_server_port()
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 29, in get_reapy_server_port
    self.activate_reapy_server()
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 19, in activate_reapy_server
    self.perform_action(action_name)
  File "D:\Development\Python\venv\lib\site-packages\reapy\tools\network\web_interface.py", line 35, in perform_action
    request.urlopen(url)
  File "C:\Program Files\Python310\lib\urllib\request.py", line 216, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Program Files\Python310\lib\urllib\request.py", line 519, in open
    response = self._open(req, data)
  File "C:\Program Files\Python310\lib\urllib\request.py", line 536, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
  File "C:\Program Files\Python310\lib\urllib\request.py", line 496, in _call_chain
    result = func(*args)
  File "C:\Program Files\Python310\lib\urllib\request.py", line 1377, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "C:\Program Files\Python310\lib\urllib\request.py", line 1348, in do_open
    h.request(req.get_method(), req.selector, req.data, headers,
  File "C:\Program Files\Python310\lib\http\client.py", line 1282, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "C:\Program Files\Python310\lib\http\client.py", line 1328, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "C:\Program Files\Python310\lib\http\client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "C:\Program Files\Python310\lib\http\client.py", line 1037, in _send_output
    self.send(msg)
  File "C:\Program Files\Python310\lib\http\client.py", line 975, in send
    self.connect()
  File "C:\Program Files\Python310\lib\http\client.py", line 941, in connect
    self.sock = self._create_connection(
  File "C:\Program Files\Python310\lib\socket.py", line 833, in create_connection
    sock.connect(sa)
KeyboardInterrupt
iamtheband commented 2 years ago

Nope, downgraded to Python 3.9.13 on Windows 10 and still has the same problem. Problem is also there if I downgrade to reapy 0.9.0.

HOWEVER, it does happen only when reapy is run outside of Reaper. No problem importing Reapy from its (dodgy) script editor.

Levitanus commented 2 years ago

well, never faced this before... Maybe this is some sort of firewall... But on such many systems.... Can't imagine what is wrong

Maybe a problem is the Reaper is already configured to some interpreter and reapy does not know what to do with that... When I have time — I'll try to make it again on the clean system, but last time I installed it on the fresh laptop (about of 30.07.22, Manjaro) — everything looked fine.

iamtheband commented 2 years ago

Hi Levitanus, thanks for chiming in!

Admittedly I had reapy lock up on both my systems after a Python version update. Fedora went like that after an update from 33 to 35, and Windows had its Python version bumped up from 3.9 to 3.10. I relinked Reaper to the correct Python library after each update.

I couldn't figure out from the source how the "remote" configuration is done, I guess I should run it from source with a debugger... I presume that configuration step is persistent, so is there a way to "un-configure" Reaper and start from fresh, without reinstalling? Thanks so much!

And awesome project, it's helped me so many times and it makes Reaper so much more interesting, hehehe...

EDIT: deleting ~/.config/REAPER and re-configuring Reaper from scratch, the problem goes away (tested only on Fedora, Py 3.10.6, Reaper updated to 6.66 for the occasion) . Pretty destructive workaround though!

john-kurkowski commented 1 year ago

EDIT: deleting ~/.config/REAPER and re-configuring Reaper from scratch, the problem goes away (tested only on Fedora, Py 3.10.6, Reaper updated to 6.66 for the occasion) . Pretty destructive workaround though!

Destructive indeed! 😬 I wanted to fix the hanging interpreter more surgically. In my case, I tracked down the issue to a bogus line in reaper-kb.ini. I was poking around for all references to reapy, and this grep output caught my eye.

$ rg reapy ~'/Library/Application Support/REAPER/'
/Users/john/Library/Application Support/REAPER/reaper-kb.ini
5:[Omitted long line with 6 matches]

…

What's that long line? It's 1 line with 2 entries. Mine for example was mixing a "global" Python interpreter path and a virtualenv interpreter path.

SCR 4 0 RS6UQ3Xh1OeiYfWbZyZAHR5Vz8HnkAaU2Zo98CyMNX "Custom: activate_reapy_server.py" /Users/john/.pyenv/versions/3.10.5/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/reapy/reascripts/activate_reapy_server.pySCR 4 0 RS9I5F1Ye5Qf339jncCCMJ5aUgc0DhYf8XKEmcNMOJ "Custom: activate_reapy_server.py" /Users/john/.pyenv/versions/music/lib/python3.10/site-packages/reapy/reascripts/activate_reapy_server.py

I manually removed the 2nd, newer entry, in my editor, which includes newlines at the end of the file. import reapy started working again. Then I was able to re-run reapy.configure_reaper() and reaper-kb.ini was correctly formatted, albeit with both interpreter paths. I manually removed the 1st, older entry. That fixes the hang for me. 👌

john-kurkowski commented 1 year ago

I think my reaper-kb.ini lines were originally mashed together because newlines are unhandled in the following code. Also the function doesn't clean up old interpreter paths.

https://github.com/RomeoDespres/reapy/blob/730627cee6f39fc26d6ebc8a3df0112e5921cd9f/reapy/config/config.py#L132

rewgs commented 10 months ago

Chiming in with a similar issue. I'm on macOS 13 and have tried with the most recent versions of Python 3.9, 3.10, 3.11, all installed via pyenv. I tried both before and after configuring Reaper to use the correct interpretor, but the result was always the same.

I've attached a capture of stderr/stdout after running the python -c "import reapy; reapy.configure_reaper()" command with 3.11.6; aside from the version number, the output was identical for all other tests. I too ^c'd out of the hang a few times and got an output similar to @iamtheband, but I figured letting the hang complete would be helpful.

Tried the fix suggested by @john-kurkowski but unfortunately it didn't work.

reapy_err.txt