Skip to content

Conversation

@cdce8p
Copy link
Collaborator

@cdce8p cdce8p commented Dec 13, 2025

This PR deprecates the --force-union-syntax flag and makes it a no-op. It also removes the temporary --overwrite-union-syntax flag which was added to be able to update the mypy test output.

@cdce8p cdce8p added the topic-configuration Configuration files and flags label Dec 13, 2025
@github-actions

This comment has been minimized.

@cdce8p
Copy link
Collaborator Author

cdce8p commented Dec 13, 2025

The primer output is expected since mypy does still support type checking with --python-version 3.9. I do think though that it makes sense to move to a unified output now, even if it's technically a bit early. By now, almost everyone using type hints should have seen the PEP 604 syntax and know what it means.

@cdce8p cdce8p requested a review from sobolevn December 13, 2025 01:58
@github-actions
Copy link
Contributor

Diff from mypy_primer, showing the effect of this PR on open source code:

PyWinCtl (https://github.com/Kalmat/PyWinCtl)
- src/pywinctl/_pywinctl_linux.py:805: error: Returning Any from function declared to return "Optional[int]"  [no-any-return]
+ src/pywinctl/_pywinctl_linux.py:805: error: Returning Any from function declared to return "int | None"  [no-any-return]

manticore (https://github.com/trailofbits/manticore)
- tests/wasm/json2mc.py:103: error: Invalid index type "Optional[int]" for "list[Module]"; expected type "SupportsIndex"  [index]
+ tests/wasm/json2mc.py:103: error: Invalid index type "int | None" for "list[Module]"; expected type "SupportsIndex"  [index]
- tests/wasm/json2mc.py:159: error: Invalid index type "Optional[int]" for "list[Module]"; expected type "SupportsIndex"  [index]
+ tests/wasm/json2mc.py:159: error: Invalid index type "int | None" for "list[Module]"; expected type "SupportsIndex"  [index]
- tests/wasm/json2mc.py:161: error: Invalid index type "Optional[int]" for "list[Module]"; expected type "SupportsIndex"  [index]
+ tests/wasm/json2mc.py:161: error: Invalid index type "int | None" for "list[Module]"; expected type "SupportsIndex"  [index]
- manticore/platforms/linux.py:1767: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:1767: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:1780: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:1780: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:1810: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:1810: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:2340: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:2340: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:3512: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:3512: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:3525: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:3525: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:3560: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:3560: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:3578: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:3578: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:3590: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:3590: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:3668: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:3668: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/platforms/linux.py:3681: error: Unsupported operand type for unary - ("Optional[int]")  [operator]
+ manticore/platforms/linux.py:3681: error: Unsupported operand type for unary - ("int | None")  [operator]
- manticore/native/manticore.py:296: error: Incompatible types in assignment (expression has type "Callable[[Any, Any], Any]", variable has type "Union[Callable[[Any, Any, Any], Any], Callable[[Any, Any, Any, Any], Any]]")  [assignment]
+ manticore/native/manticore.py:296: error: Incompatible types in assignment (expression has type "Callable[[Any, Any], Any]", variable has type "Callable[[Any, Any, Any], Any] | Callable[[Any, Any, Any, Any], Any]")  [assignment]

dragonchain (https://github.com/dragonchain/dragonchain)
- dragonchain/lib/database/redis.py:399:36: error: Argument 2 to "zadd" of "SortedSetCommands" has incompatible type "dict[str, int]"; expected "Mapping[Union[str, bytes], Union[bytes, float, int, str]]"  [arg-type]
+ dragonchain/lib/database/redis.py:399:36: error: Argument 2 to "zadd" of "SortedSetCommands" has incompatible type "dict[str, int]"; expected "Mapping[str | bytes, bytes | float | int | str]"  [arg-type]
- dragonchain/lib/database/redis_utest.py:102:9: error: "Callable[[Union[str, bytes], Union[bytes, float, int, str], Union[float, timedelta, None], Union[float, timedelta, None], bool, bool, bool, bool, Optional[Any], Optional[Any]], Optional[bool]]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:106:9: error: "Callable[[Union[str, bytes], Union[bytes, float, int, str], Union[float, timedelta, None], Union[float, timedelta, None], bool, bool, bool, bool, Optional[Any], Optional[Any]], Optional[bool]]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:102:9: error: "Callable[[str | bytes, bytes | float | int | str, float | timedelta | None, float | timedelta | None, bool, bool, bool, bool, Any | None, Any | None], bool | None]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:106:9: error: "Callable[[str | bytes, bytes | float | int | str, float | timedelta | None, float | timedelta | None, bool, bool, bool, bool, Any | None, Any | None], bool | None]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:110:9: error: "Callable[[Union[str, bytes]], Optional[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:110:9: error: "Callable[[str | bytes], Any | None]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:114:9: error: "def delete(self, *names: Union[str, bytes]) -> int" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:114:9: error: "def delete(self, *names: str | bytes) -> int" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:122:9: error: "def flushall(self, asynchronous: bool = ..., **kwargs: Union[Any, Any]) -> bool" has no attribute "assert_called_once"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:122:9: error: "def flushall(self, asynchronous: bool = ..., **kwargs: Any | Any) -> bool" has no attribute "assert_called_once"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:126:9: error: "def hdel(self, name: Union[str, bytes], *keys: Union[str, bytes]) -> int" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:126:9: error: "def hdel(self, name: str | bytes, *keys: str | bytes) -> int" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:130:9: error: "def lpush(self, name: Union[bytes, float, int, str], *values: Union[bytes, float, int, str]) -> int" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:130:9: error: "def lpush(self, name: bytes | float | int | str, *values: bytes | float | int | str) -> int" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:134:9: error: "def rpush(self, name: Union[bytes, float, int, str], *values: Union[bytes, float, int, str]) -> int" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:134:9: error: "def rpush(self, name: bytes | float | int | str, *values: bytes | float | int | str) -> int" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:138:9: error: "def delete(self, *names: Union[str, bytes]) -> int" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:138:9: error: "def delete(self, *names: str | bytes) -> int" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:150:9: error: "Callable[[Any, Any, Optional[int]], Any]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:150:9: error: "Callable[[Any, Any, int | None], Any]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:154:9: error: "Callable[[Union[str, bytes]], Optional[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:158:9: error: "Callable[[Union[str, bytes], int], Optional[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:162:9: error: "Callable[[Union[str, bytes], Union[bytes, float, int, str], Union[float, timedelta, None], Union[float, timedelta, None], bool, bool, bool, bool, Optional[Any], Optional[Any]], Optional[bool]]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:166:9: error: "Callable[[Union[str, bytes], int, int], bool]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:170:9: error: "Callable[[Union[str, bytes], Union[str, bytes]], Optional[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:174:9: error: "def sadd(self, name: Union[str, bytes], *values: Union[bytes, float, int, str]) -> int" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:178:9: error: "Callable[[Union[str, bytes], Union[bytes, float, int, str]], bool]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:182:9: error: "Callable[[Union[str, bytes]], set[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:154:9: error: "Callable[[str | bytes], Any | None]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:186:9: error: "def srem(self, name: Union[str, bytes], *values: Union[bytes, float, int, str]) -> int" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:190:9: error: "Callable[[Union[str, bytes], int, int], list[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:158:9: error: "Callable[[str | bytes, int], Any | None]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:162:9: error: "Callable[[str | bytes, bytes | float | int | str, float | timedelta | None, float | timedelta | None, bool, bool, bool, bool, Any | None, Any | None], bool | None]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:166:9: error: "Callable[[str | bytes, int, int], bool]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:170:9: error: "Callable[[str | bytes, str | bytes], Any | None]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:174:9: error: "def sadd(self, name: str | bytes, *values: bytes | float | int | str) -> int" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:178:9: error: "Callable[[str | bytes, bytes | float | int | str], bool]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:182:9: error: "Callable[[str | bytes], set[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:186:9: error: "def srem(self, name: str | bytes, *values: bytes | float | int | str) -> int" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:190:9: error: "Callable[[str | bytes, int, int], list[Any]]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:198:9: error: "Callable[[Union[str, bytes]], int]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:198:9: error: "Callable[[str | bytes], int]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:206:9: error: "Callable[[Any, Optional[int]], Any]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:206:9: error: "Callable[[Any, int | None], Any]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:210:9: error: "Callable[[Union[str, bytes]], dict[Any, Any]]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:210:9: error: "Callable[[str | bytes], dict[Any, Any]]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:214:9: error: "Callable[[Union[str, bytes], Union[str, bytes]], bool]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:214:9: error: "Callable[[str | bytes, str | bytes], bool]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/database/redis_utest.py:218:9: error: "Callable[[Union[str, bytes], Mapping[Union[str, bytes], Union[bytes, float, int, str]], bool, bool, bool, bool, Optional[Any], Optional[Any]], int]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/database/redis_utest.py:218:9: error: "Callable[[str | bytes, Mapping[str | bytes, bytes | float | int | str], bool, bool, bool, bool, Any | None, Any | None], int]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/lib/interfaces/storage_utest.py:83:9: error: "Callable[[str, Union[str, bytes], Optional[int], str], bool]" has no attribute "assert_called_once_with"  [attr-defined]
+ dragonchain/lib/interfaces/storage_utest.py:83:9: error: "Callable[[str, str | bytes, int | None, str], bool]" has no attribute "assert_called_once_with"  [attr-defined]
- dragonchain/broadcast_processor/broadcast_functions.py:95:32: error: Item "None" of "Optional[Match[str]]" has no attribute "group"  [union-attr]
+ dragonchain/broadcast_processor/broadcast_functions.py:95:32: error: Item "None" of "Match[str] | None" has no attribute "group"  [union-attr]
- dragonchain/lib/authorization.py:315:19: error: Item "None" of "Optional[Match[str]]" has no attribute "group"  [union-attr]
+ dragonchain/lib/authorization.py:315:19: error: Item "None" of "Match[str] | None" has no attribute "group"  [union-attr]
- dragonchain/lib/authorization.py:317:25: error: Item "None" of "Optional[Match[str]]" has no attribute "group"  [union-attr]
+ dragonchain/lib/authorization.py:317:25: error: Item "None" of "Match[str] | None" has no attribute "group"  [union-attr]
- dragonchain/lib/authorization.py:340:31: error: Item "None" of "Optional[Match[str]]" has no attribute "group"  [union-attr]
+ dragonchain/lib/authorization.py:340:31: error: Item "None" of "Match[str] | None" has no attribute "group"  [union-attr]
- dragonchain/webserver/lib/api_keys_utest.py:48:87: error: Argument "permissions_document" to "create_api_key_v1" has incompatible type "dict[str, str]"; expected "Optional[permissions_doc]"  [arg-type]
+ dragonchain/webserver/lib/api_keys_utest.py:48:87: error: Argument "permissions_document" to "create_api_key_v1" has incompatible type "dict[str, str]"; expected "permissions_doc | None"  [arg-type]
- dragonchain/webserver/lib/api_keys_utest.py:91:59: error: Argument 3 to "update_api_key_v1" has incompatible type "dict[str, str]"; expected "Optional[permissions_doc]"  [arg-type]
+ dragonchain/webserver/lib/api_keys_utest.py:91:59: error: Argument 3 to "update_api_key_v1" has incompatible type "dict[str, str]"; expected "permissions_doc | None"  [arg-type]
- dragonchain/webserver/lib/verifications.py:85:12: error: Incompatible return value type (got "Optional[Any]", expected "str")  [return-value]
+ dragonchain/webserver/lib/verifications.py:85:12: error: Incompatible return value type (got "Any | None", expected "str")  [return-value]
- dragonchain/job_processor/contract_job_utest.py:269:13: error: "Callable[[Union[str, ContractState], str], None]" has no attribute "assert_called_once"  [attr-defined]
+ dragonchain/job_processor/contract_job_utest.py:269:13: error: "Callable[[str | ContractState, str], None]" has no attribute "assert_called_once"  [attr-defined]

@cdce8p cdce8p added the topic-error-reporting How we report errors label Dec 13, 2025
Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just delete the flag, rather than make it not work

@cdce8p
Copy link
Collaborator Author

cdce8p commented Dec 13, 2025

I think we should just delete the flag, rather than make it not work

Ideally yes. Tbh I'm not even sure it's actually used somewhere aside from maybe some mypy plugin tests. Nevertheless it was documented publicly and as such would be breaking setups if we were to remove it at once. Better to make it a noop now and remove it later. That's also how I did it for the related --force-uppercase-builtins flag in #19176.

I think we should add the full removal and cleanup for both of these to the v2 list.

@hauntsaninja
Copy link
Collaborator

hauntsaninja commented Dec 14, 2025

If a user went to the trouble of specifying it, they want that behaviour. In which case this is the change that breaks their setup.

If you want to break this more gently, you should have it raise the warning and not change the behaviour yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic-configuration Configuration files and flags topic-error-reporting How we report errors

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants