Skip to content

Commit e6c8221

Browse files
author
BiffoBear
committed
Checked type hints and doc strings. Added setblocking and getblocking functions.
1 parent c47cd07 commit e6c8221

File tree

1 file changed

+73
-36
lines changed

1 file changed

+73
-36
lines changed

adafruit_wiznet5k/adafruit_wiznet5k_socket.py

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
1010
A socket compatible interface with the Wiznet5k module.
1111
12-
* Author(s): ladyada, Brent Rubell, Patrick Van Oosterwijck, Adam Cummick
12+
* Author(s): ladyada, Brent Rubell, Patrick Van Oosterwijck, Adam Cummick, Martin Stephens
1313
1414
"""
1515
from __future__ import annotations
@@ -39,7 +39,7 @@ def _is_ipv4_string(ipv4_address: str) -> bool:
3939
4040
:param: str ipv4_address: The string to test.
4141
42-
:returns bool: True if a valid IPv4 address, False otherwise.
42+
:return bool: True if a valid IPv4 address, False otherwise.
4343
"""
4444
octets = ipv4_address.split(".", 3)
4545
if len(octets) == 4 and "".join(octets).isdigit():
@@ -58,9 +58,9 @@ def set_interface(iface: WIZNET5K) -> None:
5858
_the_interface = iface
5959

6060

