Pylons 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
. Остальные изменения меня вполне устроили.