Fork me on GitHub
9/9/2007

Pylons 0.9.6

Вышла новая версия веб-фреймворка Pylons: 0.9.6. По changelog сложно выделить ключевые изменения, так что я просто расскажу, какие изменения пришлось сделать мне, чтобы перевести несложный проект с 0.9.4 до 0.9.6.

Мне не очень понравилась процедура обновления при помощи Paste. Дело в том, что diff сложно окинуть одним взглядом, особенно когда файлы сильно различаются. Мне показалось проще создать новый проект по обновленному шаблону со схожим названием (для проекта MyProject я просто указал MyProject2 ;-)) и вручную сравнить нужные файлы.

Итак, для автогенеренных файлов (которые у меня не сильно отличаются от шаблонных) у меня получилось так:

  • Замена config/environment.py
  • Замена config/middleware.py
  • Исправление config/routing.py (взял обновленный шаблон, добавил свои настройки путей)
  • Исправление lib/base.py (взял обновленный шаблон, добавил свой код в BaseController)
  • Исправление lib/app_globals.py (взял обновленный шаблон, добавил свой код в Globals)
  • Замена controllers/error.py
  • Замена websetup.py

Помимо этого, пришлось сделать кое-какие изменения в коде, в связи с:

  • Теперь методы контролеров возвращают юникодные строки, а не Response-объекты (как следствие, нужно использовать render вместо render_response и убрать использование Response-объектов)
  • Response-объект стал глобальным
  • Используется собственная система доступа к настройкам (pylons.config), а не из Paste (paste.deploy.CONFIG)

Вот что мне сильно не понравилось в 0.9.6, так это сильный скачок в сторону. Обратной совместимости по указанным изменениям нет (по крайней мере, мне пришлось править код). Т.е. это не желательные, а обязательные изменения. Теперь render_response просто нет, теперь нельзя возвращать Response-объект, теперь не получится использовать paste.deploy.CONFIG.

Теперь чуть подробнее, о каждой правке:

render вместо render_response

Теперь вместо render_response нужно использовать render. С заменой всё легко и просто -- тупо заменяете все render_response на render.

Было:

return render_response('/about.mak')

Стало:

return render('/about.mak')

response - глобальный

Если вы раньше использовали Response-объект (для того, чтобы установить cookie, или чтобы вернуть ответ с нужным Content-Type), то теперь нужно использовать глобальный response-объект:

Было:

return Response(feed.content.encode('utf-8'), 'application/rss+xml')

Стало:

response.content_type = 'application/rss+xml'
return feed.content.encode('utf-8')

И здесь я, конечно, не могу согласиться с разработчиками Pylons. Я могу понять причины, когда request-объект делается глобальным (см. комментарий Бена Бангерта), но я не могу понять мотивов к глобализации response-объекта. Если ранее я просто мог заглянуть в код lib/base.py, посмотреть откуда импортируется Response, посмотреть код этого объекта, мог посмотреть методы и атрибуты этого объекта при интерактивной отладке; то теперь я не могу этого сделать: ввиду глобальности, используются трюки (к примеру, response это объект типа StackedObjectProxy), чтобы этот объект был локальным для каждого потока.

Собственная система конфигурации

Теперь все опции (глобальные, специфичные для приложения, служебные) доступны из pylons.config. Если ранее вы использовали paste.deploy.CONFIG, то придется исправлять:

Было:

from paste.deploy.config import CONFIG

conf = CONFIG['global_conf'].copy()
conf.update(CONFIG['app_conf'])

mail_from = conf.get('info_email_from', 'msg@localhost')

Стало:

from pylons import config

mail_from = config.get('info_email_from', 'msg@localhost')

Помимо избавления от разделения глобальные настройки/специфичные для приложения, мне понравилось, что теперь доступ к маршрутам Routes доступен из настроек, а не только из environ.

Финал

После указанных изменений, приложение, написанное на Pylons 0.9.4, стало работать на 0.9.6. По тексту, я думаю, стало понятно, что я негативно отношусь к замене локального Response на глобальный response. Остальные изменения меня вполне устроили.

Комментарии

Все статьи