Great... Now my ugly hack is immortalized! ;) Seriously, it may be worth pointing out that all three techniques have the same end result of adding the 'illegal-name' to the module's namespace. Neil, I had no ideal you could mutate globals() like that! I thought the dict so returned was to be considered read-only, in the "you can change it, but your efforts will be discarded" sense... Clever! I guess I got that idea from the vars() documentation... I forgot all about _q_resolve(), as I never use it... But being reminded of it, I think that's your cleanest option, without considering the modification of the _q_exports logic. ----------- Another idea for modifying the _q_exports handling... Trying to have least performance impact, least code changes to code that's already stable: Add an Alias class (as a helper class) somewhere in Quixote (util?): class Alias: def __init__(self, theAlias, resolvesTo): self.alias = resolvesTo self.resolvesTo = resolvesTo def __cmp__ (self, other): return cmp(self.alias, other) Now, given: _q_exports = ['foo', 'bar', Alias('foo-bar', 'foo_bar')] The existing publisher logic of: if (component != "_q_index" and component not in container._q_exports): will still work unchanged (although slightly slower when an Alias' __cmp__ function has to be called). Meanwhile, inside the "else:" block of that "if" (where Qx is about to give up, complaining that the object doesn't exist in the namespace, but is in _q_exports), we do something like: else: # Check to see if the _q_export entry was an alias pointing to # something else. (untested ... beware typos, etc) index = _q_exports.index(component) realComponent = getattr(_q_exports[index], 'resolvesTo', None) if realComponent: object = getattr(container, realComponent) setattr(container, component, object) else: # a non-existent attribute is in _q_exports, # and the container is not a module. Give up. raise errors.TraversalError( private_msg=("%r in _q_exports list, " "but not found in %r" % (component, container)))else: ######### Or something like that... Once resolved, it is permanently added to the correct namespace so that future checks have similar performance to the _q_resolve solution. Actually, a more conprehensive analysis may reveal that the check should be done sooner in the process, rather than at the last moment. Jason > -----Original Message----- > From: quixote-users-bounces+jsibre=chironsys.com@mems-exchange.org > [mailto:quixote-users-bounces+jsibre=chironsys.com@mems-exchange.org]On > Behalf Of Kendall Clark > Sent: Monday, April 05, 2004 3:12 PM > To: quixote-users@mems-exchange.org > Subject: [Quixote-users] Illegal Python Names cookbook recipe > > > I wrote up a simple Cookbook recipe collecting the responses to my > query earlier today about valid Python and URI component identifiers: > > http://www.quixote.ca/qx/IllegalPythonNames > > I put in a bit of an argument near the end for changing the format of > _q_exports from a list of strings to a list of strings and optional > dictionaries (which I suspect can be implemented in a way that breaks > no existing code). Some details in the recipe if you care about this > issue. > > Thanks for the responses. > > Kendall Clark > > > _______________________________________________ > Quixote-users mailing list > Quixote-users@mems-exchange.org > http://mail.mems-exchange.org/mailman/listinfo/quixote-users >