Skip to content

Commit

Permalink
turns out I hadn't really made the relative importing useful for the …
Browse files Browse the repository at this point in the history
…query, so Query.ref will now use the Query.orm_class and its parents to attempt to resolve relative classpaths
  • Loading branch information
Jaymon committed Jun 12, 2017
1 parent 7b1c6f3 commit 065f274
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 3 deletions.
42 changes: 41 additions & 1 deletion prom/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import multiprocessing
from multiprocessing import queues
import math
import inspect

import threading
try:
Expand Down Expand Up @@ -620,7 +621,46 @@ def ref(self, orm_classpath, cls_pk=None):
return -- Query()
"""
# split orm from module path
orm_module, orm_class = get_objects(orm_classpath, __name__)
if orm_classpath.startswith("."):
# we handle relative classpaths by using the orm_class and its parents
# to find the relative import
if self.orm_class:
try:
orm_module, orm_class = get_objects(
orm_classpath,
self.orm_class.__module__
)
except ImportError:
parents = inspect.getmro(self.orm_class)
if parents:
for pc in parents[1:-1]:
try:
orm_module, orm_class = get_objects(
orm_classpath,
pc.__module__
)
except ImportError:
pass

if not orm_module or not orm_class:
raise ImportError(
"Unable to resolve relative ref using {}".format(
self.orm_class.__module__
)
)

else:
raise ImportError("trying relative ref without orm_class")

else:
orm_module, orm_class = get_objects(orm_classpath)


# if isinstance(orm_classpath, basestring):
# orm_module, orm_class = get_objects(orm_classpath)
# else:
# orm_module, orm_class = get_objects(orm_classpath[0], orm_classpath[1])

q = orm_class.query
if cls_pk:
for fn, f in orm_class.schema.fields.items():
Expand Down
50 changes: 48 additions & 2 deletions tests/query_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import datetime
import time
from threading import Thread
import sys

import testdata

Expand Down Expand Up @@ -266,8 +267,6 @@ def test_ref_threading(self):
]
})

import sys

tqr1 = basedir.module("rtfoo.rtbar.tqr1")
sys.modules.pop("rtfoo.rtbar.tqr2.Bar", None)
#tqr2 = basedir.module("tqr2")
Expand Down Expand Up @@ -325,6 +324,53 @@ def test_query_ref(self):
l = list(ti1.query.ref(orm_classpath).select_foo().all().values())
self.assertEqual(2, len(l))

def test_ref_relative(self):
basedir = testdata.create_modules({
"rrel1.relimp.one": [
"import prom",
"",
"class Foo(prom.Orm):",
" table_name = 'relimp1'",
" one = prom.Field(int, True)",
"",
],
"rrel1.relimp.two": [
"import prom",
"",
"class Bar(prom.Orm):",
" table_name = 'relimp2'",
" one = prom.Field(int, True)",
"",
" @property",
" def fooq(self):",
" return self.query.ref('..one.Foo')",
""
],
"rrel1.three": [
"import prom",
"from .relimp.two import Bar",
"",
"class Che(Bar):",
" table_name = 'relimp3'",
" three = prom.Field(int, True)",
"",
],
})

one = basedir.module("rrel1.relimp.one")
two = basedir.module("rrel1.relimp.two")
three = basedir.module("rrel1.three")

c = three.Che()
fooq = c.fooq
self.assertEqual(one.__name__, fooq.orm_class.__module__)
self.assertEqual(one.Foo, fooq.orm_class)

b = two.Bar()
fooq = b.fooq
self.assertEqual(one.__name__, fooq.orm_class.__module__)
self.assertEqual(one.Foo, fooq.orm_class)

def test_null_iterator(self):
"""you can now pass empty lists to in and nin and not have them throw an
error, instead they return an empty iterator"""
Expand Down

0 comments on commit 065f274

Please sign in to comment.