Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
zzzeek opened this issue Jul 20, 2024 · 5 comments
Labels
bug mypy got something wrong crash

Comments

@zzzeek
Copy link

zzzeek commented Jul 20, 2024

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.

@zzzeek zzzeek added the bug mypy got something wrong label Jul 20, 2024
@zzzeek
Copy link
Author

zzzeek commented Jul 20, 2024

if you want to reproduce this, here are the steps:

git clone https://github.com/sqlalchemy/sqlalchemy.git
cd sqlalchemy
tox -e mypy -- test/ext/mypy/test_mypy_plugin_py3k.py -x -s

@mr-c
Copy link
Contributor

mr-c commented Aug 4, 2024

Oof, I wish I saw this before I uploaded mypy 1.11.x to Debian

@zzzeek Do you think this is just a failure of how the tests are run, or do you think this also affects the regular functionality of sqlalchemy? That is to say, would it be safe for the Debian package of sqlalchemy to ignore these tests for now?

@CaselIT
Copy link

CaselIT commented Aug 4, 2024

It's unclear at the moment. No one reported issues for the moment, and the fix for another issue that rendered the plugin unusable is not yet released.

It's likely that the plugin is not used a lot

@ilevkivskyi
Copy link
Member

Most likely this is fixed on latest master. Please feel free to re-open if it's not fixed on master.

@k4nar
Copy link

k4nar commented Aug 12, 2024

I can confirm this is fixed on master, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong crash
Projects
None yet
Development

No branches or pull requests

5 participants