- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 371
 
Permit referring to some generic types in generic ways #908
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
Conversation
Specifically, declare `SendChannel`, `ReceiveChannel`, `Listener`, and `RunVar` to be generic in one type parameter, and also support the `open_memory_channel[T](bufsize)` syntax at runtime. Until trio is able to support typing directly, this change allows users of external stubs to use correctly-typed channels without too many hacks.
          Codecov Report
 @@            Coverage Diff             @@
##           master     #908      +/-   ##
==========================================
- Coverage    99.4%   99.36%   -0.04%     
==========================================
  Files         102      102              
  Lines       12679    12707      +28     
  Branches      926      927       +1     
==========================================
+ Hits        12603    12626      +23     
- Misses         56       60       +4     
- Partials       20       21       +1
  | 
    
          Codecov Report
 @@            Coverage Diff            @@
##           master    #908      +/-   ##
=========================================
+ Coverage    99.4%   99.4%   +<.01%     
=========================================
  Files         102     102              
  Lines       12681   12715      +34     
  Branches      927     927              
=========================================
+ Hits        12605   12639      +34     
  Misses         56      56              
  Partials       20      20
  | 
    
| 
           What's the advantage of keeping the actual stubs out of trio here? Oh, I see the force-push. We gotta fix sphinxcontrib-trio to handle these better...  | 
    
| 
           Putting the type hints in trio currently has limited utility because in the absence of stubs mypy chokes when you try to  More context here: I'm working on a   | 
    
| 
           Looks like 3.5.0 doesn't support instantiating generic slots classes. :-( I'll remove the RunVar genericization because it's much less usability-relevant than the others: not many people create RunVars, and no one inherits from them so the workaround is just quotes rather than some elaborate   | 
    
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 wrote a few comments. They're mostly "thoughts that occurred to me while reading" than "critique". Overall it seems fine, and moves us incrementally in a good direction, so feel free to take them or leave them :-)
| 
               | 
          ||
| # The type of object produced by a Listener (covariant plus must be | ||
| # an AsyncResource) | ||
| T_resource = TypeVar("T_resource", bound=AsyncResource, covariant=True) | 
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 think the bound=AsyncResource will disappear when we fix #636. We could start skipping it now, or we could put it in and then take it out later, doesn't make much difference IMO.
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.
You think we'll have Listeners that provide objects not representable as an AsyncResource? I'm a bit surprised at that, can you give an example?
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 have an example in mind. But the reason we restrict it to AsyncResource right now is because serve_listeners automatically closes the object after the handler returns: 
trio/trio/_highlevel_serve_listeners.py
Lines 25 to 29 in 0a815a0
| async def _run_handler(stream, handler): | |
| try: | |
| await handler(stream) | |
| finally: | |
| await trio.aclose_forcefully(stream) | 
With #636, this code goes away, because the Listener itself is responsible for managing the handler lifetime. So... at that point it's really between the person developing a Listener[X] and their users, what kind of API X should support :-).
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, that makes sense! I think it's probably sensible to keep the AsyncResource bound for now, since it reflects the current requirements, and we can easily change it later.
| return self._fn(*args, **kwargs) | ||
| 
               | 
          ||
| def __getitem__(self, _): | ||
| return self | 
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.
So you actually can make open_memory_channel directly typeable by mypy without any plugin, and it's not too terribly awful: python/mypy#6073 (comment)
But I think it does require inlining this class into the definition of open_memory_channel.
If that's where were going to end up, then maybe setting up a standalone @generic_function decorator, testing it, etc., is overkill, and we should instead move this code into _memory_channels.py right now?
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.
The problem with that approach is that AFAICT, when you write Type[T], mypy can't infer T as one of its "special forms" (Tuple, Union, Callable, etc). You just silently get Any if you use such a one. I figured that was error-prone enough that we should go this route instead, at least for now.
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 ick.
| 
           CI problem is codecov.io returning an invalid script  | 
    
Specifically, declare
SendChannel,ReceiveChannel,Listener, andRunVartobe generic in one type parameter, and also support the
open_memory_channel[T](bufsize)syntax at runtime. Until trio is able to support typing directly, this change allows
users of external stubs to use correctly-typed channels without too many hacks.