[Python-checkins] bpo-34962: make doctest in Doc/ now passes, and is enforced in CI (GH-9806)

Julien Palard webhook-mailer at python.org
Fri Oct 12 03:51:15 EDT 2018


https://github.com/python/cpython/commit/859c068e52a31e13e2b9bb6a3f861fa8c290cb0e
commit: 859c068e52a31e13e2b9bb6a3f861fa8c290cb0e
branch: master
author: Stéphane Wirtel <stephane at wirtel.be>
committer: Julien Palard <julien at palard.fr>
date: 2018-10-12T09:51:05+02:00
summary:

bpo-34962: make doctest in Doc/ now passes, and is enforced in CI (GH-9806)

files:
A Misc/NEWS.d/next/Tests/2018-10-11-22-34-27.bpo-34962.0PLBi8.rst
M .travis.yml
M Doc/conf.py
M Doc/distutils/examples.rst
M Doc/library/multiprocessing.rst
M Doc/library/re.rst
M Doc/library/turtle.rst
M Doc/library/unittest.mock-examples.rst
M Doc/library/unittest.mock.rst

diff --git a/.travis.yml b/.travis.yml
index d1a6da70e508..19be17e2f25e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -53,8 +53,8 @@ matrix:
         - cd Doc
         # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures.
         # (Updating the version is fine as long as no warnings are raised by doing so.)
-        # The theme used by the docs is stored seperately, so we need to install that as well.
-        - python -m pip install sphinx~=1.6.1 blurb python-docs-theme
+        # The theme used by the docs is stored separately, so we need to install that as well.
+        - python -m pip install sphinx blurb python-docs-theme
       script:
         - make check suspicious html SPHINXOPTS="-q -W -j4"
     - os: osx
@@ -155,8 +155,14 @@ script:
   # Check that all symbols exported by libpython start with "Py" or "_Py"
   - make smelly
   # `-r -w` implicitly provided through `make buildbottest`.
-  - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then XVFB_RUN=xvfb-run; fi; $XVFB_RUN make buildbottest TESTOPTS="-j4 -uall,-cpu"
-
+  - |
+    if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
+      XVFB_RUN=xvfb-run;
+    fi
+    $XVFB_RUN make buildbottest TESTOPTS="-j4 -uall,-cpu"
+    if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
+      $XVFB_RUN make PYTHON=../python SPHINXOPTS="-q -W -j4" -C Doc/ venv doctest
+    fi
 notifications:
   email: false
   webhooks:
diff --git a/Doc/conf.py b/Doc/conf.py
index 7f720ce3832d..6060ac176c95 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -16,6 +16,13 @@
 extensions = ['sphinx.ext.coverage', 'sphinx.ext.doctest',
               'pyspecific', 'c_annotations', 'escape4chm']
 
+
+doctest_global_setup = '''
+try:
+    import _tkinter
+except ImportError:
+    _tkinter = None
+'''
 # General substitutions.
 project = 'Python'
 copyright = '2001-%s, Python Software Foundation' % time.strftime('%Y')
diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst
index 4e2761d8a7d0..f81e06b5e605 100644
--- a/Doc/distutils/examples.rst
+++ b/Doc/distutils/examples.rst
@@ -1,4 +1,4 @@
-.. _examples:
+.. _distutils_examples:
 
 ********
 Examples
diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst
index a7d26f9b4554..8402370d98f6 100644
--- a/Doc/library/multiprocessing.rst
+++ b/Doc/library/multiprocessing.rst
@@ -621,18 +621,19 @@ The :mod:`multiprocessing` package mostly replicates the API of the
    Example usage of some of the methods of :class:`Process`:
 
    .. doctest::
+      :options: +ELLIPSIS
 
        >>> import multiprocessing, time, signal
        >>> p = multiprocessing.Process(target=time.sleep, args=(1000,))
        >>> print(p, p.is_alive())
-       <Process(Process-1, initial)> False
+       <Process(..., initial)> False
        >>> p.start()
        >>> print(p, p.is_alive())
-       <Process(Process-1, started)> True
+       <Process(..., started)> True
        >>> p.terminate()
        >>> time.sleep(0.1)
        >>> print(p, p.is_alive())
-       <Process(Process-1, stopped[SIGTERM])> False
+       <Process(..., stopped[SIGTERM])> False
        >>> p.exitcode == -signal.SIGTERM
        True
 
diff --git a/Doc/library/re.rst b/Doc/library/re.rst
index e90840d9acc1..67f85705169b 100644
--- a/Doc/library/re.rst
+++ b/Doc/library/re.rst
@@ -1234,9 +1234,7 @@ Checking for a Pair
 ^^^^^^^^^^^^^^^^^^^
 
 In this example, we'll use the following helper function to display match
-objects a little more gracefully:
-
-.. testcode::
+objects a little more gracefully::
 
    def displaymatch(match):
        if match is None:
@@ -1269,10 +1267,9 @@ To match this with a regular expression, one could use backreferences as such::
    "<Match: '354aa', groups=('a',)>"
 
 To find out what card the pair consists of, one could use the
-:meth:`~Match.group` method of the match object in the following manner:
-
-.. doctest::
+:meth:`~Match.group` method of the match object in the following manner::
 
+   >>> pair = re.compile(r".*(.).*\1")
    >>> pair.match("717ak").group(1)
    '7'
 
