def test_collection_with_backref(self):
        for base in (object, MyBaseClass, MyClass):
            class Post(base):pass
            class Blog(base):pass

            attributes.register_class(Post)
            attributes.register_class(Blog)
            attributes.register_attribute(Post, 'blog', uselist=False, extension=attributes.GenericBackrefExtension('posts'), trackparent=True, useobject=True)
            attributes.register_attribute(Blog, 'posts', uselist=True, extension=attributes.GenericBackrefExtension('blog'), trackparent=True, useobject=True)
            b = Blog()
            (p1, p2, p3) = (Post(), Post(), Post())
            b.posts.append(p1)
            b.posts.append(p2)
            b.posts.append(p3)
            self.assert_(b.posts == [p1, p2, p3])
            self.assert_(p2.blog is b)

            p3.blog = None
            self.assert_(b.posts == [p1, p2])
            p4 = Post()
            p4.blog = b
            self.assert_(b.posts == [p1, p2, p4])

            p4.blog = b
            p4.blog = b
            self.assert_(b.posts == [p1, p2, p4])

            # assert no failure removing None
            p5 = Post()
            p5.blog = None
            del p5.blog
    def test_inheritance(self):
        """tests that attributes are polymorphic"""

        for base in (object, MyBaseClass, MyClass):
            class Foo(base):pass
            class Bar(Foo):pass

            attributes.register_class(Foo)
            attributes.register_class(Bar)

            def func1(**kw):
                print "func1"
                return "this is the foo attr"
            def func2(**kw):
                print "func2"
                return "this is the bar attr"
            def func3(**kw):
                print "func3"
                return "this is the shared attr"
            attributes.register_attribute(Foo, 'element', uselist=False, callable_=lambda o:func1, useobject=True)
            attributes.register_attribute(Foo, 'element2', uselist=False, callable_=lambda o:func3, useobject=True)
            attributes.register_attribute(Bar, 'element', uselist=False, callable_=lambda o:func2, useobject=True)

            x = Foo()
            y = Bar()
            assert x.element == 'this is the foo attr'
            assert y.element == 'this is the bar attr', y.element
            assert x.element2 == 'this is the shared attr'
            assert y.element2 == 'this is the shared attr'
Beispiel #3
0
    def test_basic(self):
        for base in (object, MyBaseClass, MyClass):

            class User(base):
                pass

            attributes.register_class(User)
            attributes.register_attribute(User,
                                          'user_id',
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(User,
                                          'user_name',
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(User,
                                          'email_address',
                                          uselist=False,
                                          useobject=False)

            u = User()
            u.user_id = 7
            u.user_name = 'john'
            u.email_address = '*****@*****.**'

            self.assert_(u.user_id == 7 and u.user_name == 'john'
                         and u.email_address == '*****@*****.**')
            attributes.instance_state(u).commit_all()
            self.assert_(u.user_id == 7 and u.user_name == 'john'
                         and u.email_address == '*****@*****.**')

            u.user_name = 'heythere'
            u.email_address = '*****@*****.**'
            self.assert_(u.user_id == 7 and u.user_name == 'heythere'
                         and u.email_address == '*****@*****.**')
Beispiel #4
0
    def test_dict_collections(self):
        class Foo(_base.BasicEntity):
            pass
        class Bar(_base.BasicEntity):
            pass

        from sqlalchemy.orm.collections import attribute_mapped_collection

        attributes.register_class(Foo)
        attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True, typecallable=attribute_mapped_collection('name'))

        hi = Bar(name='hi')
        there = Bar(name='there')
        old = Bar(name='old')
        new = Bar(name='new')

        f = Foo()
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [], ()))

        f.someattr['hi'] = hi
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi], [], []))

        f.someattr['there'] = there
        eq_(tuple([set(x) for x in attributes.get_history(attributes.instance_state(f), 'someattr')]), (set([hi, there]), set(), set()))

        attributes.instance_state(f).commit(['someattr'])
        eq_(tuple([set(x) for x in attributes.get_history(attributes.instance_state(f), 'someattr')]), (set(), set([hi, there]), set()))
Beispiel #5
0
    def test_collections_via_backref(self):
        class Foo(_base.BasicEntity):
            pass
        class Bar(_base.BasicEntity):
            pass

        attributes.register_class(Foo)
        attributes.register_class(Bar)
        attributes.register_attribute(Foo, 'bars', uselist=True, extension=attributes.GenericBackrefExtension('foo'), trackparent=True, useobject=True)
        attributes.register_attribute(Bar, 'foo', uselist=False, extension=attributes.GenericBackrefExtension('bars'), trackparent=True, useobject=True)

        f1 = Foo()
        b1 = Bar()
        eq_(attributes.get_history(attributes.instance_state(f1), 'bars'), ((), [], ()))
        eq_(attributes.get_history(attributes.instance_state(b1), 'foo'), ((), [None], ()))

        #b1.foo = f1
        f1.bars.append(b1)
        eq_(attributes.get_history(attributes.instance_state(f1), 'bars'), ([b1], [], []))
        eq_(attributes.get_history(attributes.instance_state(b1), 'foo'), ([f1], (), ()))

        b2 = Bar()
        f1.bars.append(b2)
        eq_(attributes.get_history(attributes.instance_state(f1), 'bars'), ([b1, b2], [], []))
        eq_(attributes.get_history(attributes.instance_state(b1), 'foo'), ([f1], (), ()))
        eq_(attributes.get_history(attributes.instance_state(b2), 'foo'), ([f1], (), ()))
Beispiel #6
0
    def test_collection_with_backref(self):
        for base in (object, MyBaseClass, MyClass):
            class Post(base):pass
            class Blog(base):pass

            attributes.register_class(Post)
            attributes.register_class(Blog)
            attributes.register_attribute(Post, 'blog', uselist=False, extension=attributes.GenericBackrefExtension('posts'), trackparent=True, useobject=True)
            attributes.register_attribute(Blog, 'posts', uselist=True, extension=attributes.GenericBackrefExtension('blog'), trackparent=True, useobject=True)
            b = Blog()
            (p1, p2, p3) = (Post(), Post(), Post())
            b.posts.append(p1)
            b.posts.append(p2)
            b.posts.append(p3)
            self.assert_(b.posts == [p1, p2, p3])
            self.assert_(p2.blog is b)

            p3.blog = None
            self.assert_(b.posts == [p1, p2])
            p4 = Post()
            p4.blog = b
            self.assert_(b.posts == [p1, p2, p4])

            p4.blog = b
            p4.blog = b
            self.assert_(b.posts == [p1, p2, p4])

            # assert no failure removing None
            p5 = Post()
            p5.blog = None
            del p5.blog
Beispiel #7
0
    def test_inheritance(self):
        """tests that attributes are polymorphic"""

        for base in (object, MyBaseClass, MyClass):
            class Foo(base):pass
            class Bar(Foo):pass

            attributes.register_class(Foo)
            attributes.register_class(Bar)

            def func1():
                print "func1"
                return "this is the foo attr"
            def func2():
                print "func2"
                return "this is the bar attr"
            def func3():
                print "func3"
                return "this is the shared attr"
            attributes.register_attribute(Foo, 'element', uselist=False, callable_=lambda o:func1, useobject=True)
            attributes.register_attribute(Foo, 'element2', uselist=False, callable_=lambda o:func3, useobject=True)
            attributes.register_attribute(Bar, 'element', uselist=False, callable_=lambda o:func2, useobject=True)

            x = Foo()
            y = Bar()
            assert x.element == 'this is the foo attr'
            assert y.element == 'this is the bar attr', y.element
            assert x.element2 == 'this is the shared attr'
            assert y.element2 == 'this is the shared attr'
    def test_dict_collections(self):
        class Foo(fixtures.Base):
            pass
        class Bar(fixtures.Base):
            pass

        from sqlalchemy.orm.collections import attribute_mapped_collection

        attributes.register_class(Foo)
        attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True, typecallable=attribute_mapped_collection('name'))

        hi = Bar(name='hi')
        there = Bar(name='there')
        old = Bar(name='old')
        new = Bar(name='new')

        f = Foo()
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], []))

        f.someattr['hi'] = hi
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], []))

        f.someattr['there'] = there
        self.assertEquals(tuple([set(x) for x in attributes.get_history(f._state, 'someattr')]), (set([hi, there]), set([]), set([])))

        f._state.commit(['someattr'])
        self.assertEquals(tuple([set(x) for x in attributes.get_history(f._state, 'someattr')]), (set([]), set([hi, there]), set([])))
    def test_standard(self):
        class A(object):
            pass

        attributes.register_class(A)

        eq_(type(attributes.manager_of_class(A)), attributes.ClassManager)
Beispiel #10
0
    def test_list(self):
        class User(object):pass
        class Address(object):pass

        attributes.register_class(User)
        attributes.register_class(Address)
        attributes.register_attribute(User, 'user_id', uselist=False, useobject=False)
        attributes.register_attribute(User, 'user_name', uselist=False, useobject=False)
        attributes.register_attribute(User, 'addresses', uselist = True, useobject=True)
        attributes.register_attribute(Address, 'address_id', uselist=False, useobject=False)
        attributes.register_attribute(Address, 'email_address', uselist=False, useobject=False)

        u = User()
        u.user_id = 7
        u.user_name = 'john'
        u.addresses = []
        a = Address()
        a.address_id = 10
        a.email_address = '*****@*****.**'
        u.addresses.append(a)

        self.assert_(u.user_id == 7 and u.user_name == 'john' and u.addresses[0].email_address == '*****@*****.**')
        u, attributes.instance_state(a).commit_all()
        self.assert_(u.user_id == 7 and u.user_name == 'john' and u.addresses[0].email_address == '*****@*****.**')

        u.user_name = 'heythere'
        a = Address()
        a.address_id = 11
        a.email_address = '*****@*****.**'
        u.addresses.append(a)
        self.assert_(u.user_id == 7 and u.user_name == 'heythere' and u.addresses[0].email_address == '*****@*****.**' and u.addresses[1].email_address == '*****@*****.**')
Beispiel #11
0
    def test_lazy_backref_collections(self):
        class Foo(_base.BasicEntity):
            pass
        class Bar(_base.BasicEntity):
            pass

        lazy_load = []
        def lazyload(instance):
            def load():
                return lazy_load
            return load

        attributes.register_class(Foo)
        attributes.register_class(Bar)
        attributes.register_attribute(Foo, 'bars', uselist=True, extension=attributes.GenericBackrefExtension('foo'), trackparent=True, callable_=lazyload, useobject=True)
        attributes.register_attribute(Bar, 'foo', uselist=False, extension=attributes.GenericBackrefExtension('bars'), trackparent=True, useobject=True)

        bar1, bar2, bar3, bar4 = [Bar(id=1), Bar(id=2), Bar(id=3), Bar(id=4)]
        lazy_load = [bar1, bar2, bar3]

        f = Foo()
        bar4 = Bar()
        bar4.foo = f
        eq_(attributes.get_history(attributes.instance_state(f), 'bars'), ([bar4], [bar1, bar2, bar3], []))

        lazy_load = None
        f = Foo()
        bar4 = Bar()
        bar4.foo = f
        eq_(attributes.get_history(attributes.instance_state(f), 'bars'), ([bar4], [], []))

        lazy_load = [bar1, bar2, bar3]
        attributes.instance_state(f).expire_attributes(['bars'])
        eq_(attributes.get_history(attributes.instance_state(f), 'bars'), ((), [bar1, bar2, bar3], ()))
Beispiel #12
0
    def test_lazyhistory(self):
        """tests that history functions work with lazy-loading attributes"""

        class Foo(_base.BasicEntity):
            pass
        class Bar(_base.BasicEntity):
            pass

        attributes.register_class(Foo)
        attributes.register_class(Bar)

        bar1, bar2, bar3, bar4 = [Bar(id=1), Bar(id=2), Bar(id=3), Bar(id=4)]
        def func1():
            return "this is func 1"
        def func2():
            return [bar1, bar2, bar3]

        attributes.register_attribute(Foo, 'col1', uselist=False, callable_=lambda o:func1, useobject=True)
        attributes.register_attribute(Foo, 'col2', uselist=True, callable_=lambda o:func2, useobject=True)
        attributes.register_attribute(Bar, 'id', uselist=False, useobject=True)

        x = Foo()
        attributes.instance_state(x).commit_all()
        x.col2.append(bar4)
        eq_(attributes.get_history(attributes.instance_state(x), 'col2'), ([bar4], [bar1, bar2, bar3], []))
Beispiel #13
0
    def test_lazytrackparent(self):
        """test that the "hasparent" flag works properly when lazy loaders and backrefs are used"""

        class Post(object):pass
        class Blog(object):pass
        attributes.register_class(Post)
        attributes.register_class(Blog)

        # set up instrumented attributes with backrefs
        attributes.register_attribute(Post, 'blog', uselist=False, extension=attributes.GenericBackrefExtension('posts'), trackparent=True, useobject=True)
        attributes.register_attribute(Blog, 'posts', uselist=True, extension=attributes.GenericBackrefExtension('blog'), trackparent=True, useobject=True)

        # create objects as if they'd been freshly loaded from the database (without history)
        b = Blog()
        p1 = Post()
        attributes.instance_state(b).set_callable('posts', lambda:[p1])
        attributes.instance_state(p1).set_callable('blog', lambda:b)
        p1, attributes.instance_state(b).commit_all()

        # no orphans (called before the lazy loaders fire off)
        assert attributes.has_parent(Blog, p1, 'posts', optimistic=True)
        assert attributes.has_parent(Post, b, 'blog', optimistic=True)

        # assert connections
        assert p1.blog is b
        assert p1 in b.posts

        # manual connections
        b2 = Blog()
        p2 = Post()
        b2.posts.append(p2)
        assert attributes.has_parent(Blog, p2, 'posts')
        assert attributes.has_parent(Post, b2, 'blog')
Beispiel #14
0
    def test_defaulted_init(self):
        class X(object):
            def __init__(self_, a, b=123, c='abc'):
                self_.a = a
                self_.b = b
                self_.c = c

        attributes.register_class(X)

        o = X('foo')
        eq_(o.a, 'foo')
        eq_(o.b, 123)
        eq_(o.c, 'abc')

        class Y(object):
            unique = object()

            class OutOfScopeForEval(object):
                def __repr__(self_):
                    # misleading repr
                    return '123'

            outofscope = OutOfScopeForEval()

            def __init__(self_, u=unique, o=outofscope):
                self_.u = u
                self_.o = o

        attributes.register_class(Y)

        o = Y()
        assert o.u is Y.unique
        assert o.o is Y.outofscope
Beispiel #15
0
    def test_parenttrack(self):
        class Foo(object):pass
        class Bar(object):pass

        attributes.register_class(Foo)
        attributes.register_class(Bar)

        attributes.register_attribute(Foo, 'element', uselist=False, trackparent=True, useobject=True)
        attributes.register_attribute(Bar, 'element', uselist=False, trackparent=True, useobject=True)

        f1 = Foo()
        f2 = Foo()
        b1 = Bar()
        b2 = Bar()

        f1.element = b1
        b2.element = f2

        assert attributes.has_parent(Foo, b1, 'element')
        assert not attributes.has_parent(Foo, b2, 'element')
        assert not attributes.has_parent(Foo, f2, 'element')
        assert attributes.has_parent(Bar, f2, 'element')

        b2.element = None
        assert not attributes.has_parent(Bar, f2, 'element')

        # test that double assignment doesn't accidentally reset the 'parent' flag.
        b3 = Bar()
        f4 = Foo()
        b3.element = f4
        assert attributes.has_parent(Bar, f4, 'element')
        b3.element = f4
        assert attributes.has_parent(Bar, f4, 'element')
