Skip to content

[BUG] type unions with pipes not supported #140

@analog-cbarber

Description

@analog-cbarber

I have code that subclasses a class in the bokeh library

from bokeh.application.handlers import Handler
from bokeh.server.server import Server

class ShutdownOnSessionDestroyed(Handler):
    """A bokeh application handler that will shutdown server when last session is closed.

    This is not normally what you want, but can be useful if you just want
    to debug one session or run a bokeh application from a single command
    line invocation.
    """
    def __init__(self, server:Server):
        self.server = server
        super().__init__()

    def modify_document(self, doc):
        pass

    async def on_session_destroyed(self, session_context):
        if len(self.server.get_sessions()) == 0:
            self.server.stop()

    def on_server_unloaded(self, server_context):
        sys.exit(0)

when I try to generate documentation for this using mkdocstrings 0.17 I get the following stack dump:

            Traceback (most recent call last):
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/site-packages/pytkdocs/cli.py", line 205, in main
                output = json.dumps(process_json(line))
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/site-packages/pytkdocs/cli.py", line 114, in process_json
                return process_config(json.loads(json_input))
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/site-packages/pytkdocs/cli.py", line 91, in process_config
                obj = loader.get_object_documentation(path, members)
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/site-packages/pytkdocs/loader.py", line 358, in get_object_documentation
                root_object = self.get_module_documentation(leaf, members)
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/site-packages/pytkdocs/loader.py", line 426, in get_module_documentation
                root_object.add_child(self.get_class_documentation(child_node))
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/site-packages/pytkdocs/loader.py", line 483, in get_class_documentation
                merge(attributes_data, get_class_attributes(parent_class))
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/site-packages/pytkdocs/parsers/attributes.py", line 115, in get_class_attributes
                type_hints = get_type_hints(cls)
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/typing.py", line 981, in get_type_hints
                value = _eval_type(value, base_globals, localns)
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/typing.py", line 263, in _eval_type
                return t._evaluate(globalns, localns)
              File "/Users/cbarber/miniconda3/envs/garpy.panel-dev/lib/python3.7/typing.py", line 467, in _evaluate
                eval(self.__forward_code__, globalns, localns),
              File "<string>", line 1, in <module>
            TypeError: unsupported operand type(s) for |: 'type' and 'NoneType'

One issue here is that the output does not indicate what code caused the problem, so it took a little experimentation
to figure out this came from this particular class.

The actual error is caused by bokeh's use of the new PEP 640 pipe syntax for union types even though their code does
not require python 3.10:

class Handler:
    ''' Provide a mechanism for Bokeh applications to build up new Bokeh
    Documents.

    .. autoclasstoc::

    '''

    _failed: bool
    _error: str | None
    _error_detail: str | None
    _static: str | None

   ...

So strictly speaking bokeh should not be using those declarations but they have decided to do so anyway,
so it would be nice to have a way to work around this without having to resort to building docs in a python 3.10
environment.

Perhaps code that calls get_type_hints should be prepared to catch and reasonably handle TypeErrors
resulting from this kind of thing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions