Esempio n. 1
0
    def test_sets(self):
        # Py2K
        import sets

        # end Py2K
        class SetLike(object):
            def add(self):
                pass

        class ForcedSet(list):
            __emulates__ = set

        for type_ in (
                set,
                # Py2K
                sets.Set,
                # end Py2K
                SetLike,
                ForcedSet):
            eq_(util.duck_type_collection(type_), set)
            instance = type_()
            eq_(util.duck_type_collection(instance), set)

        for type_ in (
                frozenset,
                # Py2K
                sets.ImmutableSet
                # end Py2K
        ):
            is_(util.duck_type_collection(type_), None)
            instance = type_()
            is_(util.duck_type_collection(instance), None)
Esempio n. 2
0
    def test_sets(self):
        # Py2K
        import sets
        # end Py2K
        class SetLike(object):
            def add(self):
                pass

        class ForcedSet(list):
            __emulates__ = set

        for type_ in (set,
                      # Py2K
                      sets.Set,
                      # end Py2K
                      SetLike,
                      ForcedSet):
            eq_(util.duck_type_collection(type_), set)
            instance = type_()
            eq_(util.duck_type_collection(instance), set)

        for type_ in (frozenset,
                      # Py2K
                      sets.ImmutableSet
                      # end Py2K
                      ):
            is_(util.duck_type_collection(type_), None)
            instance = type_()
            is_(util.duck_type_collection(instance), None)
Esempio n. 3
0
 def __ior__(self, value):
     if sautil.duck_type_collection(value) is not Set:
         return NotImplemented
     for item in value:
         if item not in self:
             self.add(item)
     return self
Esempio n. 4
0
def replicate_relation(source, target, attr, target_attr, cache=None):
    if attr.property.cascade.delete_orphan:
        process_scalar = replicate_no_merge
        process_list = replicate_filter
    else:
        process_scalar = reflect
        process_list = reflect_filter
    value = getattr(source, attr.key)
    target_attr_model = target_attr.property.mapper.class_
    if attr.property.uselist:
        adapter = collection_adapter(value)
        if adapter:
            # XXX The magic passes below are adapted from logic in
            # CollectionAttributeImpl.set() method without proper
            # understanding.  The `elif` branch isn't even coverered by tests.
            if hasattr(value, '_sa_iterator'):
                value = value._sa_iterator()
            elif duck_type_collection(value) is dict:
                value = value.values()
        reflection = process_list(value, target_attr_model, cache=cache)
        impl = instance_state(target).get_impl(attr.key)
        impl.set(
            instance_state(target),
            instance_dict(target),
            reflection,
            # XXX We either have to convert reflection back to original
            # collection type or use this private parameter.
            _adapt=False)
    else:
        reflection = process_scalar(value, target_attr_model, cache=cache)
        setattr(target, attr.key, reflection)
        if (reflection is None and attr.property.direction is MANYTOONE
                and any(col.primary_key and not col.nullable
                        for col in attr.property.local_columns)):
            raise _PrimaryKeyIsNull()
Esempio n. 5
0
def replicate_relation(source, target, attr, target_attr, cache=None):
    if attr.property.cascade.delete_orphan:
        process_scalar = replicate_no_merge
        process_list = replicate_filter
    else:
        process_scalar = reflect
        process_list = reflect_filter
    value = getattr(source, attr.key)
    target_attr_model = target_attr.property.mapper.class_
    if attr.property.uselist:
        adapter = collection_adapter(value)
        if adapter:
            # XXX The magic passes below are adapted from logic in
            # CollectionAttributeImpl.set() method without proper
            # understanding.  The `elif` branch isn't even coverered by tests.
            if hasattr(value, '_sa_iterator'):
                value = value._sa_iterator()
            elif duck_type_collection(value) is dict:
                value = value.values()
        reflection = process_list(value, target_attr_model, cache=cache)
        impl = instance_state(target).get_impl(attr.key)
        impl.set(instance_state(target), instance_dict(target), reflection,
                 # XXX We either have to convert reflection back to original
                 # collection type or use this private parameter.
                 _adapt=False)
    else:
        reflection = process_scalar(value, target_attr_model, cache=cache)
        setattr(target, attr.key, reflection)
        if (reflection is None and
                attr.property.direction is MANYTOONE and
                any(col.primary_key and not col.nullable
                    for col in attr.property.local_columns)):
            raise _PrimaryKeyIsNull()
    def __init__(
        self,
        class_,
        key,
        callable_,
        typecallable=None,
        trackparent=False,
        extension=None,
        copy_function=None,
        compare_function=None,
        **kwargs
    ):
        super(CollectionAttributeImpl, self).__init__(
            class_,
            key,
            callable_,
            trackparent=trackparent,
            extension=extension,
            compare_function=compare_function,
            **kwargs
        )

        if copy_function is None:
            copy_function = self.__copy
        self.copy = copy_function

        if typecallable is None:
            typecallable = list
        self.collection_factory = collections._prepare_instrumentation(typecallable)
        # may be removed in 0.5:
        self.collection_interface = util.duck_type_collection(self.collection_factory())
Esempio n. 7
0
    def __init__(self,
                 class_,
                 key,
                 callable_,
                 typecallable=None,
                 trackparent=False,
                 extension=None,
                 copy_function=None,
                 compare_function=None,
                 **kwargs):
        super(CollectionAttributeImpl,
              self).__init__(class_,
                             key,
                             callable_,
                             trackparent=trackparent,
                             extension=extension,
                             compare_function=compare_function,
                             **kwargs)

        if copy_function is None:
            copy_function = self.__copy
        self.copy = copy_function

        if typecallable is None:
            typecallable = list
        self.collection_factory = \
          collections._prepare_instrumentation(typecallable)
        # may be removed in 0.5:
        self.collection_interface = \
          util.duck_type_collection(self.collection_factory())
Esempio n. 8
0
    def _new(self, lazy_collection):
        creator = self.creator and self.creator or self.target_class
        self.collection_class = util.duck_type_collection(lazy_collection())

        if self.proxy_factory:
            return self.proxy_factory(lazy_collection, creator,
                                      self.value_attr, self)

        if self.getset_factory:
            getter, setter = self.getset_factory(self.collection_class, self)
        else:
            getter, setter = self._default_getset(self.collection_class)

        if self.collection_class is list:
            return _AssociationList(lazy_collection, creator, getter, setter,
                                    self)
        elif self.collection_class is dict:
            return _AssociationDict(lazy_collection, creator, getter, setter,
                                    self)
        elif self.collection_class is set:
            return _AssociationSet(lazy_collection, creator, getter, setter,
                                   self)
        else:
            raise exceptions.ArgumentError(
                'could not guess which interface to use for '
                'collection_class "%s" backing "%s"; specify a '
                'proxy_factory and proxy_bulk_set manually' %
                (self.collection_class.__name__, self.target_collection))
    def _new(self, lazy_collection):
        creator = self.creator and self.creator or self.target_class

        # Prefer class typing here to spot dicts with the required append()
        # method.
        collection = lazy_collection()
        if isinstance(collection.data, dict):
            self.collection_class = dict
        else:
            self.collection_class = util.duck_type_collection(collection.data)
        del collection

        if self.proxy_factory:
            return self.proxy_factory(lazy_collection, creator, self.value_attr)

        value_attr = self.value_attr
        getter = lambda o: getattr(o, value_attr)
        setter = lambda o, v: setattr(o, value_attr, v)
        
        if self.collection_class is list:
            return _AssociationList(lazy_collection, creator, getter, setter)
        elif self.collection_class is dict:
            kv_setter = lambda o, k, v: setattr(o, value_attr, v)
            return _AssociationDict(lazy_collection, creator, getter, kv_setter)
        elif self.collection_class is util.Set:
            return _AssociationSet(lazy_collection, creator, getter, setter)
        else:
            raise exceptions.ArgumentError(
                'could not guess which interface to use for '
                'collection_class "%s" backing "%s"; specify a '
                'proxy_factory and proxy_bulk_set manually' %
                (self.collection_class.__name__, self.target_collection))
Esempio n. 10
0
 def __ior__(self, value):
     if sautil.duck_type_collection(value) is not Set:
         return NotImplemented
     for item in value:
         if item not in self:
             self.add(item)
     return self
Esempio n. 11
0
    def test_sets(self):
        class SetLike(object):
            def add(self):
                pass

        class ForcedSet(list):
            __emulates__ = set

        for type_ in (set, SetLike, ForcedSet):
            eq_(util.duck_type_collection(type_), set)
            instance = type_()
            eq_(util.duck_type_collection(instance), set)

        for type_ in (frozenset, ):
            is_(util.duck_type_collection(type_), None)
            instance = type_()
            is_(util.duck_type_collection(instance), None)
