Skip to content

Incorrect error for unions syntax in comments and strings (Python 3.9) #19722

Closed

Description

@relikd

Bug Report

Minimal example python code is attached below. mypy output is:

main.py:4: error: X | Y syntax for unions requires Python 3.10  [syntax]
main.py:12: error: X | Y syntax for unions requires Python 3.10  [syntax]
Found 2 errors in 1 file (checked 1 source file)

To Reproduce

https://mypy-play.net/?mypy=latest&python=3.9&gist=03da1f2a4b60eb95088e81958066deb5

just in case, here a copy of the gist

#!/usr/bin/env python3
class C3:
    futureDef: 'C2'
    two: 'str|None'


class C2:
    pass


class C1:
    ONE = None  # type: str|None

    def begin(self) -> None:
        C1.ONE = 'a'

Expected Behavior

This file should produce no errors

Actual Behavior

Both errors are incorrect, as both types are provided in a 3.8 safe way (encased in a string or as a comment)

Your Environment

  • Mypy version used: 1.17.1 (latest)
  • Python version used: 3.9

Activity

  1. JawadAliAI commented on Sep 5, 2025

    @JawadAliAI

    Mypy currently raises X | Y syntax for unions requires Python 3.10 when string-quoted type hints include the | operator under Python < 3.10 (e.g., "str | None"). Since these annotations are provided as strings (permitted forward references under PEP 563), they should not be subject to version-specific syntax restrictions. For compatibility with Python 3.9, mypy should treat such cases as plain forward references rather than parsing them with Python 3.10+ rules.

    As a workaround, Optional[str] or Union[str, None] can be used, but the expected behavior is that quoted annotations using | should be accepted without error.

    I would be happy to work on this issue if it is considered valid. Please let me know if I can proceed with a pull request.

  2. relikd commented on Oct 28, 2025

    @relikd
    Author

    Any progress on the issue? I feel sad that people are willing to work on this but no one is giving the go signal.

  3. JelleZijlstra commented on Oct 29, 2025

    @JelleZijlstra
    Member

    The best way to move something like this forward is to submit a PR. Unfortunately maintainer time on mypy is limited, so it may take a while before a maintainer is able to review and merge a PR.

    I would consider this issue valid, but given that Python 3.9 is about to go out of support in about two days, realistically the outcome may well be that mypy drops support for 3.9 before this gets fixed.

  4. relikd commented on Oct 29, 2025

    @relikd
    Author

    Thank you for your insight. I'd understand if that were to happen though it would still be a shame :( macOS (15) is still shipping with 3.9 as default. I know Apple is here to blame, but still it would be nice to use software out of the box.

  5. Avasam commented on May 18, 2026

    @Avasam
    SponsorContributor
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

    bugmypy got something wrongtopic-quoted-annotationsDetecting problems with quoted annotationstopic-runtime-semanticsmypy doesn't model runtime semantics correctly

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions