mitmproxy / mitmproxy/pdoc

Defining a type alias referencing a type imported in a `TYPE_CHECKING` block causes `pdoc` to exit with a `NameError` on the imported type

Open
#821 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
2.5k
Forks
228
PR merge metrics
No merged PRs in 30d

Description

Problem Description

Presence of type alias referencing a type which is imported in an if typing.TYPE_CHECKING block causes pdoc to exit with a NameError on the imported type.

Related I think: #695

Consider the code:

from __future__ import annotations

import typing

import numpy

if typing.TYPE_CHECKING:
    from numpy.typing import NDArray

type Array = NDArray[numpy.float64]

This requires python 3.12 or newer for the type alias, and can be happily imported and used.

Running pdoc over this causes a failure because it does not see the NDArray type:

$ PDOC_ALLOW_EXEC=1 uv run --quiet --locked pdoc -d google -o docs --math foo/
Traceback (most recent call last):
  File "/home/me/pdoc_test/.venv/bin/pdoc", line 10, in <module>
    sys.exit(cli())
             ~~~^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/__main__.py", line 198, in cli
    pdoc.pdoc(
    ~~~~~~~~~^
        *opts.modules,
        ^^^^^^^^^^^^^^
        output_directory=opts.output_directory,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/__init__.py", line 529, in pdoc
    out = render.html_module(module, all_modules)
  File "/home/williamg/.local/share/uv/python/cpython-3.13.1-linux-x86_64-gnu/lib/python3.13/contextlib.py", line 85, in inner
    return func(*args, **kwds)
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/render.py", line 106, in html_module
    return env.get_template("module.html.jinja2").render(
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        module=module,
        ^^^^^^^^^^^^^^
    ...<7 lines>...
        mtime=mtime,
        ^^^^^^^^^^^^
    )
    ^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/jinja2/environment.py", line 1295, in render
    self.environment.handle_exception()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/jinja2/environment.py", line 942, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/module.html.jinja2", line 315, in top-level template code
    {%- if loop.nextitem -%}
    ^^^^^^^^^^^^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/frame.html.jinja2", line 36, in top-level template code
    {% block body %}
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/frame.html.jinja2", line 42, in block 'body'
    {% block content %}{% endblock %}
    ^^^^^^^^^^^^^^^^^^^^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/module.html.jinja2", line 101, in block 'content'
    {% block module_contents %}
    ^^^^^^^^^^^^^^^^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/module.html.jinja2", line 104, in block 'module_contents'
    {{ member(m) }}
    ^^^^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/jinja2/runtime.py", line 784, in _invoke
    rv = self._func(*arguments)
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/module.html.jinja2", line 202, in template
    {{ variable(doc) }}
    ^^^^^^^^^^^^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/jinja2/runtime.py", line 784, in _invoke
    rv = self._func(*arguments)
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/module.html.jinja2", line 181, in template
    <span class="name">{{ var.name }}</span>{{ annotation(var) }}{{ default_value(var) }}
    ^^^^^^^^^^^^^^^^^^^^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/jinja2/runtime.py", line 784, in _invoke
    rv = self._func(*arguments)
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/templates/default/module.html.jinja2", line 149, in template
    {%- if var.default_value_str %}
    ^^^^^^^^^^^^^^^^^^^^^
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/jinja2/environment.py", line 490, in getattr
    return getattr(obj, attribute)
  File "/home/williamg/.local/share/uv/python/cpython-3.13.1-linux-x86_64-gnu/lib/python3.13/functools.py", line 1039, in __get__
    val = self.func(instance)
  File "/home/me/pdoc_test/.venv/lib/python3.13/site-packages/pdoc/doc.py", line 1135, in default_value_str
    formatted = formatannotation(self.default_value.__value__)
                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/me/pdoc_test/foo/foo.py", line 7, in Array
    type Array = NDArray[numpy.float64]
                 ^^^^^^^
NameError: name 'NDArray' is not defined. Did you mean: 'Array'?
Steps to reproduce the behavior:
  1. write a file foo.py containing the code above
  2. run pdoc on the file
System Information
$ uv run pdoc --version
pdoc: 15.0.4
Python: 3.13.1
Platform: Linux-5.15.167.4-microsoft-standard-WSL2-x86_64-with-glibc2.36

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the foo.py reproduction and run the shown pdoc command to confirm the NameError. Trace the failure from pdoc/doc.py's default_value_str through the documented type alias, then verify that pdoc completes and renders the alias without requiring the TYPE_CHECKING-only import at runtime.

Written by the indexing model from the issue text.

Assessment

Tech stack
numpy, python
Domain
documentation
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.