Skip to content

Commit

Permalink
Python 3.7 compatibilty (#33)
Browse files Browse the repository at this point in the history
* Fix syntax errors in python 3.7 due to async being a reserved word
* Update tests to use await/async syntax
* drop python3.4 and custom coverage combining
* document 1.0.1 release, project status: seeking new owner :-)
  • Loading branch information
AndrewNelis authored and jquast committed Dec 27, 2018
1 parent 0b75f8c commit c914299
Show file tree
Hide file tree
Showing 29 changed files with 410 additions and 493 deletions.
13 changes: 5 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@ language: python
matrix:
fast_finish: true
include:
- python: 3.3
env: TOXENV=py33 COVERAGE_ID=travis-ci
- python: 3.4
env: TOXENV=py34 COVERAGE_ID=travis-ci
- python: 3.5
env: TOXENV=sa
- python: 3.5
env: TOXENV=py35,coveralls COVERAGE_ID=travis-ci
# some errors only present themselves when using with ASYNCIODEBUG,
# especially exceptions in tasks and so on.
- python: 3.5
env: ASYNCIODEBUG=1 TOXENV=py35 COVERAGE_ID=travis-ci
- python: 3.6
env: ASYNCIODEBUG=1 TOXENV=py36 COVERAGE_ID=travis-ci
- python: 3.7
env: ASYNCIODEBUG=1 TOXENV=py37 COVERAGE_ID=travis-ci

install:
- pip install tox
script:
Expand Down
5 changes: 5 additions & 0 deletions DESIGN.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Project Status
==============

Retired by author, looking for new owner :)

Design
======

Expand Down
6 changes: 2 additions & 4 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,10 @@
# built documents.
#
# The short X.Y version.
version = json.load(
open(os.path.join(HERE, os.pardir, 'version.json'), 'r')
)['version']
version = '1.0'

# The full version, including alpha/beta/rc tags.
release = version
release = '1.0.1'

# The language for content auto-generated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
4 changes: 4 additions & 0 deletions docs/history.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
History
=======
1.0.1
* add python3.7 support, drop python 3.4 and earlier, :ghissue:`33` by
:ghuser:`AndrewNelis`.

1.0.0
* First general release for standard API: Instead of encouraging twisted-like
override of protocol methods, we provide a "shell" callback interface,
Expand Down
1 change: 0 additions & 1 deletion requirements-tests.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
pytest-capturelog
pytest-asyncio
pytest-xdist
pytest-cov
Expand Down
14 changes: 2 additions & 12 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,9 @@ def _get_long_description(fname, encoding='utf8'):
return open(fname, 'r', encoding=encoding).read()


def _get_install_requires():
if platform.python_version_tuple() < ('3', '4'):
return ['asyncio']
return []

def _get_version(fname):
import json
return json.load(open(fname, 'r'))['version']


setup(name='telnetlib3',
version=_get_version(fname=_get_here('version.json')),
# keep in sync w/docs/conf.py manually for now, please!
version='1.0.1',
url='http://telnetlib3.rtfd.org/',
license='ISC',
author='Jeff Quast',
Expand Down Expand Up @@ -52,5 +43,4 @@ def _get_version(fname):
'Topic :: System :: Shells',
'Topic :: Internet',
],
install_requires=_get_install_requires(),
)
7 changes: 1 addition & 6 deletions telnetlib3/accessories.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# std imports
import pkg_resources
import importlib
import platform
import logging
import asyncio

Expand Down Expand Up @@ -90,8 +89,4 @@ def function_lookup(pymod_path):

def make_reader_task(reader, size=2**12):
"""Return asyncio task wrapping coroutine of reader.read(size)."""
if platform.python_version_tuple() <= ('3', '4', '4'):
task = asyncio.async
else:
task = asyncio.ensure_future
return task(reader.read(size))
return asyncio.ensure_future(reader.read(size))
4 changes: 2 additions & 2 deletions telnetlib3/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,8 @@ def send_charset(self, offered):
if selected:
self.log.debug('encoding negotiated: {0}'.format(selected))
else:
self.log.warn('No suitable encoding offered by server: {!r}.'
.format(offered))
self.log.warning('No suitable encoding offered by server: {!r}.'
.format(offered))
return selected

def send_naws(self):
Expand Down
2 changes: 1 addition & 1 deletion telnetlib3/client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def data_received(self, data):
try:
recv_inband = self.writer.feed_byte(bytes([byte]))
except:
self._log_exception(self.log.warn, *sys.exc_info())
self._log_exception(self.log.warning, *sys.exc_info())
else:
if recv_inband:
# forward to reader (shell).
Expand Down
4 changes: 2 additions & 2 deletions telnetlib3/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ def on_ttype(self, ttype):

elif (not ttype or self._ttype_count > self.TTYPE_LOOPMAX):
# empty reply string or too many responses!
self.log.warn('ttype cycle stop at {0}: {1}.'.format(key, ttype))
self.log.warning('ttype cycle stop at {0}: {1}.'.format(key, ttype))

