def test_dict(self):
        meta = {
            'exclude': ['foo'],
            'readonly': ['bar'],
            'dynamic': False,
            'alias': 'spam.eggs',
            'proxy_attrs': None,
            'synonym_attrs': None,
            'amf3': True,
            'static': ['baz'],
            'external': True
        }

        class A:
            __amf__ = meta

        class B(object):
            __amf__ = meta

        ret = {
            'readonly_attrs': ['bar'],
            'static_attrs': ['baz'],
            'proxy_attrs': None,
            'dynamic': False,
            'alias': 'spam.eggs',
            'amf3': True,
            'exclude_attrs': ['foo'],
            'synonym_attrs': None,
            'proxy_attrs': None,
            'external': True
        }

        self.assertEqual(util.get_class_meta(A), ret)
        self.assertEqual(util.get_class_meta(B), ret)
Exemple #2
0
    def test_dict(self):
        meta = {
            'exclude': ['foo'],
            'readonly': ['bar'],
            'dynamic': False,
            'alias': 'spam.eggs',
            'proxy_attrs': None,
            'synonym_attrs': None,
            'amf3': True,
            'static': ['baz'],
            'external': True
        }

        class A:
            __amf__ = meta

        class B(object):
            __amf__ = meta

        ret = {
            'readonly_attrs': ['bar'],
            'static_attrs': ['baz'],
            'proxy_attrs': None,
            'dynamic': False,
            'alias': 'spam.eggs',
            'amf3': True,
            'exclude_attrs': ['foo'],
            'synonym_attrs': None,
            'proxy_attrs': None,
            'external': True
        }

        self.assertEqual(util.get_class_meta(A), ret)
        self.assertEqual(util.get_class_meta(B), ret)
    def test_synonym(self):
        class A:
            class __amf__:
                synonym = {'foo': 'bar'}

        class B(object):
            class __amf__:
                synonym = {'foo': 'bar'}

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': None,
            'proxy_attrs': None,
            'synonym_attrs': {
                'foo': 'bar'
            },
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEqual(util.get_class_meta(A), meta)
        self.assertEqual(util.get_class_meta(B), meta)
Exemple #4
0
    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
Exemple #5
0
    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
Exemple #6
0
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
Exemple #7
0
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
Exemple #8
0
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
Exemple #9
0
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
Exemple #10
0
    def test_no_meta(self):
        class A:
            pass

        class B(object):
            pass

        empty = {
            'readonly_attrs': None,
            'static_attrs': None,
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'exclude_attrs': None,
            'external': None
        }

        self.assertEquals(util.get_class_meta(A), empty)
        self.assertEquals(util.get_class_meta(B), empty)
Exemple #11
0
    def test_no_meta(self):
        class A:
            pass

        class B(object):
            pass

        empty = {
            'readonly_attrs': None,
            'static_attrs': None,
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'exclude_attrs': None,
            'external': None
        }

        self.assertEquals(util.get_class_meta(A), empty)
        self.assertEquals(util.get_class_meta(B), empty)
Exemple #12
0
    def test_readonly(self):
        class A:
            class __amf__:
                readonly = ('foo', 'bar')

        class B(object):
            class __amf__:
                readonly = ('foo', 'bar')

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': ['foo', 'bar'],
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEquals(util.get_class_meta(A), meta)
        self.assertEquals(util.get_class_meta(B), meta)
Exemple #13
0
    def test_alias(self):
        class A:
            class __amf__:
                alias = 'foo.bar.Spam'

        class B(object):
            class __amf__:
                alias = 'foo.bar.Spam'

        meta = {
            'readonly_attrs': None,
            'static_attrs': None,
            'dynamic': None,
            'alias': 'foo.bar.Spam',
            'amf3': None,
            'exclude_attrs': None,
            'external': None
        }

        self.assertEquals(util.get_class_meta(A), meta)
        self.assertEquals(util.get_class_meta(B), meta)
Exemple #14
0
    def test_external(self):
        class A:
            class __amf__:
                external = True

        class B(object):
            class __amf__:
                external = True

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': None,
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': True
        }

        self.assertEquals(util.get_class_meta(A), meta)
        self.assertEquals(util.get_class_meta(B), meta)
Exemple #15
0
    def test_readonly(self):
        class A:
            class __amf__:
                readonly = ('foo', 'bar')

        class B(object):
            class __amf__:
                readonly = ('foo', 'bar')

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': ['foo', 'bar'],
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEquals(util.get_class_meta(A), meta)
        self.assertEquals(util.get_class_meta(B), meta)
Exemple #16
0
    def test_alias(self):
        class A:
            class __amf__:
                alias = 'foo.bar.Spam'

        class B(object):
            class __amf__:
                alias = 'foo.bar.Spam'

        meta = {
            'readonly_attrs': None,
            'static_attrs': None,
            'dynamic': None,
            'alias': 'foo.bar.Spam',
            'amf3': None,
            'exclude_attrs': None,
            'external': None
        }

        self.assertEquals(util.get_class_meta(A), meta)
        self.assertEquals(util.get_class_meta(B), meta)
Exemple #17
0
    def test_external(self):
        class A:
            class __amf__:
                external = True

        class B(object):
            class __amf__:
                external = True

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': None,
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': True
        }

        self.assertEquals(util.get_class_meta(A), meta)
        self.assertEquals(util.get_class_meta(B), meta)
Exemple #18
0
    def test_proxy(self):
        class A:
            class __amf__:
                proxy = ['foo', 'bar']

        class B(object):
            class __amf__:
                proxy = ['foo', 'bar']

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': None,
            'proxy_attrs': ['foo', 'bar'],
            'synonym_attrs': None,
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEqual(util.get_class_meta(A), meta)
        self.assertEqual(util.get_class_meta(B), meta)
    def test_proxy(self):
        class A:
            class __amf__:
                proxy = ['foo', 'bar']

        class B(object):
            class __amf__:
                proxy = ['foo', 'bar']

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': None,
            'proxy_attrs': ['foo', 'bar'],
            'synonym_attrs': None,
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEqual(util.get_class_meta(A), meta)
        self.assertEqual(util.get_class_meta(B), meta)
Exemple #20
0
    def test_synonym(self):
        class A:
            class __amf__:
                synonym = {'foo': 'bar'}

        class B(object):
            class __amf__:
                synonym = {'foo': 'bar'}

        meta = {
            'exclude_attrs': None,
            'readonly_attrs': None,
            'proxy_attrs': None,
            'synonym_attrs': {'foo': 'bar'},
            'dynamic': None,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEqual(util.get_class_meta(A), meta)
        self.assertEqual(util.get_class_meta(B), meta)
Exemple #21
0
    def test_dynamic(self):
        class A:
            class __amf__:
                dynamic = False

        class B(object):
            class __amf__:
                dynamic = False

        meta = {
            'exclude_attrs': None,
            'proxy_attrs': None,
            'readonly_attrs': None,
            'proxy_attrs': None,
            'dynamic': False,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEquals(util.get_class_meta(A), meta)
        self.assertEquals(util.get_class_meta(B), meta)
    def test_dynamic(self):
        class A:
            class __amf__:
                dynamic = False

        class B(object):
            class __amf__:
                dynamic = False

        meta = {
            'exclude_attrs': None,
            'proxy_attrs': None,
            'synonym_attrs': None,
            'readonly_attrs': None,
            'proxy_attrs': None,
            'dynamic': False,
            'alias': None,
            'amf3': None,
            'static_attrs': None,
            'external': None
        }

        self.assertEqual(util.get_class_meta(A), meta)
        self.assertEqual(util.get_class_meta(B), meta)
Exemple #23
0
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
Exemple #24
0
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
Exemple #25
0
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
Exemple #26
0
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
Exemple #27
0
    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)