예제 #1
0
    def __new__(cls, **kwargs):    # Support *args?
        result = super(PClass, cls).__new__(cls)
        factory_fields = kwargs.pop('_factory_fields', None)
        ignore_extra = kwargs.pop('ignore_extra', None)
        missing_fields = []
        invariant_errors = []
        for name, field in cls._pclass_fields.items():
            if name in kwargs:
                if factory_fields is None or name in factory_fields:
                    if is_field_ignore_extra_complaint(PClass, field, ignore_extra):
                        value = field.factory(kwargs[name], ignore_extra=ignore_extra)
                    else:
                        value = field.factory(kwargs[name])
                else:
                    value = kwargs[name]
                _check_and_set_attr(cls, field, name, value, result, invariant_errors)
                del kwargs[name]
            elif field.initial is not PFIELD_NO_INITIAL:
                initial = field.initial() if callable(field.initial) else field.initial
                _check_and_set_attr(
                    cls, field, name, initial, result, invariant_errors)
            elif field.mandatory:
                missing_fields.append('{0}.{1}'.format(cls.__name__, name))

        if invariant_errors or missing_fields:
            raise InvariantException(tuple(invariant_errors), tuple(missing_fields), 'Field invariant failed')

        if kwargs:
            raise AttributeError("'{0}' are not among the specified fields for {1}".format(
                ', '.join(kwargs), cls.__name__))

        check_global_invariants(result, cls._pclass_invariants)

        result._pclass_frozen = True
        return result
예제 #2
0
    def set(self, key, original_value):
        field = self._destination_cls._precord_fields.get(key)
        if field:
            if self._factory_fields is None or field in self._factory_fields:
                try:
                    if is_field_ignore_extra_complaint(PRecord, field, self._ignore_extra):
                        value = field.factory(original_value, ignore_extra=self._ignore_extra)
                    else:
                        value = field.factory(original_value)
                except InvariantException as e:
                    self._invariant_error_codes += e.invariant_errors
                    self._missing_fields += e.missing_fields
                    return self
            else:
                value = original_value

            check_type(self._destination_cls, field, key, value)

            is_ok, error_code = field.invariant(value)
            if not is_ok:
                self._invariant_error_codes.append(error_code)

            return super(_PRecordEvolver, self).set(key, value)
        else:
            raise AttributeError("'{0}' is not among the specified fields for {1}".format(key, self._destination_cls.__name__))
예제 #3
0
    def set(self, key, original_value):
        field = self._destination_cls._precord_fields.get(key)
        if field:
            if self._factory_fields is None or field in self._factory_fields:
                try:
                    if is_field_ignore_extra_complaint(PRecord, field, self._ignore_extra):
                        value = field.factory(original_value, ignore_extra=self._ignore_extra)
                    else:
                        value = field.factory(original_value)
                except InvariantException as e:
                    self._invariant_error_codes += e.invariant_errors
                    self._missing_fields += e.missing_fields
                    return self
            else:
                value = original_value

            check_type(self._destination_cls, field, key, value)

            is_ok, error_code = field.invariant(value)
            if not is_ok:
                self._invariant_error_codes.append(error_code)

            return super(_PRecordEvolver, self).set(key, value)
        else:
            raise AttributeError("'{0}' is not among the specified fields for {1}".format(key, self._destination_cls.__name__))