Skip to content

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

Open

Description

@wgmo

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions