mypyc / mypyc

Compile type annotated Python to fast C extensions
1.75k stars 46 forks source link

Incorrect call-arg error when using attrs inheritance #883

Open davfsa opened 3 years ago

davfsa commented 3 years ago

I recently tried using mypyc to speedup our python project, but I encountered this unfixable error that doesn't appear with strict mypy.

(.venv) davfsa@galaxy:~/coding/hikari (task/mypyc) # pip install -r requirements -r speedup-requirements.txt -r dev-requirements
....

(.venv) davfsa@galaxy:~/coding/hikari (task/mypyc) # mypyc -p hikari
hikari/invites.py:222:13: note: Revealed type is "def (*, app: hikari.traits.RESTAware, id: hikari.snowflakes.Snowflake, icon_hash: Union[builtins.str, None], name: builtins.str) -> hikari.guilds.PartialGuild"

hikari/invites.py:224:13: note: Revealed type is "def (*, features: typing.Sequence[Union[hikari.guilds.GuildFeature, builtins.str]], splash_hash: Union[builtins.str, None], banner_hash: Union[builtins.str, None], description: Union[builtins.str, None], verification_level: Union[hikari.guilds.GuildVerificationLevel, builtins.int], vanity_url_code: Union[builtins.str, None], welcome_screen: Union[hikari.guilds.WelcomeScreen, None], nsfw_level: hikari.guilds.GuildNSFWLevel)"

hikari/impl/entity_factory.py: note: In member "_set_invite_attributes" of class "EntityFactoryImpl":
hikari/impl/entity_factory.py:1536:21: error: Unexpected keyword argument "app" for "InviteGuild"  [call-arg]
                guild = invite_models.InviteGuild(
                        ^
hikari/impl/entity_factory.py:1536:21: error: Unexpected keyword argument "id" for "InviteGuild"  [call-arg]
                guild = invite_models.InviteGuild(
                        ^
hikari/impl/entity_factory.py:1536:21: error: Unexpected keyword argument "name" for "InviteGuild"  [call-arg]
                guild = invite_models.InviteGuild(
                        ^
hikari/impl/entity_factory.py:1536:21: error: Unexpected keyword argument "icon_hash" for "InviteGuild"  [call-arg]
                guild = invite_models.InviteGuild(
                        ^

First reveal type is for PartialGuild before the inheritance and the second one is for InviteGuild after the inheritance, note that all the attributes that should be inherited aren't there in the init

The interesting thing about this is that it only happens with this specific class inheritance, no other, and moving the class to a different file temporarily makes it work perfectly.

Code can be found here: https://github.com/davfsa/hikari/tree/69274b58b3c139872d9b051a65aac67dde378b14

I am sorry I haven't been able to provide a more consise example, as I have not been able to figure out what is going on nor reproduce it in any other environment.

Package versions

mypy/mypyc - 0.910 attrs - 21.2.0

pranavrajpal commented 3 years ago

I think the problem here is that the attrs plugin relies on subclasses of attrs classes being processed after any attrs classes they inherit from (we check if any of the base classes have been processed by the attrs plugin at https://github.com/python/mypy/blob/4c90aa42e6a74f127956124aec94f55dbc46a281/mypy/plugins/attrs.py#L371).

That seems to stop being true when compiling with mypyc because of the plugin mypyc uses to put all modules placed in a single mypyc group in the same SCC, because removing that plugin does appear to get rid of these errors.

davfsa commented 3 years ago

Funny thing I found out too, if you try to reveal the type of the class that errors right before it is defined, it reveals the type correctly and works fine (the reveal type prevents it from compiling, as you would expect). Similarly, moving the class definition to any other file works too.