Beispiel #16
0
    def test_collections_via_backref(self):
        class Foo(fixtures.Base):
            pass
        class Bar(fixtures.Base):
            pass

        attributes.register_class(Foo)
        attributes.register_class(Bar)
        attributes.register_attribute(Foo, 'bars', uselist=True, extension=attributes.GenericBackrefExtension('foo'), trackparent=True, useobject=True)
        attributes.register_attribute(Bar, 'foo', uselist=False, extension=attributes.GenericBackrefExtension('bars'), trackparent=True, useobject=True)

        f1 = Foo()
        b1 = Bar()
        self.assertEquals(attributes.get_history(f1._state, 'bars'), ([], [], []))
        self.assertEquals(attributes.get_history(b1._state, 'foo'), ([], [None], []))

        #b1.foo = f1
        f1.bars.append(b1)
        self.assertEquals(attributes.get_history(f1._state, 'bars'), ([b1], [], []))
        self.assertEquals(attributes.get_history(b1._state, 'foo'), ([f1], [], []))

        b2 = Bar()
        f1.bars.append(b2)
        self.assertEquals(attributes.get_history(f1._state, 'bars'), ([b1, b2], [], []))
        self.assertEquals(attributes.get_history(b1._state, 'foo'), ([f1], [], []))
        self.assertEquals(attributes.get_history(b2._state, 'foo'), ([f1], [], []))
Beispiel #17
0
    def setUp(self):
        global Post, Blog, called, lazy_load

        class Post(object):
            def __init__(self, name):
                self.name = name
            __hash__ = None
            def __eq__(self, other):
                return other.name == self.name

        class Blog(object):
            def __init__(self, name):
                self.name = name
            __hash__ = None
            def __eq__(self, other):
                return other.name == self.name

        called = [0]

        lazy_load = []
        def lazy_posts(instance):
            def load():
                called[0] += 1
                return lazy_load
            return load

        attributes.register_class(Post)
        attributes.register_class(Blog)
        attributes.register_attribute(Post, 'blog', uselist=False, extension=attributes.GenericBackrefExtension('posts'), trackparent=True, useobject=True)
        attributes.register_attribute(Blog, 'posts', uselist=True, extension=attributes.GenericBackrefExtension('blog'), callable_=lazy_posts, trackparent=True, useobject=True)
    def test_nativeext_submanager(self):
        class Mine(attributes.ClassManager): pass
        class A(object):
            __sa_instrumentation_manager__ = Mine

        attributes.register_class(A)
        eq_(type(attributes.manager_of_class(A)), Mine)
Beispiel #19
0
    def test_instance_dict(self):
        class User(MyClass):
            pass

        attributes.register_class(User)
        attributes.register_attribute(User,
                                      'user_id',
                                      uselist=False,
                                      useobject=False)
        attributes.register_attribute(User,
                                      'user_name',
                                      uselist=False,
                                      useobject=False)
        attributes.register_attribute(User,
                                      'email_address',
                                      uselist=False,
                                      useobject=False)

        u = User()
        u.user_id = 7
        u.user_name = 'john'
        u.email_address = '*****@*****.**'
        self.assert_(
            u.__dict__ == {
                '_my_state': u._my_state,
                '_goofy_dict': {
                    'user_id': 7,
                    'user_name': 'john',
                    'email_address': '*****@*****.**'
                }
            })
    def test_defaulted_init(self):
        class X(object):
            def __init__(self_, a, b=123, c='abc'):
                self_.a = a
                self_.b = b
                self_.c = c
        attributes.register_class(X)

        o = X('foo')
        eq_(o.a, 'foo')
        eq_(o.b, 123)
        eq_(o.c, 'abc')

        class Y(object):
            unique = object()

            class OutOfScopeForEval(object):
                def __repr__(self_):
                    # misleading repr
                    return '123'

            outofscope = OutOfScopeForEval()

            def __init__(self_, u=unique, o=outofscope):
                self_.u = u
                self_.o = o

        attributes.register_class(Y)

        o = Y()
        assert o.u is Y.unique
        assert o.o is Y.outofscope
    def test_customfinder_pass(self):
        class A(object): pass
        def find(cls):
            return None

        attributes.instrumentation_finders.insert(0, find)
        attributes.register_class(A)
        eq_(type(attributes.manager_of_class(A)), attributes.ClassManager)
 def register(self, cls, canary):
     original_init = cls.__init__
     attributes.register_class(cls)
     ne_(cls.__init__, original_init)
     manager = attributes.manager_of_class(cls)
     def on_init(state, instance, args, kwargs):
         canary.append((cls, 'on_init', type(instance)))
     manager.events.add_listener('on_init', on_init)
Beispiel #23
0
    def test_pickleness(self):
        attributes.register_class(MyTest)
        attributes.register_class(MyTest2)
        attributes.register_attribute(MyTest, 'user_id', uselist=False, useobject=False)
        attributes.register_attribute(MyTest, 'user_name', uselist=False, useobject=False)
        attributes.register_attribute(MyTest, 'email_address', uselist=False, useobject=False)
        attributes.register_attribute(MyTest2, 'a', uselist=False, useobject=False)
        attributes.register_attribute(MyTest2, 'b', uselist=False, useobject=False)
        # shouldnt be pickling callables at the class level
        def somecallable(*args):
            return None
        attr_name = 'mt2'
        attributes.register_attribute(MyTest, attr_name, uselist = True, trackparent=True, callable_=somecallable, useobject=True)

        o = MyTest()
        o.mt2.append(MyTest2())
        o.user_id=7
        o.mt2[0].a = 'abcde'
        pk_o = pickle.dumps(o)

        o2 = pickle.loads(pk_o)
        pk_o2 = pickle.dumps(o2)

        # so... pickle is creating a new 'mt2' string after a roundtrip here,
        # so we'll brute-force set it to be id-equal to the original string
        if False:
            o_mt2_str = [ k for k in o.__dict__ if k == 'mt2'][0]
            o2_mt2_str = [ k for k in o2.__dict__ if k == 'mt2'][0]
            self.assert_(o_mt2_str == o2_mt2_str)
            self.assert_(o_mt2_str is not o2_mt2_str)
            # change the id of o2.__dict__['mt2']
            former = o2.__dict__['mt2']
            del o2.__dict__['mt2']
            o2.__dict__[o_mt2_str] = former

            self.assert_(pk_o == pk_o2)

        # the above is kind of distrurbing, so let's do it again a little
        # differently.  the string-id in serialization thing is just an
        # artifact of pickling that comes up in the first round-trip.
        # a -> b differs in pickle memoization of 'mt2', but b -> c will
        # serialize identically.

        o3 = pickle.loads(pk_o2)
        pk_o3 = pickle.dumps(o3)
        o4 = pickle.loads(pk_o3)
        pk_o4 = pickle.dumps(o4)

        self.assert_(pk_o3 == pk_o4)

        # and lastly make sure we still have our data after all that.
        # identical serialzation is great, *if* it's complete :)
        self.assert_(o4.user_id == 7)
        self.assert_(o4.user_name is None)
        self.assert_(o4.email_address is None)
        self.assert_(len(o4.mt2) == 1)
        self.assert_(o4.mt2[0].a == 'abcde')
        self.assert_(o4.mt2[0].b is None)
Beispiel #24
0
    def test_scalar(self):
        class Foo(_base.BasicEntity):
            pass

        attributes.register_class(Foo)
        attributes.register_attribute(Foo, 'someattr', uselist=False, useobject=False)

        # case 1.  new object
        f = Foo()
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), (), ()))

        f.someattr = "hi"
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), (['hi'], (), ()))

        attributes.instance_state(f).commit(['someattr'])
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), ['hi'], ()))

        f.someattr = 'there'

        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), (['there'], (), ['hi']))
        attributes.instance_state(f).commit(['someattr'])

        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), ['there'], ()))

        del f.someattr
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), (), ['there']))

        # case 2.  object with direct dictionary settings (similar to a load operation)
        f = Foo()
        f.__dict__['someattr'] = 'new'
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), ['new'], ()))

        f.someattr = 'old'
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), (['old'], (), ['new']))

        attributes.instance_state(f).commit(['someattr'])
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), ['old'], ()))

        # setting None on uninitialized is currently a change for a scalar attribute
        # no lazyload occurs so this allows overwrite operation to proceed
        f = Foo()
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), (), ()))
        f.someattr = None
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([None], (), ()))

        f = Foo()
        f.__dict__['someattr'] = 'new'
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), ['new'], ()))
        f.someattr = None
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([None], (), ['new']))

        # set same value twice
        f = Foo()
        attributes.instance_state(f).commit(['someattr'])
        f.someattr = 'one'
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), (['one'], (), ()))
        f.someattr = 'two'
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), (['two'], (), ()))
Beispiel #25
0
    def test_null_instrumentation(self):
        class Foo(MyBaseClass):
            pass
        attributes.register_class(Foo)
        attributes.register_attribute(Foo, "name", uselist=False, useobject=False)
        attributes.register_attribute(Foo, "bars", uselist=True, trackparent=True, useobject=True)

        assert Foo.name == attributes.manager_of_class(Foo)['name']
        assert Foo.bars == attributes.manager_of_class(Foo)['bars']
    def test_null_instrumentation(self):
        class Foo(MyBaseClass):
            pass
        attributes.register_class(Foo)
        attributes.register_attribute(Foo, "name", uselist=False, useobject=False)
        attributes.register_attribute(Foo, "bars", uselist=True, trackparent=True, useobject=True)

        assert Foo.name == attributes.manager_of_class(Foo)['name']
        assert Foo.bars == attributes.manager_of_class(Foo)['bars']
    def test_single_down(self):
        class A(object): pass
        attributes.register_class(A)

        mgr_factory = lambda cls: attributes.ClassManager(cls)
        class B(A):
            __sa_instrumentation_manager__ = staticmethod(mgr_factory)

        assert_raises_message(TypeError, "multiple instrumentation implementations", attributes.register_class, B)