Esempio n. 12
0
    def test_sets(self):
        class SetLike(object):
            def add(self):
                pass

        class ForcedSet(list):
            __emulates__ = set

        for type_ in (set,
                      SetLike,
                      ForcedSet):
            eq_(util.duck_type_collection(type_), set)
            instance = type_()
            eq_(util.duck_type_collection(instance), set)

        for type_ in (frozenset, ):
            is_(util.duck_type_collection(type_), None)
            instance = type_()
            is_(util.duck_type_collection(instance), None)
Esempio n. 13
0
        def __iand__(self, other):
            if sautil.duck_type_collection(other) is not Set:
                return NotImplemented
            want, have = self.intersection(other), Set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
            return self
Esempio n. 14
0
        def __ixor__(self, other):
            if sautil.duck_type_collection(other) is not Set:
                return NotImplemented
            want, have = self.symmetric_difference(other), Set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
            return self
Esempio n. 15
0
        def __iand__(self, other):
            if sautil.duck_type_collection(other) is not Set:
                return NotImplemented
            want, have = self.intersection(other), Set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
            return self
Esempio n. 16
0
        def __ixor__(self, other):
            if sautil.duck_type_collection(other) is not Set:
                return NotImplemented
            want, have = self.symmetric_difference(other), Set(self)
            remove, add = have - want, want - have

            for item in remove:
                self.remove(item)
            for item in add:
                self.add(item)
            return self
Esempio n. 17
0
    def __ixor__(self, other):
        if util.duck_type_collection(other) is not util.Set:
            return NotImplemented
        want, have = self.symmetric_difference(other), util.Set(self)

        remove, add = have - want, want - have

        for value in remove:
            self.remove(value)
        for value in add:
            self.add(value)
        return self
Esempio n. 18
0
    def __iand__(self, other):
        if util.duck_type_collection(other) is not util.Set:
            return NotImplemented
        want, have = self.intersection(other), util.Set(self)

        remove, add = have - want, want - have

        for value in remove:
            self.remove(value)
        for value in add:
            self.add(value)
        return self
Esempio n. 19
0
    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 = getattr(self._data(), '_sa_converter', None)
        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 getattr(obj, '_sa_adapter')
        elif setting_type == dict:
            return getattr(obj, 'itervalues', getattr(obj, 'values'))()
        else:
            return iter(obj)
Esempio n. 20
0
 def _convert(self, collection):
     # TODO We could check if the objects' type is correct.
     type_ = util.duck_type_collection(collection)
     if type_ is dict:
         for key, value in util.dictlike_iteritems(collection):
             if key != self.keyfunc(value):
                 raise TypeError("Found incompatible key '%r' for value '%r'" % (key, value))
             yield value
     elif type_ in (list, set):
         for value in collection:
             yield value
     else:
         raise TypeError("Object '%r' is not dict-like nor iterable" % collection)
Esempio n. 21
0
 def _convert(self, coll):
     # TODO We could check if the objects' type is correct.
     type_ = util.duck_type_collection(coll)
     if type_ is dict:
         for key, value in util.dictlike_iteritems(coll):
             if key != self.keyfunc(value):
                 raise TypeError(
                     "Found incompatible key '%r' for value '%r'" %
                     (key, value))
             yield value
     elif type_ in (list, set):
         for value in coll:
             yield value
     else:
         raise TypeError("Object '%r' is not dict-like nor iterable" % coll)
