Index: publish.py =================================================================== --- publish.py (revision 23883) +++ publish.py (working copy) @@ -719,6 +719,31 @@ return object +def _lookup_export (name, exports): + """Search an exports list for a name. Returns the internal name for + 'name' or return None if 'name' is not in 'exports'. + + Each element of the export list can be either a string or a 2-tuple + of strings that maps an external name into internal name. The + mapping is useful when the desired external name is not a valid + Python identifier. + """ + for value in exports: + if value == name: + internal_name = name + break + elif type(value) is types.TupleType: + if value[0] == name: + internal_name = value[1] # internal name is different + break + else: + if name == '_q_index': + internal_name = name # _q_index does not need to be in exports list + else: + internal_name = None # not found in exports + return internal_name + + def _get_component (container, component, path, request, namespace_stack): """Get one component of a path from a namespace. """ @@ -747,7 +772,8 @@ # _q_lookup() doesn't exist or is None, a TraversalError is # raised. - if (component != "_q_index" and component not in container._q_exports): + internal_name = _lookup_export(component, container._q_exports) + if internal_name is None: # Component is not in exports list. object = None if hasattr(container, "_q_lookup"): @@ -762,13 +788,12 @@ container, component)) - # From here on, you can assume that the name is either in - # _q_exports, or the name is '_q_index' - elif hasattr(container, component): + # From here on, you can assume that the internal_name is not None + elif hasattr(container, internal_name): # attribute is in _q_exports and exists - object = getattr(container, component) + object = getattr(container, internal_name) - elif component == '_q_index': + elif internal_name == '_q_index': if hasattr(container, "_q_lookup"): object = container._q_lookup(request, "") else: @@ -776,21 +801,21 @@ private_msg=("_q_index not found in %r" % container)) elif hasattr(container, "_q_resolve"): - object = container._q_resolve(component) + object = container._q_resolve(internal_name) if object is None: - raise RuntimeError, ("component %r listed in _q_exports, " - "but not returned by _q_resolve()" - % component) + raise RuntimeError, ("component listed in _q_exports, " + "but not returned by _q_resolve(%r)" + % internal_name) else: # Set the object, so _q_resolve won't need to be called again. - setattr(container, component, object) + setattr(container, internal_name, object) elif type(container) is types.ModuleType: # try importing it as a sub-module. If we get an ImportError # here we don't catch it. It means that something that # doesn't exist was exported or an exception was raised from # deeper in the code. - mod_name = container.__name__ + '.' + component + mod_name = container.__name__ + '.' + internal_name object = _get_module(mod_name) else: