Skip to content

pdoc trips over unittest.mock.Mock #350

Closed
@Terrance

Description

@Terrance

Expected behavior

I can document classes that include mock object members (for example, when documenting testing utilities).

Actual behavior

Traceback
Traceback (most recent call last):
  File "/usr/bin/pdoc", line 33, in <module>
    sys.exit(load_entry_point('pdoc3', 'console_scripts', 'pdoc')())
  File "/usr/lib/python3.9/site-packages/pdoc/cli.py", line 575, in main
    recursive_write_files(module, ext='.html', **template_config)
  File "/usr/lib/python3.9/site-packages/pdoc/cli.py", line 351, in recursive_write_files
    recursive_write_files(submodule, ext=ext, **kwargs)
  File "/usr/lib/python3.9/site-packages/pdoc/cli.py", line 346, in recursive_write_files
    f.write(m.html(**kwargs))
  File "/usr/lib/python3.9/site-packages/pdoc/__init__.py", line 880, in html
    html = _render_template('/html.mako', module=self, **kwargs)
  File "/usr/lib/python3.9/site-packages/pdoc/__init__.py", line 155, in _render_template
    return t.render(**config).strip()
  File "/usr/lib/python3.9/site-packages/mako/template.py", line 473, in render
    return runtime._render(self, self.callable_, args, data)
  File "/usr/lib/python3.9/site-packages/mako/runtime.py", line 878, in _render
    _render_context(
  File "/usr/lib/python3.9/site-packages/mako/runtime.py", line 920, in _render_context
    _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)
  File "/usr/lib/python3.9/site-packages/mako/runtime.py", line 947, in _exec_template
    callable_(context, *args, **kwargs)
  File "_html_mako", line 143, in render_body
  File "_html_mako", line 45, in show_module
  File "_html_mako", line 500, in render_show_module
  File "_html_mako", line 321, in show_func
  File "/usr/lib/python3.9/site-packages/pdoc/__init__.py", line 1431, in params
    return self._params(self, annotate=annotate, link=link, module=self.module)
  File "/usr/lib/python3.9/site-packages/pdoc/__init__.py", line 1447, in _params
    signature = inspect.signature(doc_obj.obj)
  File "/usr/lib/python3.9/inspect.py", line 3130, in signature
    return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
  File "/usr/lib/python3.9/inspect.py", line 2879, in from_callable
    return _signature_from_callable(obj, sigcls=cls,
  File "/usr/lib/python3.9/inspect.py", line 2330, in _signature_from_callable
    return _signature_from_function(sigcls, obj,
  File "/usr/lib/python3.9/inspect.py", line 2173, in _signature_from_function
    positional = arg_names[:pos_count]
TypeError: 'Mock' object is not subscriptable

A naive solution would be to just not treat mocks as functions:

diff --git a/pdoc/__init__.py b/pdoc/__init__.py
index 0f05b2c..7ac7eb7 100644
--- a/pdoc/__init__.py
+++ b/pdoc/__init__.py
@@ -27,4 +27,5 @@ from typing import (  # noqa: F401
     Optional, Set, Tuple, Type, TypeVar, Union,
 )
+from unittest.mock import Mock
 from warnings import warn

@@ -411,5 +412,5 @@ def _is_public(ident_name):

 def _is_function(obj):
-    return inspect.isroutine(obj) and callable(obj)
+    return inspect.isroutine(obj) and callable(obj) and not isinstance(obj, Mock)

To reproduce

class MockService:

    async def _run(value: int) -> int: ...
    run = AsyncMock(spec=_run, side_effect=lambda value: value + 1)

Additional info

  • pdoc version: 0.10.0 / master

Metadata

Metadata

Assignees

No one assigned

    Labels

    upstreamIssue affects a dependency of ours

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions