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
Add PEP484 Typing + typing to setup.py #27
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,7 +6,14 @@ | |
import trollius as asyncio | ||
import pycares | ||
|
||
from . import error | ||
from typing import ( | ||
Any, | ||
List, | ||
Optional, | ||
) | ||
|
||
# TODO: Work out mypy no attribute error and remove ignore | ||
from . import error # type: ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this import needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems to be a mypy bug with this kind of import
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, right! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cooperlees What was the issue that you encountered? Seems to work fine with Python3 mypy, so I guess that this workaround should be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
|
||
__version__ = '1.1.1' | ||
|
@@ -33,26 +40,30 @@ | |
class DNSResolver(object): | ||
|
||
def __init__(self, nameservers=None, loop=None, **kwargs): | ||
# type: (Optional[List[str]], Optional[asyncio.AbstractEventLoop], Any) -> None | ||
self.loop = loop or asyncio.get_event_loop() | ||
assert self.loop is not None | ||
kwargs.pop('sock_state_cb', None) | ||
self._channel = pycares.Channel(sock_state_cb=self._sock_state_cb, **kwargs) | ||
if nameservers: | ||
self.nameservers = nameservers | ||
self._read_fds = set() | ||
self._write_fds = set() | ||
self._read_fds = set() # type: Set[int] | ||
self._write_fds = set() # type: Set[int] | ||
self._timer = None | ||
|
||
@property | ||
def nameservers(self): | ||
# type: () -> pycares.Channel | ||
return self._channel.servers | ||
|
||
@nameservers.setter | ||
def nameservers(self, value): | ||
# type: (List[str]) -> None | ||
self._channel.servers = value | ||
|
||
@staticmethod | ||
def _callback(fut, result, errorno): | ||
# type: (asyncio.Future, Any, int) -> None | ||
if fut.cancelled(): | ||
return | ||
if errorno is not None: | ||
|
@@ -61,6 +72,7 @@ def _callback(fut, result, errorno): | |
fut.set_result(result) | ||
|
||
def query(self, host, qtype): | ||
# type: (str, str) -> asyncio.Future | ||
try: | ||
qtype = query_type_map[qtype] | ||
except KeyError: | ||
|
@@ -71,15 +83,18 @@ def query(self, host, qtype): | |
return fut | ||
|
||
def gethostbyname(self, host, family): | ||
# type: (str, str) -> asyncio.Future | ||
fut = asyncio.Future(loop=self.loop) | ||
cb = functools.partial(self._callback, fut) | ||
self._channel.gethostbyname(host, family, cb) | ||
return fut | ||
|
||
def cancel(self): | ||
# type: () -> None | ||
self._channel.cancel() | ||
|
||
def _sock_state_cb(self, fd, readable, writable): | ||
# type: (int, bool, bool) -> None | ||
if readable or writable: | ||
if readable: | ||
self.loop.add_reader(fd, self._handle_event, fd, READ) | ||
|
@@ -104,6 +119,7 @@ def _sock_state_cb(self, fd, readable, writable): | |
self._timer = None | ||
|
||
def _handle_event(self, fd, event): | ||
# type: (int, Any) -> None | ||
read_fd = pycares.ARES_SOCKET_BAD | ||
write_fd = pycares.ARES_SOCKET_BAD | ||
if event == READ: | ||
|
@@ -113,12 +129,13 @@ def _handle_event(self, fd, event): | |
self._channel.process_fd(read_fd, write_fd) | ||
|
||
def _timer_cb(self): | ||
# type: () -> None | ||
if self._read_fds or self._write_fds: | ||
self._channel.process_fd(pycares.ARES_SOCKET_BAD, pycares.ARES_SOCKET_BAD) | ||
self._timer = self.loop.call_later(1.0, self._timer_cb) | ||
else: | ||
self._timer = None | ||
|
||
def __del__(self): | ||
# type: () -> None | ||
self._channel.destroy() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for my ignorance, but why are these needed if we are not really using them (just in comments) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those comments are evaluated by the tools performing the type checking (like mypy).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://mypy.readthedocs.io/en/latest/python2.html