From aa92a7cf210c98ad94229f282221136d846942db Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Sat, 16 May 2020 19:31:54 +0900 Subject: [PATCH] bpo-39305: Update nntplib to merge nntplib.NNTP and nntplib._NNTPBase (GH-19817) --- Lib/nntplib.py | 98 ++++++++----------- Lib/test/test_nntplib.py | 16 ++- .../2020-05-01-00-22-58.bpo-39305.Cuwu_H.rst | 2 + 3 files changed, 56 insertions(+), 60 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2020-05-01-00-22-58.bpo-39305.Cuwu_H.rst diff --git a/Lib/nntplib.py b/Lib/nntplib.py index aa9b46a8aaa..f6e746e7c95 100644 --- a/Lib/nntplib.py +++ b/Lib/nntplib.py @@ -293,7 +293,7 @@ if _have_ssl: # The classes themselves -class _NNTPBase: +class NNTP: # UTF-8 is the character set for all NNTP commands and responses: they # are automatically encoded (when sending) and decoded (and receiving) # by this class. @@ -309,13 +309,18 @@ class _NNTPBase: encoding = 'utf-8' errors = 'surrogateescape' - def __init__(self, file, host, - readermode=None, timeout=_GLOBAL_DEFAULT_TIMEOUT): + def __init__(self, host, port=NNTP_PORT, user=None, password=None, + readermode=None, usenetrc=False, + timeout=_GLOBAL_DEFAULT_TIMEOUT): """Initialize an instance. Arguments: - - file: file-like object (open for read/write in binary mode) - - host: hostname of the server + - host: hostname to connect to + - port: port to connect to (default the standard NNTP port) + - user: username to authenticate with + - password: password to use with username - readermode: if true, send 'mode reader' command after connecting. + - usenetrc: allow loading username and password from ~/.netrc file + if not specified explicitly - timeout: timeout (in seconds) used for socket connections readermode is sometimes necessary if you are connecting to an @@ -325,7 +330,24 @@ class _NNTPBase: readermode. """ self.host = host - self.file = file + self.port = port + self.sock = self._create_socket(timeout) + self.file = None + try: + self.file = self.sock.makefile("rwb") + self._base_init(readermode) + if user or usenetrc: + self.login(user, password, usenetrc) + except: + if self.file: + self.file.close() + self.sock.close() + raise + + def _base_init(self, readermode): + """Partial initialization for the NNTP protocol. + This instance method is extracted for supporting the test code. + """ self.debugging = 0 self.welcome = self._getresp() @@ -370,6 +392,12 @@ class _NNTPBase: if is_connected(): self._close() + def _create_socket(self, timeout): + if timeout is not None and not timeout: + raise ValueError('Non-blocking socket (timeout=0) is not supported') + sys.audit("nntplib.connect", self, self.host, self.port) + return socket.create_connection((self.host, self.port), timeout) + def getwelcome(self): """Get the welcome message from the server (this is read and squirreled away by __init__()). @@ -888,8 +916,12 @@ class _NNTPBase: return self._post('IHAVE {0}'.format(message_id), data) def _close(self): - self.file.close() - del self.file + try: + if self.file: + self.file.close() + del self.file + finally: + self.sock.close() def quit(self): """Process a QUIT command and close the socket. Returns: @@ -979,56 +1011,6 @@ class _NNTPBase: raise NNTPError("TLS failed to start.") -class NNTP(_NNTPBase): - - def __init__(self, host, port=NNTP_PORT, user=None, password=None, - readermode=None, usenetrc=False, - timeout=_GLOBAL_DEFAULT_TIMEOUT): - """Initialize an instance. Arguments: - - host: hostname to connect to - - port: port to connect to (default the standard NNTP port) - - user: username to authenticate with - - password: password to use with username - - readermode: if true, send 'mode reader' command after - connecting. - - usenetrc: allow loading username and password from ~/.netrc file - if not specified explicitly - - timeout: timeout (in seconds) used for socket connections - - readermode is sometimes necessary if you are connecting to an - NNTP server on the local machine and intend to call - reader-specific commands, such as `group'. If you get - unexpected NNTPPermanentErrors, you might need to set - readermode. - """ - self.host = host - self.port = port - self.sock = self._create_socket(timeout) - file = None - try: - file = self.sock.makefile("rwb") - super().__init__(file, host, readermode, timeout) - if user or usenetrc: - self.login(user, password, usenetrc) - except: - if file: - file.close() - self.sock.close() - raise - - def _create_socket(self, timeout): - if timeout is not None and not timeout: - raise ValueError('Non-blocking socket (timeout=0) is not supported') - sys.audit("nntplib.connect", self, self.host, self.port) - return socket.create_connection((self.host, self.port), timeout) - - def _close(self): - try: - super()._close() - finally: - self.sock.close() - - if _have_ssl: class NNTP_SSL(NNTP): diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index 8d296818e64..1df64fa7c6b 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -5,6 +5,7 @@ import textwrap import unittest import functools import contextlib +import nntplib import os.path import re import threading @@ -12,7 +13,6 @@ import threading from test import support from test.support import socket_helper from nntplib import NNTP, GroupInfo -import nntplib from unittest.mock import patch try: import ssl @@ -411,6 +411,18 @@ def make_mock_file(handler): return (sio, file) +class NNTPServer(nntplib.NNTP): + + def __init__(self, f, host, readermode=None): + self.file = f + self.host = host + self._base_init(readermode) + + def _close(self): + self.file.close() + del self.file + + class MockedNNTPTestsMixin: # Override in derived classes handler_class = None @@ -426,7 +438,7 @@ class MockedNNTPTestsMixin: def make_server(self, *args, **kwargs): self.handler = self.handler_class() self.sio, file = make_mock_file(self.handler) - self.server = nntplib._NNTPBase(file, 'test.server', *args, **kwargs) + self.server = NNTPServer(file, 'test.server', *args, **kwargs) return self.server diff --git a/Misc/NEWS.d/next/Library/2020-05-01-00-22-58.bpo-39305.Cuwu_H.rst b/Misc/NEWS.d/next/Library/2020-05-01-00-22-58.bpo-39305.Cuwu_H.rst new file mode 100644 index 00000000000..7c6fdb3ede1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-05-01-00-22-58.bpo-39305.Cuwu_H.rst @@ -0,0 +1,2 @@ +Update :mod:`nntplib` to merge :class:`nntplib.NNTP` and +:class:`nntplib._NNTPBase`. Patch by Dong-hee Na.