Skip to content

Commit f0daf49

Browse files
committed
Merge branch 'master' into feature/35967-platform-processor-resolved-late
2 parents 77dabaf + e72cbcb commit f0daf49

13 files changed

+88
-38
lines changed

Doc/library/inspect.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,12 +473,15 @@ Retrieving source code
473473

474474
Get the documentation string for an object, cleaned up with :func:`cleandoc`.
475475
If the documentation string for an object is not provided and the object is
476-
a class, a method, a property or a descriptor, retrieve the documentation
476+
a method, a property or a descriptor, retrieve the documentation
477477
string from the inheritance hierarchy.
478478

479479
.. versionchanged:: 3.5
480480
Documentation strings are now inherited if not overridden.
481481

482+
.. versionchanged:: 3.9
483+
Documentation strings for classes are no longer inherited.
484+
482485

483486
.. function:: getcomments(object)
484487

Doc/whatsnew/3.9.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,13 @@ pprint
346346
:mod:`pprint` can now pretty-print :class:`types.SimpleNamespace`.
347347
(Contributed by Carl Bordum Hansen in :issue:`37376`.)
348348

349+
pydoc
350+
-----
351+
352+
The documentation string is now shown not only for class, function,
353+
method etc, but for any object that has its own ``__doc__`` attribute.
354+
(Contributed by Serhiy Storchaka in :issue:`40257`.)
355+
349356
signal
350357
------
351358

@@ -798,6 +805,12 @@ Changes in the Python API
798805
:class:`ftplib.FTP_TLS` as a keyword-only parameter, and the default encoding
799806
is changed from Latin-1 to UTF-8 to follow :rfc:`2640`.
800807

808+
* :func:`inspect.getdoc` no longer returns docstring inherited from the type
809+
of the object or from parent class if it is a class if it is not defined
810+
in the object itself.
811+
(Contributed by Serhiy Storchaka in :issue:`40257`.)
812+
813+
801814
CPython bytecode changes
802815
------------------------
803816

Lib/inspect.py

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -542,17 +542,6 @@ def _findclass(func):
542542
return cls
543543

544544
def _finddoc(obj):
545-
if isclass(obj):
546-
for base in obj.__mro__:
547-
if base is not object:
548-
try:
549-
doc = base.__doc__
550-
except AttributeError:
551-
continue
552-
if doc is not None:
553-
return doc
554-
return None
555-
556545
if ismethod(obj):
557546
name = obj.__func__.__name__
558547
self = obj.__self__
@@ -596,23 +585,35 @@ def _finddoc(obj):
596585
return None
597586
for base in cls.__mro__:
598587
try:
599-
doc = getattr(base, name).__doc__
588+
doc = _getowndoc(getattr(base, name))
600589
except AttributeError:
601590
continue
602591
if doc is not None:
603592
return doc
604593
return None
605594

595+
def _getowndoc(obj):
596+
"""Get the documentation string for an object if it is not
597+
inherited from its class."""
598+
try:
599+
doc = object.__getattribute__(obj, '__doc__')
600+
if doc is None:
601+
return None
602+
if obj is not type:
603+
typedoc = type(obj).__doc__
604+
if isinstance(typedoc, str) and typedoc == doc:
605+
return None
606+
return doc
607+
except AttributeError:
608+
return None
609+
606610
def getdoc(object):
607611
"""Get the documentation string for an object.
608612
609613
All tabs are expanded to spaces. To clean up docstrings that are
610614
indented to line up with blocks of code, any whitespace than can be
611615
uniformly removed from the second line onwards is removed."""
612-
try:
613-
doc = object.__doc__
614-
except AttributeError:
615-
return None
616+
doc = _getowndoc(object)
616617
if doc is None:
617618
try:
618619
doc = _finddoc(object)

Lib/pydoc.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -825,11 +825,8 @@ def spilldata(msg, attrs, predicate):
825825
push(msg)
826826
for name, kind, homecls, value in ok:
827827
base = self.docother(getattr(object, name), name, mod)
828-
if callable(value) or inspect.isdatadescriptor(value):
829-
doc = getattr(value, "__doc__", None)
830-
else:
831-
doc = None
832-
if doc is None:
828+
doc = getdoc(value)
829+
if not doc:
833830
push('<dl><dt>%s</dl>\n' % base)
834831
else:
835832
doc = self.markup(getdoc(value), self.preformat,
@@ -1309,10 +1306,7 @@ def spilldata(msg, attrs, predicate):
13091306
hr.maybe()
13101307
push(msg)
13111308
for name, kind, homecls, value in ok:
1312-
if callable(value) or inspect.isdatadescriptor(value):
1313-
doc = getdoc(value)
1314-
else:
1315-
doc = None
1309+
doc = getdoc(value)
13161310
try:
13171311
obj = getattr(object, name)
13181312
except AttributeError:
@@ -1448,7 +1442,9 @@ def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=No
14481442
chop = maxlen - len(line)
14491443
if chop < 0: repr = repr[:chop] + '...'
14501444
line = (name and self.bold(name) + ' = ' or '') + repr
1451-
if doc is not None:
1445+
if not doc:
1446+
doc = getdoc(object)
1447+
if doc:
14521448
line += '\n' + self.indent(str(doc))
14531449
return line
14541450

@@ -1672,7 +1668,8 @@ def render_doc(thing, title='Python Library Documentation: %s', forceload=0,
16721668
if not (inspect.ismodule(object) or
16731669
inspect.isclass(object) or
16741670
inspect.isroutine(object) or
1675-
inspect.isdatadescriptor(object)):
1671+
inspect.isdatadescriptor(object) or
1672+
inspect.getdoc(object)):
16761673
# If the passed object is a piece of data or an instance,
16771674
# document its available methods instead of its value.
16781675
object = type(object)

Lib/selectors.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,10 @@ def unregister(self, fileobj):
552552

553553
def select(self, timeout=None):
554554
timeout = None if timeout is None else max(timeout, 0)
555-
max_ev = len(self._fd_to_key)
555+
# If max_ev is 0, kqueue will ignore the timeout. For consistent
556+
# behavior with the other selector classes, we prevent that here
557+
# (using max). See https://bugs.python.org/issue29255
558+
max_ev = max(len(self._fd_to_key), 1)
556559
ready = []
557560
try:
558561
kev_list = self._selector.control(None, max_ev, timeout)

Lib/test/test_inspect.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,19 +439,28 @@ def test_getdoc(self):
439439
@unittest.skipIf(sys.flags.optimize >= 2,
440440
"Docstrings are omitted with -O2 and above")
441441
def test_getdoc_inherited(self):
442-
self.assertEqual(inspect.getdoc(mod.FesteringGob),
443-
'A longer,\n\nindented\n\ndocstring.')
442+
self.assertIsNone(inspect.getdoc(mod.FesteringGob))
444443
self.assertEqual(inspect.getdoc(mod.FesteringGob.abuse),
445444
'Another\n\ndocstring\n\ncontaining\n\ntabs')
446445
self.assertEqual(inspect.getdoc(mod.FesteringGob().abuse),
447446
'Another\n\ndocstring\n\ncontaining\n\ntabs')
448447
self.assertEqual(inspect.getdoc(mod.FesteringGob.contradiction),
449448
'The automatic gainsaying.')
450449

450+
@unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
451+
def test_getowndoc(self):
452+
getowndoc = inspect._getowndoc
453+
self.assertEqual(getowndoc(type), type.__doc__)
454+
self.assertEqual(getowndoc(int), int.__doc__)
455+
self.assertEqual(getowndoc(int.to_bytes), int.to_bytes.__doc__)
456+
self.assertEqual(getowndoc(int().to_bytes), int.to_bytes.__doc__)
457+
self.assertEqual(getowndoc(int.from_bytes), int.from_bytes.__doc__)
458+
self.assertEqual(getowndoc(int.real), int.real.__doc__)
459+
451460
@unittest.skipIf(MISSING_C_DOCSTRINGS, "test requires docstrings")
452461
def test_finddoc(self):
453462
finddoc = inspect._finddoc
454-
self.assertEqual(finddoc(int), int.__doc__)
463+
self.assertIsNone(finddoc(int))
455464
self.assertEqual(finddoc(int.to_bytes), int.to_bytes.__doc__)
456465
self.assertEqual(finddoc(int().to_bytes), int.to_bytes.__doc__)
457466
self.assertEqual(finddoc(int.from_bytes), int.from_bytes.__doc__)

Lib/test/test_platform.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,12 @@ def test_uname_processor(self):
169169
of 'uname -p'. See Issue 35967 for rationale.
170170
"""
171171
with contextlib.suppress(subprocess.CalledProcessError):
172-
self.assertEqual(
173-
platform.uname().processor,
174-
subprocess.check_output(['uname', '-p'], text=True).strip(),
175-
)
172+
expect = subprocess.check_output(['uname', '-p'], text=True).strip()
173+
174+
if expect == 'unknown':
175+
expect = ''
176+
177+
self.assertEqual(platform.uname().processor, expect)
176178

177179
@unittest.skipUnless(sys.platform.startswith('win'), "windows only test")
178180
def test_uname_win32_ARCHITEW6432(self):

Lib/test/test_pydoc.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,8 @@ class X:
12541254

12551255
X.attr.__doc__ = 'Custom descriptor'
12561256
self.assertEqual(self._get_summary_lines(X.attr), """\
1257-
<test.test_pydoc.TestDescriptions.test_custom_non_data_descriptor.<locals>.Descr object>""")
1257+
<test.test_pydoc.TestDescriptions.test_custom_non_data_descriptor.<locals>.Descr object>
1258+
Custom descriptor""")
12581259

12591260
X.attr.__name__ = 'foo'
12601261
self.assertEqual(self._get_summary_lines(X.attr), """\

Lib/test/test_selectors.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,19 @@ def test_register_bad_fd(self):
543543
with self.assertRaises(KeyError):
544544
s.get_key(bad_f)
545545

546+
def test_empty_select_timeout(self):
547+
# Issues #23009, #29255: Make sure timeout is applied when no fds
548+
# are registered.
549+
s = self.SELECTOR()
550+
self.addCleanup(s.close)
551+
552+
t0 = time()
553+
self.assertEqual(s.select(1), [])
554+
t1 = time()
555+
dt = t1 - t0
556+
# Tolerate 2.0 seconds for very slow buildbots
557+
self.assertTrue(0.8 <= dt <= 2.0, dt)
558+
546559

547560
@unittest.skipUnless(hasattr(selectors, 'DevpollSelector'),
548561
"Test needs selectors.DevpollSelector")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Wait in `KqueueSelector.select` when no fds are registered
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The included copy of sqlite3 on Windows is now compiled with the json
2+
extension. This allows the use of functions such as ``json_object``.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
func:`inspect.getdoc` no longer returns docstring inherited from the type of
2+
the object or from parent class if it is a class if it is not defined in the
3+
object itself. In :mod:`pydoc` the documentation string is now shown not
4+
only for class, function, method etc, but for any object that has its own
5+
``__doc__`` attribute.

PCbuild/sqlite3.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
<ItemDefinitionGroup>
9999
<ClCompile>
100100
<AdditionalIncludeDirectories>$(sqlite3Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
101-
<PreprocessorDefinitions>SQLITE_ENABLE_FTS4;SQLITE_ENABLE_FTS5;SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions)</PreprocessorDefinitions>
101+
<PreprocessorDefinitions>SQLITE_ENABLE_JSON1;SQLITE_ENABLE_FTS4;SQLITE_ENABLE_FTS5;SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions)</PreprocessorDefinitions>
102102
<WarningLevel>Level1</WarningLevel>
103103
</ClCompile>
104104
<ResourceCompile>

0 commit comments

Comments
 (0)