24 нояб. 2013 г.

.hgrc



Используем в новом большом проекте Jenkins. Он очень хорош, для того чтобы дать тебе вовремя понять, что ты спорол какую-то чушь, и теперь тесты закосячены, а сними и код. Но как быть, если самодисциплины не всегда хватает на выполнение тестов перед коммитом и проверку кода на соответствие стандартам? Хуки! Мы используем mercurial, для него уже есть https://pypi.python.org/pypi/hghooks/.
[hooks]
pretxncommit.pep8 = python:hghooks.code.pep8hook
pretxncommit.pyflakes = python:hghooks.code.pyflakeshook
pretxncommit.pdb = python:hghooks.code.pdbhook
pretxncommit.jslint = python:hghooks.code.jslinthook

[hghooks]
strict_checking = true

[pep8]
ignore = E501
Осталось написать собственный хук, который будет откатывать коммиты с запоротыми тестами.
UPD:
preoutgoing.confirm = hg summary; read -p 'Are you sure you want to push to remote? (y/n): '; echo $REPLY | grep -q 'y'

13 нояб. 2013 г.

Разработчики Python VS Django

Во многих компаниях давно использующих python недолюбливают django. Раньше мне было не вполне понятно почему. Я считал это снобизмом. Теперь уверился, что джуниоры, начинающие свой практический путь с использования только фреймворков теряют потенцию искать решение самостоятельно. Первое, что они делают, когда сталкиваются с проблемой - гуглят готовое решение или желательно сразу батарейку. Если удалось найти решение сразу на стэковерфлоу - это победа. Скорей всего, люди писавшие ответ уже подумали, а значит нам думать и вовсе не нужно.Если ошибочное мнение повторено еще и в чьем-нибудь бложике, так вообще здорово. Ты на верном пути, будущий Лайнус Торвальдс. Проблемы начинаются потом. Решение нужно масштабировать/поддерживать/развивать, а понимания того, как оно работает нет.

Порой доходит до совсем смешного. Предположим некое API, в одном из методов принимает два POST параметра, для которых по сути не нужны ни валидаторы диапазона, ни проверка ввода. Как это правильно делать с точки зрения Django? Надо написать форму!

class DjangoForm(forms.Form):
    param1 = forms.CharField(required=False)
    param2 = forms.CharField(required=False)


def testFormView(request):
    form = DjangoForm(request.POST)
    if form.is_valid():
        param1 = form.cleaned_data['param1']
        param2 = form.cleaned_data['param2'] 

Но в рамках того же проекта на django можно просто обработать POST-параметры:
def testPOSTView(request):
    if request.method == 'POST':
        param1 = request.POST.get('param1')
        param2 = request.POST.get('param2') 

Возьмем для простоты улучшенный RequestFactory из https://djangosnippets.org/snippets/2231/ и напишем простяцкий тест:
request = RequestFactory().post('/submit/', {'param1': 'value1', 'param2': 'value2'})


def timeit(func, times):
    start = time.time()
    for i in range(0, times):
        func(request)
    return time.time() - start


def main():
    print timeit(testFormView, 10000)
    print timeit(testPOSTView, 10000)

Результат этого теста 1.77991509438 против 0.0828511714935.