Beispiel #28
0
    def test_nativeext_submanager(self):
        class Mine(attributes.ClassManager):
            pass

        class A(object):
            __sa_instrumentation_manager__ = Mine

        attributes.register_class(A)
        eq_(type(attributes.manager_of_class(A)), Mine)
    def test_deferred(self):
        for base in (object, MyBaseClass, MyClass):

            class Foo(base):
                pass

            data = {'a': 'this is a', 'b': 12}

            def loader(state, keys):
                for k in keys:
                    state.dict[k] = data[k]
                return attributes.ATTR_WAS_SET

            attributes.register_class(Foo)
            manager = attributes.manager_of_class(Foo)
            manager.deferred_scalar_loader = loader
            attributes.register_attribute(Foo,
                                          'a',
                                          uselist=False,
                                          useobject=False)
            attributes.register_attribute(Foo,
                                          'b',
                                          uselist=False,
                                          useobject=False)

            assert Foo in attributes.instrumentation_registry._state_finders
            f = Foo()
            attributes.instance_state(f).expire_attributes(
                attributes.instance_dict(f), None)
            eq_(f.a, "this is a")
            eq_(f.b, 12)

            f.a = "this is some new a"
            attributes.instance_state(f).expire_attributes(
                attributes.instance_dict(f), None)
            eq_(f.a, "this is a")
            eq_(f.b, 12)

            attributes.instance_state(f).expire_attributes(
                attributes.instance_dict(f), None)
            f.a = "this is another new a"
            eq_(f.a, "this is another new a")
            eq_(f.b, 12)

            attributes.instance_state(f).expire_attributes(
                attributes.instance_dict(f), None)
            eq_(f.a, "this is a")
            eq_(f.b, 12)

            del f.a
            eq_(f.a, None)
            eq_(f.b, 12)

            attributes.instance_state(f).commit_all(
                attributes.instance_dict(f))
            eq_(f.a, None)
            eq_(f.b, 12)
    def test_single_up(self):

        class A(object): pass
        # delay registration

        mgr_factory = lambda cls: attributes.ClassManager(cls)
        class B(A):
            __sa_instrumentation_manager__ = staticmethod(mgr_factory)
        attributes.register_class(B)
        assert_raises(TypeError, attributes.register_class, A)
Beispiel #31
0
    def test_customfinder_pass(self):
        class A(object):
            pass

        def find(cls):
            return None

        attributes.instrumentation_finders.insert(0, find)
        attributes.register_class(A)
        eq_(type(attributes.manager_of_class(A)), attributes.ClassManager)
Beispiel #32
0
    def register(self, cls, canary):
        original_init = cls.__init__
        attributes.register_class(cls)
        ne_(cls.__init__, original_init)
        manager = attributes.manager_of_class(cls)

        def on_init(state, instance, args, kwargs):
            canary.append((cls, 'on_init', type(instance)))

        manager.events.add_listener('on_init', on_init)
    def test_diamond_b2(self):
        mgr_factory = lambda cls: attributes.ClassManager(cls)

        class A(object): pass
        class B1(A): pass
        class B2(A):
            __sa_instrumentation_manager__ = staticmethod(mgr_factory)
        class C(object): pass

        attributes.register_class(B2)
        assert_raises_message(TypeError, "multiple instrumentation implementations", attributes.register_class, B1)
    def test_diamond_c_b(self):
        mgr_factory = lambda cls: attributes.ClassManager(cls)

        class A(object): pass
        class B1(A): pass
        class B2(A):
            __sa_instrumentation_manager__ = mgr_factory
        class C(object): pass

        attributes.register_class(C)
        assert_raises(TypeError, attributes.register_class, B1)
Beispiel #35
0
    def test_single_down(self):
        class A(object):
            pass

        attributes.register_class(A)

        mgr_factory = lambda cls: attributes.ClassManager(cls)

        class B(A):
            __sa_instrumentation_manager__ = staticmethod(mgr_factory)

        assert_raises(TypeError, attributes.register_class, B)
    def test_subclassed(self):
        class MyEvents(attributes.Events):
            pass
        class MyClassManager(attributes.ClassManager):
            event_registry_factory = MyEvents

        attributes.instrumentation_finders.insert(0, lambda cls: MyClassManager)

        class A(object): pass

        attributes.register_class(A)
        manager = attributes.manager_of_class(A)
        assert isinstance(manager.events, MyEvents)
