Skip to content

Preconfigured bson converter errors when destructuring class with dictionary field that has a Literal key #629

@jrpat

Description

@jrpat

Using cattrs 24.1.2 and attrs 25.1.0

Repro

from typing import Literal

import attrs
import cattrs.preconf.bson

ThingType = Literal["a", "b"]

@attrs.define
class UserDoc:
    things: dict[ThingType, bool | None]


raw_user = {"things": {"a": True}}

converter = cattrs.preconf.bson.make_converter()
demo = converter.structure(raw_user, UserDoc)

Error

Traceback (most recent call last):
  File "/Users/jrpat/.vscode/extensions/ms-python.python-2025.1.2025022102-darwin-arm64/python_files/python_server.py", line 133, in exec_user_input
    retval = callable_(user_input, user_globals)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 1, in <module>
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/converters.py", line 558, in structure
    return self._structure_func.dispatch(cl)(obj, cl)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/dispatch.py", line 134, in dispatch_without_caching
    res = self._function_dispatch.dispatch(typ)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/dispatch.py", line 76, in dispatch
    return handler(typ)
           ^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/converters.py", line 1290, in gen_structure_attrs_fromdict
    return make_dict_structure_fn(
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/gen/__init__.py", line 772, in make_dict_structure_fn
    return make_dict_structure_fn_from_attrs(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/gen/__init__.py", line 406, in make_dict_structure_fn_from_attrs
    handler = find_structure_handler(
              ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/gen/_shared.py", line 52, in find_structure_handler
    handler = c.get_structure_hook(type, cache_result=False)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/converters.py", line 576, in get_structure_hook
    else self._structure_func.dispatch_without_caching(type)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/dispatch.py", line 134, in dispatch_without_caching
    res = self._function_dispatch.dispatch(typ)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/dispatch.py", line 76, in dispatch
    return handler(typ)
           ^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/converters.py", line 697, in _find_type_alias_structure_hook
    res = self.get_structure_hook(base)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/converters.py", line 574, in get_structure_hook
    self._structure_func.dispatch(type)
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/dispatch.py", line 134, in dispatch_without_caching
    res = self._function_dispatch.dispatch(typ)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/dispatch.py", line 76, in dispatch
    return handler(typ)
           ^^^^^^^^^^^^
  File "/Users/jrpat/example/.venv/lib/python3.12/site-packages/cattrs/preconf/bson.py", line 74, in gen_structure_mapping
    if args and issubclass(args[0], bytes):
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 1 must be a class

Notes

  • This also happens if ThingType is a type alias, eg. type ThingType = … or if inline like things: dict[Literal[…], …]

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions