Доброе утро. Вчера поста не было. Я решил посвятить 20 часов своей жизни (это в тему предыдущего поста, да) на изучение Pathfinder Core Rulebook’а. Поэтому сегодня будет нормальный такой пост :) Речь пойдёт о контрактном программировании.
Статья о самой концепции: https://habrahabr.ru/post/38612/
А теперь, как всегда, пару реализаций концепции в питоне.
PyContracts. Условия задаются в своём особом синтаксисе в виде строк. Довольно интересный подход. Позволяет писать условия кратко и ёмко, в виде этаких схем. Правда, как результат, IDE такое не подсветит, да и нормальные схемы (типа marshmallow и PySchemes) без боли не использовать. https://andreacensi.github.io/contracts/
Pycontract. Автор этого модуля пошёл ещё дальше и реализовал модуль, который позволяет описывать контракты в docstring’ах, также в своём синтаксисе. Причём он подошёл серьезно и написал PEP с предложением включить это в стандартную библиотеку питона. Если бы это приняли, IDE умела бы это подсвечивать. Но нет. PEP: https://www.python.org/dev/peps/pep-0316/ Модуль и примеры: https://http://www.wayforward.net/pycontract/
Ок, я перерыл около 30 модулей, пытающихся реализовать контрактное программирование в виде обычных декораторов, хавающих в качестве контрактов любые функции. Но они все недостаточно хороши. То в качестве исключения поднимают Exception, то не реализуют инвариант, то работают только с какими-то своими сложными интерфейсами валидаторов, без возможности задать обычное lambda-выражение… В общем, встречайте почти идеальный модуль. Возможно, первый, у которого внутренности сделаны в терминах ООП, а не жуткой функциональщины, в которой и автор, вероятно, уже не ориентируется. https://github.com/orsinium/deal
Используйте, исследуйте, ставьте звёздочки :) P.S. В планах осталось только update_wrapper подружить с тем, что я возвращаю не функцию, а метод. Это будет в версии 1.2.