Инструменты для проверки статического типа в Python
Я работаю с большой существующей кодовой базой Python и хотел бы начать добавлять аннотации типов, чтобы я мог получить некоторый уровень статической проверки. Я представляю себе что-то вроде Erlang, Strongtalk, или Типичная схема /Racket.
Я видел быстрых и грязных декораторов, которые вставляют динамические проверки на основе параметров функций и аннотаций типа возвращаемого типа, но я ищу что-то более надежное и выполняет проверки во время компиляции.
Какие инструменты доступны прямо сейчас для такого рода вещей? Я знаком с компиляторами и проверкой типов, и я определенно готов улучшить неполный инструмент, если он имеет хорошую основу.
(Примечание: меня не интересует обсуждение плюсов и минусов статической типизации.)
EDIT: Пример:
def put(d, k, v):
d[k] = v
Я хотел бы иметь возможность комментировать функцию put
как имеющую тип put<K,V>(dict<K,V>, K, V) -> None
.
UPDATE. Новый PEP 484 (сентябрь 2014) определяет стандарт для статической типизации и аннотации типов в Python 3.5+. Там есть инструмент проверки типов mypy, который совместим с PEP 484.
Ответы
Ответ 1
Изменить 2016-11-11: Просто используйте mypy. Тип подсказки можно добавлять постепенно. В исходном коде Python 3 он проверяет стандартные подсказки типа PEP 484. Типы все еще могут быть выражены в Python 2 с помощью специальных комментариев. Гвидо любит его.
Эта запись была написана давно, прежде чем у меня возникла проблема. Я сохранил исходный контент ниже, хотя это не совсем точно.
Оригинальное сообщение:
Возможно, вы захотите проверить некоторые из проектов, упомянутых в этом связанном столбце StackOverflow в статическом анализе для Python.
Вкратце:
Так как Python использует duck typing, вещи, которые могут называться "ошибки типа" на других языках, могут оказаться "объектом X doesn 't метод поддержки Y" в Python.
Изменить 2011-05-17:
Я согласен с delnan, что статическая типизация для Python невозможна (видимо, неправильно). Но поскольку наш скептицизм, похоже, не сдерживает вас, я могу дать вам больше информации по этому вопросу. Я представляю:
- Обсуждение вывода типа для Python. (Другие ссылки отсюда.)
- Статьи Guido van van Rossum о добавлении необязательного статического ввода: часть 1 и часть 2.
- RPython, подмножество Python, которое может быть подвергнуто статистическому анализу достаточно, чтобы выполнить некоторую проверку типов.
Ответ 2
Вы можете найти mypy интересный. Он был предложен для включения в Python 3.5 от Guido.
Ответ 3
Отправлено: PySonar: статический анализатор для Python. PySonar - это инструмент, который описывает типы, использующие абстрактную интерпретацию (частично выполняющую) кода. Он находит все возможные пути выполнения вашей программы и находит все возможные типы всех переменных.
Существуют три версии PySonar:
- Open-sourced Java (индексатор Jython)
- Закрытая Java (скрытая в Google)
- Open-sourced Python (mini-pysonar)
Ни один из них (кроме закрытого исходного) полностью не реализован. Но основная идея заключается в том, что вы можете использовать его в качестве основы для своей работы.
Ответ 4
Я не знаю, помогает ли это, но для чего это стоит, Джереми Сиек из У Колорадо сделал некоторую работу по постепенному набору текста, и я нашел, что это делает быстрый поиск.
http://www.wiki.jvmlangsummit.com/pdf/28_Siek_gradual.pdf
Мое предположение (возможно, я ошибаюсь), нет никаких перспективных инструментов с открытым исходным кодом, которые вы можете найти на данный момент, так как его исследование выглядит относительно новым.
Лучше всего связаться с авторами и спросить, могут ли они выпустить свой код для вас.
Ответ 5
Существует пакет "постепенный" для Python 3; см. PIP или Bitbucket Repo
По-видимому, это реализация группы вокруг Джереми Сика, которая, похоже, является авторитетом в области постепенного набора текста.
Некоторые аннотации, по-видимому, необходимы, вот пример:
from gradual import *
@typed
def calculate_total(a:int, b:int) -> int:
return a + b//100
Что касается аннотаций, это не так уж плохо. Я не использовал пакет, поэтому я не могу говорить о его качестве, но синтаксис (и люди, стоящие за ним), безусловно, делают его перспективным.
Ответ 6
Мне нравится prospector, backend landscape.io. Он объединяет выходные данные существующих анализаторов, таких как pylint, pyflakes, pep8, frosted..., в один отчет. Ухоженная.
Ответ 7
У меня была подобная потребность некоторое время назад.
Все существующие решения, которые я нашел, имели некоторые проблемы или не имеют функции, которые я хотел бы иметь, поэтому я сделал свой собственный.
Вот как вы его используете:
from requiretype import require
@require(name=str, age=(int, float, long))
def greet_person(name, age):
print "Hello {0} ({1})".format(name, age)
>>> greet_person("John", 42)
Hello John (42)
>>> greet_person("John", "Doe")
# [...traceback...]
TypeError: Doe is not a valid type.
Valid types: <type 'int'>, <type 'float'>, <type 'long'>
>>> greet_person(42, 43)
# [...traceback...]
TypeError: 42 is not a <type 'str'> type
Я надеюсь, что это будет полезно для вас.
Подробнее:
P.S.: (цитируя себя из github repo)
В большинстве случаев я бы рекомендовал использовать тесты вместо проверки типов, поскольку это более естественно сделать в Python. Но есть некоторые случаи, когда вы хотите/должны указать конкретный тип для использования, и поскольку python не имеет проверок типов для параметров здесь, где это полезно.