Gaetan de Menten schrieb:
> On Wed, Aug 12, 2009 at 00:52, Johannes Janssen<[email protected]> 
> wrote:
>
> [...]
>
>   
>> I propose a patch for resolve(), which makes to major changes:
>>
>> User defined resolve function:
>>     
>
> [...]
>
> This is a good idea to address a real need. The thing is that I am not
> sure this is the best approach to solve the problem. What I've been
> using for my last project using elixir (a few months ago) is a custom
> EntityCollection class (inheriting from the default one) overriding
> the resolve method. We could probably add a hook in the default one so
> that it's easier to provide a custom method though I'm unsure whether
> it's worth it. My main concern about your approach is that I fail to
> see any usecase where setting the resolve method on a per-entity basis
> instead of per-collection makes sense. I might be lacking imagination
> though. Can you provide an example of such a situation?
>   

I agree with you that there is no need for having a user-defined resolve 
function on per-entity basis. I'm just not that familiar how elixir 
works. As I know now that you can implement your own resolve function by 
using your own EntityCollection class, I see no real need adding code on 
user-defined functions. Though it should be documented in some way how 
to do it.

>> Resolving the module path:
>>
>> My second idea is to change the way module paths are resolved by
>> default. Basically I would like to have tow ways to do that: relative
>> and (pseudo) absolute paths. An relative path starts with a dot and is
>> relative to the entity which is passed to resolve(key, entity) or better
>> to entity.__module__. Therefore it is only possible to use relative
>> paths when an entity is passed to resolve().
>> The absolute path instead must not start with a dot. They are by the
>> default real absolute path (that means they are relative to __main__).
>> Using "resolve_root" option you can change this.
>>     
>
> Good ideas. I didn't think of those. I was using an alternate resolve
> method to emulate your "resolve_root" option but since it's probably a
> common use case, it's a nice idea to have such an option.
>   

I assume that you agree that having "resolve_root" on a per-entity basis 
makes sense. There may be better names like "module_root" for that option.

>> (What I said about module paths (not) starting with a dot is not quite
>> true. "..foo.bar" will still be an abs path and while "...foo.bar" is an
>> rel path. Got it? Have a look at the example!)
>>     
>
> Hmmm, I lost you there. The relative path idea seems good. Using a
> leading dot seems good but this ".. is a no-op" idea seems artificial
> and very different to how python's relative imports work, hence very
> confusing. Honestly, I don't understand what's the point.
>   
Yeah, I totally don't understand how I came up with this, now. Perhaps 
it was bit too late, when I did this. It is not how relative imports 
work in python, but like paths in common OSes. Okay just ignore all the 
".." stuff. That leaves this:

    * absolute paths (must not start with a dot)
          o they are "relative" to the resolve_root option
          o you can't address classes living not within the module given
            by resolve_root or any of it's submodules
          o resolve_root defaults to __main__ module, making the paths
            real absolute paths like in the current resolve method
    * relative paths (must start with at least one dot)
          o they are relative to the entity class passed to the resolve
            function
          o each additional dot at the beginning of the path has the
            meaning of going up one module/package level

[...]

I append a new version of the resolve function implementing this 
behavior (http://paste.pocoo.org/show/134345/).

Kind regards

Johannes

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"SQLElixir" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/sqlelixir?hl=en
-~----------~----~----~----~------~----~------~--~---

    def resolve(self, key, entity=None):
        '''
        Resolve a key to an Entity. The optional `entity` argument is the
        "source" entity when resolving relationship targets.
        '''
        if entity is not None:
            module_root = entity._descriptor.resolve_root
        else:
            module_root = options_defaults.get('resolve_root')
        
        if key.startswith('.'):
            if entity is None:
                raise Exception("Couldn't resolve relative target '%s', "
                                "because no entity was passed." % key)
            else:
                full_path = key[1:]
                entity_module = entity.__module__
                
                if entity_module is not '__main__':
                    while full_path.startswith('.'):
                        full_path = full_path[1:]
                        entity_module = entity_module[:entity_module.rfind('.')]
                    
                    full_path = '%s.%s' % (entity_module, full_path)
        else:
            if module_root is not None:
                full_path = '%s.%s' % (module_root, key)
            else:
                full_path = key
          
        module_path, classname = rsplit(full_path, '.', 1)
        module = sys.modules[module_path]       
        res = getattr(module, classname, None)

        if res is None:
            if entity is not None:
                raise Exception("Couldn't resolve target '%s' <%s> in '%s'!"
                            % (key, full_path, entity.__name__) )
            else:
                raise Exception("Couldn't resolve target '%s' <%s>!"
                                % (key, full_path) )
            
        return res

Reply via email to