Skip to content

SQLAlchemy plugin has "AssertionError: Synthetic types don't serialize" starting with 1.11.0 - no idea how to fix #17548

Description

@zzzeek

In SQLAlchemy's mypy plugin , we have custom attributes that are serialized, using code that is taken directly from Mypy's own dataclasses plugin:

class SQLAlchemyAttribute:
    def __init__(
        self,
        name: str,
        line: int,
        column: int,
        typ: Optional[Type],
        info: TypeInfo,
    ) -> None:
        self.name = name
        self.line = line
        self.column = column
        self.type = typ
        self.info = info

    def serialize(self) -> JsonDict:
        assert self.type
        return {
            "name": self.name,
            "line": self.line,
            "column": self.column,
            "type": self.type.serialize(),
        }

    # ...

as of mypy 1.11.0 we are getting this stack trace when an UnboundType is serialized:

 File "mypy/api.py", line 71, in run
  File "mypy/api.py", line 58, in _run
  File "mypy/api.py", line 72, in <lambda>
  File "mypy/main.py", line 103, in main
  File "mypy/main.py", line 187, in run_build
  File "mypy/build.py", line 193, in build
  File "mypy/build.py", line 268, in _build
  File "mypy/build.py", line 2950, in dispatch
  File "mypy/build.py", line 3348, in process_graph
  File "mypy/build.py", line 3443, in process_stale_scc
  File "mypy/semanal_main.py", line 93, in semantic_analysis_for_scc
  File "mypy/semanal_main.py", line 220, in process_top_levels
  File "mypy/semanal_main.py", line 349, in semantic_analyze_target
  File "mypy/semanal.py", line 619, in refresh_partial
  File "mypy/semanal.py", line 630, in refresh_top_level
  File "mypy/semanal.py", line 7094, in accept
  File "mypy/errors.py", line 1269, in report_internal_error
  File "mypy/semanal.py", line 7092, in accept
  File "mypy/nodes.py", line 1183, in accept
  File "mypy/semanal.py", line 1700, in visit_class_def
  File "mypy/semanal.py", line 1891, in analyze_class
  File "mypy/semanal.py", line 1925, in analyze_class_body_common
  File "mypy/semanal.py", line 2010, in apply_class_plugin_hooks
  File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/ext/mypy/plugin.py", line 267, in _base_cls_hook
    decl_class.scan_declarative_assignments_and_apply_types(ctx.cls, ctx.api)
  File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/ext/mypy/decl_class.py", line 114, in scan_declarative_assignments_and_apply_types
    util.set_mapped_attributes(info, mapped_attributes)
  File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/ext/mypy/util.py", line 181, in set_mapped_attributes
    [attribute.serialize() for attribute in attributes],
     ^^^^^^^^^^^^^^^^^^^^^
  File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/ext/mypy/util.py", line 77, in serialize
    "type": self.type.serialize(),
            ^^^^^^^^^^^^^^^^^^^^^
  File "mypy/types.py", line 960, in serialize
  File "mypy/types.py", line 2726, in serialize
AssertionError: Synthetic types don't serialize

I looked at mypy's source to see if this was new, however, that assertion seems to be 6 years old.

pdbing, if I come into the place where this happens, the type that fails is:

(Pdb) self.type
List?[Address?]
(Pdb) type(self.type)
<class 'mypy.types.UnboundType'>

When using mypy 1.10.1, this type can be serialized:

(Pdb) self.type
List?[Address?]
(Pdb) type(self.type)
<class 'mypy.types.UnboundType'>
(Pdb) self.type.serialize()
{'.class': 'UnboundType', 'name': 'List', 'args': [{'.class': 'UnboundType', 'name': 'Address', 'args': [], 'expr': 'Address', 'expr_fallback': 'builtins.str'}], 'expr': None, 'expr_fallback': None}

so....I have no idea what to do here. Can this type just do what it used to do? I dont see how this is making things better to just throw an error for a serialization that has no reason it can't be serialized.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongcrash
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions