bpo-39305: Update nntplib to merge nntplib.NNTP and nntplib._NNTPBase (GH-19817)
This commit is contained in:
parent
372fa3ead5
commit
aa92a7cf21
|
@ -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):
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Update :mod:`nntplib` to merge :class:`nntplib.NNTP` and
|
||||
:class:`nntplib._NNTPBase`. Patch by Dong-hee Na.
|
Loading…
Reference in New Issue