@@ -1377,7 +1374,9 @@ easily read and modified by Python as demonstrated in the following example that
 creates a phonebook.
 
 First, here is the input.  Normally it may come from a file, here we are using
-triple-quoted string syntax::
+triple-quoted string syntax
+
+.. doctest::
 
    >>> text = """Ross McFluff: 834.345.1254 155 Elm Street
    ...
diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst
index 595a244342c4..83903648b427 100644
--- a/Doc/library/turtle.rst
+++ b/Doc/library/turtle.rst
@@ -250,6 +250,7 @@ Turtle motion
    turtle is headed.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.position()
       (0.00,0.00)
@@ -276,6 +277,7 @@ Turtle motion
       >>> turtle.goto(0, 0)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.position()
       (0.00,0.00)
@@ -294,11 +296,13 @@ Turtle motion
    orientation depends on the turtle mode, see :func:`mode`.
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> turtle.setheading(22)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.heading()
       22.0
@@ -317,11 +321,13 @@ Turtle motion
    orientation depends on the turtle mode, see :func:`mode`.
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> turtle.setheading(22)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.heading()
       22.0
@@ -344,11 +350,13 @@ Turtle motion
    not change the turtle's orientation.
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> turtle.goto(0, 0)
 
    .. doctest::
+      :skipif: _tkinter is None
 
        >>> tp = turtle.pos()
        >>> tp
@@ -372,11 +380,13 @@ Turtle motion
    unchanged.
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> turtle.goto(0, 240)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.position()
       (0.00,240.00)
@@ -392,11 +402,13 @@ Turtle motion
    Set the turtle's second coordinate to *y*, leave first coordinate unchanged.
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> turtle.goto(0, 40)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.position()
       (0.00,40.00)
@@ -423,6 +435,7 @@ Turtle motion
    =================== ====================
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.setheading(90)
       >>> turtle.heading()
@@ -435,12 +448,14 @@ Turtle motion
    its start-orientation (which depends on the mode, see :func:`mode`).
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> turtle.setheading(90)
       >>> turtle.goto(0, -10)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.heading()
       90.0
@@ -472,6 +487,7 @@ Turtle motion
    calculated automatically.  May be used to draw regular polygons.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.position()
@@ -500,6 +516,7 @@ Turtle motion
 
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.dot()
@@ -517,6 +534,7 @@ Turtle motion
    it by calling ``clearstamp(stamp_id)``.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.color("blue")
       >>> turtle.stamp()
@@ -532,6 +550,7 @@ Turtle motion
    Delete stamp with given *stampid*.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.position()
       (150.00,-0.00)
@@ -576,6 +595,7 @@ Turtle motion
    undo actions is determined by the size of the undobuffer.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> for i in range(4):
       ...     turtle.fd(50); turtle.lt(80)
@@ -608,6 +628,7 @@ Turtle motion
    turtle turn instantly.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.speed()
       3
@@ -628,6 +649,7 @@ Tell Turtle's state
    Return the turtle's current location (x,y) (as a :class:`Vec2D` vector).
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.pos()
       (440.00,-0.00)
@@ -643,6 +665,7 @@ Tell Turtle's state
    orientation which depends on the mode - "standard"/"world" or "logo").
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.goto(10, 10)
       >>> turtle.towards(0,0)
@@ -654,6 +677,7 @@ Tell Turtle's state
    Return the turtle's x coordinate.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.left(50)
@@ -669,6 +693,7 @@ Tell Turtle's state
    Return the turtle's y coordinate.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.left(60)
@@ -685,6 +710,7 @@ Tell Turtle's state
    :func:`mode`).
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.left(67)
@@ -701,6 +727,7 @@ Tell Turtle's state
    other turtle, in turtle step units.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.distance(30,40)
@@ -724,6 +751,7 @@ Settings for measurement
    Default value is 360 degrees.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.left(90)
@@ -746,6 +774,7 @@ Settings for measurement
    ``degrees(2*math.pi)``.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.left(90)
@@ -756,6 +785,7 @@ Settings for measurement
       1.5707963267948966
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> turtle.degrees(360)
@@ -791,6 +821,7 @@ Drawing state
    thickness.  If no argument is given, the current pensize is returned.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.pensize()
       1
@@ -822,6 +853,7 @@ Drawing state
    attributes in one statement.
 
    .. doctest::
+      :skipif: _tkinter is None
       :options: +NORMALIZE_WHITESPACE
 
       >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
@@ -844,6 +876,7 @@ Drawing state
    Return ``True`` if pen is down, ``False`` if it's up.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.penup()
       >>> turtle.isdown()
@@ -884,6 +917,7 @@ Color control
     newly set pencolor.
 
    .. doctest::
+      :skipif: _tkinter is None
 
        >>> colormode()
        1.0
@@ -932,6 +966,7 @@ Color control
     with the newly set fillcolor.
 
    .. doctest::
+      :skipif: _tkinter is None
 
        >>> turtle.fillcolor("violet")
        >>> turtle.fillcolor()
@@ -970,6 +1005,7 @@ Color control
     with the newly set colors.
 
    .. doctest::
+      :skipif: _tkinter is None
 
        >>> turtle.color("red", "green")
        >>> turtle.color()
@@ -986,6 +1022,7 @@ Filling
 ~~~~~~~
 
 .. doctest::
+   :skipif: _tkinter is None
    :hide:
 
    >>> turtle.home()
@@ -995,6 +1032,7 @@ Filling
    Return fillstate (``True`` if filling, ``False`` else).
 
    .. doctest::
+      :skipif: _tkinter is None
 
        >>> turtle.begin_fill()
        >>> if turtle.filling():
@@ -1014,6 +1052,7 @@ Filling
    Fill the shape drawn after the last call to :func:`begin_fill`.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.color("black", "red")
       >>> turtle.begin_fill()
@@ -1030,6 +1069,7 @@ More drawing control
    variables to the default values.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.goto(0,-22)
       >>> turtle.left(100)
@@ -1080,6 +1120,7 @@ Visibility
    drawing observably.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.hideturtle()
 
@@ -1090,6 +1131,7 @@ Visibility
    Make the turtle visible.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.showturtle()
 
@@ -1120,6 +1162,7 @@ Appearance
    deal with shapes see Screen method :func:`register_shape`.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.shape()
       'classic'
@@ -1145,6 +1188,7 @@ Appearance
    resizemode("user") is called by :func:`shapesize` when used with arguments.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.resizemode()
       'noresize'
@@ -1168,6 +1212,7 @@ Appearance
    of the shapes's outline.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.shapesize()
       (1.0, 1.0, 1)
@@ -1192,6 +1237,7 @@ Appearance
    heading of the turtle are sheared.
 
    .. doctest::
+      :skipif: _tkinter is None
 
        >>> turtle.shape("circle")
        >>> turtle.shapesize(5,2)
@@ -1208,6 +1254,7 @@ Appearance
    change the turtle's heading (direction of movement).
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.reset()
       >>> turtle.shape("circle")
@@ -1227,6 +1274,7 @@ Appearance
    (direction of movement).
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.reset()
       >>> turtle.shape("circle")
@@ -1252,6 +1300,7 @@ Appearance
    turtle (its direction of movement).
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.reset()
       >>> turtle.shape("circle")
@@ -1280,6 +1329,7 @@ Appearance
    given matrix.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle = Turtle()
       >>> turtle.shape("square")
@@ -1295,6 +1345,7 @@ Appearance
    can be used to define a new shape or components of a compound shape.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.shape("square")
       >>> turtle.shapetransform(4, -1, 0, 2)
@@ -1318,6 +1369,7 @@ Using events
    procedural way:
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> def turn(x, y):
       ...     left(180)
@@ -1338,6 +1390,7 @@ Using events
    ``None``, existing bindings are removed.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> class MyTurtle(Turtle):
       ...     def glow(self,x,y):
@@ -1365,6 +1418,7 @@ Using events
    mouse-click event on that turtle.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.ondrag(turtle.goto)
 
@@ -1392,6 +1446,7 @@ Special Turtle methods
    Return the last recorded polygon.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.home()
       >>> turtle.begin_poly()
@@ -1411,6 +1466,7 @@ Special Turtle methods
    turtle properties.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> mick = Turtle()
       >>> joe = mick.clone()
@@ -1423,6 +1479,7 @@ Special Turtle methods
    return the "anonymous turtle":
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> pet = getturtle()
       >>> pet.fd(50)
@@ -1436,6 +1493,7 @@ Special Turtle methods
    TurtleScreen methods can then be called for that object.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> ts = turtle.getscreen()
       >>> ts
@@ -1453,6 +1511,7 @@ Special Turtle methods
    ``None``, the undobuffer is disabled.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> turtle.setundobuffer(42)
 
@@ -1462,6 +1521,7 @@ Special Turtle methods
    Return number of entries in the undobuffer.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> while undobufferentries():
       ...     undo()
@@ -1484,6 +1544,7 @@ below:
    For example:
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> s = Shape("compound")
       >>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5))
@@ -1494,6 +1555,7 @@ below:
 3. Now add the Shape to the Screen's shapelist and use it:
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> register_shape("myshape", s)
       >>> shape("myshape")
@@ -1513,6 +1575,7 @@ Most of the examples in this section refer to a TurtleScreen instance called
 ``screen``.
 
 .. doctest::
+   :skipif: _tkinter is None
    :hide:
 
    >>> screen = Screen()
@@ -1529,6 +1592,7 @@ Window control
    Set or return background color of the TurtleScreen.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.bgcolor("orange")
       >>> screen.bgcolor()
@@ -1614,6 +1678,7 @@ Window control
    distorted.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.reset()
       >>> screen.setworldcoordinates(-50,-7.5,50,7.5)
@@ -1624,6 +1689,7 @@ Window control
       ...     left(45); fd(2)   # a regular octagon
 
    .. doctest::
+      :skipif: _tkinter is None
       :hide:
 
       >>> screen.reset()
@@ -1645,6 +1711,7 @@ Animation control
    Optional argument:
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.delay()
       10
@@ -1666,6 +1733,7 @@ Animation control
    :func:`delay`).
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.tracer(8, 25)
       >>> dist = 2
@@ -1702,6 +1770,7 @@ Using screen events
    must have the focus. (See method :func:`listen`.)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> def f():
       ...     fd(50)
@@ -1722,6 +1791,7 @@ Using screen events
    must have focus. (See method :func:`listen`.)
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> def f():
       ...     fd(50)
@@ -1746,6 +1816,7 @@ Using screen events
    named turtle:
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.onclick(turtle.goto) # Subsequently clicking into the TurtleScreen will
       >>>                             # make the turtle move to the clicked point.
@@ -1765,6 +1836,7 @@ Using screen events
    Install a timer that calls *fun* after *t* milliseconds.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> running = True
       >>> def f():
@@ -1846,6 +1918,7 @@ Settings and special methods
    ============ ========================= ===================
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> mode("logo")   # resets turtle heading to north
       >>> mode()
@@ -1860,6 +1933,7 @@ Settings and special methods
    values of color triples have to be in the range 0..\ *cmode*.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.colormode(1)
       >>> turtle.pencolor(240, 160, 80)
@@ -1880,6 +1954,7 @@ Settings and special methods
    do with a Tkinter Canvas.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> cv = screen.getcanvas()
       >>> cv
@@ -1891,6 +1966,7 @@ Settings and special methods
    Return a list of names of all currently available turtle shapes.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.getshapes()
       ['arrow', 'blank', 'circle', ..., 'turtle']
@@ -1914,6 +1990,7 @@ Settings and special methods
        coordinates: Install the corresponding polygon shape.
 
        .. doctest::
+          :skipif: _tkinter is None
 
           >>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3)))
 
@@ -1929,6 +2006,7 @@ Settings and special methods
    Return the list of turtles on the screen.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> for turtle in screen.turtles():
       ...     turtle.color("red")
@@ -1990,6 +2068,7 @@ Methods specific to Screen, not inherited from TurtleScreen
                   center window vertically
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.setup (width=200, height=200, startx=0, starty=0)
       >>>              # sets window to 200x200 pixels, in upper left of screen
@@ -2005,6 +2084,7 @@ Methods specific to Screen, not inherited from TurtleScreen
    Set title of turtle window to *titlestring*.
 
    .. doctest::
+      :skipif: _tkinter is None
 
       >>> screen.title("Welcome to the turtle zoo!")
 
@@ -2075,6 +2155,7 @@ Public classes
       Example:
 
       .. doctest::
+         :skipif: _tkinter is None
 
          >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
          >>> s = Shape("compound")
@@ -2421,6 +2502,7 @@ Changes since Python 3.0
 
 
 .. doctest::
+   :skipif: _tkinter is None
    :hide:
 
    >>> for turtle in turtles():
diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst
index 65dee7c0eb2d..60db4c2ba4da 100644
--- a/Doc/library/unittest.mock-examples.rst
+++ b/Doc/library/unittest.mock-examples.rst
@@ -9,6 +9,19 @@
 
 .. _getting-started:
 
+
+.. testsetup::
+
+    import unittest
+    from unittest.mock import Mock, MagicMock, patch, call, sentinel
+
+    class SomeClass:
+        attribute = 'this is a doctest'
+
+        @staticmethod
+        def static_method():
+            pass
+
 Using Mock
 ----------
 
@@ -99,7 +112,7 @@ by looking at the return value of the mocked class.
 In the example below we have a function ``some_function`` that instantiates ``Foo``
 and calls a method on it. The call to :func:`patch` replaces the class ``Foo`` with a
 mock. The ``Foo`` instance is the result of calling the mock, so it is configured
-by modifying the mock :attr:`~Mock.return_value`.
+by modifying the mock :attr:`~Mock.return_value`. ::
 
     >>> def some_function():
     ...     instance = module.Foo()
@@ -321,7 +334,7 @@ whatever) to be replaced with. 'patch.object' takes an object and the name of
 the attribute you would like patched, plus optionally the value to patch it
 with.
 
-``patch.object``:
+``patch.object``::
 
     >>> original = SomeClass.attribute
     >>> @patch.object(SomeClass, 'attribute', sentinel.attribute)
@@ -348,7 +361,7 @@ instead of :func:`patch.object`:
     >>> mock.assert_called_with('filename', 'r')
     >>> assert handle == sentinel.file_handle, "incorrect file handle returned"
 
-The module name can be 'dotted', in the form ``package.module`` if needed:
+The module name can be 'dotted', in the form ``package.module`` if needed::
 
     >>> @patch('package.module.ClassName.attribute', sentinel.attribute)
     ... def test():
@@ -380,7 +393,7 @@ passed into the test function / method:
     ...
     >>> MyTest('test_something').test_something()
 
-You can stack up multiple patch decorators using this pattern:
+You can stack up multiple patch decorators using this pattern::
 
     >>> class MyTest(unittest.TestCase):
     ...     @patch('package.module.ClassName1')
@@ -485,7 +498,7 @@ response object for it. To set the response as the return value for that final
     mock_backend.get_endpoint.return_value.create_call.return_value.start_call.return_value = mock_response
 
 We can do that in a slightly nicer way using the :meth:`~Mock.configure_mock`
-method to directly set the return value for us:
+method to directly set the return value for us::
 
     >>> something = Something()
     >>> mock_response = Mock(spec=open)
@@ -494,7 +507,7 @@ method to directly set the return value for us:
     >>> mock_backend.configure_mock(**config)
 
 With these we monkey patch the "mock backend" in place and can make the real
-call:
+call::
 
     >>> something.backend = mock_backend
     >>> something.method()
@@ -502,7 +515,7 @@ call:
 Using :attr:`~Mock.mock_calls` we can check the chained call with a single
 assert. A chained call is several calls in one line of code, so there will be
 several entries in ``mock_calls``. We can use :meth:`call.call_list` to create
-this list of calls for us:
+this list of calls for us::
 
     >>> chained = call.get_endpoint('foobar').create_call('spam', 'eggs').start_call()
     >>> call_list = chained.call_list()
@@ -525,7 +538,7 @@ The :func:`patch decorator <patch>` is used here to
 mock out the ``date`` class in the module under test. The :attr:`side_effect`
 attribute on the mock date class is then set to a lambda function that returns
 a real date. When the mock date class is called a real date will be
-constructed and returned by ``side_effect``.
+constructed and returned by ``side_effect``. ::
 
     >>> from datetime import date
     >>> with patch('mymodule.date') as mock_date:
@@ -534,7 +547,6 @@ constructed and returned by ``side_effect``.
     ...
     ...     assert mymodule.date.today() == date(2010, 10, 8)
     ...     assert mymodule.date(2009, 6, 8) == date(2009, 6, 8)
-    ...
 
 Note that we don't patch :class:`datetime.date` globally, we patch ``date`` in the
 module that *uses* it. See :ref:`where to patch <where-to-patch>`.
@@ -600,10 +612,10 @@ is to apply the patch decorators to every method. This can feel like unnecessary
 repetition. For Python 2.6 or more recent you can use :func:`patch` (in all its
 various forms) as a class decorator. This applies the patches to all test
 methods on the class. A test method is identified by methods whose names start
-with ``test``:
+with ``test``::
 
     >>> @patch('mymodule.SomeClass')
-    ... class MyTest(TestCase):
+    ... class MyTest(unittest.TestCase):
     ...
     ...     def test_one(self, MockSomeClass):
     ...         self.assertIs(mymodule.SomeClass, MockSomeClass)
@@ -621,8 +633,9 @@ with ``test``:
 
 An alternative way of managing patches is to use the :ref:`start-and-stop`.
 These allow you to move the patching into your ``setUp`` and ``tearDown`` methods.
+::
 
-    >>> class MyTest(TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...     def setUp(self):
     ...         self.patcher = patch('mymodule.foo')
     ...         self.mock_foo = self.patcher.start()
@@ -638,9 +651,9 @@ These allow you to move the patching into your ``setUp`` and ``tearDown`` method
 If you use this technique you must ensure that the patching is "undone" by
 calling ``stop``. This can be fiddlier than you might think, because if an
 exception is raised in the setUp then tearDown is not called.
-:meth:`unittest.TestCase.addCleanup` makes this easier:
+:meth:`unittest.TestCase.addCleanup` makes this easier::
 
-    >>> class MyTest(TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...     def setUp(self):
     ...         patcher = patch('mymodule.foo')
     ...         self.addCleanup(patcher.stop)
@@ -753,7 +766,7 @@ defined in 'mymodule'::
         val.clear()
 
 When we try to test that ``grob`` calls ``frob`` with the correct argument look
-what happens:
+what happens::
 
     >>> with patch('mymodule.frob') as mock_frob:
     ...     val = {6}
@@ -777,7 +790,7 @@ functionality. If you provide a ``side_effect`` function for a mock then
 opportunity to copy the arguments and store them for later assertions. In this
 example I'm using *another* mock to store the arguments so that I can use the
 mock methods for doing the assertion. Again a helper function sets this up for
-me.
+me. ::
 
     >>> from copy import deepcopy
     >>> from unittest.mock import Mock, patch, DEFAULT
@@ -854,9 +867,9 @@ Nesting Patches
 
 Using patch as a context manager is nice, but if you do multiple patches you
 can end up with nested with statements indenting further and further to the
-right:
+right::
 
-    >>> class MyTest(TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...
     ...     def test_foo(self):
     ...         with patch('mymodule.Foo') as mock_foo:
@@ -873,9 +886,9 @@ right:
 With unittest ``cleanup`` functions and the :ref:`start-and-stop` we can
 achieve the same effect without the nested indentation. A simple helper
 method, ``create_patch``, puts the patch in place and returns the created mock
-for us:
+for us::
 
-    >>> class MyTest(TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...
     ...     def create_patch(self, name):
     ...         patcher = patch(name)
@@ -969,7 +982,7 @@ mock methods and attributes:
     >>> mock.__setitem__.call_args_list
     [call('b', 'fish'), call('d', 'eggs')]
     >>> my_dict
-    {'a': 1, 'c': 3, 'b': 'fish', 'd': 'eggs'}
+    {'a': 1, 'b': 'fish', 'c': 3, 'd': 'eggs'}
 
 
 Mock subclasses and their attributes
@@ -1064,6 +1077,7 @@ previously will be restored safely.
 
 Here's an example that mocks out the 'fooble' module.
 
+    >>> import sys
     >>> mock = Mock()
     >>> with patch.dict('sys.modules', {'fooble': mock}):
     ...    import fooble
@@ -1132,7 +1146,7 @@ the ``mock_calls`` attribute on the manager mock:
 
 If ``patch`` is creating, and putting in place, your mocks then you can attach
 them to a manager mock using the :meth:`~Mock.attach_mock` method. After
-attaching calls will be recorded in ``mock_calls`` of the manager.
+attaching calls will be recorded in ``mock_calls`` of the manager. ::
 
     >>> manager = MagicMock()
     >>> with patch('mymodule.Class1') as MockClass1:
@@ -1141,14 +1155,13 @@ attaching calls will be recorded in ``mock_calls`` of the manager.
     ...         manager.attach_mock(MockClass2, 'MockClass2')
     ...         MockClass1().foo()
     ...         MockClass2().bar()
-    ...
     <MagicMock name='mock.MockClass1().foo()' id='...'>
     <MagicMock name='mock.MockClass2().bar()' id='...'>
     >>> manager.mock_calls
     [call.MockClass1(),
-     call.MockClass1().foo(),
-     call.MockClass2(),
-     call.MockClass2().bar()]
+    call.MockClass1().foo(),
+    call.MockClass2(),
+    call.MockClass2().bar()]
 
 If many calls have been made, but you're only interested in a particular
 sequence of them then an alternative is to use the
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
index 06009e4a0971..edafca0c674e 100644
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -41,6 +41,22 @@ available as `mock on PyPI <https://pypi.org/project/mock>`_.
 Quick Guide
 -----------
 
+.. testsetup::
+
+    class ProductionClass:
+        def method(self, a, b, c):
+            pass
+
+    class SomeClass:
+        @staticmethod
+        def static_method(args):
+            return args
+
+        @classmethod
+        def class_method(cls, args):
+            return args
+
+
 :class:`Mock` and :class:`MagicMock` objects create all attributes and
 methods as you access them and store details of how they have been used. You
 can configure them, to specify return values or limit what attributes are
@@ -80,7 +96,7 @@ that don't exist on the spec will fail with an :exc:`AttributeError`.
 
 The :func:`patch` decorator / context manager makes it easy to mock classes or
 objects in a module under test. The object you specify will be replaced with a
-mock (or other object) during the test and restored when the test ends:
+mock (or other object) during the test and restored when the test ends::
 
     >>> from unittest.mock import patch
     >>> @patch('module.ClassName2')
@@ -183,6 +199,12 @@ the ``__call__`` method.
 The Mock Class
 --------------
 
+.. testsetup::
+
+    import unittest
+    from unittest.mock import sentinel, DEFAULT, ANY
+    from unittest.mock import patch, call, Mock, MagicMock, PropertyMock
+    from unittest.mock import mock_open
 
 :class:`Mock` is a flexible mock object intended to replace the use of stubs and
 test doubles throughout your code. Mocks are callable and create attributes as
@@ -774,7 +796,7 @@ apply to method calls on the mock object.
    so you can specify a return value when it is fetched.
 
    Fetching a :class:`PropertyMock` instance from an object calls the mock, with
-   no args. Setting it calls the mock with the value being set.
+   no args. Setting it calls the mock with the value being set. ::
 
         >>> class Foo:
         ...     @property
@@ -1001,7 +1023,7 @@ the "parenting" if for some reason you don't want it to happen.
 
 Mocks created for you by :func:`patch` are automatically given names. To
 attach mocks that have names to a parent you use the :meth:`~Mock.attach_mock`
-method:
+method::
 
     >>> thing1 = object()
     >>> thing2 = object()
@@ -1117,7 +1139,7 @@ patch
     available for alternate use-cases.
 
 :func:`patch` as function decorator, creating the mock for you and passing it into
-the decorated function:
+the decorated function::
 
     >>> @patch('__main__.SomeClass')
     ... def function(normal_argument, mock_class):
@@ -1135,7 +1157,7 @@ If the class is instantiated multiple times you could use
 can set the *return_value* to be anything you want.
 
 To configure return values on methods of *instances* on the patched class
-you must do this on the :attr:`return_value`. For example:
+you must do this on the :attr:`return_value`. For example::
 
     >>> class Class:
     ...     def method(self):
@@ -1149,7 +1171,7 @@ you must do this on the :attr:`return_value`. For example:
     ...
 
 If you use *spec* or *spec_set* and :func:`patch` is replacing a *class*, then the
-return value of the created mock will have the same spec.
+return value of the created mock will have the same spec. ::
 
     >>> Original = Class
     >>> patcher = patch('__main__.Class', spec=True)
@@ -1160,7 +1182,7 @@ return value of the created mock will have the same spec.
 
 The *new_callable* argument is useful where you want to use an alternative
 class to the default :class:`MagicMock` for the created mock. For example, if
-you wanted a :class:`NonCallableMock` to be used:
+you wanted a :class:`NonCallableMock` to be used::
 
     >>> thing = object()
     >>> with patch('__main__.thing', new_callable=NonCallableMock) as mock_thing:
@@ -1171,7 +1193,7 @@ you wanted a :class:`NonCallableMock` to be used:
       ...
     TypeError: 'NonCallableMock' object is not callable
 
-Another use case might be to replace an object with an :class:`io.StringIO` instance:
+Another use case might be to replace an object with an :class:`io.StringIO` instance::
 
     >>> from io import StringIO
     >>> def foo():
@@ -1187,7 +1209,7 @@ Another use case might be to replace an object with an :class:`io.StringIO` inst
 When :func:`patch` is creating a mock for you, it is common that the first thing
 you need to do is to configure the mock. Some of that configuration can be done
 in the call to patch. Any arbitrary keywords you pass into the call will be
-used to set attributes on the created mock:
+used to set attributes on the created mock::
 
     >>> patcher = patch('__main__.thing', first='one', second='two')
     >>> mock_thing = patcher.start()
@@ -1200,7 +1222,7 @@ As well as attributes on the created mock attributes, like the
 :attr:`~Mock.return_value` and :attr:`~Mock.side_effect`, of child mocks can
 also be configured. These aren't syntactically valid to pass in directly as
 keyword arguments, but a dictionary with these as keys can still be expanded
-into a :func:`patch` call using ``**``:
+into a :func:`patch` call using ``**``::
 
     >>> config = {'method.return_value': 3, 'other.side_effect': KeyError}
     >>> patcher = patch('__main__.thing', **config)
@@ -1359,7 +1381,7 @@ patch.multiple
 
 If you want :func:`patch.multiple` to create mocks for you, then you can use
 :data:`DEFAULT` as the value. If you use :func:`patch.multiple` as a decorator
-then the created mocks are passed into the decorated function by keyword.
+then the created mocks are passed into the decorated function by keyword. ::
 
     >>> thing = object()
     >>> other = object()
@@ -1372,7 +1394,7 @@ then the created mocks are passed into the decorated function by keyword.
     >>> test_function()
 
 :func:`patch.multiple` can be nested with other ``patch`` decorators, but put arguments
-passed by keyword *after* any of the standard arguments created by :func:`patch`:
+passed by keyword *after* any of the standard arguments created by :func:`patch`::
 
     >>> @patch('sys.exit')
     ... @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
@@ -1384,7 +1406,7 @@ passed by keyword *after* any of the standard arguments created by :func:`patch`
     >>> test_function()
 
 If :func:`patch.multiple` is used as a context manager, the value returned by the
-context manger is a dictionary where created mocks are keyed by name:
+context manger is a dictionary where created mocks are keyed by name::
 
     >>> with patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) as values:
     ...     assert 'other' in repr(values['other'])
@@ -1408,7 +1430,7 @@ normal and keep a reference to the returned ``patcher`` object. You can then
 call :meth:`start` to put the patch in place and :meth:`stop` to undo it.
 
 If you are using :func:`patch` to create a mock for you then it will be returned by
-the call to ``patcher.start``.
+the call to ``patcher.start``. ::
 
     >>> patcher = patch('package.module.ClassName')
     >>> from package import module
@@ -1422,9 +1444,9 @@ the call to ``patcher.start``.
 
 
 A typical use case for this might be for doing multiple patches in the ``setUp``
-method of a :class:`TestCase`:
+method of a :class:`TestCase`::
 
-    >>> class MyTest(TestCase):
+    >>> class MyTest(unittest.TestCase):
     ...     def setUp(self):
     ...         self.patcher1 = patch('package.module.Class1')
     ...         self.patcher2 = patch('package.module.Class2')
@@ -1446,9 +1468,9 @@ method of a :class:`TestCase`:
     If you use this technique you must ensure that the patching is "undone" by
     calling ``stop``. This can be fiddlier than you might think, because if an
     exception is raised in the ``setUp`` then ``tearDown`` is not called.
-    :meth:`unittest.TestCase.addCleanup` makes this easier:
+    :meth:`unittest.TestCase.addCleanup` makes this easier::
 
-        >>> class MyTest(TestCase):
+        >>> class MyTest(unittest.TestCase):
         ...     def setUp(self):
         ...         patcher = patch('package.module.Class')
         ...         self.MockClass = patcher.start()
@@ -1474,7 +1496,7 @@ It is also possible to stop all patches which have been started by using
 patch builtins
 ~~~~~~~~~~~~~~
 You can patch any builtins within a module. The following example patches
-builtin :func:`ord`:
+builtin :func:`ord`::
 
     >>> @patch('__main__.ord')
     ... def test(mock_ord):
@@ -1494,7 +1516,7 @@ start with ``'test'`` as being test methods. This is the same way that the
 :class:`unittest.TestLoader` finds test methods by default.
 
 It is possible that you want to use a different prefix for your tests. You can
-inform the patchers of the different prefix by setting ``patch.TEST_PREFIX``:
+inform the patchers of the different prefix by setting ``patch.TEST_PREFIX``::
 
     >>> patch.TEST_PREFIX = 'foo'
     >>> value = 3
@@ -1931,7 +1953,7 @@ arguments are a dictionary:
     >>> args
     (1, 2, 3)
     >>> kwargs
-    {'arg2': 'two', 'arg': 'one'}
+    {'arg': 'one', 'arg2': 'two'}
     >>> args is kall[0]
     True
     >>> kwargs is kall[1]
@@ -1947,7 +1969,7 @@ arguments are a dictionary:
     >>> args
     (4, 5, 6)
     >>> kwargs
-    {'arg2': 'three', 'arg': 'two'}
+    {'arg': 'two', 'arg2': 'three'}
     >>> name is m.mock_calls[0][0]
     True
 
@@ -2027,11 +2049,17 @@ If the mock was created with a *spec* (or *autospec* of course) then all the
 attributes from the original are shown, even if they haven't been accessed
 yet:
 
+.. doctest::
+    :options: +ELLIPSIS,+NORMALIZE_WHITESPACE
+
     >>> dir(Mock())
     ['assert_any_call',
+     'assert_called',
+     'assert_called_once',
      'assert_called_once_with',
      'assert_called_with',
      'assert_has_calls',
+     'assert_not_called',
      'attach_mock',
      ...
     >>> from urllib import request
@@ -2048,6 +2076,9 @@ filtered from the result of calling :func:`dir` on a :class:`Mock`. If you disli
 behaviour you can switch it off by setting the module level switch
 :data:`FILTER_DIR`:
 
+.. doctest::
+    :options: +ELLIPSIS,+NORMALIZE_WHITESPACE
+
     >>> from unittest import mock
     >>> mock.FILTER_DIR = False
     >>> dir(mock.Mock())
@@ -2110,7 +2141,7 @@ The issue is that even if you mock out the call to :func:`open` it is the
 :meth:`__exit__` called).
 
 Mocking context managers with a :class:`MagicMock` is common enough and fiddly
-enough that a helper function is useful.
+enough that a helper function is useful. ::
 
     >>> m = mock_open()
     >>> with patch('__main__.open', m):
@@ -2126,7 +2157,7 @@ enough that a helper function is useful.
     >>> handle = m()
     >>> handle.write.assert_called_once_with('some stuff')
 
-And for reading files:
+And for reading files::
 
     >>> with patch('__main__.open', mock_open(read_data='bibble')) as m:
     ...     with open('foo') as h:
@@ -2219,7 +2250,7 @@ accessed) you can use it with very complex or deeply nested objects (like
 modules that import modules that import modules) without a big performance
 hit.
 
-Here's an example of it in use:
+Here's an example of it in use::
 
     >>> from urllib import request
     >>> patcher = patch('__main__.request', autospec=True)
@@ -2231,7 +2262,7 @@ Here's an example of it in use:
 
 You can see that :class:`request.Request` has a spec. :class:`request.Request` takes two
 arguments in the constructor (one of which is *self*). Here's what happens if
-we try to call it incorrectly:
+we try to call it incorrectly::
 
     >>> req = request.Request()
     Traceback (most recent call last):
@@ -2239,7 +2270,7 @@ we try to call it incorrectly:
     TypeError: <lambda>() takes at least 2 arguments (1 given)
 
 The spec also applies to instantiated classes (i.e. the return value of
-specced mocks):
+specced mocks)::
 
     >>> req = request.Request('foo')
     >>> req
@@ -2247,7 +2278,7 @@ specced mocks):
 
 :class:`Request` objects are not callable, so the return value of instantiating our
 mocked out :class:`request.Request` is a non-callable mock. With the spec in place
-any typos in our asserts will raise the correct error:
+any typos in our asserts will raise the correct error::
 
     >>> req.add_header('spam', 'eggs')
     <MagicMock name='request.Request().add_header()' id='...'>
@@ -2281,7 +2312,7 @@ objects so that introspection is safe [#]_.
 A more serious problem is that it is common for instance attributes to be
 created in the :meth:`__init__` method and not to exist on the class at all.
 *autospec* can't know about any dynamically created attributes and restricts
-the api to visible attributes.
+the api to visible attributes. ::
 
     >>> class Something:
     ...   def __init__(self):
@@ -2299,7 +2330,7 @@ There are a few different ways of resolving this problem. The easiest, but
 not necessarily the least annoying, way is to simply set the required
 attributes on the mock after creation. Just because *autospec* doesn't allow
 you to fetch attributes that don't exist on the spec it doesn't prevent you
-setting them:
+setting them::
 
     >>> with patch('__main__.Something', autospec=True):
     ...   thing = Something()
@@ -2350,7 +2381,7 @@ spec rather than the class. The other is to create a subclass of the
 production class and add the defaults to the subclass without affecting the
 production class. Both of these require you to use an alternative object as
 the spec. Thankfully :func:`patch` supports this - you can simply pass the
-alternative object as the *autospec* argument:
+alternative object as the *autospec* argument::
 
     >>> class Something:
     ...   def __init__(self):
@@ -2372,6 +2403,11 @@ alternative object as the *autospec* argument:
 Sealing mocks
 ~~~~~~~~~~~~~
 
+
+.. testsetup::
+
+    from unittest.mock import seal
+
 .. function:: seal(mock)
 
     Seal will disable the creation of mock children by preventing getting or setting
@@ -2379,7 +2415,7 @@ Sealing mocks
 
     If a mock instance is assigned to an attribute instead of being dynamically created
     it won't be considered in the sealing chain. This allows one to prevent seal from
-    fixing part of the mock object.
+    fixing part of the mock object. ::
 
         >>> mock = Mock()
         >>> mock.submock.attribute1 = 2
diff --git a/Misc/NEWS.d/next/Tests/2018-10-11-22-34-27.bpo-34962.0PLBi8.rst b/Misc/NEWS.d/next/Tests/2018-10-11-22-34-27.bpo-34962.0PLBi8.rst
new file mode 100644
index 000000000000..0d0f6a1ff77e
--- /dev/null
+++ b/Misc/NEWS.d/next/Tests/2018-10-11-22-34-27.bpo-34962.0PLBi8.rst
@@ -0,0 +1 @@
+make docstest in Doc now passes., and is enforced in CI



More information about the Python-checkins mailing list