Skip to content

Commit b79ae2f

Browse files
authored
Fix missing docstring for types with custom constructors (#1865)
1 parent 60a719c commit b79ae2f

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

src/runtime/ClassManager.cs

+12-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ internal static ClassManagerState SaveRuntimeData()
8787
if ((Runtime.PyDict_DelItemString(dict.Borrow(), member) == -1) &&
8888
(Exceptions.ExceptionMatches(Exceptions.KeyError)))
8989
{
90-
// Trying to remove a key that's not in the dictionary
90+
// Trying to remove a key that's not in the dictionary
9191
// raises an error. We don't care about it.
9292
Runtime.PyErr_Clear();
9393
}
@@ -215,7 +215,7 @@ internal static void InitClassBase(Type type, ClassBase impl, ReflectedClrType p
215215
impl.indexer = info.indexer;
216216
impl.richcompare.Clear();
217217

218-
218+
219219
// Finally, initialize the class __dict__ and return the object.
220220
using var newDict = Runtime.PyObject_GenericGetDict(pyType.Reference);
221221
BorrowedReference dict = newDict.Borrow();
@@ -271,6 +271,15 @@ internal static void InitClassBase(Type type, ClassBase impl, ReflectedClrType p
271271
Runtime.PyDict_SetItem(dict, PyIdentifier.__doc__, doc.Borrow());
272272
}
273273
}
274+
275+
if (Runtime.PySequence_Contains(dict, PyIdentifier.__doc__) != 1)
276+
{
277+
// Ensure that at least some doc string is set
278+
using var fallbackDoc = Runtime.PyString_FromString(
279+
$"Python wrapper for .NET type {type}"
280+
);
281+
Runtime.PyDict_SetItem(dict, PyIdentifier.__doc__, fallbackDoc.Borrow());
282+
}
274283
}
275284
doc.Dispose();
276285

@@ -562,7 +571,7 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl)
562571

563572
return ci;
564573
}
565-
574+
566575
/// <summary>
567576
/// This class owns references to PyObjects in the `members` member.
568577
/// The caller has responsibility to DECREF them.

tests/test_docstring.py

+7
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,10 @@ def test_doc_without_ctor():
2525
assert DocWithoutCtorTest.__doc__ == 'DocWithoutCtorTest Class'
2626
assert DocWithoutCtorTest.TestMethod.__doc__ == 'DocWithoutCtorTest TestMethod'
2727
assert DocWithoutCtorTest.StaticTestMethod.__doc__ == 'DocWithoutCtorTest StaticTestMethod'
28+
29+
30+
def test_doc_primitve():
31+
from System import Int64, String
32+
33+
assert Int64.__doc__ is not None
34+
assert String.__doc__ is not None

tests/test_enum.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ def test_enum_standard_attrs():
1515
assert DayOfWeek.__name__ == 'DayOfWeek'
1616
assert DayOfWeek.__module__ == 'System'
1717
assert isinstance(DayOfWeek.__dict__, DictProxyType)
18-
assert DayOfWeek.__doc__ is None
1918

2019

2120
def test_enum_get_member():
@@ -139,7 +138,7 @@ def test_enum_undefined_value():
139138
# This should fail because our test enum doesn't have it.
140139
with pytest.raises(ValueError):
141140
Test.FieldTest().EnumField = Test.ShortEnum(20)
142-
141+
143142
# explicitly permit undefined values
144143
Test.FieldTest().EnumField = Test.ShortEnum(20, True)
145144

@@ -157,6 +156,6 @@ def test_enum_conversion():
157156

158157
with pytest.raises(TypeError):
159158
Test.FieldTest().EnumField = "str"
160-
159+
161160
with pytest.raises(TypeError):
162161
Test.FieldTest().EnumField = 1

0 commit comments

Comments
 (0)