diff options
-rw-r--r-- | Doc/howto/sockets.rst | 4 | ||||
-rw-r--r-- | Lib/http/client.py | 3 | ||||
-rwxr-xr-x | Lib/pydoc.py | 3 | ||||
-rw-r--r-- | Lib/test/test_pydoc.py | 11 | ||||
-rw-r--r-- | Misc/NEWS | 6 |
5 files changed, 24 insertions, 3 deletions
diff --git a/Doc/howto/sockets.rst b/Doc/howto/sockets.rst index d240008d6d..ca6528b06f 100644 --- a/Doc/howto/sockets.rst +++ b/Doc/howto/sockets.rst @@ -153,7 +153,7 @@ I'm not going to talk about it here, except to warn you that you need to use there, you may wait forever for the reply, because the request may still be in your output buffer. -Now we come the major stumbling block of sockets - ``send`` and ``recv`` operate +Now we come to the major stumbling block of sockets - ``send`` and ``recv`` operate on the network buffers. They do not necessarily handle all the bytes you hand them (or expect from them), because their major focus is handling the network buffers. In general, they return when the associated network buffers have been @@ -164,7 +164,7 @@ been completely dealt with. When a ``recv`` returns 0 bytes, it means the other side has closed (or is in the process of closing) the connection. You will not receive any more data on this connection. Ever. You may be able to send data successfully; I'll talk -about that some on the next page. +more about this later. A protocol like HTTP uses a socket for only one transfer. The client sends a request, then reads a reply. That's it. The socket is discarded. This means that diff --git a/Lib/http/client.py b/Lib/http/client.py index 0002072ff2..eb857c03ca 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -786,6 +786,9 @@ class HTTPConnection: line = response.fp.readline(_MAXLINE + 1) if len(line) > _MAXLINE: raise LineTooLong("header line") + if not line: + # for sites which EOF without sending a trailer + break if line == b'\r\n': break diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 8b94993928..b319d11b5e 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -1521,7 +1521,8 @@ def resolve(thing, forceload=0): raise ImportError('no Python documentation found for %r' % thing) return object, thing else: - return thing, getattr(thing, '__name__', None) + name = getattr(thing, '__name__', None) + return thing, name if isinstance(name, str) else None def render_doc(thing, title='Python Library Documentation: %s', forceload=0, renderer=None): diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index a9f75b9fdd..8e2001ba5f 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -286,6 +286,17 @@ class PydocDocTest(unittest.TestCase): result, doc_loc = get_pydoc_text(xml.etree) self.assertEqual(doc_loc, "", "MODULE DOCS incorrectly includes a link") + def test_non_str_name(self): + # issue14638 + # Treat illegal (non-str) name like no name + class A: + __name__ = 42 + class B: + pass + adoc = pydoc.render_doc(A()) + bdoc = pydoc.render_doc(B()) + self.assertEqual(adoc.replace("A", "B"), bdoc) + def test_not_here(self): missing_module = "test.i_am_not_here" result = str(run_pydoc(missing_module), 'ascii') @@ -65,6 +65,12 @@ Core and Builtins Library ------- +- Issue #14638: pydoc now treats non-string __name__ values as if they + were missing, instead of raising an error. + +- Issue #13684: Fix httplib tunnel issue of infinite loops for certain sites + which send EOF without trailing \r\n. + - Issue #14605: Add importlib.abc.FileLoader, importlib.machinery.(FileFinder, SourceFileLoader, _SourcelessFileLoader, ExtensionFileLoader). |