def test_custom_type(self): def write_as_list(list_interface_obj, encoder): list_interface_obj.ran = True self.assertEqual(id(encoder), id(self.encoder)) return list(list_interface_obj) class ListWrapper(object): ran = False def __iter__(self): return iter([1, 2, 3]) pyamf.add_type(ListWrapper, write_as_list) x = ListWrapper() self.encoder.writeElement(x) self.assertEqual(x.ran, True) self.assertEqual( self.buf.getvalue(), "\n\x00\x00\x00\x03\x00?\xf0" "\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00@" "\x08\x00\x00\x00\x00\x00\x00", )
def when_imported(mod): """ This function is called immediately after mymodule has been imported. It configures PyAMF to encode a list when an instance of mymodule.CustomClass is encountered. """ import pyamf pyamf.add_type(mod.CustomClass, lambda obj: list(obj))
def setUp(self): CollectionsTestCase.setUp(self) if not hasattr(collections, 'namedtuple'): self.skipTest("'collections.namedtuple' not available") user_vo = collections.namedtuple('user_vo', 'id name age') pyamf.add_type(user_vo, lambda obj, encoder: obj._asdict()) self.obj = user_vo(1, 'Hadrien', 30) self.orig = self.obj._asdict()
def test_add_class(self): class A: pass class B(object): pass pyamf.add_type(A) self.assertTrue(A in pyamf.TYPE_MAP) pyamf.add_type(B) self.assertTrue(B in pyamf.TYPE_MAP)
def test_add_multiple(self): td = pyamf.add_type((chr,)) class A(object): pass class B(object): pass class C(object): pass td = pyamf.add_type([A, B, C])
def test_add_multiple(self): td = pyamf.add_type((chr,)) class A(object): pass class B(object): pass class C(object): pass td = pyamf.add_type([A, B, C]) self.assertEqual(td, pyamf.get_type([A, B, C]))
def test_remove(self): self.assertRaises(KeyError, pyamf.remove_type, chr) td = pyamf.add_type((chr,)) self.assertRaises(KeyError, pyamf.remove_type, chr) td2 = pyamf.remove_type((chr,)) self.assertEqual(td, td2)
def test_custom_type(self): def write_as_list(list_interface_obj, encoder): list_interface_obj.ran = True self.assertEqual(id(self.encoder), id(encoder)) return list(list_interface_obj) class ListWrapper(object): ran = False def __iter__(self): return iter([1, 2, 3]) pyamf.add_type(ListWrapper, write_as_list) x = ListWrapper() self.assertEncoded(x, '\t\x07\x01\x04\x01\x04\x02\x04\x03') self.assertTrue(x.ran)
def test_custom_type(self): def write_as_list(list_interface_obj): list_interface_obj.ran = True return list(list_interface_obj) class ListWrapper(object): ran = False def __iter__(self): return iter([1, 2, 3]) pyamf.add_type(ListWrapper, write_as_list) x = ListWrapper() self.encoder.writeElement(x) self.assertEquals(x.ran, True) self.assertEquals(self.buf.getvalue(), '\t\x07\x01\x04\x01\x04\x02\x04\x03')
def test_get_type(self): self.assertRaises(KeyError, pyamf.get_type, chr) td = pyamf.add_type((chr,)) self.assertRaises(KeyError, pyamf.get_type, chr) td2 = pyamf.get_type((chr,)) self.assertEqual(td, td2) td2 = pyamf.get_type([chr,]) self.assertEqual(td, td2)
C{object.__class__: {key1: object1, key2: object2, .., keyn: objectn}}. We use the datastore key to do the reference checking. @since: 0.4.1 """ if not obj.is_saved(): encoder.writeObject(obj) return context = encoder.context kls = obj.__class__ s = obj.key() gae_objects = getGAEObjects(context) try: referenced_object = gae_objects.getClassKey(kls, s) except KeyError: referenced_object = obj gae_objects.addClassKey(kls, s, obj) encoder.writeObject(referenced_object) # initialise the module here: hook into pyamf pyamf.register_alias_type(DataStoreClassAlias, db.Model) pyamf.add_type(db.Query, util.to_list) pyamf.add_type(db.Model, writeGAEObject)
# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ SQLAlchemy adapter module. @see: U{SQLAlchemy homepage (external)<http://www.sqlalchemy.org>} @since: 0.4 """ from sqlalchemy.orm import collections import pyamf from pyamf.adapters import util pyamf.add_type(collections.InstrumentedList, util.to_list) pyamf.add_type(collections.InstrumentedDict, util.to_dict) pyamf.add_type(collections.InstrumentedSet, util.to_set)
# Copyright (c) The PyAMF Project. # See LICENSE.txt for details. """ U{array<http://docs.python.org/library/array.html>} adapter module. Will convert all array.array instances to a python list before encoding. All type information is lost (but degrades nicely). @since: 0.5 """ import array import pyamf from pyamf.adapters import util if hasattr(array, 'ArrayType'): pyamf.add_type(array.ArrayType, util.to_list)
# Copyright (c) The PyAMF Project. # See LICENSE.txt for details. """ Django query adapter module. Sets up basic type mapping and class mappings for a Django models. @see: U{Django Project<http://www.djangoproject.com>} @since: 0.1b """ from django.db.models import query import pyamf from pyamf.adapters import util pyamf.add_type(query.QuerySet, util.to_list)
# Copyright (c) The PyAMF Project. # See LICENSE.txt for details. """ U{collections<http://docs.python.org/library/collections.html>} adapter module. @since: 0.5 """ import collections import pyamf from pyamf.adapters import util if hasattr(collections, 'deque'): pyamf.add_type(collections.deque, util.to_list) if hasattr(collections, 'defaultdict'): pyamf.add_type(collections.defaultdict, util.to_dict)
# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ C{django.db.models.fields} adapter module. @see: U{Django Project<http://www.djangoproject.com>} @since: 0.4 """ from django.db.models import fields import pyamf def convert_NOT_PROVIDED(x, encoder): """ @rtype: L{Undefined<pyamf.Undefined>} """ return pyamf.Undefined pyamf.add_type(lambda x: x is fields.NOT_PROVIDED, convert_NOT_PROVIDED)
try: referenced_object = gae_objects.getClassKey(kls, s) except KeyError: gae_objects.addClassKey(kls, s, object) self.writeNonGAEObject(object, *args, **kwargs) return self.writeNonGAEObject(referenced_object, *args, **kwargs) def install_gae_reference_model_hook(mod): """ Called when L{pyamf.amf0} or L{pyamf.amf3} are imported. Attaches the L{writeGAEObject} method to the C{Encoder} class in that module. @param mod: The module imported. @since: 0.4.1 """ if not hasattr(mod.Encoder, 'writeNonGAEObject'): mod.Encoder.writeNonGAEObject = mod.Encoder.writeObject mod.Encoder.writeObject = writeGAEObject # initialise the module here: hook into pyamf pyamf.add_type(db.Query, util.to_list) pyamf.register_alias_type(DataStoreClassAlias, db.Model, db.Expando) # hook the L{writeGAEObject} method to the Encoder class on import imports.whenImported('pyamf.amf0', install_gae_reference_model_hook) imports.whenImported('pyamf.amf3', install_gae_reference_model_hook)
def test_add_callable(self): td = pyamf.add_type(ord) self.assertTrue(ord in pyamf.TYPE_MAP) self.assertTrue(td in pyamf.TYPE_MAP.values())
def test_add_same(self): pyamf.add_type(chr) self.assertRaises(KeyError, pyamf.add_type, chr)
# Copyright (c) The PyAMF Project. # See LICENSE.txt for details. """ Adapter for the stdlib C{sets} module. @since: 0.4 """ import sets import pyamf from pyamf.adapters import util if hasattr(sets, 'ImmutableSet'): pyamf.add_type(sets.ImmutableSet, util.to_tuple) if hasattr(sets, 'Set'): pyamf.add_type(sets.Set, util.to_tuple)
# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE.txt for details. """ Django query adapter module. Sets up basic type mapping and class mappings for a Django models. @see: U{Django Project<http://www.djangoproject.com>} @since: 0.1b """ from django.db.models import query import pyamf from pyamf.adapters import util pyamf.add_type(query.QuerySet, util.to_list)
given object graph. We create a new map on the encoder context object which contains a dict of C{object.__class__: {key1: object1, key2: object2, .., keyn: objectn}}. We use the primary key to do the reference checking. @since: 0.5 """ s = obj.pk if s is None: encoder.writeObject(obj) return django_objects = getDjangoObjects(encoder.context) kls = obj.__class__ try: referenced_object = django_objects.getClassKey(kls, s) except KeyError: referenced_object = obj django_objects.addClassKey(kls, s, obj) encoder.writeObject(referenced_object) # initialise the module here: hook into pyamf pyamf.register_alias_type(DjangoClassAlias, Model) pyamf.add_type(Model, writeDjangoObject)
Adapter for the U{decimal<http://docs.python.org/library/decimal.html>} module. @since: 0.4 """ import decimal import pyamf def convert_Decimal(x, encoder): """ Called when an instance of U{decimal.Decimal<http:// docs.python.org/library/decimal.html#decimal-objects>} is about to be encoded to an AMF stream. @return: If the encoder is in 'strict' mode then C{x} will be converted to a float. Otherwise an L{pyamf.EncodeError} with a friendly message is raised. """ if encoder.strict is False: return float(x) raise pyamf.EncodeError('Unable to encode decimal.Decimal instances as ' 'there is no way to guarantee exact conversion. Use strict=False to ' 'convert to a float.') if hasattr(decimal, 'Decimal'): pyamf.add_type(decimal.Decimal, convert_Decimal)
# Copyright (c) The PyAMF Project. # See LICENSE.txt for details. """ U{collections<http://docs.python.org/library/collections.html>} adapter module. @since: 0.5 """ import collections import pyamf from pyamf.adapters import util if hasattr(collections, 'deque'): pyamf.add_type(collections.deque, util.to_list) if hasattr(collections, 'defaultdict'): pyamf.add_type(collections.defaultdict, util.to_dict) if hasattr(collections, 'Counter'): pyamf.add_type(collections.Counter, util.to_dict) if hasattr(collections, 'OrderedDict'): pyamf.add_type(collections.OrderedDict, util.to_dict)
fields = obj._fields for key, value in attrs.items(): if key not in fields.keys(): print "Got unknown key '%s' for %r" % (key, obj) del attrs[key] return attrs def map_mongoengine_document(klass): if not isinstance(klass, type): klass = type(klass) if issubclass(klass, BaseDocument): return True return False def objectIDHack(obj, encoder=None): """ For some reason ObjectIDs f**k everything up. I dont know why and when I try to find out I end up smashing things. So here a little hack! @param obj: @param encoder: @return: """ encoder.writeObject({}) pyamf.register_alias_type(MongoEngineDocumentAlias, map_mongoengine_document) pyamf.add_type(ObjectId, objectIDHack)
@since: 0.4 """ import decimal import pyamf def convert_Decimal(x, encoder): """ Called when an instance of L{decimal.Decimal} is about to be encoded to an AMF stream. @param x: The L{decimal.Decimal} instance to encode. @param encoder: The L{pyamf.BaseEncoder} instance about to perform the operation. @return: If the encoder is in 'strict' mode then C{x} will be converted to a float. Otherwise an L{pyamf.EncodeError} with a friendly message is raised. """ if encoder is not None and isinstance(encoder, pyamf.BaseEncoder): if encoder.strict is False: return float(x) raise pyamf.EncodeError('Unable to encode decimal.Decimal instances as ' 'there is no way to guarantee exact conversion. Use strict=False to ' 'convert to a float.') if hasattr(decimal, 'Decimal'): pyamf.add_type(decimal.Decimal, convert_Decimal)
# Copyright (c) 2007-2008 The PyAMF Project. # See LICENSE for details. """ Django adapter module. Sets up basic type mapping and class mappings for a Django project. @see: U{Django Project<http://www.djangoproject.com>} @author: U{Nick Joyce<mailto:[email protected]>} @since: 0.1b """ import pyamf try: from django.db.models.query import QuerySet except ImportError: QuerySet = None if QuerySet is not None: def _write_queryset(qs): return list(qs) pyamf.add_type(QuerySet, _write_queryset)
return value # TimeProperty fields expect specific types of data # whereas PyAMF only decodes into datetime.datetime # objects. return value.time() def transform_xdb_stubs(payload, context): """ Called when a successful decode has been performed. Transform the stubs within the payload to proper db.Model instances. """ stubs = context.get(XDB_STUB_NAME, None) if not stubs: return payload stubs.transform() return payload # initialise the module here: hook into pyamf pyamf.register_alias_type(DataStoreClassAlias, db.Model) pyamf.add_type(db.Query, util.to_list) pyamf.add_type(db.Key, encode_xdb_key) pyamf.add_type(db.Model, encode_xdb_entity) pyamf.add_post_decode_processor(transform_xdb_stubs)
@since: 0.6.2 """ import weakref import pyamf from pyamf.adapters import util class Foo(object): pass weakref_type = type(weakref.ref(Foo())) def get_referent(reference, **kwargs): return reference() pyamf.add_type(weakref_type, get_referent) if hasattr(weakref, 'WeakValueDictionary'): pyamf.add_type(weakref.WeakValueDictionary, util.to_dict) if hasattr(weakref, 'WeakSet'): pyamf.add_type(weakref.WeakSet, util.to_list)
# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE.txt for details. """ collections adapter module. @since: 0.5 """ import collections import pyamf from pyamf.adapters import util if hasattr(collections, 'deque'): pyamf.add_type(collections.deque, util.to_list) if hasattr(collections, 'defaultdict'): pyamf.add_type(collections.defaultdict, util.to_dict)
# Copyright (c) The PyAMF Project. # See LICENSE.txt for details. """ C{django.utils.translation} adapter module. @see: U{Django Project<http://www.djangoproject.com>} @since: 0.4.2 """ from django.utils.translation import ugettext_lazy import pyamf def convert_lazy(l, encoder=None): if l.__class__._delegate_unicode: return unicode(l) if l.__class__._delegate_str: return str(l) raise ValueError('Don\'t know how to convert lazy value %s' % (repr(l),)) pyamf.add_type(type(ugettext_lazy('foo')), convert_lazy)
# Copyright (c) The PyAMF Project. # See LICENSE for details. """ Adapter for the stdlib C{sets} module. @since: 0.4 """ import sets import pyamf from pyamf.adapters import util if hasattr(sets, 'ImmutableSet'): pyamf.add_type(sets.ImmutableSet, util.to_tuple) if hasattr(sets, 'Set'): pyamf.add_type(sets.Set, util.to_tuple)
if self.KEY_ATTR in attrs: del attrs[self.KEY_ATTR] for key, prop in self.klass.__dict__.iteritems(): if isinstance(prop, property) and key in attrs.keys(): if prop.fset is None: del attrs[key] pyamf.util.set_attrs(obj, attrs) def is_class_sa_mapped(klass): """ @rtype: C{bool} """ if not isinstance(klass, type): klass = type(klass) try: class_mapper(klass) except UnmappedInstanceError: return False return True pyamf.register_alias_type(SaMappedClassAlias, is_class_sa_mapped) pyamf.add_type(collections.InstrumentedList, util.to_list) pyamf.add_type(collections.InstrumentedDict, util.to_dict) pyamf.add_type(collections.InstrumentedSet, util.to_set)
datetime.time(0, 0, 0) ) def post_ndb_process(payload, context): """ """ stubs = context.get(NDB_STUB_NAME, None) if not stubs: return payload stubs.transform() return payload # small optimisation to compile the ndb.Model base class if hasattr(ndb.model, '_NotEqualMixin'): not_equal_mixin = pyamf.register_class(ndb.model._NotEqualMixin) not_equal_mixin.compile() del not_equal_mixin # initialise the module here: hook into pyamf pyamf.register_alias_type(NDBClassAlias, ndb.Model, ndb.Expando) pyamf.add_type(ndb.Query, util.to_list) pyamf.add_type(ndb.Model, encode_ndb_instance) pyamf.add_post_decode_processor(post_ndb_process) pyamf.add_type(ndb.Key, encode_ndb_key)
# Copyright (c) 2007-2008 The PyAMF Project. # See LICENSE for details. """ C{django.db.models.fields} adapter module. @see: U{Django Project<http://www.djangoproject.com>} @since: 0.3.2 """ from django.db.models import fields import pyamf def convert_NOT_PROVIDED(x): return pyamf.Undefined pyamf.add_type(lambda x: x == fields.NOT_PROVIDED, convert_NOT_PROVIDED)
# Copyright (c) 2007-2008 The PyAMF Project. # See LICENSE for details. """ Django model adapter module. Sets up basic type mapping and class mappings for a Django models. @see: U{Django Project<http://www.djangoproject.com>} @author: U{Nick Joyce<mailto:[email protected]>} @since: 0.1b """ from django.db.models import query import pyamf def write_queryset(qs): return list(qs) pyamf.add_type(query.QuerySet, write_queryset)
# Copyright (c) 2007-2009 The PyAMF Project. # See LICENSE for details. """ Django model adapter module. Sets up basic type mapping and class mappings for a Django models. @see: U{Django Project<http://www.djangoproject.com>} @since: 0.1b """ from django.db.models import query import pyamf def write_queryset(qs, encoder): return list(qs) pyamf.add_type(query.QuerySet, write_queryset)