Skip to content

Cannot combine special types in alternative TypedDict syntax #20401

Description

@alicederyn

Bug Report

mypy is raising an internal error when attempting to combine special types in a TypedDict using the alternative functional syntax.

To Reproduce

from typing import NotRequired, TypedDict
from typing_extensions import ReadOnly

Foo = TypedDict("Foo", {
    "required-field-with-hyphens": ReadOnly[int],
    "optional-field-with-hyphens": NotRequired[ReadOnly[int]],
})

value: Foo = {"required-field-with-hyphens": 1, "optional-field-with-hyphens": 2}

Playground

Expected Behavior

This should pass type-checking. PEP-705 states that

  • The alternative functional syntax for TypedDict also supports the new type qualifier
  • ReadOnly can be used with Required, NotRequired and Annotated, in any nesting order

Actual Behavior

Running this specific snippet with mypy in Python 3.12, I get:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "mypy/checkexpr.py", line 6044, in accept
  File "mypy/types.py", line 3677, in get_proper_type
TypeError: mypy.types.ProperType object expected; got mypy.types.ReadOnlyType

It passes if the second field is removed, so this is just combining special types which is causing the problem; ReadOnly inside the functional syntax by itself is working fine. Additionally, it works fine if using the class-based syntax (though obviously I can't do that as there are hyphens). I can work around the issue by using total=False and inheritance, so it's not a critical blocker,

Additionally, if I remove the last line (value: Foo = ...) from the code, when I run mypy locally, I get the following internal error:

  File "mypy/main.py", line 127, in main
  File "mypy/main.py", line 211, in run_build
  File "mypy/build.py", line 215, in build
  File "mypy/build.py", line 294, in _build
  File "mypy/build.py", line 2945, in dispatch
  File "mypy/build.py", line 3336, in process_graph
  File "mypy/build.py", line 918, in wait_for_done
  File "mypy/build.py", line 3502, in process_stale_scc
  File "mypy/build.py", line 2501, in write_cache
  File "mypy/build.py", line 1601, in write_cache
  File "mypy/nodes.py", line 425, in serialize
  File "mypy/nodes.py", line 4742, in serialize
  File "mypy/nodes.py", line 4631, in serialize
  File "mypy/nodes.py", line 3916, in serialize
  File "mypy/types.py", line 3031, in serialize
  File "mypy/types.py", line 310, in serialize
    if (coro.__class__ is CoroutineType or
NotImplementedError: Cannot serialize ReadOnlyType instance

I can't reproduce this on the playground (I assume because the cache path is disabled).

Your Environment

  • Mypy version used: 1.19.0
  • Python version used: 3.12

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

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions