-
-
Notifications
You must be signed in to change notification settings - Fork 26
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 inline type hints #167
Conversation
Pull Request Test Coverage Report for Build 233
💛 - Coveralls |
# needed for explicit re-exports | ||
useless-import-alias, | ||
# false positives with generics | ||
unsubscriptable-object |
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.
Thank you for the proposal-- I'm a little hesitant to go full type-hints with trio-websocket.
There are benefits, but they doesn't come for free-- at the cost of more verbose code, more complexity, and more dependencies.
Things like the tedious re-exporting, or having to disable useful pylint checkers, are example downsides. Also, it can be corrected, but it seems unnecessary to type hint variables and args that can be inferred by initialization (max_message_size: int = MAX_MESSAGE_SIZE
, etc.).
May I ask if you're actively using trio-websocket in a project? Also, did this exercise uncover any bugs in the implementation?
(This comment is overall for the PR, but I'll start the thread here.)
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.
May I ask if you're actively using trio-websocket in a project?
Yep! Though I have just gotten by by including those stubs in a folder.
Project is open-source actually: https://github.com/A5rocks/bloom
Also, did this exercise uncover any bugs in the implementation?
As mentioned, I started with a base set of stubs so I didn't find any bugs in my implementation.
There are benefits, but they doesn't come for free-- at the cost of more verbose code, more complexity, and more dependencies.
Yep, although I should be able to just extract the stubs out into .pyi
files (I haven't played with mypy's stubgen
and stubtest
yet), if the downsides are too much.
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 don't know if external pyi files improves much. stubgen
would just provide a starting point, and would have to be manually edited and kept up to date with the source. And it doesn't address some of the complexity issues (typing can get quite complex, such as nested types, async generators, etc.).
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.
Hey, sorry for taking a while to get back, wanted to do this when I felt I had enough time to actually write a decent response.
Since you seem to already know many of the downsides, let me try my hand at listing the upsides of having type hints in the code itself:
- While not the greatest guarantees, making sure to satisfy type hints can help reduce races (why? because type systems want the state to always be there). This doesn't help too much, but I felt it was worth mentioning.
- More up to date than documentation.
One example of this that comes to mind is CloseReason.reason
which was documented as a string but was actually optional.
- Easier to check that they are right than 3rd party stubs
Here's a relevant part of a diff between stubs extracted from trio-websocket now vs the ones I had included in my project mentioned earlier (left is new stubs, right is old stubs)
90c71
< def handshake_headers(self) -> typing.Tuple[typing.Tuple[bytes, bytes], ...]: ...
---
> def handshake_headers(self) -> Tuple[Tuple[str, str], ...]: ...
Also, I had CloseReason.reason
as an non-optional string.
- Should help other projects.
I'll be honest, I had trouble finding a project using code search that used both mypy and trio-websocket.
However, if I only try to get trio-websocket, then I find some stuff like https://github.com/AcckiyGerman/python_trio_websockets_stress_test
Here's what I get as mypy output:
➜ python_trio_websockets_stress_test git:(master) mypy --check-untyped-defs server.py stress-test.py (env: tmp-a92fbb44261cfc4)
Success: no issues found in 2 source files
which isn't great yeah.
If I annotate the function arguments (oops, though check-untyped-defs
should have helped a bit maybe)... then it still doesn't find anything. Perhaps this project was too trivial to check against.
So I invite you to try yourself, but I believe this holds true? (If you want to try against some project of yours that has more complex usage then that would be nice)
I'll definitely rebase soon + try to clean up unnecessary type hints, of course.
.travis.yml
Outdated
- python: 3.5 | ||
env: REQUIREMENTS=requirements-dev-3.5.txt |
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've just merged an existing PR that drops 3.5.
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.
Ah, cool. I won't be able to rebase right now (life catching up), but I will soon-ish!
5b40d83
to
03c2d4b
Compare
I am very sorry I left this out to dry for so long. I'm here to try to push this through, although it may take a bit more work. Here's some reasons why it's useful to have type hints in the library:
It's been a solid couple months so I will have to get re-adjusted to everything, but I'll take a look to see if something can be done about the additional dependencies and I'll bring this up to date. I'd love a re-review (and will be requesting another review after I have done everything I need to) |
I will re-"update" them on 3.6 in a while, but in the meantime have this
trio-websocket is kind of on life support, and I'm the closest thing to a maintainer. When something does come up that needs attention, I can barely get to it. I'd prefer not to include "fighting with the type system" as more obstacles to my future self. There's are a number of areas the library could use improvement if there were time, but I wouldn't rank typing too high-- and in any case there are not enough actual users (of trio-websocket or trio) to warrant the work. I appreciate that you've spent time on this-- but I had mentioned I'm hesitant, and hope I didn't mislead you into investing more time. |
Ah, shame. I was planning on trying to combine wsproto with httpx's (httpcore, really) streams anyways (would support anyio + have less deps for my project that already depends on httpx), just wanted to finish this up in case people wanted it. Thanks for the notice though, yup! PS thanks for the library, I remember struggling with a choice and eventually choosing this one (and being happy due to its testability -- I could just chuck a memory stream at it and it would be in-memory for tests). |
A couple review notes:
Sorry for the large PR, but I wanted to upstream my stubs (and make sure they were right -- after all, this way you yourself can run mypy and find things!)
BTW, if I bump the python version to 3.7 in mypy's configuration, I get all these issues from the wsproto event dataclasses currently ignored:
However, I do not want to fix them (similar to how I just added
TODO
s to things that were Optional and shouldn't be), as that would make the scope of the PR too broad; these could be follow-up changes!Additionally, this might make a potential port to anyio easier since you will know what types to update!