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