Skip to content

Commit

Permalink
Make renderText gracefully handle non-str values. Fixes #16
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Aug 9, 2018
1 parent fe2d7f7 commit 6ff4905
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGES.rst
Expand Up @@ -11,6 +11,10 @@
``None``. This can be the case with namespace packages, especially
under Python 3.7. See `issue #17 <https://github.com/zopefoundation/zope.app.apidoc/issues/17>`_.

- Rendering documentation for a class that has a ``__doc__`` property
no longer fails but produces a descriptive message. See `issue 16
<https://github.com/zopefoundation/zope.app.apidoc/issues/16>`_.

- Host documentation at https://zopeappapidoc.readthedocs.io/

- Add argument to ``static-apidoc`` for loading a specific ZCML file. To use this feature, the ZCML file you specify needs to
Expand Down
23 changes: 22 additions & 1 deletion src/zope/app/apidoc/codemodule/browser/tests.py
Expand Up @@ -15,6 +15,7 @@
"""
import unittest
from BTrees import OOBTree

from zope.traversing.api import traverse

Expand Down Expand Up @@ -107,7 +108,7 @@ def testZCMLFileDetailsView(self):
body, '/++apidoc++/Code/zope/app/apidoc/configure.zcml/index.html',
basic='mgr:mgrpw')

from BTrees import OOBTree

class TestClass(unittest.TestCase):

layer = APIDocLayer
Expand All @@ -128,6 +129,26 @@ def test_listClasses_C(self):
info = details._listClasses([items_class])
self.assertIsNone(info[0]['url'], None)

def test_not_fail_with_doc_property(self):
from zope.app.apidoc.codemodule.browser.class_ import ClassDetails
from zope.app.apidoc.codemodule.class_ import Class

# Such as in zope.hookable._py_hookable
class WithProperty(object):
@property
def __doc__(self):
return "Some Docs"

class Parent(object):
def getPath(self):
return '/'

details = ClassDetails()
details.context = Class(Parent(), WithProperty.__name__, WithProperty)

self.assertIn('Failed to render non-text', details.getDoc())


class TestIntrospectorNS(unittest.TestCase):

def _check_namespace(self, kind, context, name):
Expand Down
9 changes: 9 additions & 0 deletions src/zope/app/apidoc/tests.py
Expand Up @@ -236,6 +236,15 @@ def test_keyword_only_arguments(self):
'()',
getFunctionSignature(TestUtilities.test_keyword_only_arguments))

def test_renderText_non_text(self):
# If we pass something that isn't actually text, we get a
# descriptive error back.
from zope.app.apidoc.utilities import renderText

text = renderText(self)
self.assertIn("Failed to render non-text", text)


from zope.app.apidoc import static

class TestStatic(unittest.TestCase):
Expand Down
7 changes: 6 additions & 1 deletion src/zope/app/apidoc/utilities.py
Expand Up @@ -370,6 +370,7 @@ def dedentString(text):


def renderText(text, module=None, format=None, dedent=True):
# dedent is ignored, we always dedent
if not text:
return u''

Expand All @@ -387,7 +388,11 @@ def renderText(text, module=None, format=None, dedent=True):
if isinstance(text, bytes):
text = text.decode('utf-8', 'replace')

text = dedentString(text)
try:
text = dedentString(text)
except TypeError as e:
return u'Failed to render non-text (%r): %s' %(text, e,)

source = createObject(format, text)

renderer = getMultiAdapter((source, TestRequest()))
Expand Down

0 comments on commit 6ff4905

Please sign in to comment.