diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-01-15 08:53:18 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-15 08:53:18 (GMT) |
commit | efcf82f94572abcdbd70336e0b2c3d0f4df280bc (patch) | |
tree | 3af379fca24788ac7196139940ba250148c84114 /Lib/test/test_pydoc.py | |
parent | 6fe9c446f8302553952f63fc6d96be4dfa48ceba (diff) | |
download | cpython-efcf82f94572abcdbd70336e0b2c3d0f4df280bc.zip cpython-efcf82f94572abcdbd70336e0b2c3d0f4df280bc.tar.gz cpython-efcf82f94572abcdbd70336e0b2c3d0f4df280bc.tar.bz2 |
bpo-35619: Improve support of custom data descriptors in help() and pydoc. (GH-11366)
Diffstat (limited to 'Lib/test/test_pydoc.py')
-rw-r--r-- | Lib/test/test_pydoc.py | 174 |
1 files changed, 164 insertions, 10 deletions
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index ffe80fc..c2bd9f3 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -743,15 +743,6 @@ class PydocDocTest(unittest.TestCase): self.assertEqual(pydoc.splitdoc(example_string), ('I Am A Doc', '\nHere is my description')) - def test_is_object_or_method(self): - doc = pydoc.Doc() - # Bound Method - self.assertTrue(pydoc._is_some_method(doc.fail)) - # Method Descriptor - self.assertTrue(pydoc._is_some_method(int.__add__)) - # String - self.assertFalse(pydoc._is_some_method("I am not a method")) - def test_is_package_when_not_package(self): with test.support.temp_cwd() as test_dir: self.assertFalse(pydoc.ispackage(test_dir)) @@ -1093,6 +1084,12 @@ class TestDescriptions(unittest.TestCase): assert len(lines) >= 2 return lines[2] + @staticmethod + def _get_summary_lines(o): + text = pydoc.plain(pydoc.render_doc(o)) + lines = text.split('\n') + return '\n'.join(lines[2:]) + # these should include "self" def test_unbound_python_method(self): self.assertEqual(self._get_summary_line(textwrap.TextWrapper.wrap), @@ -1108,7 +1105,6 @@ class TestDescriptions(unittest.TestCase): t = textwrap.TextWrapper() self.assertEqual(self._get_summary_line(t.wrap), "wrap(text) method of textwrap.TextWrapper instance") - def test_field_order_for_named_tuples(self): Person = namedtuple('Person', ['nickname', 'firstname', 'agegroup']) s = pydoc.render_doc(Person) @@ -1138,6 +1134,164 @@ class TestDescriptions(unittest.TestCase): self.assertEqual(self._get_summary_line(os.stat), "stat(path, *, dir_fd=None, follow_symlinks=True)") + @requires_docstrings + def test_staticmethod(self): + class X: + @staticmethod + def sm(x, y): + '''A static method''' + ... + self.assertEqual(self._get_summary_lines(X.__dict__['sm']), + "<staticmethod object>") + self.assertEqual(self._get_summary_lines(X.sm), """\ +sm(x, y) + A static method +""") + self.assertIn(""" + | Static methods defined here: + |\x20\x20 + | sm(x, y) + | A static method +""", pydoc.plain(pydoc.render_doc(X))) + + @requires_docstrings + def test_classmethod(self): + class X: + @classmethod + def cm(cls, x): + '''A class method''' + ... + self.assertEqual(self._get_summary_lines(X.__dict__['cm']), + "<classmethod object>") + self.assertEqual(self._get_summary_lines(X.cm), """\ +cm(x) method of builtins.type instance + A class method +""") + self.assertIn(""" + | Class methods defined here: + |\x20\x20 + | cm(x) from builtins.type + | A class method +""", pydoc.plain(pydoc.render_doc(X))) + + @requires_docstrings + def test_getset_descriptor(self): + # Currently these attributes are implemented as getset descriptors + # in CPython. + self.assertEqual(self._get_summary_line(int.numerator), "numerator") + self.assertEqual(self._get_summary_line(float.real), "real") + self.assertEqual(self._get_summary_line(Exception.args), "args") + self.assertEqual(self._get_summary_line(memoryview.obj), "obj") + + @requires_docstrings + def test_member_descriptor(self): + # Currently these attributes are implemented as member descriptors + # in CPython. + self.assertEqual(self._get_summary_line(complex.real), "real") + self.assertEqual(self._get_summary_line(range.start), "start") + self.assertEqual(self._get_summary_line(slice.start), "start") + self.assertEqual(self._get_summary_line(property.fget), "fget") + self.assertEqual(self._get_summary_line(StopIteration.value), "value") + + @requires_docstrings + def test_slot_descriptor(self): + class Point: + __slots__ = 'x', 'y' + self.assertEqual(self._get_summary_line(Point.x), "x") + + @requires_docstrings + def test_dict_attr_descriptor(self): + class NS: + pass + self.assertEqual(self._get_summary_line(NS.__dict__['__dict__']), + "__dict__") + + @requires_docstrings + def test_structseq_member_descriptor(self): + self.assertEqual(self._get_summary_line(type(sys.hash_info).width), + "width") + self.assertEqual(self._get_summary_line(type(sys.flags).debug), + "debug") + self.assertEqual(self._get_summary_line(type(sys.version_info).major), + "major") + self.assertEqual(self._get_summary_line(type(sys.float_info).max), + "max") + + @requires_docstrings + def test_namedtuple_field_descriptor(self): + Box = namedtuple('Box', ('width', 'height')) + self.assertEqual(self._get_summary_lines(Box.width), """\ + Alias for field number 0 +""") + + @requires_docstrings + def test_property(self): + class Rect: + @property + def area(self): + '''Area of the rect''' + return self.w * self.h + + self.assertEqual(self._get_summary_lines(Rect.area), """\ + Area of the rect +""") + self.assertIn(""" + | area + | Area of the rect +""", pydoc.plain(pydoc.render_doc(Rect))) + + @requires_docstrings + def test_custom_non_data_descriptor(self): + class Descr: + def __get__(self, obj, cls): + if obj is None: + return self + return 42 + class X: + attr = Descr() + + text = pydoc.plain(pydoc.render_doc(X.attr)) + self.assertEqual(self._get_summary_lines(X.attr), """\ +<test.test_pydoc.TestDescriptions.test_custom_non_data_descriptor.<locals>.Descr object>""") + + X.attr.__doc__ = 'Custom descriptor' + self.assertEqual(self._get_summary_lines(X.attr), """\ +<test.test_pydoc.TestDescriptions.test_custom_non_data_descriptor.<locals>.Descr object>""") + + X.attr.__name__ = 'foo' + self.assertEqual(self._get_summary_lines(X.attr), """\ +foo(...) + Custom descriptor +""") + + @requires_docstrings + def test_custom_data_descriptor(self): + class Descr: + def __get__(self, obj, cls): + if obj is None: + return self + return 42 + def __set__(self, obj, cls): + 1/0 + class X: + attr = Descr() + + text = pydoc.plain(pydoc.render_doc(X.attr)) + self.assertEqual(self._get_summary_lines(X.attr), "") + + X.attr.__doc__ = 'Custom descriptor' + text = pydoc.plain(pydoc.render_doc(X.attr)) + self.assertEqual(self._get_summary_lines(X.attr), """\ + Custom descriptor +""") + + X.attr.__name__ = 'foo' + text = pydoc.plain(pydoc.render_doc(X.attr)) + self.assertEqual(self._get_summary_lines(X.attr), """\ +foo + Custom descriptor +""") + class PydocServerTest(unittest.TestCase): """Tests for pydoc._start_server""" |