-
-
Notifications
You must be signed in to change notification settings - Fork 675
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
Add mypy to the codebase #1773
Comments
I've never given mypy a proper shot before. The one time I tried it I got a bad impression because I was immediately trying to do something it cannot support (defining a JSON type, which is recursive). It's left me with the impression that it may be a burden trying to appease mypy. Anyway, I am open to trying it. My concern is the type stubs. Do all packages we use have type stubs? Are they all well maintained and up to date? What recourse do we have if something is lacking type stubs or falls out of date? |
To install all the known stubs we can do As for libraries without stubs, we can just not check those libraries by passing We'd also need to use the TLDR; The command I use for mypy on the bot currently is |
What are the benefits of adding mypy to the CI? |
To ensure the code conforms to mypy. We can encourage contributors all we want, but ultimately we have no way to enforce that they run mypy before making commits. However, we do have control over CI, so that's where we can enforce it. |
Of course, that's what adding mypy to the CI does. But why do we want the code to strictly conform to mypy? That was my question |
How do you use mypy? Is there some middle ground between not using it at all and enforcing it in CI? Or are you instead asking why we should be using mypy in any capacity? |
Yes, that's what I'm asking. As you mentioned, mypy isn't perfect, and there are issues like missing/outdated/poor type stubs, which could be an obstacle. Therefore I'm asking what benefits it would bring so we can evaluate the pros vs cons. |
Perhaps we should also evaluate alternative type checkers, like |
An advantage is that it provides type safety, which can catch more errors. A disadvantage is that we cannot be lazy with the type annotations (e.g. the callables for decorators). |
I've actually been briefly looking over some mypy and there's a lot of false positives. Perhaps some of these could be brought down further by using the correct command line arguments but it's certainly annoying as-is. As an example, we get for role_id in role_ids:
if (role := guild.get_role(role_id)) is not None:
members += len(role.members)
else:
raise NonExistentRoleError(role_id)
return {name or role.name.title(): members} The error comes from the The only way I can find to "fix" this is to just ignore all union-attr errors, which then means potentially missing actual issues and sorta defeats the entire purpose of adding mypy. EDIT: I've just been informed that return {name or cast(Role, role).name.title(): members} |
I've started having a look into whether this would be an improvement. So far it's seeming pretty good IMO. Some things I've looked into: Custom convertersCustom converters don't represent the actual type passed to the function async def my_command(self, ctx: Context, argument: URLConverter) -> None:
reveal_type(argument) # URLConverter. uh oh We can fix these using async def my_command(self, ctx: Context, argument: Annotated[str, URLConverter]) -> None:
reveal_type(argument) # str From a quick look it seems discord.py should support this. Defining the annotated versions in Getting channels/roles etc from constantschannel = self.bot.get_channel(Channels.off_topic_0)
channel.send("HI")
I think this is a good thing! Especially in dev it's quite possible that these things are undefined, and the error from that can be quite unclear, so I think it would make sense to change this even if we don't decide to use a type checker. One solution would be to create our own functions that instead error if the channel is Different types of Messageable/ChannelThis is one thing I noticed where I think a type checker would be a big improvement. Discord has added a lot of new channel types recently (threads, forum channels, voice chat), and currently it's really difficult to work out what code needs to be updated to handle those (e.g. the Site API and other external APIsCurrently we just assume responses fit the schema we're expecting to recieve. If we're happy with this assumption we can just type those responses as Other librariesThe main library we rely on is discord.py, which seems to be type hinted pretty well. python-discord/bot-core#134 would be helpful, as currently Should we try and add mypy support?Personally I think having mypy support would be pretty helpful. There are quite a few cases where bugs that have happened would have been caught by a type checker (#2274, #2273, #2260 are recent examples). I wouldn't suggest trying to make a massive PR adding mypy support everywhere at once, that would be a massive task, there's no issue with starting by just enabling it file by file. When I get a chance I'll try modifying a cog or two to pass mypy's checks. That should help us get a proper idea of whether this will be more invasive or helpful. |
Am I correct that |
Yeah (to both things) I just realised we currently use the hacky solution of redefining the converters as the types they convert to under a |
Is there any accepted workaround for when annotations are used for something other than annotating types (such as for us with converters)? Or do type checkers work on the assumption that annotations always correspond to types? |
That's what There is also the |
I'd like to propose that we add mypy to the codebase and add it to our linting workflow.
The initial PR for this would be a large one, fixing the legacy issues, but from then on it'll be picked up before a PR can even be merged.
There are stubs that we can add as dev dependencies for discord.py and any other deps that we find lacking in the type hinting department.
This issue is mostly for planning for now, as I'd like to get more opinions on this change.
The text was updated successfully, but these errors were encountered: