Here are two changes to the _traverse function I'd like to make, but am not sure they're correct. The first fix is to move the check for __access__ before the check for __getname__. Without it, __access__ is never called when there's a __getname__ function. The second change ensures there's a trailing slash when the traversal ends up at an object (most likely something returned from __getname__), so /process/review/300 redirects to /process/review/300/. These seem OK? --amk Index: publish.py =================================================================== RCS file: /projects/cvsroot/mems/quixote/publish.py,v retrieving revision 1.43 diff -u -r1.43 publish.py --- publish.py 2000/10/27 15:31:20 1.43 +++ publish.py 2000/11/09 20:42:10 @@ -70,6 +70,12 @@ "%s has no __exports__ list" % repr(object), original_path) + # Call __access__ function or method, if it's present + if hasattr(object, '__access__'): + access_func = getattr(object, '__access__') + # will raise AccessError if access failed + access_func(request, response) + # Second security check: make sure the current name component is # in the export list. If not, there's a backdoor around the # usual traversal algorithm: namespaces may provide a @@ -97,12 +103,6 @@ (repr(component), object)), original_path) - # Call __access__ function or method, if it's present - if hasattr(object, '__access__'): - access_func = getattr(object, '__access__') - # will raise AccessError if access failed - access_func(request, response) - is_module = type(object) is types.ModuleType has_component = hasattr(object, component) if is_module and not has_component: @@ -168,7 +168,7 @@ not hasattr(object, '__bases__')) is_module = type(object) == types.ModuleType - if is_module: + if is_module or (type(object) is types.InstanceType): # It's a module, which isn't callable. First, make sure URL has # trailing slash if original_path[-1] != '/':