Add more tests for the descriptor tutorial (GH-25164)

diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index 420d9b9..819401e 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -281,7 +281,9 @@
     INFO:root:Updating 'name' to 'Catherine C'
     INFO:root:Updating 'age' to 20
 
-The two *Person* instances contain only the private names::
+The two *Person* instances contain only the private names:
+
+.. doctest::
 
     >>> vars(pete)
     {'_name': 'Peter P', '_age': 10}
@@ -710,6 +712,38 @@
                 raise
         return type(obj).__getattr__(obj, name)             # __getattr__
 
+.. doctest::
+    :hide:
+
+
+    >>> class ClassWithGetAttr:
+    ...     x = 123
+    ...     def __getattr__(self, attr):
+    ...         return attr.upper()
+    ...
+    >>> cw = ClassWithGetAttr()
+    >>> cw.y = 456
+    >>> getattr_hook(cw, 'x')
+    123
+    >>> getattr_hook(cw, 'y')
+    456
+    >>> getattr_hook(cw, 'z')
+    'Z'
+
+    >>> class ClassWithoutGetAttr:
+    ...     x = 123
+    ...
+    >>> cwo = ClassWithoutGetAttr()
+    >>> cwo.y = 456
+    >>> getattr_hook(cwo, 'x')
+    123
+    >>> getattr_hook(cwo, 'y')
+    456
+    >>> getattr_hook(cwo, 'z')
+    Traceback (most recent call last):
+        ...
+    AttributeError: 'ClassWithoutGetAttr' object has no attribute 'z'
+
 So if :meth:`__getattr__` exists, it is called whenever :meth:`__getattribute__`
 raises :exc:`AttributeError` (either directly or in one of the descriptor calls).
 
@@ -1139,8 +1173,8 @@
 *cls* comes from in class methods, this is it!
 
 
-Other kinds of methods
-----------------------
+Kinds of methods
+----------------
 
 Non-data descriptors provide a simple mechanism for variations on the usual
 patterns of binding functions into methods.
@@ -1193,19 +1227,19 @@
     class E:
         @staticmethod
         def f(x):
-            print(x)
+            return x * 10
 
 .. doctest::
 
     >>> E.f(3)
-    3
+    30
     >>> E().f(3)
-    3
+    30
 
 Using the non-data descriptor protocol, a pure Python version of
 :func:`staticmethod` would look like this:
 
-.. doctest::
+.. testcode::
 
     class StaticMethod:
         "Emulate PyStaticMethod_Type() in Objects/funcobject.c"
@@ -1216,6 +1250,22 @@
         def __get__(self, obj, objtype=None):
             return self.f
 
+.. testcode::
+    :hide:
+
+    class E_sim:
+        @StaticMethod
+        def f(x):
+            return x * 10
+
+.. doctest::
+    :hide:
+
+    >>> E_sim.f(3)
+    30
+    >>> E_sim().f(3)
+    30
+
 
 Class methods
 -------------