elif (self._ttype_count == 3 and ttype.upper().startswith('MTTS ')):
val = self.get_extra_info('ttype2')
Expand Down Expand Up @@ -505,7 +505,7 @@ def run_server(host=CONFIG.host, port=CONFIG.port, loglevel=CONFIG.loglevel,
connect_maxwait=connect_maxwait))

# SIGTERM cases server to gracefully stop
loop.add_signal_handler(signal.SIGTERM, asyncio.async,
loop.add_signal_handler(signal.SIGTERM, asyncio.ensure_future,
_sigterm_handler(server, log))

log.info('Server ready on {0}:{1}'.format(host, port))
Expand Down
2 changes: 1 addition & 1 deletion telnetlib3/server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def data_received(self, data):
try:
recv_inband = self.writer.feed_byte(bytes([byte]))
except:
self._log_exception(self.log.warn, *sys.exc_info())
self._log_exception(self.log.warning, *sys.exc_info())
else:
if recv_inband:
# forward to reader (shell).
Expand Down
2 changes: 1 addition & 1 deletion telnetlib3/server_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def telnet_server_shell(reader, writer):
elif command == 'proto':
writer.write(repr(writer.protocol))
elif command == 'version':
writer.write(accessories.get_version()['shell'])
writer.write(accessories.get_version())
elif command == 'slc':
writer.write(get_slcdata(writer))
elif command.startswith('toggle'):
Expand Down
34 changes: 17 additions & 17 deletions telnetlib3/stream_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ def handle_xdisploc(self, xdisploc):
def handle_send_xdisploc(self):
"""Send XDISPLAY value ``xdisploc``, :rfc:`1096`."""
# xdisploc string format is '<host>:<dispnum>[.<screennum>]'.
self.log.warn('X Display requested, sending empty string.')
self.log.warning('X Display requested, sending empty string.')
return ''

def handle_sndloc(self, location):
Expand All @@ -1083,7 +1083,7 @@ def handle_sndloc(self, location):

def handle_send_sndloc(self):
"""Send LOCATION value ``location``, :rfc:`779`."""
self.log.warn('Location requested, sending empty response.')
self.log.warning('Location requested, sending empty response.')
return ''

def handle_ttype(self, ttype):
Expand All @@ -1098,7 +1098,7 @@ def handle_ttype(self, ttype):

def handle_send_ttype(self):
"""Send TTYPE value ``ttype``, :rfc:`1091`."""
self.log.warn('Terminal type requested, sending empty string.')
self.log.warning('Terminal type requested, sending empty string.')
return ''

def handle_naws(self, width, height):
Expand All @@ -1107,7 +1107,7 @@ def handle_naws(self, width, height):

def handle_send_naws(self):
"""Send window size ``width`` and ``height``, :rfc:`1073`."""
self.log.warn('Terminal size requested, sending 80x24.')
self.log.warning('Terminal size requested, sending 80x24.')
return 80, 24

def handle_environ(self, env):
Expand Down Expand Up @@ -1367,7 +1367,7 @@ def handle_will(self, opt):
# option value of -1 toggles opt.unsupported()
self.iac(DONT, opt)
self.remote_option[opt] = -1
self.log.warn('Unhandled: WILL {}.'.format(name_command(opt),))
self.log.warning('Unhandled: WILL {}.'.format(name_command(opt),))
self.local_option[opt] = -1
if self.pending_option.enabled(DO + opt):
self.pending_option[DO + opt] = False
Expand All @@ -1393,7 +1393,7 @@ def handle_wont(self, opt):
assert not (self.server), (
'cannot recv WONT LOGOUT on server end')
if not self.pending_option.enabled(DO + LOGOUT):
self.log.warn('Server sent WONT LOGOUT unsolicited')
self.log.warning('Server sent WONT LOGOUT unsolicited')
self._ext_callback[LOGOUT](WONT)
else:
self.remote_option[opt] = False
Expand Down Expand Up @@ -1507,7 +1507,7 @@ def _handle_sb_charset(self, buf):
.format(charset))
self._ext_callback[CHARSET](charset)
elif opt == REJECTED:
self.log.warn('recv IAC SB CHARSET REJECTED IAC SE')
self.log.warning('recv IAC SB CHARSET REJECTED IAC SE')
elif opt in (TTABLE_IS, TTABLE_ACK, TTABLE_NAK, TTABLE_REJECTED):
raise NotImplementedError('Translation table command received '
'but not supported: {!r}'.format(opt))
Expand Down Expand Up @@ -1657,8 +1657,8 @@ def _handle_sb_environ(self, buf):
# a pending option of value of 'False' means it was previously
# completed, subsequent environment values *should* have been
# sent as command INFO ...
self.log.warn('{} IS already recv; expected INFO.'
.format(name_command(cmd)))
self.log.warning('{} IS already recv; expected INFO.'
.format(name_command(cmd)))
if env:
self._ext_callback[cmd](env)
elif opt == SEND:
Expand Down Expand Up @@ -1910,11 +1910,11 @@ def _handle_sb_linemode_mode(self, mode):
# and the mode is different that what the current mode is,
# the client will ignore the new mode"
#
self.log.warn('server mode differs from local mode, '
'though ACK bit is set. Local mode will '
'remain.')
self.log.warn('!remote: {0!r}'.format(suggest_mode))
self.log.warn(' local: {0!r}'.format(self._linemode))
self.log.warning('server mode differs from local mode, '
'though ACK bit is set. Local mode will '
'remain.')
self.log.warning('!remote: {0!r}'.format(suggest_mode))
self.log.warning(' local: {0!r}'.format(self._linemode))
return

self.log.debug('Linemode matches, acknowledged by server.')
Expand Down Expand Up @@ -2024,8 +2024,8 @@ def _slc_process(self, func, slc_def):
"""
# out of bounds checking
if ord(func) > slc.NSLC:
self.log.warn('SLC not supported (out of range): ({!r})'
.format(func))
self.log.warning('SLC not supported (out of range): ({!r})'
.format(func))
self._slc_add(func, slc.SLC_nosupport())
return

Expand All @@ -2040,7 +2040,7 @@ def _slc_process(self, func, slc_def):
self.log.debug('_slc_process: client request SLC_VARIABLE')
self._slc_send()
else:
self.log.warn('func(0) flag expected, got {}.'.format(slc_def))
self.log.warning('func(0) flag expected, got {}.'.format(slc_def))
return

self.log.debug('_slc_process {:<9} mine={}, his={}'.format(
Expand Down
26 changes: 13 additions & 13 deletions telnetlib3/tests/test_charset.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


@pytest.mark.asyncio
def test_telnet_server_on_charset(
async def test_telnet_server_on_charset(
event_loop, bind_host, unused_tcp_port):
"""Test Server's callback method on_charset()."""
# given
Expand All @@ -31,15 +31,15 @@ def on_charset(self, charset):
super().on_charset(charset)
_waiter.set_result(self)

yield from telnetlib3.create_server(
await telnetlib3.create_server(
protocol_factory=ServerTestCharset,
host=bind_host, port=unused_tcp_port,
loop=event_loop)

reader, writer = yield from asyncio.open_connection(
reader, writer = await asyncio.open_connection(
host=bind_host, port=unused_tcp_port, loop=event_loop)

val = yield from asyncio.wait_for(reader.readexactly(3), 0.5)
val = await asyncio.wait_for(reader.readexactly(3), 0.5)
# exercise,
writer.write(IAC + WILL + CHARSET)
writer.write(IAC + WONT + TTYPE)
Expand All @@ -48,12 +48,12 @@ def on_charset(self, charset):
IAC + SE)

# verify,
srv_instance = yield from asyncio.wait_for(_waiter, 2.0)
srv_instance = await asyncio.wait_for(_waiter, 2.0)
assert srv_instance.get_extra_info('charset') == given_charset


@pytest.mark.asyncio
def test_telnet_client_send_charset(event_loop, bind_host, unused_tcp_port):
async def test_telnet_client_send_charset(event_loop, bind_host, unused_tcp_port):
"""Test Client's callback method send_charset() selection for illegals."""
# given
_waiter = asyncio.Future()
Expand All @@ -68,27 +68,27 @@ def send_charset(self, offered):
_waiter.set_result(selected)
return selected

yield from asyncio.wait_for(
await asyncio.wait_for(
telnetlib3.create_server(
protocol_factory=ServerTestCharset,
host=bind_host, port=unused_tcp_port,
loop=event_loop),
0.15)

reader, writer = yield from asyncio.wait_for(
reader, writer = await asyncio.wait_for(
telnetlib3.open_connection(
client_factory=ClientTestCharset,
host=bind_host, port=unused_tcp_port, loop=event_loop,
encoding='latin1', connect_minwait=0.05),
0.15)

val = yield from asyncio.wait_for(_waiter, 1.5)
val = await asyncio.wait_for(_waiter, 1.5)
assert val == 'cp437'
assert writer.get_extra_info('charset') == 'cp437'


@pytest.mark.asyncio
def test_telnet_client_no_charset(event_loop, bind_host, unused_tcp_port):
async def test_telnet_client_no_charset(event_loop, bind_host, unused_tcp_port):
"""Test Client's callback method send_charset() does not select."""
# given
_waiter = asyncio.Future()
Expand All @@ -103,17 +103,17 @@ def send_charset(self, offered):
_waiter.set_result(selected)
return selected

yield from telnetlib3.create_server(
await telnetlib3.create_server(
protocol_factory=ServerTestCharset,
host=bind_host, port=unused_tcp_port,
loop=event_loop)

reader, writer = yield from telnetlib3.open_connection(
reader, writer = await telnetlib3.open_connection(
client_factory=ClientTestCharset,
host=bind_host, port=unused_tcp_port, loop=event_loop,
encoding='latin1', connect_minwait=0.05)

# charset remains latin1
val = yield from asyncio.wait_for(_waiter, 0.5)
val = await asyncio.wait_for(_waiter, 0.5)
assert val == ''
assert writer.get_extra_info('charset') == 'latin1'

0 comments on commit c914299

Please sign in to comment.