Python sqlalchemy.orm.collections.collection.converter() Examples

The following are 22 code examples of sqlalchemy.orm.collections.collection.converter(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module sqlalchemy.orm.collections.collection , or try the search function .
Example #1
Source File: collections.py    From pyRevit with GNU General Public License v3.0 5 votes vote down vote up
def _locate_roles_and_methods(cls):
    """search for _sa_instrument_role-decorated methods in
    method resolution order, assign to roles.

    """

    roles = {}
    methods = {}

    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not util.callable(method):
                continue

            # note role declarations
            if hasattr(method, '_sa_instrument_role'):
                role = method._sa_instrument_role
                assert role in ('appender', 'remover', 'iterator',
                                'linker', 'converter')
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, '_sa_instrument_before'):
                op, argument = method._sa_instrument_before
                assert op in ('fire_append_event', 'fire_remove_event')
                before = op, argument
            if hasattr(method, '_sa_instrument_after'):
                op = method._sa_instrument_after
                assert op in ('fire_append_event', 'fire_remove_event')
                after = op
            if before:
                methods[name] = before + (after, )
            elif after:
                methods[name] = None, None, after
    return roles, methods 
Example #2
Source File: collections.py    From moviegrabber with GNU General Public License v3.0 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        it's sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #3
Source File: collections.py    From jarvis with GNU General Public License v2.0 5 votes vote down vote up
def _locate_roles_and_methods(cls):
    """search for _sa_instrument_role-decorated methods in
    method resolution order, assign to roles.

    """

    roles = {}
    methods = {}

    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not util.callable(method):
                continue

            # note role declarations
            if hasattr(method, '_sa_instrument_role'):
                role = method._sa_instrument_role
                assert role in ('appender', 'remover', 'iterator',
                                'linker', 'converter')
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, '_sa_instrument_before'):
                op, argument = method._sa_instrument_before
                assert op in ('fire_append_event', 'fire_remove_event')
                before = op, argument
            if hasattr(method, '_sa_instrument_after'):
                op = method._sa_instrument_after
                assert op in ('fire_append_event', 'fire_remove_event')
                after = op
            if before:
                methods[name] = before + (after, )
            elif after:
                methods[name] = None, None, after
    return roles, methods 
Example #4
Source File: collections.py    From jarvis with GNU General Public License v2.0 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #5
Source File: test_deprecations.py    From sqlalchemy with MIT License 5 votes vote down vote up
def test_dict_subclass4(self):
        # tests #2654
        with testing.expect_deprecated(
            r"The collection.converter\(\) handler is deprecated and will "
            "be removed in a future release.  Please refer to the "
            "AttributeEvents"
        ):

            class MyDict(collections.MappedCollection):
                def __init__(self):
                    super(MyDict, self).__init__(lambda value: "k%d" % value)

                @collection.converter
                def _convert(self, dictlike):
                    for key, value in dictlike.items():
                        yield value + 5

        class Foo(object):
            pass

        instrumentation.register_class(Foo)
        attributes.register_attribute(
            Foo, "attr", uselist=True, typecallable=MyDict, useobject=True
        )

        f = Foo()
        f.attr = {"k1": 1, "k2": 2}

        eq_(f.attr, {"k7": 7, "k6": 6}) 
Example #6
Source File: collections.py    From sqlalchemy with MIT License 5 votes vote down vote up
def _locate_roles_and_methods(cls):
    """search for _sa_instrument_role-decorated methods in
    method resolution order, assign to roles.

    """

    roles = {}
    methods = {}

    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not callable(method):
                continue

            # note role declarations
            if hasattr(method, "_sa_instrument_role"):
                role = method._sa_instrument_role
                assert role in (
                    "appender",
                    "remover",
                    "iterator",
                    "converter",
                )
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, "_sa_instrument_before"):
                op, argument = method._sa_instrument_before
                assert op in ("fire_append_event", "fire_remove_event")
                before = op, argument
            if hasattr(method, "_sa_instrument_after"):
                op = method._sa_instrument_after
                assert op in ("fire_append_event", "fire_remove_event")
                after = op
            if before:
                methods[name] = before + (after,)
            elif after:
                methods[name] = None, None, after
    return roles, methods 
