ellipsis_match():  Changed treatment of start- and end-of-string exact
matches to be symmetric.  This makes the algorithm easier to understand.
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 6c5679d..c7a183b 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -364,47 +364,57 @@
 
 # Worst-case linear-time ellipsis matching.
 def ellipsis_match(want, got):
+    """
+    Essentially the only subtle case:
+    >>> ellipsis_match('aa...aa', 'aaa')
+    False
+    """
     if ELLIPSIS_MARKER not in want:
         return want == got
     # Remove \n from ...\n, else the newline will be required,
     # and (for example) ... on a line by itself can't match
     # nothing gracefully.
     want = want.replace(ELLIPSIS_MARKER + '\n', ELLIPSIS_MARKER)
+
     # Find "the real" strings.
     ws = want.split(ELLIPSIS_MARKER)
     assert len(ws) >= 2
-    # Match.  In general, we only need to find the leftmost non-overlapping
-    # match for each piece.  "Real strings" at the start or end of `want`
-    # are special cases.
-    w = ws[0]
-    if w:
-        # An ellipsis didn't start `want`.  We need to match exactly
-        # at the start.
-        if not got.startswith(w):
-            return False
-        pos = len(w)
-        del ws[0]
-    else:
-        pos = 0
 
+    # Deal with exact matches possibly needed at one or both ends.
+    startpos, endpos = 0, len(got)
+    w = ws[0]
+    if w:   # starts with exact match
+        if got.startswith(w):
+            startpos = len(w)
+            del ws[0]
+        else:
+            return False
+    w = ws[-1]
+    if w:   # ends with exact match
+        if got.endswith(w):
+            endpos -= len(w)
+            del ws[-1]
+        else:
+            return False
+
+    if startpos > endpos:
+        # Exact end matches required more characters than we have, as in
+        # ellipsis_match('aa...aa', 'aaa')
+        return False
+
+    # For the rest, we only need to find the leftmost non-overlapping
+    # match for each piece.  If there's no overall match that way alone,
+    # there's no overall match period.
     for w in ws:
         # w may be '' at times, if there are consecutive ellipses, or
         # due to an ellipsis at the start or end of `want`.  That's OK.
-        # Search for an empty string succeeds, and doesn't change pos.
-        pos = got.find(w, pos)
-        if pos < 0:
+        # Search for an empty string succeeds, and doesn't change startpos.
+        startpos = got.find(w, startpos, endpos)
+        if startpos < 0:
             return False
-        pos += len(w)
+        startpos += len(w)
 
-    # If `want` ended with an ellipsis, the tail matches anything.
-    if ws[-1] == '':
-        return True
-    # Else `want` ended with a real string.  If the last real match
-    # exhausted `got`, we win.
-    if pos == len(got):
-        return True
-    # Else maybe we matched the last real string too early.
-    return got.endswith(ws[-1])
+    return True
 
 ######################################################################
 ## 2. Example & DocTest