Tox (https://tox.readthedocs.io/) — инструмент командной строки, который использует виртуальные среды для запуска тестов. Вы можете запускать их на своем компьютере (tox в командной строке), если установлены интерпретаторы Python. Интегрирован с GitHub, поэтому, если у вас есть файл tox.ini на высшем уровне репозитория, как у Werkzeug, он автоматически будет запускать тесты при каждом коммите.
Рассмотрим конфигурационный файл Werkzeug tox.ini целиком:
[tox]
envlist = py{26,27,py,33,34,35}-normal, py{26,27,33,34,35}-uwsgi
[testenv]
passenv = LANG
deps=
# General
pyopenssl
greenlet
pytest
pytest-xprocess
redis
requests
watchdog
uwsgi: uwsgi
# Python 2
py26: python-memcached
py27: python-memcached
pypy: python-memcached
# Python 3
py33: python3-memcached
py34: python3-memcached
py35: python3-memcached
whitelist_externals=
redis-server
memcached
uwsgi
commands=
normal: py.test []
uwsgi: uwsgi
--pyrun {envbindir}/py.test
--pyargv -kUWSGI --cache2=name=werkzeugtest,items=20 --master
Примеры стиля из Werkzeug
В главе 4 мы уже рассмотрели большую часть принятых соглашений по стилю. Первый пример стиля в этом разделе демонстрирует элегантный способ угадать типы на основе строки, второй показывает, что вы можете использовать параметр VERBOSE при определении длинных регулярных выражений, поэтому другие пользователи смогут понять, что делает выражение, не затратив на это много времени.
Элегантный способ угадать тип (если реализацию легко объяснить — идея, возможно, хороша)
Вам, скорее всего, приходилось анализировать текстовые файлы и преобразовывать содержимое к разным типам. Это решение выглядит особенно питонским, поэтому мы включили его в книгу.
Регулярные выражения (читаемость имеет значение)
Если вы используете в своем коде длинные регулярные выражения, не забывайте про параметр re.VERBOSE69 — сделайте их более понятными для других людей. Пример регулярных выражений показан во фрагменте файла werkzeug/routing.py: import re
(?P
<
(?:
(?P
(?:\((?P
\: # разделитель переменных
)?
(?P
>
''', re.VERBOSE)
Примеры структуры из Werkzeug
В первых двух примерах, связанных со структурой, демонстрируются питонские способы использования динамической типизации. Мы предупреждали, что присваивание переменной разных значений может приводить к появлению проблем (см. подраздел «Динамическая типизация» раздела «Структурируем проект» главы 4), но не упомянули преимущества такого присваивания. Одно из них заключается в том, что вы можете использовать любой тип объекта, который ведет себя предсказуемо. Это называется
В обоих примерах используется возможность вызвать объекты, которые не являются функциями: вызов cached_property.__init__() позволяет проинициализировать экземпляры класса, чтобы их можно быть применять как обычные функции, а вызов Response.__call__() позволяет объекту класса Response вызвать как функцию самого себя.
В последнем фрагменте используется реализация некоторых классов-примесей (каждый из них определяет какую-либо функциональность в объекте класса Request), характерная для Werkzeug, чтобы продемонстрировать, что такие классы — это тоже отличная штука.