diff --git a/pythonnet/src/runtime/classmanager.cs b/pythonnet/src/runtime/classmanager.cs
index 2eb3cfd90..164c37cb6 100644
--- a/pythonnet/src/runtime/classmanager.cs
+++ b/pythonnet/src/runtime/classmanager.cs
@@ -132,7 +132,7 @@ private static ClassBase CreateClass(Type type) {
// If class has constructors, generate an __doc__ attribute.
- IntPtr doc;
+ IntPtr doc = IntPtr.Zero;
Type marker = typeof(DocStringAttribute);
Attribute[] attrs = (Attribute[])type.GetCustomAttributes(marker, false);
if (attrs.Length == 0) {
@@ -160,7 +160,9 @@ private static ClassBase CreateClass(Type type) {
Runtime.PyDict_SetItemString(dict, "__overloads__", ctors.pyHandle);
Runtime.PyDict_SetItemString(dict, "Overloads", ctors.pyHandle);
}
- if (!CLRModule._SuppressDocs)
+
+ // don't generate the docstring if one was already set from a DocStringAttribute.
+ if (!CLRModule._SuppressDocs && doc == IntPtr.Zero)
{
doc = co.GetDocString();
Runtime.PyDict_SetItemString(dict, "__doc__", doc);
diff --git a/pythonnet/src/testing/Python.Test.csproj b/pythonnet/src/testing/Python.Test.csproj
index 19846c26f..97d5d09e7 100644
--- a/pythonnet/src/testing/Python.Test.csproj
+++ b/pythonnet/src/testing/Python.Test.csproj
@@ -119,6 +119,7 @@
+
diff --git a/pythonnet/src/testing/doctest.cs b/pythonnet/src/testing/doctest.cs
new file mode 100644
index 000000000..00fa2a904
--- /dev/null
+++ b/pythonnet/src/testing/doctest.cs
@@ -0,0 +1,61 @@
+// ==========================================================================
+// This software is subject to the provisions of the Zope Public License,
+// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+// FOR A PARTICULAR PURPOSE.
+// ==========================================================================
+
+using Python.Runtime;
+
+namespace Python.Test {
+
+ //========================================================================
+ // Supports units tests for exposing docstrings from C# to Python
+ //========================================================================
+
+ // Classes with a constructor have their docstring set to the ctor signature.
+ // Test if a class has an explicit doc string it gets set correctly.
+ [DocStringAttribute("DocWithCtorTest Class")]
+ public class DocWithCtorTest {
+
+ public DocWithCtorTest() {
+ }
+
+ [DocStringAttribute("DocWithCtorTest TestMethod")]
+ public void TestMethod() {
+ }
+
+ [DocStringAttribute("DocWithCtorTest StaticTestMethod")]
+ public static void StaticTestMethod() {
+ }
+
+ }
+
+ public class DocWithCtorNoDocTest
+ {
+ public DocWithCtorNoDocTest(bool x) {
+ }
+
+ public void TestMethod(double a, int b) {
+ }
+
+ public static void StaticTestMethod(double a, int b) {
+ }
+ }
+
+ [DocStringAttribute("DocWithoutCtorTest Class")]
+ public class DocWithoutCtorTest {
+
+ [DocStringAttribute("DocWithoutCtorTest TestMethod")]
+ public void TestMethod() {
+ }
+
+ [DocStringAttribute("DocWithoutCtorTest StaticTestMethod")]
+ public static void StaticTestMethod() {
+ }
+
+ }
+
+}
diff --git a/pythonnet/src/tests/test_docstring.py b/pythonnet/src/tests/test_docstring.py
new file mode 100644
index 000000000..0d0e49f77
--- /dev/null
+++ b/pythonnet/src/tests/test_docstring.py
@@ -0,0 +1,46 @@
+# ===========================================================================
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+# ===========================================================================
+import unittest
+import clr
+clr.AddReference('Python.Test')
+
+from Python.Test import DocWithCtorTest, DocWithoutCtorTest, DocWithCtorNoDocTest
+
+
+class DocStringTests(unittest.TestCase):
+ """Test doc strings support."""
+
+ def testDocWithCtor(self):
+ self.assertEqual(DocWithCtorTest.__doc__, 'DocWithCtorTest Class')
+ self.assertEqual(DocWithCtorTest.TestMethod.__doc__, 'DocWithCtorTest TestMethod')
+ self.assertEqual(DocWithCtorTest.StaticTestMethod.__doc__, 'DocWithCtorTest StaticTestMethod')
+
+
+ def testDocWithCtorNoDoc(self):
+ self.assertEqual(DocWithCtorNoDocTest.__doc__, 'Void .ctor(Boolean)')
+ self.assertEqual(DocWithCtorNoDocTest.TestMethod.__doc__, 'Void TestMethod(Double, Int32)')
+ self.assertEqual(DocWithCtorNoDocTest.StaticTestMethod.__doc__, 'Void StaticTestMethod(Double, Int32)')
+
+
+ def testDocWithoutCtor(self):
+ self.assertEqual(DocWithoutCtorTest.__doc__, 'DocWithoutCtorTest Class')
+ self.assertEqual(DocWithoutCtorTest.TestMethod.__doc__, 'DocWithoutCtorTest TestMethod')
+ self.assertEqual(DocWithoutCtorTest.StaticTestMethod.__doc__, 'DocWithoutCtorTest StaticTestMethod')
+
+
+def test_suite():
+ return unittest.makeSuite(DocStringTests)
+
+
+def main():
+ unittest.TextTestRunner().run(test_suite())
+
+
+if __name__ == '__main__':
+ main()