[Async-sig] SansIO (Was: PEP: asynchronous generators)

Yury Selivanov yselivanov at gmail.com
Mon Aug 8 12:33:25 EDT 2016


> On Aug 8, 2016, at 12:16 PM, Cory Benfield <cory at lukasa.co.uk> wrote:
> 
> 
>> On 8 Aug 2016, at 17:06, Yury Selivanov <yselivanov at gmail.com> wrote:
>>> 
>>> As to having a PEP or putting something in PEP 8, I feel pretty lukewarm to those ideas. If the core Python team was able to legislate good coding practices via PEPs I think the world would be a very different place.
>> 
>> What does this mean?  A lot of people, in any serious project at least, follow PEP 8 and coding with linters is a wide-spread practice.
> 
> Sure, but that only works for things that linters can enforce, and I sincerely doubt that this is one of them.

Correct.  I don’t think it should be PEP 8 either.  I think Guido’s idea on including h11 to the stdlib is cool, and that’s the better way to send the message.  We can also add a *new* informational PEP instructing people on why (and how) they should write IO free protocol implementations.  It would be great if you have time to champion such a PEP (I’d be glad to help if needed.)

The other problem with sans-IO approach is that it takes longer to implement properly.  You need at least a synchronous and an asynchronous versions to make sure that you got the design parts “right”.  

For instance, just few days ago we’ve open sourced a new PostgreSQL driver [1], and right now it’s bound to asyncio.  While the foundational layer of the protocol is IO free, it would still take me a lot of time to (a) document it, (b) to build and test anything but asyncio on top of it.

And, since our driver is far more feature packed (and faster!) than psycopg2, I’d love to make a synchronous version of it (but don’t have time atm).  So what I was thinking about is a library that would provide a set of base Protocol (meta?) classes, one for asyncio, one for sync io, etc.  Then the only thing you would need is to mixin your sans-IO protocol to them and write some glue code.  Timeouts, cancellations, etc will be already taken care of for you.

This is something that is super hard to make for protocols like HTTP, but shouldn’t be a big problem for DB protocols (redis, postgres, etc).  Something to think about :)

[1] http://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/

Thanks,
Yury






> How would you code a linter in order to confirm that protocol code and I/O code are separated?
> 
> More importantly though, people follow the bits of PEP 8 that are easy to enforce and that don’t require substantive architectural changes. If PEP 8 said something like “wherever possible use dependency injection as a design pattern”, that guideline would be ignored as both entirely unenforceable and totally subjective. Where is the line for “wherever possible”? How does one enforce the use of dependency injection? Can you programmatically determine dependency injection? What dependencies do not need to be injected?
> 
> Dependency injection is a great design pattern that produces lots of useful side effects, and I use it often. But if I saw PEP 8 mandating it I’d be extremely perplexed. Realistically, at a certain point it’s the equivalent of writing “You should write good, maintainable code, obeying all relevant best practices” into PEP 8. *Of course* you should. This goes without saying. But that makes the advice not that helpful.
> 
> Now, PEP 8 could *recommend* design patterns to follow, and that’s a whole other kettle of fish. But then we’re just asking a different question: how universally praised does a design pattern have to be to become part of PEP 8?
> 
> Cory



More information about the Async-sig mailing list