61-
def getdefaulttimeout():
61+
def getdefaulttimeout() -> Optional[float]:
6262
"""
63-
Return the default timeout in seconds (float) for new socket objects. A value of
63+
Return the default timeout in seconds for new socket objects. A value of
6464
None indicates that new socket objects have no timeout. When the socket module is
6565
first imported, the default is None.
6666
"""
@@ -114,7 +114,7 @@ def inet_aton(ip_address: str) -> bytes:
114114
115115
:param str ip_address: The IPv4 address to convert.
116116
117-
:returns bytes: The converted IPv4 address.
117+
:return bytes: The converted IPv4 address.
118118
"""
119119
if not _is_ipv4_string(ip_address):
120120
raise ValueError("The IPv4 address must be a dotted-quad string.")
@@ -131,7 +131,7 @@ def inet_ntoa(ip_address: Union[bytes, bytearray]) -> str:
131131
132132
:param Union[bytes, bytearray ip_address: The IPv4 address to convert.
133133
134-
:returns str: The converted ip_address:
134+
:return str: The converted ip_address:
135135
"""
136136
if len(ip_address) != 4:
137137
raise ValueError("The IPv4 address must be 4 bytes.")
@@ -152,7 +152,7 @@ def getaddrinfo(
152152
host: str,
153153
port: int,
154154
family: int = 0,
155-
socktype: int = 0,
155+
soc_type: int = 0,
156156
proto: int = 0,
157157
flags: int = 0,
158158
) -> List[Tuple[int, int, int, str, Tuple[str, int]]]:
@@ -164,23 +164,28 @@ def getaddrinfo(
164164
None.
165165
:param int port: Port number to connect to (0 - 65536).
166166
:param int family: Ignored and hardcoded as 0x03 (the only family implemented) by the function.
167-
:param int socktype: The type of socket, either SOCK_STREAM (0x21) for TCP or SOCK_DGRAM (0x02)
168-
for UDP, defaults to 0x00.
167+
:param int soc_type: The type of socket, either SOCK_STREAM (0x21) for TCP or SOCK_DGRAM (0x02)
168+
for UDP, defaults to 0.
169169
:param int proto: Unused in this implementation of socket.
170170
:param int flags: Unused in this implementation of socket.
171171
172-
:return List[Tuple[int, int, int, str, Tuple[str, int]]]: Address info entries.
172+
:return List[Tuple[int, int, int, str, Tuple[str, int]]]: Address info entries in the form
173+
(family, type, proto, canonname, sockaddr). In these tuples, family, type, proto are meant
174+
to be passed to the socket() function. canonname will always be an empty string, sockaddr
175+
is a tuple describing a socket address, whose format is (address, port), and is meant to be
176+
passed to the socket.connect() method.
173177
"""
174178
if not isinstance(port, int):
175179
raise ValueError("Port must be an integer")
176180
if not _is_ipv4_string(host):
177181
host = gethostbyname(host)
178-
return [(AF_INET, socktype, proto, "", (host, port))]
182+
return [(AF_INET, soc_type, proto, "", (host, port))]
179183

180184

181185
def gethostbyname(hostname: str) -> str:
182186
"""
183-
Lookup a host name's IPv4 address.
187+
Translate a host name to IPv4 address format. The IPv4 address is returned as a string, such
188+
as '100.50.200.5'. If the host name is an IPv4 address itself it is returned unchanged.
184189
185190
:param str hostname: Hostname to lookup.
186191
@@ -214,7 +219,6 @@ def __init__(
214219
defaults to SOCK_STREAM.
215220
:param int proto: Unused, retained for compatibility.
216221
:param Optional[int] fileno: Unused, retained for compatibility.
217-
:param Optional[int] socknum: Unused, retained for compatibility.
218222
"""
219223
if family != AF_INET:
220224
raise RuntimeError("Only AF_INET family supported by W5K modules.")
@@ -300,7 +304,7 @@ def bind(self, address: Tuple[Optional[str], int]) -> None:
300304
:raises ValueError: If the IPv4 address specified is not the address
301305
assigned to the WIZNET5K interface.
302306
"""
303-
# Check is disabled to allow socket.accept to swap sockets.
307+
# Check to see if the socket is bound is disabled to allow socket.accept to swap sockets.
304308
# if self._listen_port:
305309
# raise ConnectionError("The socket is already bound.")
306310
if address[0]:
@@ -338,15 +342,9 @@ def accept(
338342
self,
339343
) -> Tuple[socket, Tuple[str, int]]:
340344
"""
341-
Accept a connection.
345+
Accept a connection. The socket must be bound to an address and listening for connections.
342346
343-
The socket must be bound to an address and listening for connections.
344-
345-
The return value is a pair (conn, address) where conn is a new
346-
socket object to send and receive data on the connection, and address is
347-
the address bound to the socket on the other end of the connection.
348-
349-
:returns OptionalTuple[socket, Tuple[str, int]]: TThe return value is a pair
347+
:return Tuple[socket, Tuple[str, int]]: The return value is a pair
350348
(conn, address) where conn is a new socket object to send and receive data on
351349
the connection, and address is the address bound to the socket on the other
352350
end of the connection.
@@ -395,31 +393,30 @@ def connect(self, address: Tuple[str, int]) -> None:
395393

396394
def send(self, data: Union[bytes, bytearray]) -> int:
397395
"""
398-
Send data to the socket.
399-
400396
Send data to the socket. The socket must be connected to a remote socket.
401397
Applications are responsible for checking that all data has been sent; if
402398
only some of the data was transmitted, the application needs to attempt
403399
delivery of the remaining data.
404400
405401
:param bytearray data: Data to send to the socket.
406402
407-
:returns int: Number of bytes sent.
403+
:return int: Number of bytes sent.
408404
"""
409405
bytes_sent = _the_interface.socket_write(self._socknum, data, self._timeout)
410406
gc.collect()
411407
return bytes_sent
412408

413409
def sendto(self, data: bytearray, *flags_and_or_address: any) -> int:
414410
"""
415-
Connect to a remote socket and send data.
416-
417-
:param bytearray data: Data to send to the socket.
411+
Send data to the socket. The socket should not be connected to a remote socket, since the
412+
destination socket is specified by address. Return the number of bytes sent..
418413
419414
Either:
415+
:param bytearray data: Data to send to the socket.
420416
:param [Tuple[str, int]] address: Remote socket as a (host, port) tuple.
421417
422418
Or:
419+
:param bytearray data: Data to send to the socket.
423420
:param int flags: Not implemented, kept for compatibility.
424421
:param Tuple[int, Tuple(str, int)] address: Remote socket as a (host, port) tuple
425422
"""
@@ -439,12 +436,13 @@ def recv(
439436
flags: int = 0,
440437
) -> bytes:
441438
"""
442-
Receive data from the socket.
439+
Receive data from the socket. The return value is a bytes object representing the data
440+
received. The maximum amount of data to be received at once is specified by bufsize.
443441
444442
:param int bufsize: Maximum number of bytes to receive.
445443
:param int flags: ignored, present for compatibility.
446444
447-
:returns bytes: Data from the socket.
445+
:return bytes: Data from the socket.
448446
"""
449447
stamp = time.monotonic()
450448
while not self._available():
@@ -488,13 +486,15 @@ def _embed_recv(
488486

489487
def recvfrom(self, bufsize: int, flags: int = 0) -> Tuple[bytes, Tuple[str, int]]:
490488
"""
491-
Receive data from the socket.
489+
Receive data from the socket. The return value is a pair (bytes, address) where bytes is
490+
a bytes object representing the data received and address is the address of the socket
491+
sending the data.
492492
493493
:param int bufsize: Maximum number of bytes to receive.
494494
:param int flags: Ignored, present for compatibility.
495495
496496
:return Tuple[bytes, Tuple[str, int]]: a tuple (bytes, address)
497-
where address is a tuple (ip, port)
497+
where address is a tuple (address, port)
498498
"""
499499
return (
500500
self.recv(bufsize),
@@ -527,13 +527,14 @@ def recvfrom_into(
527527
) -> Tuple[int, Tuple[str, int]]:
528528
"""
529529
Receive data from the socket, writing it into buffer instead of creating a new bytestring.
530+
The return value is a pair (nbytes, address) where nbytes is the number of bytes received
531+
and address is the address of the socket sending the data.
530532
531533
:param bytearray buffer: Data buffer.
532534
:param int nbytes: Maximum number of bytes to receive.
533535
:param int flags: Unused, present for compatibility.
534536
535-
:return Tuple[int, Tuple[str, int]]: A tuple (nbytes, address) where nbytes is the
536-
number of bytes received and address is a tuple (IPv4 address, port).
537+
:return Tuple[int, Tuple[str, int]]: The number of bytes and address.
537538
"""
538539
return (
539540
self.recv_into(buffer, nbytes),
@@ -579,7 +580,10 @@ def _disconnect(self) -> None:
579580
_the_interface.socket_disconnect(self._socknum)
580581

581582
def close(self) -> None:
582-
"""Close the socket."""
583+
"""
584+
Mark the socket closed. Once that happens, all future operations on the socket object
585+
will fail. The remote end will receive no more data.
586+
"""
583587
_the_interface.socket_close(self._socknum)
584588

585589
def _available(self) -> int:
@@ -608,12 +612,45 @@ def settimeout(self, value: Optional[float]) -> None:
608612

609613
def gettimeout(self) -> Optional[float]:
610614
"""
611-
Timeout associated with socket operations.
615+
Return the timeout in seconds (float) associated with socket operations, or None if no
616+
timeout is set. This reflects the last call to setblocking() or settimeout().
612617
613618
:return Optional[float]: Timeout in seconds, or None if no timeout is set.
614619
"""
615620
return self._timeout
616621

622+
def setblocking(self, flag: bool) -> None:
623+
"""
624+
Set blocking or non-blocking mode of the socket: if flag is false, the socket is set
625+
to non-blocking, else to blocking mode.
626+
627+
This method is a shorthand for certain settimeout() calls:
628+
629+
sock.setblocking(True) is equivalent to sock.settimeout(None)
630+
sock.setblocking(False) is equivalent to sock.settimeout(0.0)
631+
632+
:param bool flag: The blocking mode of the socket.
633+
634+
:raises TypeError: If flag is not a bool.
635+
636+
"""
637+
if flag is True:
638+
self.settimeout(None)
639+
elif flag is False:
640+
self.settimeout(0.0)
641+
else:
642+
raise TypeError("Flag must be a boolean.")
643+
644+
def getblocking(self) -> bool:
645+
"""
646+
Return True if socket is in blocking mode, False if in non-blocking.
647+
648+
This is equivalent to checking socket.gettimeout() == 0.
649+
650+
:return bool: Blocking mode of the socket.
651+
"""
652+
return self.gettimeout() == 0
653+
617654
@property
618655
def family(self) -> int:
619656
"""Socket family (always 0x03 in this implementation)."""

0 commit comments

Comments
 (0)