Skip to content

Commit

Permalink
On python3.4+, only support asyncio and expose it to rplugins
Browse files Browse the repository at this point in the history
Disallow python3.3
python2.7 is unchanged (pyuv is still preferred; loop not exposed)
  • Loading branch information
bfredl committed Mar 1, 2018
1 parent 0160997 commit 59c184f
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 23 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ python:
# If the build matrix gets bigger, also update the number of runs
# at the bottom of .scrutinizer.yml.
- 2.7
- 3.3
- 3.4
- 3.5
- 3.6
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ connecting to and scripting Nvim processes through its msgpack-rpc API.

#### Installation

Supports python 2.7, and 3.3 or later.
Supports python 2.7, and 3.4 or later.

```sh
pip2 install neovim
Expand Down
10 changes: 10 additions & 0 deletions neovim/api/nvim.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ class Nvim(object):
`SubClass.from_nvim(nvim)` where `SubClass` is a subclass of `Nvim`, which
is useful for having multiple `Nvim` objects that behave differently
without one affecting the other.
When this library is used on python3.4+, asyncio event loop is guaranteed
to be used. It is available as the "loop" attribute of this class. Note
that asyncio callbacks cannot make blocking requests, which includes
accessing state-dependent attributes. They should instead schedule another
callback using nvim.async_call, which will not have this restriction.
"""

@classmethod
Expand Down Expand Up @@ -90,6 +96,10 @@ def __init__(self, session, channel_id, metadata, types,
self._decode = decode
self._err_cb = err_cb

# only on python3.4+ we expose asyncio
if IS_PYTHON3:
self.loop = self._session.loop._loop

def _from_nvim(self, obj, decode=None):
if decode is None:
decode = self._decode
Expand Down
1 change: 1 addition & 0 deletions neovim/msgpack_rpc/async_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(self, msgpack_stream):
1: self._on_response,
2: self._on_notification
}
self.loop = msgpack_stream.loop

def threadsafe_call(self, fn):
"""Wrapper around `MsgpackStream.threadsafe_call`."""
Expand Down
22 changes: 15 additions & 7 deletions neovim/msgpack_rpc/event_loop/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@
Tries to use pyuv as a backend, falling back to the asyncio implementation.
"""
try:
# libuv is fully implemented in C, use it when available
from .uv import UvEventLoop
EventLoop = UvEventLoop
except ImportError:
# asyncio(trollius on python 2) is pure python and should be more portable
# across python implementations

from ...compat import IS_PYTHON3

# on python3 we only support asyncio, as we expose it to plugins
if IS_PYTHON3:
from .asyncio import AsyncioEventLoop
EventLoop = AsyncioEventLoop
else:
try:
# libuv is fully implemented in C, use it when available
from .uv import UvEventLoop
EventLoop = UvEventLoop
except ImportError:
# asyncio(trollius on python 2) is pure python and should be more
# portable across python implementations
from .asyncio import AsyncioEventLoop
EventLoop = AsyncioEventLoop


__all__ = ('EventLoop')
10 changes: 5 additions & 5 deletions neovim/msgpack_rpc/msgpack_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@ class MsgpackStream(object):

def __init__(self, event_loop):
"""Wrap `event_loop` on a msgpack-aware interface."""
self._event_loop = event_loop
self.loop = event_loop
self._packer = Packer(encoding='utf-8',
unicode_errors=unicode_errors_default)
self._unpacker = Unpacker()
self._message_cb = None

def threadsafe_call(self, fn):
"""Wrapper around `BaseEventLoop.threadsafe_call`."""
self._event_loop.threadsafe_call(fn)
self.loop .threadsafe_call(fn)

def send(self, msg):
"""Queue `msg` for sending to Nvim."""
debug('sent %s', msg)
self._event_loop.send(self._packer.pack(msg))
self.loop .send(self._packer.pack(msg))

def run(self, message_cb):
"""Run the event loop to receive messages from Nvim.
Expand All @@ -41,12 +41,12 @@ def run(self, message_cb):
a message has been successfully parsed from the input stream.
"""
self._message_cb = message_cb
self._event_loop.run(self._on_data)
self.loop .run(self._on_data)
self._message_cb = None

def stop(self):
"""Stop the event loop."""
self._event_loop.stop()
self.loop .stop()

def close(self):
"""Close the event loop."""
Expand Down
1 change: 1 addition & 0 deletions neovim/msgpack_rpc/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def __init__(self, async_session):
self._pending_messages = deque()
self._is_running = False
self._setup_exception = None
self.loop = async_session.loop

def threadsafe_call(self, fn, *args, **kwargs):
"""Wrapper around `AsyncSession.threadsafe_call`."""
Expand Down
15 changes: 6 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
install_requires = [
'msgpack>=0.5.0',
]
extras_require = {
'pyuv': ['pyuv>=1.0.0'],
}

if os.name == 'nt':
install_requires.append('pyuv>=1.0.0')
elif sys.version_info < (3, 4):
# trollius is just a backport of 3.4 asyncio module
install_requires.append('trollius')
if sys.version_info < (3, 4):
if os.name == 'nt':
install_requires.append('pyuv>=1.0.0')
else:
# trollius is just a backport of 3.4 asyncio module
install_requires.append('trollius')

if platform.python_implementation() != 'PyPy':
# pypy already includes an implementation of the greenlet module
Expand All @@ -32,5 +30,4 @@
packages=['neovim', 'neovim.api', 'neovim.msgpack_rpc',
'neovim.msgpack_rpc.event_loop', 'neovim.plugin'],
install_requires=install_requires,
extras_require=extras_require,
zip_safe=False)

0 comments on commit 59c184f

Please sign in to comment.