{"id":7593,"library":"pynvim","title":"Pynvim","description":"Pynvim is the official Python client and plugin host for Neovim, enabling Python developers to interact with Neovim instances and write powerful remote plugins. Currently at version 0.6.0, it is actively maintained with regular releases addressing bug fixes, performance improvements, and new features.","status":"active","version":"0.6.0","language":"en","source_language":"en","source_url":"https://github.com/neovim/pynvim","tags":["neovim","text editor","plugin development","rpc","client"],"install":[{"cmd":"pip install pynvim","lang":"bash","label":"Install with pip"},{"cmd":"uv tool install --upgrade pynvim","lang":"bash","label":"Recommended with uv"},{"cmd":"pipx install pynvim","lang":"bash","label":"Recommended with pipx"}],"dependencies":[],"imports":[{"symbol":"attach","correct":"from pynvim import attach"},{"note":"The package was renamed from `neovim` to `pynvim` in version 0.3.1. While `import neovim` is still aliased for compatibility, `import pynvim` is the modern and recommended approach.","wrong":"import neovim","symbol":"neovim (old package name)","correct":"from pynvim import attach"}],"quickstart":{"code":"# Start Neovim in a terminal with: nvim --listen /tmp/nvim.sock\n\nimport os\nfrom pynvim import attach\n\n# Connect to a running Neovim instance via socket\n# Ensure Neovim is running with `--listen /tmp/nvim.sock`\n# For local testing, you might use os.environ.get('NVIM_LISTEN_ADDRESS')\ntry:\n    nvim = attach('socket', path=os.environ.get('NVIM_LISTEN_ADDRESS', '/tmp/nvim.sock'))\n    \n    # Execute a Neovim command\n    nvim.command('echo \"Hello from pynvim!\"')\n    \n    # Get and print the current buffer content\n    current_buffer = nvim.current.buffer\n    print(f\"First line of current buffer: {current_buffer[0]}\")\n    \n    # Set a Neovim variable\n    nvim.vars['pynvim_test_var'] = 'Python was here'\n    print(f\"Neovim variable 'pynvim_test_var': {nvim.eval('g:pynvim_test_var')}\")\n\nexcept Exception as e:\n    print(f\"Could not connect to Neovim or encountered an error: {e}\")\n    print(\"Make sure Neovim is running with '--listen /tmp/nvim.sock' or NVIM_LISTEN_ADDRESS is set.\")","lang":"python","description":"This quickstart demonstrates how to connect to a running Neovim instance using a Unix domain socket and interact with it. It executes a command, reads from the current buffer, and sets a global Neovim variable. Ensure Neovim is started with `nvim --listen /tmp/nvim.sock` (or similar for Windows/TCP) for the client to connect."},"warnings":[{"fix":"Upgrade your Python environment to 3.7 or newer. For best results with `pynvim >=0.6.0`, use Python 3.9+.","message":"Pynvim 0.5.0 raised the minimum supported Python version to 3.7. While 0.6.0 still supports 3.7, it is recommended to use Python 3.9+ for optimal compatibility, especially when using modern installation tools like `uv` or `pipx`.","severity":"breaking","affected_versions":"<0.5.0"},{"fix":"Upgrade pynvim to version 0.6.0 or higher: `pip install --upgrade pynvim`. If still encountering issues, ensure your Python installation is compatible.","message":"The `asyncio.get_child_watcher()` function was removed in Python 3.14. Older versions of pynvim (prior to 0.6.0) that relied on this function will cause `AttributeError` or similar failures when run with Python 3.14.","severity":"breaking","affected_versions":"<0.6.0 (when using Python 3.14)"},{"fix":"Update all import statements from `import neovim` to `import pynvim`. When upgrading, it's safest to `pip uninstall neovim` then `pip install pynvim`.","message":"The Python package was renamed from `neovim` to `pynvim` in version 0.3.1. While `import neovim` remains an alias for backward compatibility, new projects and updated codebases should use `import pynvim` to avoid confusion and ensure future compatibility.","severity":"deprecated","affected_versions":">=0.3.1"},{"fix":"To update a Vimscript dictionary, you must re-assign the entire dictionary back to Neovim. For example:\n```python\nmy_dict = nvim.vars['my_dict']\nmy_dict['field1'] = 'new_value'\nnvim.vars['my_dict'] = my_dict # Re-assign the modified dictionary\n```","message":"When accessing Vimscript dictionaries (e.g., `nvim.vars['my_dict']`) from Python, pynvim returns a *copy* of the dictionary, not a live reference. Modifying fields directly on the Python object will not persist changes back to Neovim.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Avoid making synchronous Neovim API calls from within `async` (default `sync=False`) plugin handlers. If a return value is required, the handler must be explicitly marked `sync=True`. For non-blocking operations within async handlers, use `async_=True` for Neovim requests or schedule new callbacks with `nvim.async_call`.","message":"In remote plugins, synchronous API calls (`sync=True` in decorators) made from within asynchronous handlers can cause Neovim to hang or deadlock, as Neovim waits for the handler to complete while the handler is waiting for Neovim.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"1. Ensure `pynvim` is installed for the Python interpreter Neovim uses (check `:py3 print(sys.executable)` and `:py3 import pynvim`).\n2. If using a virtual environment, tell Neovim its path by setting `vim.g.python3_host_prog` in your Neovim config (e.g., `init.lua` or `init.vim`):\n   `let g:python3_host_prog = '/path/to/your/venv/bin/python'` (Vimscript)\n   `vim.g.python3_host_prog = '/path/to/your/venv/bin/python'` (Lua)\n3. Run `:checkhealth` in Neovim to diagnose further.","cause":"Neovim cannot find a Python 3 interpreter with `pynvim` installed, or `g:python3_host_prog` is incorrectly configured or not set.","error":"E319: No \"python3\" provider found. Run \":checkhealth vim.provider\" for details."},{"fix":"This often indicates an issue within Neovim or a plugin. 0.6.0 improves handling, but the root cause might be external. Check Neovim's logs (if enabled, e.g., `NVIM_PYTHON_LOG_FILE=logfile nvim`), review your Neovim configuration and plugins for instability, and ensure the Neovim process remains active during `pynvim` interaction. If connecting via `socket`, verify the socket file `/tmp/nvim.sock` exists and Neovim is listening.","cause":"The connection to the Neovim instance was unexpectedly closed or interrupted, often because the Neovim process itself crashed, was killed, or backgrounded in a way that severed the communication pipe/socket.","error":"EOFError: Read beyond end of file"},{"fix":"Instead of `asyncio.run()`, use `await` directly for awaitable objects if you are within an `async` function managed by the event loop. If you need to run a task concurrently without blocking, schedule it using `asyncio.create_task()` or `nvim.async_call()`.","cause":"Attempting to call `asyncio.run()` from within an already active asyncio event loop. This commonly occurs when `pynvim` is hosting a plugin, which already operates within an asyncio event loop.","error":"RuntimeError: asyncio.run() cannot be called from a running event loop"}]}