durusmail: quixote-users: Re: Illegal Python Names cookbook recipe
Illegal Python Names cookbook recipe
2004-04-05
2004-04-05
2004-04-05
Bug fixes (was: Illegal Python Names cookbook recipe)
2004-04-07
2004-04-07
Bug fixes (was: Illegal Python Names cookbookrecipe)
2004-04-07
Patches for .7a3
2004-04-07
Re: Patches for .7a3
2004-04-08
StaticFile is broken (Quixote-0.7a3, scgi-1.2a2, Apache/1.3.27, FreeBSD 4.7)
2004-04-08
Re: Patches for .7a3
2004-04-21
2004-04-21
2004-04-06
2004-04-06
2004-04-06
2004-04-06
2004-04-06
2004-04-06
2004-04-06
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
Re: Illegal Python Names cookbook recipe
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-07
2004-04-08
2004-04-07
2004-04-07
2004-04-07
2004-04-06
2004-04-05
2004-04-05
2004-04-05
Re: R: [Quixote-users] Illegal Python Names cookbook recipe
2004-04-06
Re: Illegal Python Names cookbook recipe
Jason E. Sibre
2004-04-07
> Here's a short example that really works, with no changes to Publisher:
>
>      import _dollar_one, foo, bar
>
>      _q_exports = ['foo', 'bar']
>
>      _other_exports = {
>          '$one': _dollar_one,
>      }
>
>      _q_exports.extend(_other_exports.keys())
>
>      def _q_resolve(name):
>          return _other_exports.get(name)
>
> I actually tried this one before posting it to the list. :-;

I like these ideas since they can be handled at the application level, and
no modifications need be made in Qx to accomodate them.

[Is the horse still breathing?]

Along those lines, here's another idea for a helper class that makes the
concept of putting stuff in _q_exports possible, this time with no
modifications to Qx at all (except possibly making the helper class
available somewhere).

It's kinda convoluted, and I don't take it too seriously, and I'm sure it's
sub-optimal from a performance standpoint.  BUT, it does make it easy (if
perhaps more verbose than ideal) for an application developer to extend the
functionality of _q_exports without modifying Qx in any way.


class Aliaser:
    def __init__(self, globalsDict):
        # Store a reference to the globals dict
        self._globals = globalsDict
        self.mappingsMade = False
        self.mappings = {}

    def makeMappings(self):
        # Have to wait until after the module is loaded,
        # or the names may not exist in the module yet
        # (typically, _q_exports is at the top of the module,
        # before the names have been defined)
        for k, v in self.mappings.items():
            try:
                self._globals[k] = self._globals[v]
            except KeyError:
                # I'm not in love with this approach,
                # but is has the 'advantage' (?) of
                # blowing up IMMEDIATELY, instead of
                # waiting for someone to browse to this
                # 'dead' url.
                raise NameError(
                    ("The name '%s' (for '%s') is not defined " + \
                    "in the namespace used by this Aliaser")
                    % (v,k))
        self.mappingsMade = True

    def __call__(self, alias, callableName):
        # Make a note of the mapping requested,
        # and return self (for later __cmp__ use)
        self.mappings[alias] = callableName
        return self

    def __cmp__(self, other):
        # Make sure the mappings have been done
        if not self.mappingsMade:
            self.makeMappings()
        # Indicate that we '==' anything that's in
        # our mapping dict.
        if self.mappings.has_key(other): return 0
        else: return 1


# Need one instance for each namespace that should be
# able to handle aliases
alias = Aliaser(globals())
_q_exports = [
        alias("$blah", "blah"),
        alias("blah-2", "blah2"),
        alias("old-name-for-blah-2", "blah2"),
        alias("blah-3", "blah3")
        ]
# This will bomb when the mappings are made (first call to __cmp__), because
"blah3" doesn't exist.

def blah(request):
    return "blah"

def blah2(request):
    return "blah2"


Anyway, it's yet another approach...
Jason






reply