2009年2月26日木曜日

zope DefaultPublishTraverse:publishTraverse

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
boboとは酔っ払ったという意味らしい。googleで調べてみるとtraverseをカスタマイズするための属性のようだ。千鳥足でtraverseするといったところか。




def publishTraverse(self, request, name):
object = self.context
URL=request['URL']

if name[:1]=='_':
raise Forbidden("Object name begins with an underscore at: %s" % URL)



こちらはdelegateされているので何でもあり。なぜ__bobo_traverse_を使っていて、カスタムトラバース用のInterfaceが存在していないのだろう?(しているのかもしれないが)

if hasattr(object,'__bobo_traverse__'):
try:
subobject=object.__bobo_traverse__(request, name)
if type(subobject) is type(()) and len(subobject) > 1:
# Add additional parents into the path
# XXX There are no tests for this:
request['PARENTS'][-1:] = list(subobject[:-1])
object, subobject = subobject[-2:]
except (AttributeError, KeyError, NotFound), e:
# Try to find a view
subobject = queryMultiAdapter((object, request), Interface, name)
if subobject is not None:
# OFS.Application.__bobo_traverse__ calls
# REQUEST.RESPONSE.notFoundError which sets the HTTP
# status code to 404
request.response.setStatus(200)
# We don't need to do the docstring security check
# for views, so lets skip it and return the object here.
if IAcquirer.providedBy(subobject):
subobject = subobject.__of__(object)
return subobject
# No view found. Reraise the error raised by __bobo_traverse__
raise e

普通のケース。aq_baseはApp/Common.pyの中にある。


def aq_base(ob, getattr=getattr):
# Return the aq_base of an object.
return getattr(ob, 'aq_base', ob)



else:
# No __bobo_traverse__
# Try with an unacquired attribute:
if hasattr(aq_base(object), name):
subobject = getattr(object, name)

aq_baseの意味するところがわからない。どういうプロトコルを構成しようとしているのだろうか?

else:
# We try to fall back to a view:
subobject = queryMultiAdapter((object, request), Interface,
name)
if subobject is not None:
if IAcquirer.providedBy(subobject):
subobject = subobject.__of__(object)
return subobject

# And lastly, of there is no view, try acquired attributes, but
# only if there is no __bobo_traverse__:
try:
subobject=getattr(object, name)
# Again, clear any error status created by __bobo_traverse__
# because we actually found something:
request.response.setStatus(200)
return subobject
except AttributeError:
pass

# Lastly we try with key access:
try:
subobject = object[name]
except TypeError: # unsubscriptable
raise KeyError(name)




コメントがすべて。問題はなぜそういうポリシーを採用しているかだ。次のコメントを読むと、2.2.2でmutableなやつのdocstringがどうのこうのと書いてある。おそらくは、adapter経由で意図していない公開が起こらない安全側に倒したのだろう。組み込み型はfile終わりのほうで列挙されている。

# Ensure that the object has a docstring, or that the parent
# object has a pseudo-docstring for the object. Objects that
# have an empty or missing docstring are not published.
doc = getattr(subobject, '__doc__', None)
if doc is None:
doc = getattr(object, '%s__doc__' % name, None)
if not doc:
raise Forbidden(
"The object at %s has an empty or missing " \
"docstring. Objects must have a docstring to be " \
"published." % URL
)




# Hack for security: in Python 2.2.2, most built-in types
# gained docstrings that they didn't have before. That caused
# certain mutable types (dicts, lists) to become publishable
# when they shouldn't be. The following check makes sure that
# the right thing happens in both 2.2.2+ and earlier versions.

if not typeCheck(subobject):
raise Forbidden(
"The object at %s is not publishable." % URL
)

return subobject

0 件のコメント: