def test_simple(self): class A(object): pass pyamf.register_alias_type(DummyAlias, A) self.assertEqual(util.get_class_alias(A), DummyAlias)
def getClassAlias(self, klass): """ Gets a class alias based on the supplied C{klass}. If one is not found in the global context, one is created locally. If you supply a string alias and the class is not registered, L{pyamf.UnknownClassAlias} will be raised. @param klass: A class object or string alias. @return: The L{pyamf.ClassAlias} instance that describes C{klass} """ try: return self._class_aliases[klass] except KeyError: pass try: alias = self._class_aliases[klass] = pyamf.get_class_alias(klass) except pyamf.UnknownClassAlias: if isinstance(klass, python.str_types): raise # no alias has been found yet .. check subclasses alias = util.get_class_alias(klass) or pyamf.ClassAlias meta = util.get_class_meta(klass) alias = alias(klass, defer=True, **meta) self._class_aliases[klass] = alias return alias
def register_class(klass, alias=None): """ Registers a class to be used in the data streaming. This is the equivalent of the C{[RemoteClass(alias="foobar")]} metatag in Adobe Flex, and the C{flash.net.registerClassAlias} method in Actionscript 3.0. @return: The registered L{ClassAlias} instance. @see: L{unregister_class} @see: U{flash.net.registerClassAlias on Adobe Help (external) <http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/package.html#registerClassAlias%28%29>} """ meta = util.get_class_meta(klass) if alias is not None: meta['alias'] = alias alias_klass = util.get_class_alias(klass) or ClassAlias x = alias_klass(klass, defer=True, **meta) if not x.anonymous: CLASS_CACHE[x.alias] = x CLASS_CACHE[klass] = x return x
def register_class(klass, alias=None): """ Registers a class to be used in the data streaming. This is the equivalent of the C{[RemoteClass(alias="foobar")]} metatag in Adobe Flex, and the C{flash.net.registerClassAlias} method in Actionscript 3.0. @return: The registered L{ClassAlias} instance. @see: L{unregister_class} @see: U{flash.net.registerClassAlias on Adobe Help (external) <http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/package.html#registerClassAlias%28%29>} """ meta = util.get_class_meta(klass) if alias is not None: meta["alias"] = alias alias_klass = util.get_class_alias(klass) or ClassAlias x = alias_klass(klass, defer=True, **meta) if not x.anonymous: CLASS_CACHE[x.alias] = x CLASS_CACHE[klass] = x return x
def test_multiple(self): class A(object): pass class B(object): pass class C(object): pass pyamf.register_alias_type(DummyAlias, A) pyamf.register_alias_type(AnotherDummyAlias, B) pyamf.register_alias_type(YADummyAlias, C) self.assertEqual(util.get_class_alias(B), AnotherDummyAlias) self.assertEqual(util.get_class_alias(C), YADummyAlias) self.assertEqual(util.get_class_alias(A), DummyAlias)
def register_alias_type(klass, *args): """ This function allows you to map subclasses of L{ClassAlias} to classes listed in C{args}. When an object is read/written from/to the AMF stream, a paired L{ClassAlias} instance is created (or reused), based on the Python class of that object. L{ClassAlias} provides important metadata for the class and can also control how the equivalent Python object is created, how the attributes are applied etc. Use this function if you need to do something non-standard. @see: L{pyamf.adapters._google_appengine_ext_db.DataStoreClassAlias} for a good example. @since: 0.4 """ def check_type_registered(arg): for k, v in ALIAS_TYPES.iteritems(): for kl in v: if arg is kl: raise RuntimeError('%r is already registered under %r' % ( arg, k)) if not isinstance(klass, python.class_types): raise TypeError('klass must be class') if not issubclass(klass, ClassAlias): raise ValueError('New aliases must subclass pyamf.ClassAlias') if len(args) == 0: raise ValueError('At least one type must be supplied') if len(args) == 1 and hasattr(args[0], '__call__'): c = args[0] check_type_registered(c) else: for arg in args: if not isinstance(arg, python.class_types): raise TypeError('%r must be class' % (arg,)) check_type_registered(arg) ALIAS_TYPES[klass] = args for k, v in CLASS_CACHE.copy().iteritems(): new_alias = util.get_class_alias(v.klass) if new_alias is klass: meta = util.get_class_meta(v.klass) meta['alias'] = v.alias alias_klass = klass(v.klass, **meta) CLASS_CACHE[k] = alias_klass CLASS_CACHE[v.klass] = alias_klass
def register_alias_type(klass, *args): """ This function allows you to map subclasses of L{ClassAlias} to classes listed in C{args}. When an object is read/written from/to the AMF stream, a paired L{ClassAlias} instance is created (or reused), based on the Python class of that object. L{ClassAlias} provides important metadata for the class and can also control how the equivalent Python object is created, how the attributes are applied etc. Use this function if you need to do something non-standard. @see: L{pyamf.adapters._google_appengine_ext_db.DataStoreClassAlias} for a good example. @since: 0.4 """ def check_type_registered(arg): for k, v in ALIAS_TYPES.iteritems(): for kl in v: if arg is kl: raise RuntimeError('%r is already registered under %r' % (arg, k)) if not isinstance(klass, python.class_types): raise TypeError('klass must be class') if not issubclass(klass, ClassAlias): raise ValueError('New aliases must subclass pyamf.ClassAlias') if len(args) == 0: raise ValueError('At least one type must be supplied') if len(args) == 1 and hasattr(args[0], '__call__'): c = args[0] check_type_registered(c) else: for arg in args: if not isinstance(arg, python.class_types): raise TypeError('%r must be class' % (arg, )) check_type_registered(arg) ALIAS_TYPES[klass] = args for k, v in CLASS_CACHE.copy().iteritems(): new_alias = util.get_class_alias(v.klass) if new_alias is klass: meta = util.get_class_meta(v.klass) meta['alias'] = v.alias alias_klass = klass(v.klass, **meta) CLASS_CACHE[k] = alias_klass CLASS_CACHE[v.klass] = alias_klass
def test_subclass(self): class A(object): pass class B(A): pass pyamf.register_alias_type(DummyAlias, A) self.assertEquals(util.get_class_alias(B), DummyAlias)
def test_nested(self): class A(object): pass class B(object): pass class C(object): pass pyamf.register_alias_type(DummyAlias, A, B, C) self.assertEqual(util.get_class_alias(B), DummyAlias)
def register_class(klass, alias=None, attrs=None, attr_func=None, metadata=[]): """ Registers a class to be used in the data streaming. @type alias: C{str} @param alias: The alias of klass, i.e. C{org.example.Person}. @param attrs: A list of attributes that will be encoded for the class. @type attrs: C{list} or C{None} @type attr_func: @param attr_func: @type metadata: @param metadata: @raise TypeError: PyAMF doesn't support required init arguments. @raise TypeError: The C{klass} is not callable. @raise ValueError: The C{klass} or C{alias} is already registered. @return: The registered L{ClassAlias}. """ if not callable(klass): raise TypeError("klass must be callable") if klass in CLASS_CACHE: raise ValueError("klass %s already registered" % (klass, )) if alias is not None and alias in CLASS_CACHE.keys(): raise ValueError("alias '%s' already registered" % (alias, )) alias_klass = util.get_class_alias(klass) if alias_klass is None: alias_klass = ClassAlias x = alias_klass(klass, alias, attr_func=attr_func, attrs=attrs, metadata=metadata) if alias is None: alias = "%s.%s" % ( klass.__module__, klass.__name__, ) CLASS_CACHE[alias] = x return x
def getClassAlias(self, klass): """ Gets a class alias based on the supplied C{klass}. """ if klass not in self.class_aliases.keys(): try: self.class_aliases[klass] = get_class_alias(klass) except UnknownClassAlias: # no alias has been found yet .. check subclasses alias = util.get_class_alias(klass) if alias is not None: self.class_aliases[klass] = alias(klass, None) else: self.class_aliases[klass] = None return self.class_aliases[klass]
def getClassAlias(self, klass): """ Gets a class alias based on the supplied C{klass}. """ try: return self.class_aliases[klass] except KeyError: pass try: self.class_aliases[klass] = get_class_alias(klass) except UnknownClassAlias: # no alias has been found yet .. check subclasses alias = util.get_class_alias(klass) self.class_aliases[klass] = alias(klass) return self.class_aliases[klass]
def register_class(klass, alias=None): """ Registers a class to be used in the data streaming. @return: The registered L{ClassAlias}. """ meta = util.get_class_meta(klass) if alias is not None: meta['alias'] = alias alias_klass = util.get_class_alias(klass) x = alias_klass(klass, defer=True, **meta) if not x.anonymous: CLASS_CACHE[x.alias] = x CLASS_CACHE[klass] = x return x
def getClassAlias(self, klass): """ Gets a class alias based on the supplied C{klass}. @param klass: The class object. @return: The L{ClassAlias} that is linked to C{klass} """ try: return self.class_aliases[klass] except KeyError: pass try: self.class_aliases[klass] = get_class_alias(klass) except UnknownClassAlias: # no alias has been found yet .. check subclasses alias = util.get_class_alias(klass) self.class_aliases[klass] = alias(klass) return self.class_aliases[klass]
def register_class(klass, alias=None, attrs=None, attr_func=None, metadata=[]): """ Registers a class to be used in the data streaming. @type alias: C{str} @param alias: The alias of klass, i.e. C{org.example.Person}. @param attrs: A list of attributes that will be encoded for the class. @type attrs: C{list} or C{None} @type attr_func: @param attr_func: @type metadata: @param metadata: @raise TypeError: PyAMF doesn't support required init arguments. @raise TypeError: The C{klass} is not callable. @raise ValueError: The C{klass} or C{alias} is already registered. @return: The registered L{ClassAlias}. """ if not callable(klass): raise TypeError("klass must be callable") if klass in CLASS_CACHE: raise ValueError("klass %s already registered" % (klass,)) if alias is not None and alias in CLASS_CACHE.keys(): raise ValueError("alias '%s' already registered" % (alias,)) alias_klass = util.get_class_alias(klass) if alias_klass is None: alias_klass = ClassAlias x = alias_klass(klass, alias, attr_func=attr_func, attrs=attrs, metadata=metadata) if alias is None: alias = "%s.%s" % (klass.__module__, klass.__name__,) CLASS_CACHE[alias] = x return x
def register_class(klass, alias=None): """ Registers a class to be used in the data streaming. This is the equivalent to the C{[RemoteClass(alias="foobar")]} AS3 metatag. @return: The registered L{ClassAlias} instance. """ meta = util.get_class_meta(klass) if alias is not None: meta['alias'] = alias alias_klass = util.get_class_alias(klass) or ClassAlias x = alias_klass(klass, defer=True, **meta) if not x.anonymous: CLASS_CACHE[x.alias] = x CLASS_CACHE[klass] = x return x
def writeObject(self, obj, use_proxies=None): """ Writes an object to the stream. @param obj: The object data to be encoded to the AMF3 data stream. @type obj: object data @raise EncodeError: Encoding an object in amf3 tagged as amf0 only. """ if use_proxies is None: use_proxies = self.use_proxies if use_proxies is True: self.writeProxy(obj) return self.stream.write(TYPE_OBJECT) ref = self.context.getObjectReference(obj) if ref is not None: self._writeInteger(ref << 1) return self.context.addObject(obj) # object is not referenced, serialise it kls = obj.__class__ definition = self.context.getClass(kls) alias = None class_ref = False # if the class definition is a reference if definition: class_ref = True alias = definition.alias if alias.anonymous and definition.reference is not None: class_ref = True else: try: alias = pyamf.get_class_alias(kls) except pyamf.UnknownClassAlias: alias_klass = util.get_class_alias(kls) meta = util.get_class_meta(kls) alias = alias_klass(kls, defer=True, **meta) definition = ClassDefinition(alias) self.context.addClass(definition, alias.klass) if class_ref: self.stream.write(definition.reference) else: ref = 0 if definition.encoding != ObjectEncoding.EXTERNAL: ref += definition.attr_len << 4 final_reference = encode_int(ref | definition.encoding << 2 | REFERENCE_BIT << 1 | REFERENCE_BIT) self.stream.write(final_reference) definition.reference = encode_int( definition.reference << 2 | REFERENCE_BIT) if alias.anonymous: self.stream.write_uchar(0x01) else: self._writeString(alias.alias) # work out what the final reference for the class will be. # this is okay because the next time an object of the same # class is encoded, class_ref will be True and never get here # again. if alias.external: obj.__writeamf__(DataOutput(self)) return attrs = alias.getEncodableAttributes(obj, codec=self) if alias.static_attrs: if not class_ref: [self._writeString(attr) for attr in alias.static_attrs] for attr in alias.static_attrs: value = attrs.pop(attr) self.writeElement(value) if definition.encoding == ObjectEncoding.STATIC: return if definition.encoding == ObjectEncoding.DYNAMIC: if attrs: for attr, value in attrs.iteritems(): self._writeString(attr) self.writeElement(value) self.stream.write_uchar(0x01)
def test_none_existant(self): self.assertEqual(util.get_class_alias(self.__class__), None)
def test_none_existant(self): self.assertEquals(pyamf.ClassAlias, util.get_class_alias(self.__class__))