Example #7
Source File: collections.py    From sqlalchemy with MIT License 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = "converter"
        return fn 
Example #8
Source File: collections.py    From jbox with MIT License 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #9
Source File: collections.py    From stdm with GNU General Public License v2.0 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #10
Source File: collections.py    From pyRevit with GNU General Public License v3.0 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #11
Source File: collections.py    From planespotter with MIT License 5 votes vote down vote up
def _locate_roles_and_methods(cls):
    """search for _sa_instrument_role-decorated methods in
    method resolution order, assign to roles.

    """

    roles = {}
    methods = {}

    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not util.callable(method):
                continue

            # note role declarations
            if hasattr(method, '_sa_instrument_role'):
                role = method._sa_instrument_role
                assert role in ('appender', 'remover', 'iterator',
                                'linker', 'converter')
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, '_sa_instrument_before'):
                op, argument = method._sa_instrument_before
                assert op in ('fire_append_event', 'fire_remove_event')
                before = op, argument
            if hasattr(method, '_sa_instrument_after'):
                op = method._sa_instrument_after
                assert op in ('fire_append_event', 'fire_remove_event')
                after = op
            if before:
                methods[name] = before + (after, )
            elif after:
                methods[name] = None, None, after
    return roles, methods 
Example #12
Source File: collections.py    From planespotter with MIT License 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #13
Source File: collections.py    From Fluid-Designer with GNU General Public License v3.0 5 votes vote down vote up
def _locate_roles_and_methods(cls):
    """search for _sa_instrument_role-decorated methods in
    method resolution order, assign to roles.

    """

    roles = {}
    methods = {}

    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not util.callable(method):
                continue

            # note role declarations
            if hasattr(method, '_sa_instrument_role'):
                role = method._sa_instrument_role
                assert role in ('appender', 'remover', 'iterator',
                                'linker', 'converter')
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, '_sa_instrument_before'):
                op, argument = method._sa_instrument_before
                assert op in ('fire_append_event', 'fire_remove_event')
                before = op, argument
            if hasattr(method, '_sa_instrument_after'):
                op = method._sa_instrument_after
                assert op in ('fire_append_event', 'fire_remove_event')
                after = op
            if before:
                methods[name] = before + (after, )
            elif after:
                methods[name] = None, None, after
    return roles, methods 
Example #14
Source File: collections.py    From android_universal with MIT License 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #15
Source File: collections.py    From Fluid-Designer with GNU General Public License v3.0 5 votes vote down vote up
def converter(fn):
        """Tag the method as the collection converter.

        This optional method will be called when a collection is being
        replaced entirely, as in::

            myobj.acollection = [newvalue1, newvalue2]

        The converter method will receive the object being assigned and should
        return an iterable of values suitable for use by the ``appender``
        method.  A converter must not assign values or mutate the collection,
        its sole job is to adapt the value the user provides into an iterable
        of values for the ORM's use.

        The default converter implementation will use duck-typing to do the
        conversion.  A dict-like collection will be convert into an iterable
        of dictionary values, and other types will simply be iterated::

            @collection.converter
            def convert(self, other): ...

        If the duck-typing of the object does not match the type of this
        collection, a TypeError is raised.

        Supply an implementation of this method if you want to expand the
        range of possible types that can be assigned in bulk or perform
        validation on the values about to be assigned.

        """
        fn._sa_instrument_role = 'converter'
        return fn 
Example #16
Source File: collections.py    From jbox with MIT License 5 votes vote down vote up
def _locate_roles_and_methods(cls):
    """search for _sa_instrument_role-decorated methods in
    method resolution order, assign to roles.

    """

    roles = {}
    methods = {}

    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not util.callable(method):
                continue

            # note role declarations
            if hasattr(method, '_sa_instrument_role'):
                role = method._sa_instrument_role
                assert role in ('appender', 'remover', 'iterator',
                                'linker', 'converter')
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, '_sa_instrument_before'):
                op, argument = method._sa_instrument_before
                assert op in ('fire_append_event', 'fire_remove_event')
                before = op, argument
            if hasattr(method, '_sa_instrument_after'):
                op = method._sa_instrument_after
                assert op in ('fire_append_event', 'fire_remove_event')
                after = op
            if before:
                methods[name] = before + (after, )
            elif after:
                methods[name] = None, None, after
    return roles, methods 
