[Python-checkins] Add more tests for the descriptor tutorial (GH-25164) (#25165)

rhettinger webhook-mailer at python.org
Sat Apr 3 16:42:31 EDT 2021


https://github.com/python/cpython/commit/f12ae0b31a776c8906c428940f0c1bba48a75a45
commit: f12ae0b31a776c8906c428940f0c1bba48a75a45
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: rhettinger <rhettinger at users.noreply.github.com>
date: 2021-04-03T13:42:28-07:00
summary:

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

(cherry picked from commit e4c8895ee5457b11f52841b79b51f3c3d6373fef)

Co-authored-by: Raymond Hettinger <rhettinger at users.noreply.github.com>

Co-authored-by: Raymond Hettinger <rhettinger at users.noreply.github.com>

files:
M Doc/howto/descriptor.rst

diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst
index c7035bad4b6fa..0ddf1239ed298 100644
--- a/Doc/howto/descriptor.rst
+++ b/Doc/howto/descriptor.rst
@@ -281,7 +281,9 @@ The new class now logs access to both *name* and *age*:
     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 @@ perform attribute lookup by way of a helper function:
                 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).
 
@@ -1129,8 +1163,8 @@ If you have ever wondered where *self* comes from in regular methods or where
 *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.
@@ -1183,19 +1217,19 @@ example calls are unexciting:
     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"
@@ -1206,6 +1240,22 @@ Using the non-data descriptor protocol, a pure Python version of
         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
 -------------



More information about the Python-checkins mailing list