Skip to content

Commit 8365a5b

Browse files
bpo-44904: Fix classmethod property bug in doctest module (GH-28838)
The doctest module raised an error if a docstring contained an example that attempted to access a classmethod property. (Stacking '@classmethod' on top of `@property` has been supported since Python 3.9; see https://docs.python.org/3/howto/descriptor.htmlGH-class-methods.) Co-authored-by: Serhiy Storchaka <[email protected]> (cherry picked from commit b1302ab) Co-authored-by: Alex Waygood <[email protected]>
1 parent 21150c6 commit 8365a5b

File tree

4 files changed

+21
-4
lines changed

4 files changed

+21
-4
lines changed

Lib/doctest.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,10 +1022,8 @@ def _find(self, tests, obj, name, module, source_lines, globs, seen):
10221022
if inspect.isclass(obj) and self._recurse:
10231023
for valname, val in obj.__dict__.items():
10241024
# Special handling for staticmethod/classmethod.
1025-
if isinstance(val, staticmethod):
1026-
val = getattr(obj, valname)
1027-
if isinstance(val, classmethod):
1028-
val = getattr(obj, valname).__func__
1025+
if isinstance(val, (staticmethod, classmethod)):
1026+
val = val.__func__
10291027

10301028
# Recurse to methods, properties, and nested classes.
10311029
if ((inspect.isroutine(val) or inspect.isclass(val) or

Lib/test/test_doctest.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ def a_classmethod(cls, v):
9393
22
9494
""")
9595

96+
a_class_attribute = 42
97+
98+
@classmethod
99+
@property
100+
def a_classmethod_property(cls):
101+
"""
102+
>>> print(SampleClass.a_classmethod_property)
103+
42
104+
"""
105+
return cls.a_class_attribute
106+
96107
class NestedClass:
97108
"""
98109
>>> x = SampleClass.NestedClass(5)
@@ -498,6 +509,7 @@ def basics(): r"""
498509
1 SampleClass.NestedClass.__init__
499510
1 SampleClass.__init__
500511
2 SampleClass.a_classmethod
512+
1 SampleClass.a_classmethod_property
501513
1 SampleClass.a_property
502514
1 SampleClass.a_staticmethod
503515
1 SampleClass.double
@@ -553,6 +565,7 @@ def basics(): r"""
553565
1 some_module.SampleClass.NestedClass.__init__
554566
1 some_module.SampleClass.__init__
555567
2 some_module.SampleClass.a_classmethod
568+
1 some_module.SampleClass.a_classmethod_property
556569
1 some_module.SampleClass.a_property
557570
1 some_module.SampleClass.a_staticmethod
558571
1 some_module.SampleClass.double
@@ -594,6 +607,7 @@ def basics(): r"""
594607
1 SampleClass.NestedClass.__init__
595608
1 SampleClass.__init__
596609
2 SampleClass.a_classmethod
610+
1 SampleClass.a_classmethod_property
597611
1 SampleClass.a_property
598612
1 SampleClass.a_staticmethod
599613
1 SampleClass.double
@@ -614,6 +628,7 @@ def basics(): r"""
614628
0 SampleClass.NestedClass.square
615629
1 SampleClass.__init__
616630
2 SampleClass.a_classmethod
631+
1 SampleClass.a_classmethod_property
617632
1 SampleClass.a_property
618633
1 SampleClass.a_staticmethod
619634
1 SampleClass.double

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,6 +1846,7 @@ Bob Watson
18461846
Colin Watson
18471847
David Watson
18481848
Aaron Watters
1849+
Alex Waygood
18491850
Henrik Weber
18501851
Leon Weber
18511852
Steve Weber
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix bug in the :mod:`doctest` module that caused it to fail if a docstring
2+
included an example with a ``classmethod`` ``property``. Patch by Alex
3+
Waygood.

0 commit comments

Comments
 (0)