Kaydet (Commit) a0781154 authored tarafından Antoine Pitrou's avatar Antoine Pitrou

Issue #10282: Add a `nntp_implementation` attribute to NNTP objects.

üst 09fff7a8
...@@ -54,7 +54,7 @@ The module itself defines the following classes: ...@@ -54,7 +54,7 @@ The module itself defines the following classes:
.. class:: NNTP(host, port=119, user=None, password=None, readermode=None, usenetrc=True, [timeout]) .. class:: NNTP(host, port=119, user=None, password=None, readermode=None, usenetrc=True, [timeout])
Return a new instance of the :class:`NNTP` class, representing a connection Return a new :class:`NNTP` object, representing a connection
to the NNTP server running on host *host*, listening at port *port*. to the NNTP server running on host *host*, listening at port *port*.
An optional *timeout* can be specified for the socket connection. An optional *timeout* can be specified for the socket connection.
If the optional *user* and *password* are provided, or if suitable If the optional *user* and *password* are provided, or if suitable
...@@ -111,19 +111,41 @@ The module itself defines the following classes: ...@@ -111,19 +111,41 @@ The module itself defines the following classes:
NNTP Objects NNTP Objects
------------ ------------
:class:`NNTP` instances have the following methods. The *response* that is When connected, :class:`NNTP` objects support the following methods and
returned as the first item in the return tuple of almost all methods is the attributes.
server's response: a string beginning with a three-digit code. If the server's
response indicates an error, the method raises one of the above exceptions.
.. note:: Attributes
Many of the following methods take an optional keyword-only argument *file*. ^^^^^^^^^^
When the *file* argument is supplied, it must be either a :term:`file object`
opened for binary writing, or the name of an on-disk file to be written to.
The method will then write any data returned by the server (except for the
response line and the terminating dot) to the file; any list of lines,
tuples or objects that the method normally returns will be empty.
.. attribute:: NNTP.nntp_version
An integer representing the version of the NNTP protocol supported by the
server. In practice, this should be ``2`` for servers advertising
:rfc:`3977` compliance and ``1`` for others.
.. versionadded:: 3.2
.. attribute:: NNTP.nntp_implementation
A string describing the software name and version of the NNTP server,
or :const:`None` if not advertised by the server.
.. versionadded:: 3.2
Methods
^^^^^^^
The *response* that is returned as the first item in the return tuple of almost
all methods is the server's response: a string beginning with a three-digit
code. If the server's response indicates an error, the method raises one of
the above exceptions.
Many of the following methods take an optional keyword-only argument *file*.
When the *file* argument is supplied, it must be either a :term:`file object`
opened for binary writing, or the name of an on-disk file to be written to.
The method will then write any data returned by the server (except for the
response line and the terminating dot) to the file; any list of lines,
tuples or objects that the method normally returns will be empty.
.. versionchanged:: 3.2 .. versionchanged:: 3.2
Many of the following methods have been reworked and fixed, which makes Many of the following methods have been reworked and fixed, which makes
......
...@@ -354,6 +354,7 @@ class _NNTPBase: ...@@ -354,6 +354,7 @@ class _NNTPBase:
# Inquire about capabilities (RFC 3977) # Inquire about capabilities (RFC 3977)
self.nntp_version = 1 self.nntp_version = 1
self.nntp_implementation = None
try: try:
resp, caps = self.capabilities() resp, caps = self.capabilities()
except NNTPPermanentError: except NNTPPermanentError:
...@@ -365,6 +366,8 @@ class _NNTPBase: ...@@ -365,6 +366,8 @@ class _NNTPBase:
# The server can advertise several supported versions, # The server can advertise several supported versions,
# choose the highest. # choose the highest.
self.nntp_version = max(map(int, caps['VERSION'])) self.nntp_version = max(map(int, caps['VERSION']))
if 'IMPLEMENTATION' in caps:
self.nntp_implementation = ' '.join(caps['IMPLEMENTATION'])
def getwelcome(self): def getwelcome(self):
"""Get the welcome message from the server """Get the welcome message from the server
......
...@@ -949,6 +949,7 @@ class NNTPv1Tests(NNTPv1v2TestsMixin, MockedNNTPTestsMixin, unittest.TestCase): ...@@ -949,6 +949,7 @@ class NNTPv1Tests(NNTPv1v2TestsMixin, MockedNNTPTestsMixin, unittest.TestCase):
caps = self.server.getcapabilities() caps = self.server.getcapabilities()
self.assertEqual(caps, {}) self.assertEqual(caps, {})
self.assertEqual(self.server.nntp_version, 1) self.assertEqual(self.server.nntp_version, 1)
self.assertEqual(self.server.nntp_implementation, None)
class NNTPv2Tests(NNTPv1v2TestsMixin, MockedNNTPTestsMixin, unittest.TestCase): class NNTPv2Tests(NNTPv1v2TestsMixin, MockedNNTPTestsMixin, unittest.TestCase):
...@@ -971,6 +972,7 @@ class NNTPv2Tests(NNTPv1v2TestsMixin, MockedNNTPTestsMixin, unittest.TestCase): ...@@ -971,6 +972,7 @@ class NNTPv2Tests(NNTPv1v2TestsMixin, MockedNNTPTestsMixin, unittest.TestCase):
'READER': [], 'READER': [],
}) })
self.assertEqual(self.server.nntp_version, 3) self.assertEqual(self.server.nntp_version, 3)
self.assertEqual(self.server.nntp_implementation, 'INN 2.5.1')
class MiscTests(unittest.TestCase): class MiscTests(unittest.TestCase):
......
...@@ -65,6 +65,8 @@ Core and Builtins ...@@ -65,6 +65,8 @@ Core and Builtins
Library Library
------- -------
- Issue #10282: Add a ``nntp_implementation`` attribute to NNTP objects.
- Issue #10283: Add a ``group_pattern`` argument to NNTP.list(). - Issue #10283: Add a ``group_pattern`` argument to NNTP.list().
- Issue #10155: Add IISCGIHandler to wsgiref.handlers to support IIS - Issue #10155: Add IISCGIHandler to wsgiref.handlers to support IIS
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment