Pycon Ru 2014

http://2m.ahref.ws

Обзор некоторых выступлений, Mail.RU,  Александр Емелин   


Как не надо делать, чтобы ваш open-source продукт стал пользоваться успехом

Андрей Светлов, LevelUP

http://2o.ahref.ws




Документация на английском

ReadTheDocs



Тесты (95 %)

coverage.py

CI



Setup.py

Pypi



Обратная совместимость публичного API


_не _нужно _бояться _приватных _подчеркиваний




Если тяжело писать документацию 

значит

API плохой



Пишите читаемый код


Pep8

Правильные имена (master-slave)

Понятные тесты



Многозадачность в Python и других языках

Андрей Власовских, JetBrains



Треды

~ 20 кб/тред, ограничение 2048 тредов
1 ядро из-за GIL, race conditions, блокирующий IO

Процессы

~ 10 мб/процесс, N ядер
Медленное общение между процессами

Кооперативный подход
~ 1 кб/dispatcher, 1 ядро, С10K

Erlang, Go


Share Memory By Communicating

Do Not Communicate Using Shared Memory


Asyncio



Твиттер-клиент на asyncio 
с применением концепции акторов




Как писать для asyncio. Советы разработчика библиотеки

Андрей Светлов, LevelUP






PEP 3156

Пример

import json
import asyncio
import aiohttp

URL = 'http://p.corp.mail.ru/api/json'

@asyncio.coroutine
def get_free_parking_places():
    response = yield from aiohttp.request('GET', URL)
    body = yield from response.read_and_close()
    return json.loads(body.decode())['places']


@asyncio.coroutine
def main():
    result = yield from get_free_parking_places()


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

Обзор API


yield from
sleep
wait_for
call_soon
call_later
run_in_executor
gather
lock
queue

Явный loop



@coroutine
def sleep(delay, result=None, *, loop=None):
    """Coroutine that completes after a given time (in seconds)."""
    future = futures.Future(loop=loop)
    h = future._loop.call_later(delay, future.set_result, result)
    try:
        return (yield from future)
    finally:
        h.cancel()

Stream API


Не всегда нужно писать протоколы - есть Stream API
(High-level API)
@asyncio.coroutine
def print_http_headers(url):
    url = urllib.parse.urlsplit(url)
    reader, writer = yield from asyncio.open_connection(url.hostname, 80)
    query = (
        'HEAD {url.path} HTTP/1.0\r\n'
        'Host: {url.hostname}\r\n'
        '\r\n'
    ).format(url=url)
    writer.write(query.encode('latin-1'))
    while True:
        line = yield from reader.readline()
        if not line:
            break
        print(line.decode('latin1').rstrip())

Subprocess


Тоже есть High-level API

yield from asyncio.create_subprocess_shell(...)

yield from asyncio.create_subprocess_exec(...)


Подумали о путанице при создании Subprocess 
(cmd - список или строка, когда shell=True или False)

Библиотеки


aiohttp

aiopg

aiozmq

aioredis  в планах

Дебаг


import asyncio

@asyncio.coroutine
def test():
    print("never scheduled")

test()

Решение
export PYTHONASYNCIODEBUG=1
(env) MacAir:env fz$ PYTHONASYNCIODEBUG=1 python test.py 
Coroutine 'test' defined at test.py:3 was never yielded from

Дебаг, PDB

next, step работают корректно в PYTHON 3.4

Тестирование


class MyTest(unittest.TestCase):
    
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(None)

    def tearDown(self):
        self.loop.close()

    def test_some_case():
        @asyncio.coroutine
        def run():
            yield from asyncio.sleep(0.5, loop=self.loop)

        self.loop.run_until_complete(run())   


Trollius


yield From(f())

вместо

yield from f()


Библиотеки от asyncio на Trollius работать не будут и мало кто будет поддерживать 2 версии


Pycon Ru 2014

By Emelin Alexander

Pycon Ru 2014

  • 831