Exemplo n.º 1
0
 def func(value):
     if value is None:
         return None
     t = type(value)
     if t is not unicode:
         if t is buffer:
             value = hexlify(value).decode('ascii')
         else:
             value = unicode(value)
     result = base_func(value)
     return result
Exemplo n.º 2
0
def tostring(x):
    if isinstance(x, basestring): return x
    if hasattr(x, '__unicode__'):
        try: return unicode(x)
        except: pass
    if hasattr(x, 'makeelement'): return cElementTree.tostring(x)
    try: return str(x)
    except: pass
    try: return repr(x)
    except: pass
    if type(x) == types.InstanceType: return '<%s instance at 0x%X>' % (x.__class__.__name__)
    return '<%s object at 0x%X>' % (x.__class__.__name__)
Exemplo n.º 3
0
def tostring(x):
    if isinstance(x, basestring): return x
    if hasattr(x, '__unicode__'):
        try: return unicode(x)
        except: pass
    if hasattr(x, 'makeelement'): return cElementTree.tostring(x)
    try: return str(x)
    except: pass
    try: return repr(x)
    except: pass
    if type(x) == types.InstanceType: return '<%s instance at 0x%X>' % (x.__class__.__name__)
    return '<%s object at 0x%X>' % (x.__class__.__name__)
Exemplo n.º 4
0
def force_text(s, encoding='utf-8', strings_only=False, errors='strict'):
    """
    Similar to smart_text, except that lazy instances are resolved to
    strings, rather than kept as lazy objects.

    If strings_only is True, don't convert (some) non-string-like objects.
    """
    # Handle the common case first for performance reasons.
    if issubclass(type(s), unicode):
        return s
    if strings_only and is_protected_type(s):
        return s
    try:
        if not issubclass(type(s), basestring):
            if not PY2:
                if isinstance(s, bytes):
                    s = unicode(s, encoding, errors)
                else:
                    s = unicode(s)
            elif hasattr(s, '__unicode__'):
                s = unicode(s)
            else:
                s = unicode(bytes(s), encoding, errors)
        else:
            # Note: We use .decode() here, instead of unicode(s, encoding,
            # errors), so that if s is a SafeBytes, it ends up being a
            # SafeText at the end.
            s = s.decode(encoding, errors)
    except UnicodeDecodeError as e:
        if isinstance(s, Exception):
            # If we get to here, the caller has passed in an Exception
            # subclass populated with non-ASCII bytestring data without a
            # working unicode method. Try to handle this without raising a
            # further exception by individually forcing the exception args
            # to unicode.
            s = ' '.join(
                force_text(arg, encoding, strings_only, errors) for arg in s)
        else:
            raise
    return s
Exemplo n.º 5
0
    def _get_ops(self):
        result = []
        entities = get_entities(self.db)
        entities_prev = get_entities(self.db_prev)

        eadded = {}
        emodified = {}

        for ename, entity in self.db.entities.items():
            if ename not in self.db_prev.entities:
                eadded[ename] = sorted((a.name, a) for a in entity._new_attrs_)

        eremoved = {}

        for ename, prev_entity in self.db_prev.entities.items():
            if ename not in self.db.entities:
                eremoved[ename] = sorted(
                    (a.name, a) for a in prev_entity._new_attrs_)

        entity_renames = {}

        @contextmanager
        def apply_renames(renames):
            for from_, to_ in renames.items():
                entity = entities[to_]
                entity.__name__ = from_
            yield
            for from_, to_ in renames.items():
                entity = entities[to_]
                entity.__name__ = to_

        for rem_ename, rem_attrs in sorted(eremoved.items()):
            for add_ename, add_attrs in sorted(eadded.items()):
                with apply_renames({rem_ename: add_ename}):
                    for (add_aname,
                         add_attr), (rem_aname,
                                     rem_attr) in zip(add_attrs, rem_attrs):
                        if add_aname != rem_aname:
                            break

                        if add_attr.get_declaration_id(
                        ) != rem_attr.get_declaration_id():
                            break
                    else:
                        if self.questioner.ask_rename_model(
                                rem_ename, add_ename):
                            result.append(
                                ops.RenameEntity(rem_ename, add_ename))
                            entity_renames[rem_ename] = add_ename
                            del eadded[add_ename]
                            del eremoved[rem_ename]

        with apply_renames(entity_renames):
            for entity in sorted(self.db.entities.values(),
                                 key=attrgetter('_id_')):
                ename = entity.__name__
                if ename == 'Migration' or ename not in entities_prev:
                    continue

                prev_entity = entities_prev[ename]
                aadded, aremoved, amodified = self._get_entity_changes(
                    ename, entity, prev_entity)
                for add_name, add_attr in sorted(aadded.items()):
                    for rem_name, rem_attr in sorted(aremoved.items()):
                        try:
                            add_attr.name = rem_attr.name
                            if add_attr.get_declaration_id() == rem_attr.get_declaration_id() \
                            and self.questioner.ask_rename(ename, rem_name, add_name):
                                result.append(
                                    ops.RenameAttr(ename, rem_name, add_name))
                                del aremoved[rem_name]
                                del aadded[add_name]
                        finally:
                            add_attr.name = add_name
                emodified[ename] = aadded, aremoved, amodified

        def get_id(pair):
            return tuple(
                tuple(a and a.get_declaration_id()
                      for a in attrs or (None, None)) for attrs in pair)

        def sort_pair(pair):
            result = []
            for attrs in pair:
                if attrs:
                    attr, rattr = attrs
                    if getattr(attr, 'name', '') < getattr(rattr, 'name', ''):
                        attrs = rattr, attr
                result.append(attrs)
            return result

        pairs = {}

        for ename, (aadded, aremoved, amodified) in sorted(emodified.items()):

            # Get entity operations
            for aname, attr in sorted(aadded.items()):
                if not attr.reverse:
                    if issubclass(attr.py_type, str) and isinstance(
                            attr, orm.Optional):
                        kwargs = attr._constructor_args[1]
                        value_class = self.db.provider.sqlbuilder_cls.value_class
                        value = value_class(self.db.provider.paramstyle, '')
                        kwargs.update(sql_default=unicode(value))
                    elif not attr.nullable and attr.initial is None and attr.default is None and not attr.is_pk:
                        initial = self.questioner.ask_not_null_addition(
                            aname, ename)
                        attr.initial = attr._constructor_args[1][
                            'initial'] = initial
                    result.append(ops.AddAttr(ename, aname, attr))
            for aname, attr in sorted(aremoved.items()):
                if not attr.reverse:
                    result.append(ops.RemoveAttr(ename, aname))
            for aname, attr in sorted(amodified.items()):
                if not attr.reverse:
                    attr_prev = self.db_prev.entities[ename]._adict_[aname]
                    result.append(
                        ops.AddAttr(ename, aname, attr) if attr_prev.
                        reverse else ops.ModifyAttr(ename, aname, attr))

            new_entity = entities.get(ename) or entities.get(
                entity_renames.get(ename))
            assert new_entity is not None
            adict = {a.name: a for a in new_entity._new_attrs_}

            prev_entity = entities_prev[ename]
            prev_adict = {a.name: a for a in prev_entity._new_attrs_}

            for aname in chain(aadded, amodified):
                attr = adict[aname]
                prev_attr = prev_adict.get(aname)
                if prev_attr and not prev_attr.reverse:
                    prev_attr = None
                if attr and not attr.reverse:
                    attr = None
                if not attr and not prev_attr:
                    continue
                if prev_attr:
                    pair = (attr and attr.reverse, attr), (prev_attr,
                                                           prev_attr.reverse)
                elif attr.reverse.name in prev_adict:
                    attr = attr.reverse
                    prev_attr = getattr(prev_entity, attr.name)
                    pair = (attr, attr.reverse), (prev_attr, prev_attr.reverse)
                else:
                    pair = (attr, attr.reverse), None
                pair = sort_pair(pair)
                pairs[get_id(pair)] = pair

            for aname in aremoved:
                prev_attr = prev_adict[aname]
                if not prev_attr.reverse:
                    prev_attr = None
                attr = adict.get(aname)
                if attr and not attr.reverse:
                    attr = None
                if not attr and not prev_attr:
                    continue

                if attr:
                    pair = (attr, attr.reverse), (prev_attr, prev_attr
                                                  and prev_attr.reverse)
                else:
                    pair = None, (prev_attr, prev_attr.reverse)

                pair = sort_pair(pair)
                pairs[get_id(pair)] = pair

        def name(attr):
            return attr and attr.name

        def ename(attr):
            return attr.entity.__name__

        for pair, pair_prev in pairs.values():
            attr = attr_prev = None
            if pair_prev:
                attr_prev, rattr_prev = pair_prev
            if pair:
                attr, rattr = pair
            if getattr(attr, 'reverse', None) and getattr(
                    attr_prev, 'reverse', None):
                result.append(
                    ops.ModifyRelation(ename(attr), name(attr), attr,
                                       name(rattr), rattr))
            elif getattr(attr, 'reverse', None):
                result.append(
                    ops.AddRelation(ename(attr), name(attr), attr, name(rattr),
                                    rattr))
            elif getattr(attr_prev, 'reverse', None):
                result.append(
                    ops.RemoveRelation(ename(attr_prev), attr_prev.name))

        for ename, attrs in sorted(eadded.items(),
                                   key=lambda x: entities[x[0]]._id_):
            bases = [c.__name__ for c in entities[ename].__bases__]
            regular = [(k, v) for k, v in attrs if not v.reverse]

            # Patch by andgein. Add _table_, _discriminator_ and _table_options_ fields to entity attributes.
            special_fields = ["_table_", "_discriminator_", "_table_options_"]
            # Some special fields can't been redefined in child entity.
            special_fields_blocked_in_child = ["_table_", "_table_options_"]

            entity = self.db.entities[ename]
            for field in special_fields:
                is_child = len(entity._all_bases_) > 0
                if is_child and field in special_fields_blocked_in_child:
                    continue
                field_value = getattr(entity, field, None)
                if field_value is not None:
                    regular.append((field, field_value))

            own_indexes = [
                index for index in entity._indexes_ if index.entity == entity
            ]
            composite_indexes = [
                index for index in own_indexes
                if len(index.attrs) > 1 and not index.is_pk
            ]
            # Auto_created indices will be created by Pono automatically be entity attribute definition
            # (orm.PrimaryKey() or orm.Required(..., unique=True) will be used).
            auto_created_indexes = [
                index for index in own_indexes
                if (index.is_unique or index.is_pk) and len(index.attrs) == 1
            ]
            regular.append(("_indexes_",
                            list(
                                set(own_indexes) - set(composite_indexes) -
                                set(auto_created_indexes))))
            # End of patch by andgein

            result.append(ops.AddEntity(ename, bases, regular))
            for aname, attr in attrs:
                if not attr.reverse:
                    continue
                prev_entity = entities_prev.get(attr.reverse.entity.__name__)
                prev_attr = None
                if prev_entity:
                    prev_attr = prev_entity._adict_.get(attr.reverse.name)
                    if prev_attr is None:  # attribute was added from other entity
                        continue
                    if prev_attr.entity is not prev_entity:
                        assert False, 'Not implemented'
                    if prev_attr and not prev_attr.reverse:
                        prev_attr = None
                if prev_attr:
                    pair = (attr, attr.reverse), (prev_attr, prev_attr.reverse)
                else:
                    pair = (attr, attr.reverse), None
                pair = sort_pair(pair)
                iden = get_id(pair)
                if iden not in pairs:
                    pairs[iden] = pair
                    result.append(
                        ops.AddRelation(ename, name(attr), attr,
                                        name(attr.reverse), attr.reverse))

            # Patch by andgein. Composite indices should be added after relations
            for index in composite_indexes:
                result.append(
                    ops.AddIndex(ename, [attr.name for attr in index.attrs],
                                 index.name, index.is_unique))
            # End of patch

        for ename, attrs in sorted(eremoved.items()):
            result.append(ops.RemoveEntity(ename))
            for aname, prev_attr in attrs:
                if not prev_attr.reverse:
                    continue
                entity = entities.get(prev_attr.reverse.entity.__name__)
                attr = None
                if entity:
                    attr = entity._adict_.get(prev_attr.reverse.name)
                    if attr.entity is not entity:
                        assert False, 'Not implemented'
                    if attr and not attr.reverse:
                        attr = None
                if attr:
                    pair = (attr, attr.reverse), (prev_attr, prev_attr.reverse)
                else:
                    pair = None, (prev_attr, prev_attr.reverse)
                pair = sort_pair(pair)
                iden = get_id(pair)
                if iden not in pairs:
                    pairs[iden] = pair
                    result.append(ops.RemoveRelation(ename, aname))

        # sorting
        def keyfunc(op):
            if isinstance(op, ops.RenameAttr):
                return 0
            if isinstance(op, ops.RenameEntity):
                return 1
            if isinstance(op, ops.RemoveRelation):
                return 2
            if 'Remove' in op.__class__.__name__:
                return 3
            if isinstance(op, ops.AddEntity):
                return 4
            return 5

        return sorted(result, key=keyfunc)