Issue #25523: Correct "a" article to "an" article

This changes the main documentation, doc strings, source code comments, and a
couple error messages in the test suite. In some cases the word was removed
or edited some other way to fix the grammar.
diff --git a/Lib/_pyio.py b/Lib/_pyio.py
index c0b5fd1..f1e3a79 100644
--- a/Lib/_pyio.py
+++ b/Lib/_pyio.py
@@ -2101,7 +2101,7 @@
 
     def __repr__(self):
         # TextIOWrapper tells the encoding in its repr. In StringIO,
-        # that's a implementation detail.
+        # that's an implementation detail.
         return object.__repr__(self)
 
     @property
diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py
index fb786ed..64d1020 100644
--- a/Lib/asyncio/streams.py
+++ b/Lib/asyncio/streams.py
@@ -255,7 +255,7 @@
     def __init__(self, transport, protocol, reader, loop):
         self._transport = transport
         self._protocol = protocol
-        # drain() expects that the reader has a exception() method
+        # drain() expects that the reader has an exception() method
         assert reader is None or isinstance(reader, StreamReader)
         self._reader = reader
         self._loop = loop
diff --git a/Lib/calendar.py b/Lib/calendar.py
index 02050ea..5244b8d 100644
--- a/Lib/calendar.py
+++ b/Lib/calendar.py
@@ -142,7 +142,7 @@
 
     def iterweekdays(self):
         """
-        Return a iterator for one week of weekday numbers starting with the
+        Return an iterator for one week of weekday numbers starting with the
         configured first one.
         """
         for i in range(self.firstweekday, self.firstweekday + 7):
diff --git a/Lib/chunk.py b/Lib/chunk.py
index 84b77cc..d94dd39 100644
--- a/Lib/chunk.py
+++ b/Lib/chunk.py
@@ -21,7 +21,7 @@
 usage of the Chunk class defined here is to instantiate an instance at
 the start of each chunk and read from the instance until it reaches
 the end, after which a new instance can be instantiated.  At the end
-of the file, creating a new instance will fail with a EOFError
+of the file, creating a new instance will fail with an EOFError
 exception.
 
 Usage:
diff --git a/Lib/codecs.py b/Lib/codecs.py
index 4a4d043..6cdf3f4 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -256,7 +256,7 @@
     """
     def __init__(self, errors='strict'):
         """
-        Create a IncrementalDecoder instance.
+        Create an IncrementalDecoder instance.
 
         The IncrementalDecoder may use different error handling schemes by
         providing the errors keyword argument. See the module docstring
@@ -1007,7 +1007,7 @@
     """
     Encoding iterator.
 
-    Encodes the input strings from the iterator using a IncrementalEncoder.
+    Encodes the input strings from the iterator using an IncrementalEncoder.
 
     errors and kwargs are passed through to the IncrementalEncoder
     constructor.
@@ -1025,7 +1025,7 @@
     """
     Decoding iterator.
 
-    Decodes the input strings from the iterator using a IncrementalDecoder.
+    Decodes the input strings from the iterator using an IncrementalDecoder.
 
     errors and kwargs are passed through to the IncrementalDecoder
     constructor.
diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py
index acd05d0..b259833 100644
--- a/Lib/concurrent/futures/_base.py
+++ b/Lib/concurrent/futures/_base.py
@@ -518,7 +518,7 @@
         raise NotImplementedError()
 
     def map(self, fn, *iterables, timeout=None):
-        """Returns a iterator equivalent to map(fn, iter).
+        """Returns an iterator equivalent to map(fn, iter).
 
         Args:
             fn: A callable that will take as many arguments as there are
diff --git a/Lib/difflib.py b/Lib/difflib.py
index 7eb42a9..56d4852 100644
--- a/Lib/difflib.py
+++ b/Lib/difflib.py
@@ -1469,7 +1469,7 @@
                 yield _make_line(lines,'-',0), None, True
                 continue
             elif s.startswith(('--?+', '--+', '- ')):
-                # in delete block and see a intraline change or unchanged line
+                # in delete block and see an intraline change or unchanged line
                 # coming: yield the delete line and then blanks
                 from_line,to_line = _make_line(lines,'-',0), None
                 num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0
diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py
index d28b1b3..c879646 100644
--- a/Lib/distutils/cygwinccompiler.py
+++ b/Lib/distutils/cygwinccompiler.py
@@ -10,9 +10,9 @@
 #
 # * if you use a msvc compiled python version (1.5.2)
 #   1. you have to insert a __GNUC__ section in its config.h
