Skip to content

Drop support for old python versions and add type annotations #492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ venv
.eggs
.tox
.pytest_cache
.coverage*

# Sphinx documentation
docs/_build/
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ Python Plugin API
-----------------

Pynvim supports python _remote plugins_ (via the language-agnostic Nvim rplugin
interface), as well as _Vim plugins_ (via the `:python[3]` interface). Thus when
pynvim is installed Neovim will report support for the `+python[3]` Vim feature.
interface), as well as _Vim plugins_ (via the `:python3` interface). Thus when
pynvim is installed Neovim will report support for the `+python3` Vim feature.

The rplugin interface allows plugins to handle vimL function calls as well as
defining commands and autocommands, and such plugins can operate asynchronously
Expand Down
7 changes: 3 additions & 4 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ Development

If you change the code, you need to run::

pip2 install .
pip3 install .

for the changes to have effect.
Expand Down Expand Up @@ -45,9 +44,9 @@ You can run the plugin host in Neovim with logging enabled to debug errors::
NVIM_PYTHON_LOG_FILE=logfile NVIM_PYTHON_LOG_LEVEL=DEBUG nvim

As more than one Python host process might be started,
the log filenames take the pattern ``logfile_pyX_KIND``
where ``X`` is the major python version (2 or 3)
and ``KIND`` is either "rplugin" or "script" (for the ``:python[3]`` script interface).
the log filenames take the pattern ``logfile_py3_KIND``
where ``KIND`` is either "rplugin" or "script" (for the ``:python3`` script
interface).

If the host cannot start at all,
the error could be found in ``~/.nvimlog`` if ``nvim`` was compiled with logging.
Expand Down
10 changes: 1 addition & 9 deletions docs/installation.rst
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
Installation
============

The Neovim Python client supports Python 2.7, and 3.4 or later.
The Neovim Python client supports Python 3.7 or later.

Using pip
---------

You can install the package without being root by adding the ``--user`` flag::

pip2 install --user pynvim
pip3 install --user pynvim

.. note::

If you only use one of python2 or python3,
it is enough to install that version.

If you follow Neovim HEAD, make sure to upgrade ``pynvim`` when you upgrade
Neovim::

pip2 install --upgrade pynvim
pip3 install --upgrade pynvim

Install from source
Expand All @@ -32,5 +25,4 @@ Clone the repository somewhere on your disk and enter to the repository::

Now you can install it on your system::

pip2 install .
pip3 install .
69 changes: 43 additions & 26 deletions pynvim/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@
import logging
import os
import sys
from types import SimpleNamespace as Version
from typing import List, cast, overload

from pynvim.api import Nvim, NvimError
from pynvim.compat import IS_PYTHON3
from pynvim.msgpack_rpc import (ErrorResponse, child_session, socket_session,
stdio_session, tcp_session)
from pynvim.msgpack_rpc import (ErrorResponse, Session, TTransportType, child_session,
socket_session, stdio_session, tcp_session)
from pynvim.plugin import (Host, autocmd, command, decode, encoding, function,
plugin, rpc_export, shutdown_hook)
from pynvim.util import VERSION, Version
from pynvim.util import VERSION

if sys.version_info < (3, 8):
from typing_extensions import Literal
else:
from typing import Literal


__all__ = ('tcp_session', 'socket_session', 'stdio_session', 'child_session',
Expand All @@ -22,7 +28,7 @@
'ErrorResponse')


def start_host(session=None):
def start_host(session: Session = None) -> None:
"""Promote the current process into python plugin host for Nvim.

Start msgpack-rpc event loop for `session`, listening for Nvim requests
Expand Down Expand Up @@ -77,8 +83,30 @@ def start_host(session=None):
host.start(plugins)


def attach(session_type, address=None, port=None,
path=None, argv=None, decode=None):
@overload
def attach(session_type: Literal['tcp'], address: str, port: int = 7450) -> Nvim: ...


@overload
def attach(session_type: Literal['socket'], *, path: str) -> Nvim: ...


@overload
def attach(session_type: Literal['child'], *, argv: List[str]) -> Nvim: ...


@overload
def attach(session_type: Literal['stdio']) -> Nvim: ...


def attach(
session_type: TTransportType,
address: str = None,
port: int = 7450,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is having a default argument here OK? Also, str = None is not a valid typing annotation. I think they might be port: Optional[int] = None or address: Optional[str] = None, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct that the explicit Optional[type] is now the preferred style, though it was not always such, and mypy I think still supports implicitly inferring the Optional (it did at the time of writing this PR, but it's been a while).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default argument does seem like a little bit of a weird change to be included in this PR... maybe something that was left in from testing/debugging?

path: str = None,
argv: List[str] = None,
decode: Literal[True] = True
) -> Nvim:
"""Provide a nicer interface to create python api sessions.

Previous machinery to create python api sessions is still there. This only
Expand Down Expand Up @@ -107,22 +135,21 @@ def attach(session_type, address=None, port=None,


"""
session = (tcp_session(address, port) if session_type == 'tcp' else
socket_session(path) if session_type == 'socket' else
stdio_session() if session_type == 'stdio' else
child_session(argv) if session_type == 'child' else
None)
session = (
tcp_session(cast(str, address), port) if session_type == 'tcp' else
socket_session(cast(str, path)) if session_type == 'socket' else
stdio_session() if session_type == 'stdio' else
child_session(cast(List[str], argv)) if session_type == 'child' else
None
)

if not session:
raise Exception('Unknown session type "%s"' % session_type)

if decode is None:
decode = IS_PYTHON3

return Nvim.from_session(session).with_decode(decode)


def setup_logging(name):
def setup_logging(name: str) -> None:
"""Setup logging according to environment variables."""
logger = logging.getLogger(__name__)
if 'NVIM_PYTHON_LOG_FILE' in os.environ:
Expand All @@ -144,13 +171,3 @@ def setup_logging(name):
logger.warning('Invalid NVIM_PYTHON_LOG_LEVEL: %r, using INFO.',
env_log_level)
logger.setLevel(level)


# Required for python 2.6
class NullHandler(logging.Handler):
def emit(self, record):
pass


if not logging.root.handlers:
logging.root.addHandler(NullHandler())
Loading