Skip to content

Commit 523eeb4

Browse files
authored
Fix unexpected __doc__ values (#2556)
* fix unexpected '__doc__' values some '__doc__' fields of standard library symbols (e.g. WrapperDescriptorType.__doc__) don't return a string, they return a 'getset_descriptor'. Thus, an attempt to print "as string" fails. The solution is to check that __doc__ is an instance of str. Note that it wasn't uncovered by the tests due to classes not being attached to their parent in some cases. This is be done in one of the subsequent commits. it's a part of the campaign to get rid of non-module roots * put the "temporary_class" for the metaclass hack into adhoc module it's a part of the campaign to get rid of non-module roots
1 parent e442776 commit 523eeb4

File tree

3 files changed

+18
-10
lines changed

3 files changed

+18
-10
lines changed

astroid/nodes/node_classes.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,16 @@ def __init__(
20612061
:param end_col_offset: The end column this node appears on in the
20622062
source code. Note: This is after the last symbol.
20632063
"""
2064-
self.value: Any = value
2064+
if getattr(value, "__name__", None) == "__doc__":
2065+
warnings.warn( # pragma: no cover
2066+
"You have most likely called a __doc__ field of some object "
2067+
"and it didn't return a string. "
2068+
"That happens to some symbols from the standard library. "
2069+
"Check for isinstance(<X>.__doc__, str).",
2070+
RuntimeWarning,
2071+
stacklevel=0,
2072+
)
2073+
self.value = value
20652074
"""The value that the constant represents."""
20662075

20672076
self.kind: str | None = kind # can be None

astroid/nodes/scoped_nodes/scoped_nodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1624,7 +1624,7 @@ def infer_call_result(
16241624
col_offset=0,
16251625
end_lineno=0,
16261626
end_col_offset=0,
1627-
parent=self,
1627+
parent=AstroidManager().adhoc_module,
16281628
)
16291629
new_class.hide = True
16301630
new_class.postinit(

astroid/raw_building.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ def _add_dunder_class(func, member) -> None:
5656
if not cls_name:
5757
return
5858
cls_bases = [ancestor.__name__ for ancestor in python_cls.__bases__]
59-
ast_klass = build_class(cls_name, cls_bases, python_cls.__doc__)
59+
doc = python_cls.__doc__ if isinstance(python_cls.__doc__, str) else None
60+
ast_klass = build_class(cls_name, cls_bases, doc)
6061
func.instance_attrs["__class__"] = [ast_klass]
6162

6263

@@ -316,7 +317,7 @@ def object_build_function(
316317
args,
317318
posonlyargs,
318319
defaults,
319-
member.__doc__,
320+
member.__doc__ if isinstance(member.__doc__, str) else None,
320321
kwonlyargs=kwonlyargs,
321322
kwonlydefaults=kwonly_defaults,
322323
)
@@ -357,11 +358,8 @@ def _base_class_object_build(
357358
"""
358359
class_name = name or getattr(member, "__name__", None) or localname
359360
assert isinstance(class_name, str)
360-
klass = build_class(
361-
class_name,
362-
basenames,
363-
member.__doc__,
364-
)
361+
doc = member.__doc__ if isinstance(member.__doc__, str) else None
362+
klass = build_class(class_name, basenames, doc)
365363
klass._newstyle = isinstance(member, type)
366364
node.add_local_node(klass, localname)
367365
try:
@@ -718,11 +716,12 @@ def _astroid_bootstrapping() -> None:
718716
parent=nodes.Unknown(),
719717
)
720718
klass.parent = astroid_builtin
719+
doc = _type.__doc__ if isinstance(_type.__doc__, str) else None
721720
klass.postinit(
722721
bases=[],
723722
body=[],
724723
decorators=None,
725-
doc_node=nodes.Const(value=_type.__doc__) if _type.__doc__ else None,
724+
doc_node=nodes.Const(doc) if doc else None,
726725
)
727726
builder.object_build(klass, _type)
728727
astroid_builtin[_type.__name__] = klass

0 commit comments

Comments
 (0)