-#   2. you have to generate a import library for its dll
+#   2. you have to generate an import library for its dll
 #      - create a def-file for python??.dll
-#      - create a import library using
+#      - create an import library using
 #             dlltool --dllname python15.dll --def python15.def \
 #                       --output-lib libpython15.a
 #
@@ -318,7 +318,7 @@
         self.dll_libraries = get_msvcr()
 
 # Because these compilers aren't configured in Python's pyconfig.h file by
-# default, we should at least warn the user if he is using a unmodified
+# default, we should at least warn the user if he is using an unmodified
 # version.
 
 CONFIG_H_OK = "ok"
diff --git a/Lib/ftplib.py b/Lib/ftplib.py
index 4d92b86..1d3bd9e 100644
--- a/Lib/ftplib.py
+++ b/Lib/ftplib.py
@@ -287,7 +287,7 @@
         return self.voidcmd(cmd)
 
     def sendeprt(self, host, port):
-        '''Send a EPRT command with the current host and the given port number.'''
+        '''Send an EPRT command with the current host and the given port number.'''
         af = 0
         if self.af == socket.AF_INET:
             af = 1
@@ -852,7 +852,7 @@
 
 
 def parse229(resp, peer):
-    '''Parse the '229' response for a EPSV request.
+    '''Parse the '229' response for an EPSV request.
     Raises error_proto if it does not contain '(|||port|)'
     Return ('host.addr.as.numbers', port#) tuple.'''
 
diff --git a/Lib/getopt.py b/Lib/getopt.py
index 3d6ecbd..9d4cab1 100644
--- a/Lib/getopt.py
+++ b/Lib/getopt.py
@@ -28,7 +28,7 @@
 # - RETURN_IN_ORDER option
 # - GNU extension with '-' as first character of option string
 # - optional arguments, specified by double colons
-# - a option string with a W followed by semicolon should
+# - an option string with a W followed by semicolon should
 #   treat "-W foo" as "--foo"
 
 __all__ = ["GetoptError","error","getopt","gnu_getopt"]
diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py
index 8d6549c..34ef89d 100644
--- a/Lib/idlelib/EditorWindow.py
+++ b/Lib/idlelib/EditorWindow.py
@@ -1379,7 +1379,7 @@
             text.see("insert")
             text.undo_block_stop()
 
-    # Our editwin provides a is_char_in_string function that works
+    # Our editwin provides an is_char_in_string function that works
     # with a Tk text index, but PyParse only knows about offsets into
     # a string. This builds a function for PyParse that accepts an
     # offset.
diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py
index fc8b80f..2665a1c 100644
--- a/Lib/idlelib/ReplaceDialog.py
+++ b/Lib/idlelib/ReplaceDialog.py
@@ -59,7 +59,7 @@
     def default_command(self, event=None):
         if self.do_find(self.ok):
             if self.do_replace():   # Only find next match if replace succeeded.
-                                    # A bad re can cause a it to fail.
+                                    # A bad re can cause it to fail.
                 self.do_find(0)
 
     def _replace_expand(self, m, repl):
diff --git a/Lib/io.py b/Lib/io.py
index 8d68f1e..e03db97 100644
--- a/Lib/io.py
+++ b/Lib/io.py
@@ -19,7 +19,7 @@
 Another IOBase subclass, TextIOBase, deals with the encoding and decoding
 of streams into text. TextIOWrapper, which extends it, is a buffered text
 interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO
-is a in-memory stream for text.
+is an in-memory stream for text.
 
 Argument names are not part of the specification, and only the arguments
 of open() are intended to be used as keyword arguments.
diff --git a/Lib/lib2to3/fixes/fix_input.py b/Lib/lib2to3/fixes/fix_input.py
index 126da1b..9cf9a48 100644
--- a/Lib/lib2to3/fixes/fix_input.py
+++ b/Lib/lib2to3/fixes/fix_input.py
@@ -17,7 +17,7 @@
               """
 
     def transform(self, node, results):
-        # If we're already wrapped in a eval() call, we're done.
+        # If we're already wrapped in an eval() call, we're done.
         if context.match(node.parent.parent):
             return
 
diff --git a/Lib/nntplib.py b/Lib/nntplib.py
index 3413610..a75faad 100644
--- a/Lib/nntplib.py
+++ b/Lib/nntplib.py
@@ -201,7 +201,7 @@
     return fmt
 
 def _parse_overview(lines, fmt, data_process_func=None):
-    """Parse the response to a OVER or XOVER command according to the
+    """Parse the response to an OVER or XOVER command according to the
     overview format `fmt`."""
     n_defaults = len(_DEFAULT_OVERVIEW_FMT)
     overview = []
diff --git a/Lib/pickle.py b/Lib/pickle.py
index c7298af..d05316e 100644
--- a/Lib/pickle.py
+++ b/Lib/pickle.py
@@ -362,7 +362,7 @@
 
         The *file* argument must have a write() method that accepts a
         single bytes argument. It can thus be a file object opened for
-        binary writing, a io.BytesIO instance, or any other custom
+        binary writing, an io.BytesIO instance, or any other custom
         object that meets this interface.
 
         If *fix_imports* is True and *protocol* is less than 3, pickle
@@ -983,7 +983,7 @@
         The argument *file* must have two methods, a read() method that
         takes an integer argument, and a readline() method that requires
         no arguments.  Both methods should return bytes.  Thus *file*
-        can be a binary file object opened for reading, a io.BytesIO
+        can be a binary file object opened for reading, an io.BytesIO
         object, or any other custom object that meets this interface.
 
         The file-like object must have two methods, a read() method
diff --git a/Lib/test/decimaltestdata/fma.decTest b/Lib/test/decimaltestdata/fma.decTest
index b0a81ca..0b188fa 100644
--- a/Lib/test/decimaltestdata/fma.decTest
+++ b/Lib/test/decimaltestdata/fma.decTest
@@ -148,7 +148,7 @@
 fmax2019 fma -9.999999  9.999999  0E+999999  -> -100.000 Inexact Rounded

 fmax2020 fma -9.999999 -9.999999  0E+999999  ->  100.000 Inexact Rounded

 

--- 1999.12.21: next one is a edge case if intermediate longs are used

+-- 1999.12.21: next one is an edge case if intermediate longs are used

 precision: 15

 fmax2059 fma 999999999999 9765625  0E+999999  -> 9.76562499999023E+18 Inexact Rounded

 precision: 30

diff --git a/Lib/test/decimaltestdata/multiply.decTest b/Lib/test/decimaltestdata/multiply.decTest
index 6a23d5a..e8bd77a 100644
--- a/Lib/test/decimaltestdata/multiply.decTest
+++ b/Lib/test/decimaltestdata/multiply.decTest
@@ -49,7 +49,7 @@
 mulx019 multiply -9.999999999  9.999999999 -> -100.000 Inexact Rounded
 mulx020 multiply -9.999999999 -9.999999999 ->  100.000 Inexact Rounded
 
--- 1999.12.21: next one is a edge case if intermediate longs are used
+-- 1999.12.21: next one is an edge case if intermediate longs are used
 precision: 15
 mulx059 multiply 999999999999 9765625 -> 9.76562499999023E+18 Inexact Rounded
 precision: 30
diff --git a/Lib/test/pystone.py b/Lib/test/pystone.py
index a41f1e5..59dd99b 100755
--- a/Lib/test/pystone.py
+++ b/Lib/test/pystone.py
@@ -35,7 +35,7 @@
                 Under Python 3 version 1.1 would use the normal division
                 operator, resulting in some of the operations mistakenly
                 yielding floats. Version 1.2 instead uses floor division
-                making the benchmark a integer benchmark again.
+                making the benchmark an integer benchmark again.
 
 """
 
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 01ca2f8..cdf86e7 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -309,7 +309,7 @@
         # The exponential backoff of the timeout amounts to a total
         # of ~1 second after which the deletion is probably an error
         # anyway.
-        # Testing on a i7@4.3GHz shows that usually only 1 iteration is
+        # Testing on an i7@4.3GHz shows that usually only 1 iteration is
         # required when contention occurs.
         timeout = 0.001
         while timeout < 1.0:
diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py
index 0c31454..dd8981f 100644
--- a/Lib/test/test_cmd.py
+++ b/Lib/test/test_cmd.py
@@ -110,7 +110,7 @@
     5  12  19
     6  13
 
-    This is a interactive test, put some commands in the cmdqueue attribute
+    This is an interactive test, put some commands in the cmdqueue attribute
     and let it execute
     This test includes the preloop(), postloop(), default(), emptyline(),
     parseline(), do_help() functions
diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py
index a1079a1..8fe21fb 100644
--- a/Lib/test/test_codecs.py
+++ b/Lib/test/test_codecs.py
@@ -97,7 +97,7 @@
         self.assertEqual(r.read(), "")
         self.assertEqual(r.bytebuffer, b"")
 
-        # do the check again, this time using a incremental decoder
+        # do the check again, this time using an incremental decoder
         d = codecs.getincrementaldecoder(self.encoding)()
         result = ""
         for (c, partialresult) in zip(input.encode(self.encoding), partialresults):
diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py
index 61e23fc..e4541fb 100644
--- a/Lib/test/test_email/test_email.py
+++ b/Lib/test/test_email/test_email.py
@@ -3037,7 +3037,7 @@
         # issue 1690608.  email.utils.formataddr() should be rfc2047 aware.
         name = "H\u00e4ns W\u00fcrst"
         addr = 'person@dom.ain'
-        # A object without a header_encode method:
+        # An object without a header_encode method:
         bad_charset = object()
         self.assertRaises(AttributeError, utils.formataddr, (name, addr),
             bad_charset)
diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py
index bfb5699..95e3f04 100644
--- a/Lib/test/test_ipaddress.py
+++ b/Lib/test/test_ipaddress.py
@@ -1160,7 +1160,7 @@
         # test a /24 is summarized properly
         self.assertEqual(list(summarize(ip1, ip2))[0],
                          ipaddress.ip_network('1.1.1.0/24'))
-        # test an  IPv4 range that isn't on a network byte boundary
+        # test an IPv4 range that isn't on a network byte boundary
         ip2 = ipaddress.ip_address('1.1.1.8')
         self.assertEqual(list(summarize(ip1, ip2)),
                          [ipaddress.ip_network('1.1.1.0/29'),
@@ -1173,7 +1173,7 @@
 
         ip1 = ipaddress.ip_address('1::')
         ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
-        # test a IPv6 is sumamrized properly
+        # test an IPv6 is summarized properly
         self.assertEqual(list(summarize(ip1, ip2))[0],
                          ipaddress.ip_network('1::/16'))
         # test an IPv6 range that isn't on a network byte boundary
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 54dd9da2..1f7e49c 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -1328,7 +1328,7 @@
         except OSError as e:
             self.assertEqual(e.errno, errno.EBADF)
         else:
-            self.fail("%r didn't raise a OSError with a bad file descriptor"
+            self.fail("%r didn't raise an OSError with a bad file descriptor"
                       % f)
 
     @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()')
diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
index 16236ef..e100039 100644
--- a/Lib/test/test_urllib.py
+++ b/Lib/test/test_urllib.py
@@ -523,7 +523,7 @@
         result = urllib.request.urlretrieve("file:%s" % support.TESTFN)
         self.assertEqual(result[0], support.TESTFN)
         self.assertIsInstance(result[1], email.message.Message,
-                              "did not get a email.message.Message instance "
+                              "did not get an email.message.Message instance "
                               "as second returned value")
 
     def test_copy(self):
diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py
index 212cf34..4313c1d 100644
--- a/Lib/test/test_weakref.py
+++ b/Lib/test/test_weakref.py
@@ -934,7 +934,7 @@
 class WeakMethodTestCase(unittest.TestCase):
 
     def _subclass(self):
-        """Return a Object subclass overriding `some_method`."""
+        """Return an Object subclass overriding `some_method`."""
         class C(Object):
             def some_method(self):
                 return 6
diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py
index b9c57ad..244fb3d 100644
--- a/Lib/tkinter/ttk.py
+++ b/Lib/tkinter/ttk.py
@@ -289,7 +289,7 @@
     """Format options then call Tk command with args and options and return
     the appropriate result.
 
-    If no option is specified, a dict is returned. If a option is
+    If no option is specified, a dict is returned. If an option is
     specified with the None value, the value for that option is returned.
     Otherwise, the function just sets the passed options and the caller
     shouldn't be expecting a return value anyway."""
diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py
index 4521325..9de5111 100644
--- a/Lib/xmlrpc/client.py
+++ b/Lib/xmlrpc/client.py
@@ -831,7 +831,7 @@
             raise ValueError("unexpected type in multicall result")
 
 class MultiCall:
-    """server -> a object used to boxcar method calls
+    """server -> an object used to boxcar method calls
 
     server should be a ServerProxy object.
 
@@ -1184,7 +1184,7 @@
     ##
     # Create parser.
     #
-    # @return A 2-tuple containing a parser and a unmarshaller.
+    # @return A 2-tuple containing a parser and an unmarshaller.
 
     def getparser(self):
         # get parser and unmarshaller