Esempio n. 22
0
    def __init__(self, ftype, type, **kwargs):
        '''
    Construct the field object on an mvc class

    Parameters:
      ftype: field type (MVCTypeField, MVCTypeList, or/and MVCTypeParam)
      type:  Datatype (String, Numeric, Date, Time)
    Args:
      label: identify label for this field
      required: identify that value entered in this field is required, thus it must not empty
      enabled: identify the field is enabled for editing
      visible: set the field visibility on client
      browseable: identify if data on this field could be retrieved from lookup browser
      synchronized: identify any modification made on this field must be synchronized by server
      charcase: identify input charcase type (ecUpperCase, ecLowerCase)
      choices: set the multiple choice for this field (usually shown by a combo box control)
      updateable: set if this field updateable into persistent media (table)
    '''

        self.properties = MVCFieldProperty()
        if isinstance(type, TypeEngine):
            self.properties.type = type
        else:
            atype = object.__new__(type)
            atype.__init__()
            self.properties.type = atype
        self.properties.ftype = ftype
        self.properties.label = kwargs.pop('label', None)
        self.properties.required = kwargs.pop('required', False)
        self.properties.enabled = kwargs.pop('enabled', True)
        self.properties.visible = kwargs.pop('visible', True)
        self.properties.readOnly = kwargs.pop('readOnly', False)
        self.properties.synchronized = kwargs.pop('synchronized', False)
        self.properties.browseable = kwargs.pop('browseable', False)
        self.properties.charcase = kwargs.pop('charcase', ecNormal)
        self.properties.updateable = kwargs.pop('updateable', True)
        choice = kwargs.pop('choices', {})
        choice_type = sautil.duck_type_collection(choice)
        if choice and (choice_type == types.ListType
                       or choice == types.TupleType):
            for itval in choice:
                self.properties.choices[itval] = itval
        else:
            if (choice_type == types.DictType):
                self.properties.choices = choice.copy()
        self.properties.primaryKey = kwargs.pop('primaryKey', False)
        self.properties.kwargs = kwargs
Esempio n. 23
0
    def set(self, state, value, initiator):
        """Set a value on the given object.

        `initiator` is the ``InstrumentedAttribute`` that initiated the
        ``set()` operation and is used to control the depth of a circular
        setter operation.
        """

        if initiator is self:
            return

        setting_type = util.duck_type_collection(value)

        if value is None or setting_type != self.collection_interface:
            raise exceptions.ArgumentError(
                "Incompatible collection type on assignment: %s is not %s-like"
                % (type(value).__name__, self.collection_interface.__name__))

        if hasattr(value, '_sa_adapter'):
            value = list(getattr(value, '_sa_adapter'))
        elif setting_type == dict:
            value = value.values()

        # if an instance-wide "trigger" was set, call that
        if state.trigger:
            state.call_trigger()

        old = self.get(state)
        old_collection = self.get_collection(state, old)

        new_collection, user_data = self._build_collection(state)
        self._load_collection(state,
                              value or [],
                              emit_events=True,
                              collection=new_collection)

        state.dict[self.key] = user_data
        state.modified = True

        # mark all the old elements as detached from the parent
        if old_collection:
            old_collection.clear_with_event()
            old_collection.unlink(old)
    def _new(self, lazy_collection):
        creator = self.creator and self.creator or self.target_class
        self.collection_class = util.duck_type_collection(lazy_collection())

        if self.proxy_factory:
            return self.proxy_factory(lazy_collection, creator, self.value_attr, self)

        if self.getset_factory:
            getter, setter = self.getset_factory(self.collection_class, self)
        else:
            getter, setter = self._default_getset(self.collection_class)

        if self.collection_class is list:
            return _AssociationList(lazy_collection, creator, getter, setter, self)
        elif self.collection_class is dict:
            return _AssociationDict(lazy_collection, creator, getter, setter, self)
        elif self.collection_class is set:
            return _AssociationSet(lazy_collection, creator, getter, setter, self)
        else:
            raise exceptions.ArgumentError(
                'could not guess which interface to use for '
                'collection_class "%s" backing "%s"; specify a '
                'proxy_factory and proxy_bulk_set manually' %
                (self.collection_class.__name__, self.target_collection))
Esempio n. 25
0
def _set_binops_check_loose(self, obj):
    """Allow anything set-like to participate in set binops."""
    return (isinstance(obj, _set_binop_bases + (self.__class__,)) or
            util.duck_type_collection(obj) == set)
Esempio n. 26
0
def _instrument_class(cls):
    """Modify methods in a class and install instrumentation."""

    # TODO: more formally document this as a decoratorless/Python 2.3
    # option for specifying instrumentation.  (likely doc'd here in code only,
    # not in online docs.)  Useful for C types too.
    #
    # __instrumentation__ = {
    #   'rolename': 'methodname', # ...
    #   'methods': {
    #     'methodname': ('fire_{append,remove}_event', argspec,
    #                    'fire_{append,remove}_event'),
    #     'append': ('fire_append_event', 1, None),
    #     '__setitem__': ('fire_append_event', 1, 'fire_remove_event'),
    #     'pop': (None, None, 'fire_remove_event'),
    #     }
    #  }

    # In the normal call flow, a request for any of the 3 basic collection
    # types is transformed into one of our trivial subclasses
    # (e.g. InstrumentedList).  Catch anything else that sneaks in here...
    if cls.__module__ == '__builtin__':
        raise sa_exc.ArgumentError(
            "Can not instrument a built-in type. Use a "
            "subclass, even a trivial one.")

    collection_type = util.duck_type_collection(cls)
    if collection_type in __interfaces:
        roles = __interfaces[collection_type].copy()
        decorators = roles.pop('_decorators', {})
    else:
        roles, decorators = {}, {}

    if hasattr(cls, '__instrumentation__'):
        roles.update(copy.deepcopy(getattr(cls, '__instrumentation__')))

    methods = roles.pop('methods', {})

    for name in dir(cls):
        method = getattr(cls, name, None)
        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',
                            'on_link', 'converter')
            roles[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[0], before[1], after
        elif after:
            methods[name] = None, None, after

    # apply ABC auto-decoration to methods that need it
    for method, decorator in decorators.items():
        fn = getattr(cls, method, None)
        if (fn and method not in methods and
            not hasattr(fn, '_sa_instrumented')):
            setattr(cls, method, decorator(fn))

    # ensure all roles are present, and apply implicit instrumentation if
    # needed
    if 'appender' not in roles or not hasattr(cls, roles['appender']):
        raise sa_exc.ArgumentError(
            "Type %s must elect an appender method to be "
            "a collection class" % cls.__name__)
    elif (roles['appender'] not in methods and
          not hasattr(getattr(cls, roles['appender']), '_sa_instrumented')):
        methods[roles['appender']] = ('fire_append_event', 1, None)

    if 'remover' not in roles or not hasattr(cls, roles['remover']):
        raise sa_exc.ArgumentError(
            "Type %s must elect a remover method to be "
            "a collection class" % cls.__name__)
    elif (roles['remover'] not in methods and
          not hasattr(getattr(cls, roles['remover']), '_sa_instrumented')):
        methods[roles['remover']] = ('fire_remove_event', 1, None)

    if 'iterator' not in roles or not hasattr(cls, roles['iterator']):
        raise sa_exc.ArgumentError(
            "Type %s must elect an iterator method to be "
            "a collection class" % cls.__name__)

    # apply ad-hoc instrumentation from decorators, class-level defaults
    # and implicit role declarations
    for method, (before, argument, after) in methods.items():
        setattr(cls, method,
                _instrument_membership_mutator(getattr(cls, method),
                                               before, argument, after))
    # intern the role map
    for role, method in roles.items():
        setattr(cls, '_sa_%s' % role, getattr(cls, method))

    setattr(cls, '_sa_instrumented', id(cls))
Esempio n. 27
0
def _instrument_class(cls):
    """Modify methods in a class and install instrumentation."""

    # FIXME: more formally document this as a decoratorless/Python 2.3
    # option for specifying instrumentation.  (likely doc'd here in code only,
    # not in online docs.)
    #
    # __instrumentation__ = {
    #   'rolename': 'methodname', # ...
    #   'methods': {
    #     'methodname': ('fire_{append,remove}_event', argspec,
    #                    'fire_{append,remove}_event'),
    #     'append': ('fire_append_event', 1, None),
    #     '__setitem__': ('fire_append_event', 1, 'fire_remove_event'),
    #     'pop': (None, None, 'fire_remove_event'),
    #     }
    #  }

    # In the normal call flow, a request for any of the 3 basic collection
    # types is transformed into one of our trivial subclasses
    # (e.g. InstrumentedList).  Catch anything else that sneaks in here...
    if cls.__module__ == '__builtin__':
        raise exceptions.ArgumentError(
            "Can not instrument a built-in type. Use a "
            "subclass, even a trivial one.")

    collection_type = sautil.duck_type_collection(cls)
    if collection_type in __interfaces:
        roles = __interfaces[collection_type].copy()
        decorators = roles.pop('_decorators', {})
    else:
        roles, decorators = {}, {}

    if hasattr(cls, '__instrumentation__'):
        roles.update(copy.deepcopy(getattr(cls, '__instrumentation__')))

    methods = roles.pop('methods', {})

    for name in dir(cls):
        method = getattr(cls, name)
        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', 'on_link')
            roles[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[0], before[1], after
        elif after:
            methods[name] = None, None, after

    # apply ABC auto-decoration to methods that need it
    for method, decorator in decorators.items():
        fn = getattr(cls, method, None)
        if fn and method not in methods and not hasattr(
                fn, '_sa_instrumented'):
            setattr(cls, method, decorator(fn))

    # ensure all roles are present, and apply implicit instrumentation if
    # needed
    if 'appender' not in roles or not hasattr(cls, roles['appender']):
        raise exceptions.ArgumentError(
            "Type %s must elect an appender method to be "
            "a collection class" % cls.__name__)
    elif (roles['appender'] not in methods and
          not hasattr(getattr(cls, roles['appender']), '_sa_instrumented')):
        methods[roles['appender']] = ('fire_append_event', 1, None)

    if 'remover' not in roles or not hasattr(cls, roles['remover']):
        raise exceptions.ArgumentError(
            "Type %s must elect a remover method to be "
            "a collection class" % cls.__name__)
    elif (roles['remover'] not in methods
          and not hasattr(getattr(cls, roles['remover']), '_sa_instrumented')):
        methods[roles['remover']] = ('fire_remove_event', 1, None)

    if 'iterator' not in roles or not hasattr(cls, roles['iterator']):
        raise exceptions.ArgumentError(
            "Type %s must elect an iterator method to be "
            "a collection class" % cls.__name__)

    # apply ad-hoc instrumentation from decorators, class-level defaults
    # and implicit role declarations
    for method, (before, argument, after) in methods.items():
        setattr(
            cls, method,
            _instrument_membership_mutator(getattr(cls, method), before,
                                           argument, after))
    # intern the role map
    for role, method in roles.items():
        setattr(cls, '_sa_%s' % role, getattr(cls, method))

    setattr(cls, '_sa_instrumented', id(cls))
Esempio n. 28
0
 def __isub__(self, other):
     if util.duck_type_collection(other) is not util.Set:
         return NotImplemented
     for value in other:
         self.discard(value)
     return self
Esempio n. 29
0
 def __isub__(self, value):
     if sautil.duck_type_collection(value) is not Set:
         return NotImplemented
     for item in value:
         self.discard(item)
     return self
Esempio n. 30
0
    def __init__(self, entity, *a, **kw):
        kw.setdefault('bundle_errors', True)
        self.default_location = kw.pop('location', [])
        self.relation_overlay = kw.pop('relation_overlay', False)

        super(EntityParser, self).__init__(*a, **kw)

        columns = inspect(entity).columns
        relation_column = {}
        for relationship in inspect(entity).relationships:
            if len(relationship.local_columns):
                column, = relationship.local_columns
                relation_column[column.name] = relationship.key

        for column in columns:
            # TODO: better validation
            if column.name in ['namespace'
                               ]:  # TODO: move this to columns defination
                continue
            type_ = column.type.python_type
            if type_ == datetime:
                type_ = inputs.datetime_from_iso8601
            self.add_argument(column.name if
                              (not self.relation_overlay
                               or column.name not in relation_column) else
                              relation_column[column.name],
                              type=type_,
                              location=self.default_location,
                              store_missing=False,
                              required=FuncBool(
                                  self.default_required, column.default is None
                                  and not column.nullable),
                              dest=column.name)

        for attr in entity.attribute_models.values():
            duck_type = duck_type_collection(attr.__collector__())
            default = None

            # Don't give None on empty for compatibility with associate proxy
            action = 'store'
            if duck_type in (dict, ):
                default = duck_type()
            elif duck_type in (list, set):
                type_ = duck_type
                action = 'append'

                def duck_type(x):
                    return x
            else:
                default = None

            if not duck_type:
                logger.error(
                    'Unsupported attribute collection for attribute: {}'.
                    format(attr))

            self.add_argument(attr.ref_name,
                              type=duck_type,
                              location=self.default_location,
                              store_missing=False,
                              default=default,
                              action=action)

        self.normal_arg_names = [arg.name for arg in self.args]
Esempio n. 31
0
 def __isub__(self, value):
     if sautil.duck_type_collection(value) is not Set:
         return NotImplemented
     for item in value:
         self.discard(item)
     return self