Example #17
Source File: collections.py    From android_universal with MIT License 5 votes vote down vote up
def _locate_roles_and_methods(cls):
    """search for _sa_instrument_role-decorated methods in
    method resolution order, assign to roles.

    """

    roles = {}
    methods = {}

    for supercls in cls.__mro__:
        for name, method in vars(supercls).items():
            if not util.callable(method):
                continue

            # note role declarations
            if hasattr(method, '_sa_instrument_role'):
                role = method._sa_instrument_role
                assert role in ('appender', 'remover', 'iterator',
                                'linker', 'converter')
                roles.setdefault(role, name)

            # transfer instrumentation requests from decorated function
            # to the combined queue
            before, after = None, None
            if hasattr(method, '_sa_instrument_before'):
                op, argument = method._sa_instrument_before
                assert op in ('fire_append_event', 'fire_remove_event')
                before = op, argument
            if hasattr(method, '_sa_instrument_after'):
                op = method._sa_instrument_after
                assert op in ('fire_append_event', 'fire_remove_event')
                after = op
            if before:
                methods[name] = before + (after, )
            elif after:
                methods[name] = None, None, after
    return roles, methods 
Example #18
Source File: collections.py    From stdm with GNU General Public License v2.0 4 votes vote down vote up
def adapt_like_to_iterable(self, obj):
        """Converts collection-compatible objects to an iterable of values.

        Can be passed any type of object, and if the underlying collection
        determines that it can be adapted into a stream of values it can
        use, returns an iterable of values suitable for append()ing.

        This method may raise TypeError or any other suitable exception
        if adaptation fails.

        If a converter implementation is not supplied on the collection,
        a default duck-typing-based implementation is used.

        """
        converter = self._data()._sa_converter
        if converter is not None:
            return converter(obj)

        setting_type = util.duck_type_collection(obj)
        receiving_type = util.duck_type_collection(self._data())

        if obj is None or setting_type != receiving_type:
            given = obj is None and 'None' or obj.__class__.__name__
            if receiving_type is None:
                wanted = self._data().__class__.__name__
            else:
                wanted = receiving_type.__name__

            raise TypeError(
                "Incompatible collection type: %s is not %s-like" % (
                    given, wanted))

        # If the object is an adapted collection, return the (iterable)
        # adapter.
        if getattr(obj, '_sa_adapter', None) is not None:
            return obj._sa_adapter
        elif setting_type == dict:
            if util.py3k:
                return obj.values()
            else:
                return getattr(obj, 'itervalues', obj.values)()
        else:
            return iter(obj) 
Example #19
Source File: collections.py    From moviegrabber with GNU General Public License v3.0 4 votes vote down vote up
def adapt_like_to_iterable(self, obj):
        """Converts collection-compatible objects to an iterable of values.

        Can be passed any type of object, and if the underlying collection
        determines that it can be adapted into a stream of values it can
        use, returns an iterable of values suitable for append()ing.

        This method may raise TypeError or any other suitable exception
        if adaptation fails.

        If a converter implementation is not supplied on the collection,
        a default duck-typing-based implementation is used.

        """
        converter = self._data()._sa_converter
        if converter is not None:
            return converter(obj)

        setting_type = util.duck_type_collection(obj)
        receiving_type = util.duck_type_collection(self._data())

        if obj is None or setting_type != receiving_type:
            given = obj is None and 'None' or obj.__class__.__name__
            if receiving_type is None:
                wanted = self._data().__class__.__name__
            else:
                wanted = receiving_type.__name__

            raise TypeError(
                "Incompatible collection type: %s is not %s-like" % (
                given, wanted))

        # If the object is an adapted collection, return the (iterable)
        # adapter.
        if getattr(obj, '_sa_adapter', None) is not None:
            return obj._sa_adapter
        elif setting_type == dict:
            if util.py3k:
                return obj.values()
            else:
                return getattr(obj, 'itervalues', obj.values)()
        else:
            return iter(obj) 
Example #20
Source File: test_deprecations.py    From sqlalchemy with MIT License 4 votes vote down vote up
def test_name_setup(self):
        with testing.expect_deprecated(
            r"The collection.converter\(\) handler is deprecated and will "
            "be removed in a future release.  Please refer to the "
            "AttributeEvents"
        ):

            class Base(object):
                @collection.iterator
                def base_iterate(self, x):
                    return "base_iterate"

                @collection.appender
                def base_append(self, x):
                    return "base_append"

                @collection.converter
                def base_convert(self, x):
                    return "base_convert"

                @collection.remover
                def base_remove(self, x):
                    return "base_remove"

        from sqlalchemy.orm.collections import _instrument_class

        _instrument_class(Base)

        eq_(Base._sa_remover(Base(), 5), "base_remove")
        eq_(Base._sa_appender(Base(), 5), "base_append")
        eq_(Base._sa_iterator(Base(), 5), "base_iterate")
        eq_(Base._sa_converter(Base(), 5), "base_convert")

        with testing.expect_deprecated(
            r"The collection.converter\(\) handler is deprecated and will "
            "be removed in a future release.  Please refer to the "
            "AttributeEvents"
        ):

            class Sub(Base):
                @collection.converter
                def base_convert(self, x):
                    return "sub_convert"

                @collection.remover
                def sub_remove(self, x):
                    return "sub_remove"

        _instrument_class(Sub)

        eq_(Sub._sa_appender(Sub(), 5), "base_append")
        eq_(Sub._sa_remover(Sub(), 5), "sub_remove")
        eq_(Sub._sa_iterator(Sub(), 5), "base_iterate")
        eq_(Sub._sa_converter(Sub(), 5), "sub_convert") 
Example #21
Source File: collections.py    From Fluid-Designer with GNU General Public License v3.0 4 votes vote down vote up
def adapt_like_to_iterable(self, obj):
        """Converts collection-compatible objects to an iterable of values.

        Can be passed any type of object, and if the underlying collection
        determines that it can be adapted into a stream of values it can
        use, returns an iterable of values suitable for append()ing.

        This method may raise TypeError or any other suitable exception
        if adaptation fails.

        If a converter implementation is not supplied on the collection,
        a default duck-typing-based implementation is used.

        """
        converter = self._data()._sa_converter
        if converter is not None:
            return converter(obj)

        setting_type = util.duck_type_collection(obj)
        receiving_type = util.duck_type_collection(self._data())

        if obj is None or setting_type != receiving_type:
            given = obj is None and 'None' or obj.__class__.__name__
            if receiving_type is None:
                wanted = self._data().__class__.__name__
            else:
                wanted = receiving_type.__name__

            raise TypeError(
                "Incompatible collection type: %s is not %s-like" % (
                    given, wanted))

        # If the object is an adapted collection, return the (iterable)
        # adapter.
        if getattr(obj, '_sa_adapter', None) is not None:
            return obj._sa_adapter
        elif setting_type == dict:
            if util.py3k:
                return obj.values()
            else:
                return getattr(obj, 'itervalues', obj.values)()
        else:
            return iter(obj) 
Example #22
Source File: collections.py    From jbox with MIT License 4 votes vote down vote up
def adapt_like_to_iterable(self, obj):
        """Converts collection-compatible objects to an iterable of values.

        Can be passed any type of object, and if the underlying collection
        determines that it can be adapted into a stream of values it can
        use, returns an iterable of values suitable for append()ing.

        This method may raise TypeError or any other suitable exception
        if adaptation fails.

        If a converter implementation is not supplied on the collection,
        a default duck-typing-based implementation is used.

        """
        converter = self._data()._sa_converter
        if converter is not None:
            return converter(obj)

        setting_type = util.duck_type_collection(obj)
        receiving_type = util.duck_type_collection(self._data())

        if obj is None or setting_type != receiving_type:
            given = obj is None and 'None' or obj.__class__.__name__
            if receiving_type is None:
                wanted = self._data().__class__.__name__
            else:
                wanted = receiving_type.__name__

            raise TypeError(
                "Incompatible collection type: %s is not %s-like" % (
                    given, wanted))

        # If the object is an adapted collection, return the (iterable)
        # adapter.
        if getattr(obj, '_sa_adapter', None) is not None:
            return obj._sa_adapter
        elif setting_type == dict:
            if util.py3k:
                return obj.values()
            else:
                return getattr(obj, 'itervalues', obj.values)()
        else:
            return iter(obj)