From f23c47fea701d1adb778092f9f53532d057acffd Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Sat, 28 Jan 2017 15:39:18 +0300
Subject: [PATCH] docs/usocket: Clarify description of various methods.

---
 docs/library/usocket.rst | 55 ++++++++++++++++++++++++++++++----------
 1 file changed, 41 insertions(+), 14 deletions(-)

diff --git a/docs/library/usocket.rst b/docs/library/usocket.rst
index 16ba66c2b..a75049727 100644
--- a/docs/library/usocket.rst
+++ b/docs/library/usocket.rst
@@ -7,8 +7,8 @@
 
 This module provides access to the BSD socket interface.
 
-See corresponding `CPython module <https://docs.python.org/3/library/socket.html>`_ for
-comparison.
+See the corresponding `CPython module <https://docs.python.org/3/library/socket.html>`_
+for comparison.
 
 .. admonition:: Difference to CPython
    :class: attention
@@ -16,10 +16,19 @@ comparison.
    CPython used to have a ``socket.error`` exception which is now deprecated,
    and is an alias of OSError. In MicroPython, use OSError directly.
 
+.. admonition:: Difference to CPython
+   :class: attention
+
+   For efficiency and consistency, socket objects in MicroPython implement a stream
+   (file-like) interface directly. In CPython, you need to convert a socket to
+   a file-like object using ``makefile()`` method. This method is still supported
+   by MicroPython (but is a no-op), so where compatibility with CPython matters,
+   be sure to use it.
+
 Socket address format(s)
 ------------------------
 
-Functions below which expect a network address, accept it in the format of
+The functions below which expect a network address, accept it in the format of
 `(ipv4_address, port)`, where `ipv4_address` is a string with dot-notation numeric
 IPv4 address, e.g. ``"8.8.8.8"``, and port is integer port number in the range
 1-65535. Note the domain names are not accepted as `ipv4_address`, they should be
@@ -141,10 +150,19 @@ Methods
     .. method:: socket.send(bytes)
 
        Send data to the socket. The socket must be connected to a remote socket.
+       Returns number of bytes sent, which may be smaller than the length of data
+       ("short write").
 
     .. method:: socket.sendall(bytes)
 
-       Send data to the socket. The socket must be connected to a remote socket.
+       Send all data to the socket. The socket must be connected to a remote socket.
+       Unlike ``send()``, this method will try to send all of data, by sending data
+       chunk by chunk consecutively.
+
+       The behavior of this method on non-blocking sockets is undefined. Due to this,
+       on MicroPython, it's recommended to use ``write()`` method instead, which
+       has the same "no short writes" policy for blocking sockets, and will return
+       number of bytes sent on non-blocking sockets.
 
     .. method:: socket.recv(bufsize)
 
@@ -189,19 +207,22 @@ Methods
        Set blocking or non-blocking mode of the socket: if flag is false, the socket is set to non-blocking,
        else to blocking mode.
 
-       This method is a shorthand for certain ``settimeout()`` calls::
+       This method is a shorthand for certain ``settimeout()`` calls:
 
-          sock.setblocking(True) is equivalent to sock.settimeout(None)
-          sock.setblocking(False) is equivalent to sock.settimeout(0.0)
+       * ``sock.setblocking(True)`` is equivalent to ``sock.settimeout(None)``
+       * ``sock.setblocking(False)`` is equivalent to ``sock.settimeout(0)``
 
-    .. method:: socket.makefile(mode='rb')
+    .. method:: socket.makefile(mode='rb', buffering=0)
 
        Return a file object associated with the socket. The exact returned type depends on the arguments
-       given to makefile(). The support is limited to binary modes only ('rb' and 'wb').
+       given to makefile(). The support is limited to binary modes only ('rb', 'wb', and 'rwb').
        CPython's arguments: ``encoding``, ``errors`` and ``newline`` are not supported.
 
-       The socket must be in blocking mode; it can have a timeout, but the file object’s internal buffer
-       may end up in a inconsistent state if a timeout occurs.
+       .. admonition:: Difference to CPython
+          :class: attention
+
+          As MicroPython doesn't support buffered streams, values of ``buffering``
+          parameter is ignored and treated as if it was 0 (unbuffered).
 
        .. admonition:: Difference to CPython
           :class: attention
@@ -213,12 +234,15 @@ Methods
 
        Read up to size bytes from the socket. Return a bytes object. If ``size`` is not given, it
        reads all data available from the socket until ``EOF``; as such the method will not return until
-       the socket is closed.
+       the socket is closed. This function tries to read as much data as
+       requested (no "short reads"). This may be not possible with
+       non-blocking socket though, and then less data will be returned.
 
     .. method:: socket.readinto(buf[, nbytes])
 
        Read bytes into the ``buf``.  If ``nbytes`` is specified then read at most
-       that many bytes.  Otherwise, read at most ``len(buf)`` bytes.
+       that many bytes.  Otherwise, read at most ``len(buf)`` bytes. Just as
+       ``read()``, this method follows "no short reads" policy.
 
        Return value: number of bytes read and stored into ``buf``.
 
@@ -230,6 +254,9 @@ Methods
 
     .. method:: socket.write(buf)
 
-       Write the buffer of bytes to the socket.
+       Write the buffer of bytes to the socket. This function will try to
+       write all data to a socket (no "short writes"). This may be not possible
+       with a non-blocking socket though, and returned value will be less than
+       the length of ``buf``.
 
        Return value: number of bytes written.
-- 
GitLab