From 85abf72bb94f04adc7cbc8b8bc3668e2ea47b216 Mon Sep 17 00:00:00 2001 From: Tony Roberts Date: Fri, 7 Mar 2014 18:03:36 +0000 Subject: [PATCH] Don't default the docstring for classes with a ctor if a docstring was added using DocStringAttribute. Add unit tests for class and method docstrings. --- pythonnet/src/runtime/classmanager.cs | 6 ++- pythonnet/src/testing/Python.Test.csproj | 1 + pythonnet/src/testing/doctest.cs | 61 ++++++++++++++++++++++++ pythonnet/src/tests/test_docstring.py | 46 ++++++++++++++++++ 4 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 pythonnet/src/testing/doctest.cs create mode 100644 pythonnet/src/tests/test_docstring.py 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()