Title: polymorphic overloads on `list.__add__` and `dict.__or__` lead to divergences in type checkers. · Issue #14283 · python/typeshed · GitHub
Open Graph Title: polymorphic overloads on `list.__add__` and `dict.__or__` lead to divergences in type checkers. · Issue #14283 · python/typeshed
X Title: polymorphic overloads on `list.__add__` and `dict.__or__` lead to divergences in type checkers. · Issue #14283 · python/typeshed
Description: The overloads on list.__add__ lead to divergent behavior between mypy and pyright when doing something as simple as a list concatenation # Overloading looks unnecessary, but is needed to work around complex mypy problems @overload def __...
Open Graph Description: The overloads on list.__add__ lead to divergent behavior between mypy and pyright when doing something as simple as a list concatenation # Overloading looks unnecessary, but is needed to work aroun...
X Description: The overloads on list.__add__ lead to divergent behavior between mypy and pyright when doing something as simple as a list concatenation # Overloading looks unnecessary, but is needed to work aroun...
Opengraph URL: https://github.com/python/typeshed/issues/14283
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"polymorphic overloads on `list.__add__` and `dict.__or__` lead to divergences in type checkers.","articleBody":"The overloads on `list.__add__` lead to divergent behavior between `mypy` and `pyright` when doing something as simple as a list concatenation\n\n```python\n # Overloading looks unnecessary, but is needed to work around complex mypy problems\n @overload\n def __add__(self, value: list[_T], /) -\u003e list[_T]: ...\n @overload\n def __add__(self, value: list[_S], /) -\u003e list[_S | _T]: ...\n```\n\nCode sample in [pyright playground](https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMoCCKcANFGAG4CmIANmAIYAmAUCwMa0MDO3UAMkm4wCAbQAqAXQBcUKAGIoVCAFcuMKnwBGKpLRio%2BtITBZy5AAUo16zM%2BaZVgUAPovmTNwApuVWsDIwGAALGlkAIkFhMSlwsgB6AEooAFoAPihIkxjJcNkQKhgVEBQBbK9E%2B0trOkZWcyhHZzcPN1EAZUkfPwDyELDMqJEO3ITk9MHsiSgAHyhOvKgCopKy6IqqqE2OLl41mAAhCRk5RQB3JBCwFXwa2yZuTabXdyZPFxHu-0D%2BkAiho4LMapDJZYRHcSzea5fKFYqlAEbTYNFGotHojEKKAQRBwTENOYIOAgJBoYL4fGUlEsArUBi0FzwBBULxQYzCUTCEBdZIAajZJk5MG5FSgyXMinZMCF3IxcylMskmMAoOQ0qh0hlMlkCjlcnlQfkK1AwfXi0466VcqHGpVyeWCq1zG0NVW0qj0xmIbUKvWiw2CohwU0NSUB4i2tH23XCiNowAy5Gw3R6tayhmJfXz9umY6LxYo04r0XMC3qMa71e7NV7U1MMwas6IbbnzSXhdaUCa7Q3HZgOxHyxrPcya9FFX6G4Hg1iC5Oi92YxiE2rByn9kc6-yAWPknm14XI3vS%2BiB5Wh9qtxu902dy2TOu206%2B12Lw-e525Cfk9XDznM1vJ82053jKUKzlCL4gKB4bmKqQA), https://mypy-play.net/?mypy=latest\u0026python=3.12\u0026gist=abf6a8834020af17a16bd8cfb44b2f10\n\n```python\nfrom typing import Any, overload\n\nclass ListA[T]: # emulates builtins list\n @overload\n def __add__(self, other: \"ListA[T]\", /) -\u003e \"ListA[T]\": return ListA()\n @overload\n def __add__[S](self, other: \"ListA[S]\", /) -\u003e \"ListA[T | S]\": return ListA()\n \n \nclass ListB[T]: # without overloads\n def __add__[S](self, other: \"ListB[S]\", /) -\u003e \"ListB[T | S]\": return ListB()\n\n # mypy | pyright \nreveal_type( list[str]() + list[str]() ) # list[str] | list[str] ✅️\nreveal_type( list[str]() + list[int]() ) # list[str | int] | list[str | int] ✅️\nreveal_type( list[str]() + list[Any]() ) # list[Any] | list[str] ❌️\n\nreveal_type( ListA[str]() + ListA[str]() ) # ListA[str] | ListA[str] ✅️\nreveal_type( ListA[str]() + ListA[int]() ) # ListA[str | int] | ListA[str | int] ✅️\nreveal_type( ListA[str]() + ListA[Any]() ) # ListA[Any] | ListA[str] ❌️\n\nreveal_type( ListB[str]() + ListB[str]() ) # ListB[str] | ListB[str] ✅️\nreveal_type( ListB[str]() + ListB[int]() ) # ListB[str | int] | ListB[str | int] ✅️\nreveal_type( ListB[str]() + ListB[Any]() ) # ListB[str | Any] | ListB[str | Any] ✅️\n\n```\n\nThis ultimately causes some very annoying type errors when checking wrapper functions in `pyright`.\n\n\u003cdetails\u003e\n\nCode sample in [pyright playground](https://pyright-play.net/?code=GYJw9gtgBALgngBwJYDsDmUkQWEMoCyAhgsugDRQCCKcAUHQMRTACuKAxjEmClAO5IYACygAmKGATdeRADZQiINKwgBTFDADOdACZrgLMGAAUStAC5JAIwBWarpQD0lAFSUpMAIxWtMEFAAvFAAdGEe0mJWqPjBYSEAlFAAtAB8UAByvGpW8QzM-CAkCGoBIkT4wLj8Srpaisr1AG5IRFC6SFx6BkZgAPqFxaVmylZgdg4wlFX9ANY1jVbEpKhoANp%2BIJQ0cAC6SWmZ2RZ0UGdQzMVycFAoavztBkSsctqn5zN98%2Bb1wQDeACJPF4AVYAXd%2BH19MBnq8AQBfKAAH3anRgJk%2B30aCXeZxmIzQblcmIWaC0SQuUABmwBUA4RBQKDA%2BGsakUWi0SDQd10sDAUAQSiI6hgpSpnjEALoQA)\n\n```python\nfrom typing import Mapping, Any\n\n# function with 2 optional arguments\ndef foo(arg: object, /, *, opt1: str = ..., opt2: int = ...) -\u003e None: ...\n\n# wrapper that forwards args via dict\ndef foo_wrapper(arg: object, foo_kwargs: Mapping[str, Any]) -\u003e None:\n # apply new defaults\n foo_kwargs = {\"opt1\": \"new_default\"} | dict(foo_kwargs)\n foo(arg, **foo_kwargs) # \"str\" cannot be assigned to parameter \"opt2\"\n\n```\n\n\u003c/details\u003e\n\nPR #14282 and #14284 show mypy-primer results of simplifying the overloads away from `list.__add__` and `dict.__or__`.\n\n\n\n\n","author":{"url":"https://github.com/randolf-scholz","@type":"Person","name":"randolf-scholz"},"datePublished":"2025-06-16T11:32:09.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/14283/typeshed/issues/14283"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:f290a508-ea39-9482-0426-d75ed061e546 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | D692:8A973:DDDEBF:12EB1C6:6A61A1F3 |
| html-safe-nonce | 251bd05f481efaa179cb7ee38e2fcbd1049d2960f9ba10e5ef88457c61fce150 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJENjkyOjhBOTczOkREREVCRjoxMkVCMUM2OjZBNjFBMUYzIiwidmlzaXRvcl9pZCI6Ijg5NjE3MjE0MjgzNzYzOTYyNzUiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 65b0082e2295033eb89db4273c635b7a8b596527e66ba851a63e62f5d1224f98 |
| hovercard-subject-tag | issue:3149651348 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/typeshed/14283/issue_layout |
| twitter:image | https://opengraph.githubassets.com/3ead5be2d520a155567a8713a840a8e87d71e19144af33d214a570311fd3cd76/python/typeshed/issues/14283 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/3ead5be2d520a155567a8713a840a8e87d71e19144af33d214a570311fd3cd76/python/typeshed/issues/14283 |
| og:image:alt | The overloads on list.__add__ lead to divergent behavior between mypy and pyright when doing something as simple as a list concatenation # Overloading looks unnecessary, but is needed to work aroun... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | randolf-scholz |
| hostname | github.com |
| expected-hostname | github.com |
| None | 6f4633bcf01c1ad14b73fd07dd39ac31d61f3d3c2578ee08ec1792b7b351eeb9 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/typeshed git https://github.com/python/typeshed.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 31696383 |
| octolytics-dimension-repository_nwo | python/typeshed |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 31696383 |
| octolytics-dimension-repository_network_root_nwo | python/typeshed |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | ac296ae7f21856f1f92adbad22f870b6fbb4b907 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width