Beispiel #37
0
    def test_scalar(self):
        class Foo(fixtures.Base):
            pass

        attributes.register_class(Foo)
        attributes.register_attribute(Foo, 'someattr', uselist=False, useobject=False)

        # case 1.  new object
        f = Foo()
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], []))

        f.someattr = "hi"
        self.assertEquals(attributes.get_history(f._state, 'someattr'), (['hi'], [], []))

        f._state.commit(['someattr'])
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], ['hi'], []))

        f.someattr = 'there'

        self.assertEquals(attributes.get_history(f._state, 'someattr'), (['there'], [], ['hi']))
        f._state.commit(['someattr'])

        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], ['there'], []))

        del f.someattr
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], ['there']))

        # case 2.  object with direct dictionary settings (similar to a load operation)
        f = Foo()
        f.__dict__['someattr'] = 'new'
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], ['new'], []))

        f.someattr = 'old'
        self.assertEquals(attributes.get_history(f._state, 'someattr'), (['old'], [], ['new']))

        f._state.commit(['someattr'])
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], ['old'], []))

        # setting None on uninitialized is currently a change for a scalar attribute
        # no lazyload occurs so this allows overwrite operation to proceed
        f = Foo()
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], []))
        f.someattr = None
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([None], [], []))

        f = Foo()
        f.__dict__['someattr'] = 'new'
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], ['new'], []))
        f.someattr = None
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([None], [], ['new']))
Beispiel #38
0
    def test_collectionclasses(self):

        class Foo(object):pass
        attributes.register_class(Foo)
        attributes.register_attribute(Foo, "collection", uselist=True, typecallable=set, useobject=True)
        assert isinstance(Foo().collection, set)

        attributes.unregister_attribute(Foo, "collection")

        try:
            attributes.register_attribute(Foo, "collection", uselist=True, typecallable=dict, useobject=True)
            assert False
        except exceptions.ArgumentError, e:
            assert str(e) == "Type InstrumentedDict must elect an appender method to be a collection class"
    def test_instance_dict(self):
        class User(MyClass):
            pass

        attributes.register_class(User)
        attributes.register_attribute(User, 'user_id', uselist = False, useobject=False)
        attributes.register_attribute(User, 'user_name', uselist = False, useobject=False)
        attributes.register_attribute(User, 'email_address', uselist = False, useobject=False)

        u = User()
        u.user_id = 7
        u.user_name = 'john'
        u.email_address = '*****@*****.**'
        self.assert_(u.__dict__ == {'_my_state':u._my_state, '_goofy_dict':{'user_id':7, 'user_name':'john', 'email_address':'*****@*****.**'}}, u.__dict__)
Beispiel #40
0
    def test_object_collections_set(self):
        class Foo(_base.BasicEntity):
            pass
        class Bar(_base.BasicEntity):
            def __nonzero__(self):
                assert False

        attributes.register_class(Foo)
        attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True)

        hi = Bar(name='hi')
        there = Bar(name='there')
        old = Bar(name='old')
        new = Bar(name='new')

        # case 1.  new object
        f = Foo()
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [], ()))

        f.someattr = [hi]
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi], [], []))

        attributes.instance_state(f).commit(['someattr'])
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [hi], ()))

        f.someattr = [there]

        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([there], [], [hi]))
        attributes.instance_state(f).commit(['someattr'])

        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [there], ()))

        f.someattr = [hi]
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([hi], [], [there]))

        f.someattr = [old, new]
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([old, new], [], [there]))

        # case 2.  object with direct settings (similar to a load operation)
        f = Foo()
        collection = attributes.init_collection(attributes.instance_state(f), 'someattr')
        collection.append_without_event(new)
        attributes.instance_state(f).commit_all()
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [new], ()))

        f.someattr = [old]
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ([old], [], [new]))

        attributes.instance_state(f).commit(['someattr'])
        eq_(attributes.get_history(attributes.instance_state(f), 'someattr'), ((), [old], ()))
Beispiel #41
0
    def test_object_collections_set(self):
        class Foo(fixtures.Base):
            pass
        class Bar(fixtures.Base):
            def __nonzero__(self):
                assert False

        attributes.register_class(Foo)
        attributes.register_attribute(Foo, 'someattr', uselist=True, useobject=True)

        hi = Bar(name='hi')
        there = Bar(name='there')
        old = Bar(name='old')
        new = Bar(name='new')

        # case 1.  new object
        f = Foo()
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [], []))

        f.someattr = [hi]
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], []))

        f._state.commit(['someattr'])
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [hi], []))

        f.someattr = [there]

        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([there], [], [hi]))
        f._state.commit(['someattr'])

        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [there], []))

        f.someattr = [hi]
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([hi], [], [there]))

        f.someattr = [old, new]
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([old, new], [], [there]))

        # case 2.  object with direct settings (similar to a load operation)
        f = Foo()
        collection = attributes.init_collection(f, 'someattr')
        collection.append_without_event(new)
        f._state.commit_all()
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [new], []))

        f.someattr = [old]
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([old], [], [new]))

        f._state.commit(['someattr'])
        self.assertEquals(attributes.get_history(f._state, 'someattr'), ([], [old], []))
Beispiel #42
0
    def test_onetoone(self):
        class Port(object):pass
        class Jack(object):pass
        attributes.register_class(Port)
        attributes.register_class(Jack)
        attributes.register_attribute(Port, 'jack', uselist=False, extension=attributes.GenericBackrefExtension('port'), useobject=True)
        attributes.register_attribute(Jack, 'port', uselist=False, extension=attributes.GenericBackrefExtension('jack'), useobject=True)
        p = Port()
        j = Jack()
        p.jack = j
        self.assert_(j.port is p)
        self.assert_(p.jack is not None)

        j.port = None
        self.assert_(p.jack is None)
    def test_single_up(self):
        class A(object):
            pass

        # delay registration

        mgr_factory = lambda cls: attributes.ClassManager(cls)

        class B(A):
            __sa_instrumentation_manager__ = staticmethod(mgr_factory)

        attributes.register_class(B)

        assert_raises_message(TypeError,
                              "multiple instrumentation implementations",
                              attributes.register_class, A)
Beispiel #44
0
    def test_subclassed(self):
        class MyEvents(attributes.Events):
            pass

        class MyClassManager(attributes.ClassManager):
            event_registry_factory = MyEvents

        attributes.instrumentation_finders.insert(0,
                                                  lambda cls: MyClassManager)

        class A(object):
            pass

        attributes.register_class(A)
        manager = attributes.manager_of_class(A)
        assert isinstance(manager.events, MyEvents)
Beispiel #45
0
    def test_register_reserved_attribute(self):
        class T(object):
            pass

        attributes.register_class(T)
        manager = attributes.manager_of_class(T)

        sa = attributes.ClassManager.STATE_ATTR
        ma = attributes.ClassManager.MANAGER_ATTR

        fails = lambda method, attr: assert_raises(
            KeyError, getattr(manager, method), attr, property())

        fails('install_member', sa)
        fails('install_member', ma)
        fails('install_descriptor', sa)
        fails('install_descriptor', ma)
Beispiel #46
0
    def test_diamond_c_b(self):
        mgr_factory = lambda cls: attributes.ClassManager(cls)

        class A(object):
            pass

        class B1(A):
            pass

        class B2(A):
            __sa_instrumentation_manager__ = mgr_factory

        class C(object):
            pass

        attributes.register_class(C)
        assert_raises(TypeError, attributes.register_class, B1)
Beispiel #47
0
    def test_uninstrument(self):
        class A(object):
            pass

        manager = attributes.register_class(A)

        assert attributes.manager_of_class(A) is manager
        attributes.unregister_class(A)
        assert attributes.manager_of_class(A) is None
Beispiel #48
0
    def test_alternate_finders(self):
        """Ensure the generic finder front-end deals with edge cases."""

        class Unknown(object): pass
        class Known(MyBaseClass): pass

        attributes.register_class(Known)
        k, u = Known(), Unknown()

        assert attributes.manager_of_class(Unknown) is None
        assert attributes.manager_of_class(Known) is not None
        assert attributes.manager_of_class(None) is None

        assert attributes.instance_state(k) is not None
        assert_raises((AttributeError, KeyError),
                          attributes.instance_state, u)
        assert_raises((AttributeError, KeyError),
                          attributes.instance_state, None)
    def test_diamond_b2(self):
        mgr_factory = lambda cls: attributes.ClassManager(cls)

        class A(object):
            pass

        class B1(A):
            pass

        class B2(A):
            __sa_instrumentation_manager__ = staticmethod(mgr_factory)

        class C(object):
            pass

        attributes.register_class(B2)
        assert_raises_message(TypeError,
                              "multiple instrumentation implementations",
                              attributes.register_class, B1)
Beispiel #50
0
    def test_basic(self):
        import pickle

        global A

        class A(object):
            pass

        def canary(instance):
            assert False

        try:
            attributes.register_class(A)
            manager = attributes.manager_of_class(A)
            manager.events.add_listener('on_load', canary)

            a = A()
            p_a = pickle.dumps(a)
            re_a = pickle.loads(p_a)
        finally:
            del A
Beispiel #51
0
    def test_history(self):
        for base in (object, MyBaseClass, MyClass):
            class Foo(base):
                pass
            class Bar(base):
                pass

            attributes.register_class(Foo)
            attributes.register_class(Bar)
            attributes.register_attribute(Foo, "name", uselist=False, useobject=False)
            attributes.register_attribute(Foo, "bars", uselist=True, trackparent=True, useobject=True)
            attributes.register_attribute(Bar, "name", uselist=False, useobject=False)


            f1 = Foo()
            f1.name = 'f1'

            eq_(attributes.get_history(attributes.instance_state(f1), 'name'), (['f1'], (), ()))

            b1 = Bar()
            b1.name = 'b1'
            f1.bars.append(b1)
            eq_(attributes.get_history(attributes.instance_state(f1), 'bars'), ([b1], [], []))

            attributes.instance_state(f1).commit_all(attributes.instance_dict(f1))
            attributes.instance_state(b1).commit_all(attributes.instance_dict(b1))

            eq_(attributes.get_history(attributes.instance_state(f1), 'name'), ((), ['f1'], ()))
            eq_(attributes.get_history(attributes.instance_state(f1), 'bars'), ((), [b1], ()))

            f1.name = 'f1mod'
            b2 = Bar()
            b2.name = 'b2'
            f1.bars.append(b2)
            eq_(attributes.get_history(attributes.instance_state(f1), 'name'), (['f1mod'], (), ['f1']))
            eq_(attributes.get_history(attributes.instance_state(f1), 'bars'), ([b2], [b1], []))
            f1.bars.remove(b1)
            eq_(attributes.get_history(attributes.instance_state(f1), 'bars'), ([b2], [], [b1]))
Beispiel #52
0
    def test_none(self):
        class A(object):
            pass

        attributes.register_class(A)

        mgr_factory = lambda cls: attributes.ClassManager(cls)

        class B(object):
            __sa_instrumentation_manager__ = staticmethod(mgr_factory)

        attributes.register_class(B)

        class C(object):
            __sa_instrumentation_manager__ = attributes.ClassManager

        attributes.register_class(C)
Beispiel #53
0
    def test_nativeext_interfaceexact(self):
        class A(object):
            __sa_instrumentation_manager__ = sa.orm.interfaces.InstrumentationManager

        attributes.register_class(A)
        ne_(type(attributes.manager_of_class(A)), attributes.ClassManager)