-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Support name mangling #16715
base: master
Are you sure you want to change the base?
Support name mangling #16715
Conversation
for more information, see https://pre-commit.ci
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The first Mypy primer diff was much too long, so I made the very first steps to introduce a flag to avoid the mangling of method parameters. |
This comment has been minimized.
This comment has been minimized.
At least two libraries combine private members with the from typing import TypedDict
class A(TypedDict):
__x: str
A.__required_keys__ # frozenset({'_A__x'}) One can use the alternative syntax to avoid the mangling: B = TypedDict('B', {'__y': str})
B.__required_keys__ # frozenset({'__y'}) |
A preliminary thought on the problems with I need to fix my implementation, and I will try by mangling the strings within class A:
__slots__ = ["__x",]
A.__slots__ # ['__x'] I think Mypy never exposes the strings within class A:
__slots__ = ["__x"]
class B(A):
__slots__ = []
def __init__(self) -> None:
self.__x = 1
b = B() # AttributeError: 'B' object has no attribute '_B__x' |
Mypy also does not protect from the following runtime error: class A:
__slots__, b = ["__x"], None
def __init__(self) -> None:
self.__x = 1
self.__y = 1
A() # AttributeError: 'A' object has no attribute '_A__y' This is neither an everyday pattern nor easily readable. So, for now, I see no reason to complicate the name mangling for such multiple assignments. |
This comment has been minimized.
This comment has been minimized.
The primer differences for speedrun.com_global_scoreboard_webapp let me overthink the case of annotations starting with "__", and there is more trouble than expected. "Normally", Python mangles such annotations: __y = int
class A:
def f(self, x: __y): # NameError: name '_A__y' is not defined
pass However, when using the mechanism introduced in PEP 563, this doesn't seem to be the case: from __future__ import annotations
import typing
__y = int
class A:
def f(self, x: __y):
pass
A.f.__annotations__ # {'x': '__y'}
typing.get_type_hints(A.f, globalns=None, localns=None) # {'x': <class 'int'>} The same when using strings: import typing
__y = int
class A:
def f(self, x: "__y"):
pass
A.f.__annotations__ # {'x': '__y'} # {'x': "'__y'"}
typing.get_type_hints(A.f, globalns=None, localns=None) # {'x': <class 'int'>} No idea what PEP 649 will bring. |
…tations` statements
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
… import annotations` statements
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There were some additional error messages for Tanjun, which were due to the (numerous) uses of private identifiers in the stub files of the underlying Hikari library. A section from a relevant file: class UndefinedType(__enum.Enum):
def __bool__(self) -> __Literal[False]: ...
UNDEFINED = __enum.auto() This would never work at runtime because |
I need to have a deeper look at all this, but just wondering why |
I think the remaining differences are okay for now. Most are due to the extended suggestion mechanism. The The issue of mangled keywords in typed dictionaries is unfortunate, but to not mangle them seems like an inconsistency and unnecessary complication. Of course, I am open to other opinions. The issues of handling "private" method parameters and annotations are likely the most debatable. |
This comment has been minimized.
This comment has been minimized.
I did not investigate the reason for introducing Do you suggest using mangled versions of |
This comment has been minimized.
This comment has been minimized.
I tried it, and, according to the test suite and the Mypy primer, it works, and it removes many branches that are not required anymore. The only introduced hack is a |
This comment has been minimized.
This comment has been minimized.
What I'm saying is that this symbol has a dunder on one side exactly so it becomes private to a class and not overridden in derived classes. For example, if A is base and B is derived, and both are attrs classes, then there's |
@ikonst: If other plugins introduce non-mangled private attribute names, we might have to revive |
# Conflicts: # mypy/typeanal.py
Diff from mypy_primer, showing the effect of this PR on open source code: comtypes (https://github.com/enthought/comtypes)
+ comtypes/automation.py:163: error: Name "U_VARIANT1.__tagVARIANT.U_VARIANT2" is not defined [name-defined]
+ comtypes/__init__.py:828: error: "IUnknown" has no attribute "_IUnknown__com_QueryInterface"; maybe "_IUnknown_Base__com_QueryInterface"? [attr-defined]
+ comtypes/__init__.py:838: error: "IUnknown" has no attribute "_IUnknown__com_AddRef"; maybe "_IUnknown_Base__com_AddRef"? [attr-defined]
+ comtypes/__init__.py:842: error: "IUnknown" has no attribute "_IUnknown__com_Release"; maybe "_IUnknown_Base__com_Release"? [attr-defined]
dragonchain (https://github.com/dragonchain/dragonchain)
- dragonchain/lib/authorization_utest.py:35:13: error: "TestAuthorization" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/authorization_utest.py:35:13: error: "TestAuthorization" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
- dragonchain/lib/dto/models_utest.py:185:9: error: "TestSmartContract" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/dto/models_utest.py:185:9: error: "TestSmartContract" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
- dragonchain/lib/dto/models_utest.py:204:9: error: "TestSmartContract" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/dto/models_utest.py:204:9: error: "TestSmartContract" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
- dragonchain/lib/dto/bnb_utest.py:42:13: error: "TestBinanceMethods" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/dto/bnb_utest.py:42:13: error: "TestBinanceMethods" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
steam.py (https://github.com/Gobot1234/steam.py)
- steam/ext/csgo/state.py:216: error: "ClientUser" has no attribute "_profile_info_msg" [attr-defined]
+ steam/ext/csgo/state.py:216: error: "ClientUser" has no attribute "_profile_info_msg"; maybe "profile_info"? [attr-defined]
antidote (https://github.com/Finistere/antidote)
+ src/antidote/core/_catalog.py:541: error: Name "_CatalogOverrideImpl__dependency" is not defined [name-defined]
+ src/antidote/core/_catalog.py:542: error: Name "_CatalogOverrideImpl__dependency" is not defined [name-defined]
+ src/antidote/core/_catalog.py:543: error: Name "_CatalogOverrideImpl__dependency" is not defined [name-defined]
+ src/antidote/lib/interface_ext/_interface.py:487: error: Name "_ImplementsImpl__existing_implementation" is not defined [name-defined]
+ src/antidote/lib/interface_ext/_interface.py:493: error: Name "_ImplementsImpl__existing_implementation" is not defined [name-defined]
+ tests/core/test_wiring.py:152: error: Unused "type: ignore" comment [unused-ignore]
prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/deployments/runner.py:550: error: "Flow[Any, Any]" has no attribute "__name__" [attr-defined]
+ src/prefect/deployments/runner.py:550: error: "Flow[Any, Any]" has no attribute "__name__"; maybe "__ne__" or "__new__"? [attr-defined]
- src/prefect/server/models/block_registration.py:137: error: "SessionTransaction" has no attribute "__aenter__" [attr-defined]
+ src/prefect/server/models/block_registration.py:137: error: "SessionTransaction" has no attribute "__aenter__"; maybe "__enter__"? [attr-defined]
- src/prefect/server/models/block_registration.py:137: error: "SessionTransaction" has no attribute "__aexit__" [attr-defined]
+ src/prefect/server/models/block_registration.py:137: error: "SessionTransaction" has no attribute "__aexit__"; maybe "__exit__"? [attr-defined]
- src/prefect/server/models/block_registration.py:159: error: "SessionTransaction" has no attribute "__aenter__" [attr-defined]
+ src/prefect/server/models/block_registration.py:159: error: "SessionTransaction" has no attribute "__aenter__"; maybe "__enter__"? [attr-defined]
- src/prefect/server/models/block_registration.py:159: error: "SessionTransaction" has no attribute "__aexit__" [attr-defined]
+ src/prefect/server/models/block_registration.py:159: error: "SessionTransaction" has no attribute "__aexit__"; maybe "__exit__"? [attr-defined]
- src/prefect/server/database/interface.py:116: error: "Coroutine[Any, Any, Any]" has no attribute "__aexit__" [attr-defined]
+ src/prefect/server/database/interface.py:116: error: "Coroutine[Any, Any, Any]" has no attribute "__aexit__"; maybe "__await__"? [attr-defined]
apprise (https://github.com/caronc/apprise)
- test/helpers/rest.py:72: error: Need type annotation for "__tests" (hint: "__tests: list[<type>] = ...") [var-annotated]
+ test/helpers/rest.py:72: error: Need type annotation for "_AppriseURLTester__tests" (hint: "_AppriseURLTester__tests: list[<type>] = ...") [var-annotated]
- apprise/plugins/NotifyTelegram.py:205: error: Need type annotation for "__telegram_escape_html_entries" [var-annotated]
+ apprise/plugins/NotifyTelegram.py:205: error: Need type annotation for "_NotifyTelegram__telegram_escape_html_entries" [var-annotated]
graphql-core (https://github.com/graphql-python/graphql-core)
+ src/graphql/utilities/build_client_schema.py:80: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:676: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:678: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:700: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:702: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:717: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:730: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:750: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:772: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:789: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:811: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:833: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:857: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:881: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:905: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:926: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:947: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:964: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:968: error: Unused "type: ignore" comment [unused-ignore]
+ tests/utilities/test_build_client_schema.py:979: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:983: error: Unused "type: ignore" comment [unused-ignore]
+ tests/utilities/test_build_client_schema.py:1060: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:1090: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
schemathesis (https://github.com/schemathesis/schemathesis)
+ src/schemathesis/runner/impl/core.py: note: In function "_generate_events":
+ src/schemathesis/runner/impl/core.py:142: error: No binding for nonlocal "__probes" found [misc]
+ src/schemathesis/runner/impl/core.py:154: error: No binding for nonlocal "__analysis" found [misc]
+ src/schemathesis/runner/impl/core.py:154: error: No binding for nonlocal "__probes" found [misc]
+ src/schemathesis/runner/impl/core.py:164: error: Incompatible types in assignment (expression has type "Err[Exception]", variable has type "Ok[Union[AnalysisSuccess, AnalysisError]]") [assignment]
PyGithub (https://github.com/PyGithub/PyGithub)
+ github/GithubObject.py:448: error: Unused "type: ignore" comment [unused-ignore]
ibis (https://github.com/ibis-project/ibis)
- ibis/common/graph.py:255: error: "Node" has no attribute "__iter__" (not iterable) [attr-defined]
+ ibis/common/graph.py:255: error: "Node" has no attribute "__iter__"; maybe "__dir__" or "__str__"? (not iterable) [attr-defined]
- ibis/expr/datatypes/cast.py:119: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/datatypes/cast.py:119: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
- ibis/expr/types/structs.py:147: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/types/structs.py:147: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
- ibis/expr/types/structs.py:270: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/types/structs.py:270: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
- ibis/expr/types/structs.py:387: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/types/structs.py:387: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
discord.py (https://github.com/Rapptz/discord.py)
- discord/shard.py:354: error: Need type annotation for "__shards" (hint: "__shards: dict[<type>, <type>] = ...") [var-annotated]
+ discord/shard.py:354: error: Need type annotation for "_AutoShardedClient__shards" (hint: "_AutoShardedClient__shards: dict[<type>, <type>] = ...") [var-annotated]
- discord/shard.py:453: error: Need type annotation for "__queue" [var-annotated]
+ discord/shard.py:453: error: Need type annotation for "_AutoShardedClient__queue" [var-annotated]
+ discord/interactions.py:177: error: Unused "type: ignore" comment [unused-ignore]
+ discord/webhook/async_.py:1222: error: Unused "type: ignore" comment [unused-ignore]
+ discord/webhook/async_.py:1287: error: Unused "type: ignore" comment [unused-ignore]
+ discord/webhook/async_.py:1325: error: Unused "type: ignore" comment [unused-ignore]
hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
+ src/hydra_zen/wrapper/_implementations.py:961: error: Missing key "_StoreCallSig__kw" for TypedDict "_StoreCallSig" [typeddict-item]
+ src/hydra_zen/wrapper/_implementations.py:961: error: Extra key "__kw" for TypedDict "_StoreCallSig" [typeddict-unknown-key]
+ src/hydra_zen/wrapper/_implementations.py:1546: error: TypedDict "_StoreCallSig" has no key "__kw" [typeddict-unknown-key]
+ src/hydra_zen/wrapper/_implementations.py:1547: error: TypedDict "_StoreCallSig" has no key "__kw" [typeddict-item]
+ src/hydra_zen/wrapper/_implementations.py:1589: error: TypedDict "_StoreCallSig" has no key "__kw" [typeddict-item]
|
Shortly after starting this pull request, @srittau opened python/typeshed#11237, and @hauntsaninja seems to have implemented most of it. Thanks! So, prefixing parameters with two underscores to indicate privateness seems history. Should I then set the |
|
Diff from mypy_primer, showing the effect of this PR on open source code: setuptools (https://github.com/pypa/setuptools)
+ pkg_resources/__init__.py:3412: error: Attribute "_DistInfoDistribution__dep_map" already defined on line 3407 [no-redef]
psycopg (https://github.com/psycopg/psycopg)
- tests/dbapi20_tpc.py:36: error: "TwoPhaseCommitTests" has no attribute "assertEquals" [attr-defined]
+ tests/dbapi20_tpc.py:36: error: "TwoPhaseCommitTests" has no attribute "assertEquals"; maybe "assertEqual" or "assertFalse"? [attr-defined]
- tests/dbapi20_tpc.py:37: error: "TwoPhaseCommitTests" has no attribute "assertEquals" [attr-defined]
+ tests/dbapi20_tpc.py:37: error: "TwoPhaseCommitTests" has no attribute "assertEquals"; maybe "assertEqual" or "assertFalse"? [attr-defined]
- tests/dbapi20_tpc.py:38: error: "TwoPhaseCommitTests" has no attribute "assertEquals" [attr-defined]
+ tests/dbapi20_tpc.py:38: error: "TwoPhaseCommitTests" has no attribute "assertEquals"; maybe "assertEqual" or "assertFalse"? [attr-defined]
- tests/dbapi20_tpc.py:42: error: "TwoPhaseCommitTests" has no attribute "assertEquals" [attr-defined]
+ tests/dbapi20_tpc.py:42: error: "TwoPhaseCommitTests" has no attribute "assertEquals"; maybe "assertEqual" or "assertFalse"? [attr-defined]
- tests/dbapi20_tpc.py:44: error: "TwoPhaseCommitTests" has no attribute "assertEquals" [attr-defined]
+ tests/dbapi20_tpc.py:44: error: "TwoPhaseCommitTests" has no attribute "assertEquals"; maybe "assertEqual" or "assertFalse"? [attr-defined]
prefect (https://github.com/PrefectHQ/prefect)
- src/prefect/server/database/interface.py:112: error: "Coroutine[Any, Any, Any]" has no attribute "__aexit__" [attr-defined]
+ src/prefect/server/database/interface.py:112: error: "Coroutine[Any, Any, Any]" has no attribute "__aexit__"; maybe "__await__"? [attr-defined]
- src/prefect/deployments/runner.py:538: error: "Flow[Any, Any]" has no attribute "__name__" [attr-defined]
+ src/prefect/deployments/runner.py:538: error: "Flow[Any, Any]" has no attribute "__name__"; maybe "__ne__" or "__new__"? [attr-defined]
colour (https://github.com/colour-science/colour)
- colour/plotting/common.py:828: error: "Patch" has no attribute "get_width"; maybe "get_linewidth"? [attr-defined]
+ colour/plotting/common.py:828: error: "Patch" has no attribute "get_width" [attr-defined]
- colour/plotting/common.py:834: error: "Patch" has no attribute "get_width"; maybe "get_linewidth"? [attr-defined]
+ colour/plotting/common.py:834: error: "Patch" has no attribute "get_width" [attr-defined]
comtypes (https://github.com/enthought/comtypes)
+ comtypes/automation.py:153: error: Name "U_VARIANT1.__tagVARIANT.U_VARIANT2" is not defined [name-defined]
hydra-zen (https://github.com/mit-ll-responsible-ai/hydra-zen)
+ src/hydra_zen/wrapper/_implementations.py:994: error: Missing key "_StoreCallSig__kw" for TypedDict "_StoreCallSig" [typeddict-item]
+ src/hydra_zen/wrapper/_implementations.py:994: error: Extra key "__kw" for TypedDict "_StoreCallSig" [typeddict-unknown-key]
+ src/hydra_zen/wrapper/_implementations.py:1579: error: TypedDict "_StoreCallSig" has no key "__kw" [typeddict-unknown-key]
+ src/hydra_zen/wrapper/_implementations.py:1580: error: TypedDict "_StoreCallSig" has no key "__kw" [typeddict-item]
+ src/hydra_zen/wrapper/_implementations.py:1622: error: TypedDict "_StoreCallSig" has no key "__kw" [typeddict-item]
dragonchain (https://github.com/dragonchain/dragonchain)
- dragonchain/lib/authorization_utest.py:35:13: error: "TestAuthorization" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/authorization_utest.py:35:13: error: "TestAuthorization" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
- dragonchain/lib/dto/models_utest.py:185:9: error: "TestSmartContract" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/dto/models_utest.py:185:9: error: "TestSmartContract" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
- dragonchain/lib/dto/models_utest.py:204:9: error: "TestSmartContract" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/dto/models_utest.py:204:9: error: "TestSmartContract" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
- dragonchain/lib/dto/bnb_utest.py:42:13: error: "TestBinanceMethods" has no attribute "assertFail" [attr-defined]
+ dragonchain/lib/dto/bnb_utest.py:42:13: error: "TestBinanceMethods" has no attribute "assertFail"; maybe "assertFalse" or "assertEqual"? [attr-defined]
PyGithub (https://github.com/PyGithub/PyGithub)
+ github/GithubObject.py:530: error: Unused "type: ignore" comment [unused-ignore]
steam.py (https://github.com/Gobot1234/steam.py)
- steam/ext/csgo/state.py:220: error: "ClientUser" has no attribute "_profile_info_msg" [attr-defined]
+ steam/ext/csgo/state.py:220: error: "ClientUser" has no attribute "_profile_info_msg"; maybe "profile_info"? [attr-defined]
discord.py (https://github.com/Rapptz/discord.py)
- discord/shard.py:354: error: Need type annotation for "__shards" (hint: "__shards: dict[<type>, <type>] = ...") [var-annotated]
+ discord/shard.py:354: error: Need type annotation for "_AutoShardedClient__shards" (hint: "_AutoShardedClient__shards: dict[<type>, <type>] = ...") [var-annotated]
- discord/shard.py:453: error: Need type annotation for "__queue" [var-annotated]
+ discord/shard.py:453: error: Need type annotation for "_AutoShardedClient__queue" [var-annotated]
+ discord/interactions.py:186: error: Unused "type: ignore" comment [unused-ignore]
+ discord/webhook/async_.py:1226: error: Unused "type: ignore" comment [unused-ignore]
+ discord/webhook/async_.py:1291: error: Unused "type: ignore" comment [unused-ignore]
+ discord/webhook/async_.py:1329: error: Unused "type: ignore" comment [unused-ignore]
ibis (https://github.com/ibis-project/ibis)
- ibis/common/graph.py:299: error: "Node" has no attribute "__iter__" (not iterable) [attr-defined]
+ ibis/common/graph.py:299: error: "Node" has no attribute "__iter__"; maybe "__dir__" or "__str__"? (not iterable) [attr-defined]
- ibis/common/graph.py:514: error: "Node" has no attribute "__iter__" (not iterable) [attr-defined]
+ ibis/common/graph.py:514: error: "Node" has no attribute "__iter__"; maybe "__dir__" or "__str__"? (not iterable) [attr-defined]
- ibis/expr/datatypes/cast.py:120: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/datatypes/cast.py:120: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
- ibis/expr/types/structs.py:152: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/types/structs.py:152: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
- ibis/expr/types/structs.py:275: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/types/structs.py:275: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
- ibis/expr/types/structs.py:393: error: "DataType" has no attribute "names"; maybe "name"? [attr-defined]
+ ibis/expr/types/structs.py:393: error: "DataType" has no attribute "names"; maybe "name" or "argnames"? [attr-defined]
core (https://github.com/home-assistant/core)
+ homeassistant/components/onkyo/const.py:129: error: Unsupported target for indexed assignment ("InputSource") [index]
+ homeassistant/components/onkyo/const.py:136: error: Returning Any from function declared to return "Self" [no-any-return]
+ homeassistant/components/onkyo/const.py:136: error: Value of type "InputSource" is not indexable [index]
+ homeassistant/components/sun/entity.py:128: error: Unused "type: ignore" comment [unused-ignore]
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: error: Signature of "_EntityDescription__mypy-replace" incompatible with supertype "EntityDescription" [override]
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: Superclass:
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: def _EntityDescription__mypy-replace(*, key: str = ..., device_class: str | None = ..., entity_category: EntityCategory | None = ..., entity_registry_enabled_default: bool = ..., entity_registry_visible_default: bool = ..., force_update: bool = ..., icon: str | None = ..., has_entity_name: bool = ..., name: str | UndefinedType | None = ..., translation_key: str | None = ..., translation_placeholders: Mapping[str, str] | None = ..., unit_of_measurement: str | None = ...) -> None
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: Subclass:
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: def _EntityDescription__mypy-replace(*, is_on: Callable[..., Any] = ..., key: str = ..., device_class: BinarySensorDeviceClass | None = ..., entity_category: EntityCategory | None = ..., entity_registry_enabled_default: bool = ..., entity_registry_visible_default: bool = ..., force_update: bool = ..., icon: str | None = ..., has_entity_name: bool = ..., name: str | UndefinedType | None = ..., translation_key: str | None = ..., translation_placeholders: Mapping[str, str] | None = ..., unit_of_measurement: str | None = ...) -> None
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: Superclass:
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: def _EntityDescription__mypy-replace(*, key: str = ..., device_class: str | None = ..., entity_category: EntityCategory | None = ..., entity_registry_enabled_default: bool = ..., entity_registry_visible_default: bool = ..., force_update: bool = ..., icon: str | None = ..., has_entity_name: bool = ..., name: str | UndefinedType | None = ..., translation_key: str | None = ..., translation_placeholders: Mapping[str, str] | None = ..., unit_of_measurement: str | None = ...) -> None
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: Subclass:
+ homeassistant/components/fjaraskupan/binary_sensor.py:27: note: def _EntityDescription__mypy-replace(*, key: str = ..., device_class: BinarySensorDeviceClass | None = ..., entity_category: EntityCategory | None = ..., entity_registry_enabled_default: bool = ..., entity_registry_visible_default: bool = ..., force_update: bool = ..., icon: str | None = ..., has_entity_name: bool = ..., name: str | UndefinedType | None = ..., translation_key: str | None = ..., translation_placeholders: Mapping[str, str] | None = ..., unit_of_measurement: str | None = ..., is_on: Callable[..., Any] = ...) -> None
apprise (https://github.com/caronc/apprise)
- apprise/plugins/telegram.py:238: error: Need type annotation for "__telegram_escape_html_entries" [var-annotated]
+ apprise/plugins/telegram.py:238: error: Need type annotation for "_NotifyTelegram__telegram_escape_html_entries" [var-annotated]
- test/helpers/rest.py:73: error: Need type annotation for "__tests" (hint: "__tests: list[<type>] = ...") [var-annotated]
+ test/helpers/rest.py:73: error: Need type annotation for "_AppriseURLTester__tests" (hint: "_AppriseURLTester__tests: list[<type>] = ...") [var-annotated]
graphql-core (https://github.com/graphql-python/graphql-core)
+ src/graphql/utilities/build_client_schema.py:82: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:677: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:679: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:701: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:703: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:718: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:731: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:751: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:773: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:790: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:812: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:834: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:858: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:882: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:906: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:927: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:948: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:965: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:969: error: Unused "type: ignore" comment [unused-ignore]
+ tests/utilities/test_build_client_schema.py:980: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:984: error: Unused "type: ignore" comment [unused-ignore]
+ tests/utilities/test_build_client_schema.py:1061: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
+ tests/utilities/test_build_client_schema.py:1091: error: TypedDict "IntrospectionQuery" has no key "__schema" [typeddict-item]
schemathesis (https://github.com/schemathesis/schemathesis)
+ src/schemathesis/runner/impl/core.py: note: In function "_generate_events":
+ src/schemathesis/runner/impl/core.py:169: error: No binding for nonlocal "__probes" found [misc]
+ src/schemathesis/runner/impl/core.py:181: error: No binding for nonlocal "__analysis" found [misc]
+ src/schemathesis/runner/impl/core.py:181: error: No binding for nonlocal "__probes" found [misc]
+ src/schemathesis/runner/impl/core.py:191: error: Incompatible types in assignment (expression has type "Err[Exception]", variable has type "Ok[Union[AnalysisSuccess, AnalysisError]]") [assignment]
antidote (https://github.com/Finistere/antidote)
+ src/antidote/core/_catalog.py:541: error: Name "_CatalogOverrideImpl__dependency" is not defined [name-defined]
+ src/antidote/core/_catalog.py:542: error: Name "_CatalogOverrideImpl__dependency" is not defined [name-defined]
+ src/antidote/core/_catalog.py:543: error: Name "_CatalogOverrideImpl__dependency" is not defined [name-defined]
+ src/antidote/lib/interface_ext/_interface.py:487: error: Name "_ImplementsImpl__existing_implementation" is not defined [name-defined]
+ src/antidote/lib/interface_ext/_interface.py:493: error: Name "_ImplementsImpl__existing_implementation" is not defined [name-defined]
+ tests/core/test_wiring.py:152: error: Unused "type: ignore" comment [unused-ignore]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally feel like name mangling should not be supported and mangled names should stay private and filtered as such. People accessing symbols such as _Foo__bar
should not be able to do that in Mypy.
@@ -2994,7 +2994,7 @@ from typing import TypeVar, Protocol, Generic, Optional | |||
T = TypeVar('T') | |||
|
|||
class F(Protocol[T]): | |||
def __call__(self, __x: T) -> T: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally don't think these should be renamed. These also work fine with inspect.signature
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what you mean:
>>> import inspect
>>> class C:
... def f(self, __x: int) -> str: ...
>>> print(inspect.signature(C.f))
(self, _C__x: int) -> str
>>> print(inspect.signature(C().f))
(_C__x: int) -> str
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wow, sorry that was really my bad.
General topic "type vs. style checker". If this needs further discussion, probably better in #8267? |
Fixes #8267
After some playing around, I found it cleaner to separate the name mangling from the type-checking logic and to modify the abstract syntax trees of all class definitions instead, for which I implemented the node transformer
NameMangler
.NameMangler
is simpler than I expected because Python's mangling routine is coarser than I knew. Two runtime error examples. The first one shows why I adjusted thetestSelfTypeReallyTrickyExample
test case:The second example shows that Python does not only suggest the "direct" fields of a type but also those of its ancestors. I extended the suggestion algorithm of method
MessageBuilder.has_no_attr
accordingly so that Mypy's error messages should be equally easy to understand:I hoped I could remove function
is_private
and all its usages because, during type checking, all__attr
field names should already be mangled to_class__attr
. Unfortunately, Mypy introduces some special names for internal reasons. My first idea was to replaceis_private(str)
withnot str.isidentifier()
to filter out names like__mypy-replace
and__mypy-post_init
. But then I encountered<lambda>
, which neither looks private nor like a valid identifier. As I am not aware if there are similar pitfalls (not covered by the test suites), I decided to leaveis_private
as is but added a note.A case where
is_private
does not work is covered by thetestFinalWithPrivateAssignment
. One can only subclass an enumeration if all its members are private. As a surrogate, methodTypeChecker.is_final_enum_value
now checks if the member's name looks mangled.The possibly most controversial change is that one cannot prepend double underscores to mark method parameters as positional-only. This change seems to comply with a decision mentioned in PEP 570, but it may affect too many libraries. On the contrary, when not accepting double underscores as positional-only markers in methods, one should likely do the same for pure functions.
After writing the last paragraph, I realised that even stubs like
builtins.pyi
rely on the double underscore style. So, now it's clear this is something one should not change ad hoc. But I leave it for a first discussion and to see the results of the Mypy primer.