python 3.8 support #19

Merged
jackrobison merged 1 commit from python-3.8 into master 2019-10-25 22:20:16 +02:00
4 changed files with 40 additions and 13 deletions

View file

@ -1,7 +1,7 @@
sudo: required sudo: required
dist: xenial dist: xenial
language: python language: python
python: "3.7" python: "3.8"
jobs: jobs:
include: include:
@ -16,7 +16,8 @@ jobs:
- &tests - &tests
stage: test stage: test
name: "Unit Tests w/ Python 3.7" name: "Unit Tests w/ Python 3.8"
python: "3.8"
before_install: before_install:
- pip install pylint coverage - pip install pylint coverage
- pip install -e .[test] - pip install -e .[test]
@ -27,6 +28,10 @@ jobs:
after_success: after_success:
- bash <(curl -s https://codecov.io/bash) - bash <(curl -s https://codecov.io/bash)
- <<: *tests
name: "Unit Tests w/ Python 3.7"
python: "3.7"
- <<: *tests - <<: *tests
name: "Unit Tests w/ Python 3.6" name: "Unit Tests w/ Python 3.6"
python: "3.6" python: "3.6"

View file

@ -3,10 +3,11 @@
[![PyPI version](https://badge.fury.io/py/aioupnp.svg)](https://badge.fury.io/py/aioupnp) [![PyPI version](https://badge.fury.io/py/aioupnp.svg)](https://badge.fury.io/py/aioupnp)
[![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/) [![Python 3.6](https://img.shields.io/badge/python-3.6-blue.svg)](https://www.python.org/downloads/release/python-360/)
[![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370/) [![Python 3.7](https://img.shields.io/badge/python-3.7-blue.svg)](https://www.python.org/downloads/release/python-370/)
[![Python 3.8](https://img.shields.io/badge/python-3.8-blue.svg)](https://www.python.org/downloads/release/python-380/)
# UPnP for asyncio # UPnP for asyncio
`aioupnp` is a python 3.6/7 library and command line tool to interact with UPnP gateways using asyncio. `aioupnp` requires the `netifaces` module. `aioupnp` is a python 3.6-8 library and command line tool to interact with UPnP gateways using asyncio. `aioupnp` requires the `netifaces` module.
## Supported devices ## Supported devices
DD-WRT DD-WRT

View file

@ -25,6 +25,7 @@ setup(
"License :: OSI Approved :: MIT License", "License :: OSI Approved :: MIT License",
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Topic :: System :: Networking", "Topic :: System :: Networking",
"Topic :: Communications :: File Sharing" "Topic :: Communications :: File Sharing"
], ],
@ -35,7 +36,8 @@ setup(
packages=find_packages(exclude=('tests',)), packages=find_packages(exclude=('tests',)),
entry_points={'console_scripts': console_scripts}, entry_points={'console_scripts': console_scripts},
install_requires=[ install_requires=[
'netifaces', 'defusedxml' 'netifaces',
'defusedxml'
], ],
extras_require={ extras_require={
'test': ( 'test': (

View file

@ -2,6 +2,7 @@ import asyncio
import unittest import unittest
import contextlib import contextlib
import socket import socket
from typing import Tuple, Optional, Any
from unittest import mock from unittest import mock
from unittest.case import _Outcome from unittest.case import _Outcome
@ -25,7 +26,7 @@ def mock_tcp_and_udp(loop, udp_expected_addr=None, udp_replies=None, udp_delay_r
tcp_replies = tcp_replies or {} tcp_replies = tcp_replies or {}
async def create_connection(protocol_factory, host=None, port=None): async def create_connection(protocol_factory, host=None, port=None):
def write(p: asyncio.Protocol): def get_write(p: asyncio.Protocol):
def _write(data): def _write(data):
sent_tcp_packets.append(data) sent_tcp_packets.append(data)
if data in tcp_replies: if data in tcp_replies:
@ -41,14 +42,21 @@ def mock_tcp_and_udp(loop, udp_expected_addr=None, udp_replies=None, udp_delay_r
return _write return _write
protocol = protocol_factory() protocol = protocol_factory()
transport = asyncio.Transport(extra={'socket': mock.Mock(spec=socket.socket)}) write = get_write(protocol)
transport.close = lambda: None
transport.write = write(protocol) class MockTransport(asyncio.Transport):
def close(self):
return
def write(self, data):
write(data)
transport = MockTransport(extra={'socket': mock.Mock(spec=socket.socket)})
protocol.connection_made(transport) protocol.connection_made(transport)
return transport, protocol return transport, protocol
async def create_datagram_endpoint(proto_lam, sock=None): async def create_datagram_endpoint(proto_lam, sock=None):
def sendto(p: asyncio.DatagramProtocol): def get_sendto(p: asyncio.DatagramProtocol):
def _sendto(data, addr): def _sendto(data, addr):
sent_udp_packets.append(data) sent_udp_packets.append(data)
loop.call_later(udp_delay_reply, p.datagram_received, data, loop.call_later(udp_delay_reply, p.datagram_received, data,
@ -63,10 +71,21 @@ def mock_tcp_and_udp(loop, udp_expected_addr=None, udp_replies=None, udp_delay_r
return _sendto return _sendto
protocol = proto_lam() protocol = proto_lam()
transport = asyncio.DatagramTransport(extra={'socket': mock_sock}) sendto = get_sendto(protocol)
transport.close = lambda: mock_sock.close()
mock_sock.sendto = sendto(protocol) class MockDatagramTransport(asyncio.DatagramTransport):
transport.sendto = mock_sock.sendto def __init__(self, sock):
super().__init__(extra={'socket': sock})
self._sock = sock
def close(self):
self._sock.close()
return
def sendto(self, data: Any, addr: Optional[Tuple[str, int]] = ...) -> None:
sendto(data, addr)
transport = MockDatagramTransport(mock_sock)
protocol.connection_made(transport) protocol.connection_made(transport)
return transport, protocol return transport, protocol