def inline_small_list(sizemax=11, sizemin=0, immutable=False, unbox_num=False, nonull=False,
                      attrname="list", factoryname="make", listgettername="_get_full_list",
                      listsizename="_get_size_list", gettername="_get_list",
                      settername="_set_list"):
    """
    This function is helpful if you have a class with a field storing a
    list and the list is often very small. Calling this function will inline
    the list into instances for the small sizes. This works by adding the
    following methods (names customizable) to the class:

    _get_list(self, i): return ith element of the list

    _set_list(self, i, val): set ith element of the list

    _get_full_list(self): returns a copy of the full list

    _get_size_list(self): returns the length of the list

    @staticmethod
    make(listcontent, *args): makes a new instance with the list's content set to listcontent
    """
    if not config.type_size_specialization:
        sizemin = sizemax = 0
        unbox_num = False

    def wrapper(cls):
        def make_class(size):
            attrs = [(attrname, i) % "_%s_%s" for i in range(size)]
            unrolling_enumerate_attrs = unrolling_iterable(enumerate(attrs))

            def _get_size_list(self):
                return size
            def _get_list(self, i):
                for j, attr in unrolling_enumerate_attrs:
                    if j == i:
                        return getattr(self, attr)
                raise IndexError
            def _get_full_list(self):
                res = [None] * size
                for i, attr in unrolling_enumerate_attrs:
                    res[i] = getattr(self, attr)
                return res
            def _set_list(self, i, val):
                for j, attr in unrolling_enumerate_attrs:
                    if j == i:
                        if nonull:
                            assert val is not None
                        setattr(self, attr, val)
                        return
                raise IndexError
            def _init(self, elems, *args):
                assert len(elems) == size
                for i, attr in unrolling_enumerate_attrs:
                    val = elems[i]
                    if nonull:
                        assert val is not None
                    setattr(self, attr, elems[i])
                cls.__init__(self, *args)

            # Methods for the new class being built
            methods = {
                gettername     : _get_list,
                listsizename   : _get_size_list,
                listgettername : _get_full_list,
                settername     : _set_list,
                "__init__"     : _init,
            }

            newcls = type(cls)("%sSize%s" % (cls.__name__, size), (cls, ), methods)

            if immutable:
                setattr(newcls, "_immutable_fields_", attrs)
                newcls = add_clone_method(newcls)

            return newcls

        classes = map(make_class, range(sizemin, sizemax))

        # Build the arbitrary sized variant
        def _get_arbitrary(self, i):
            return getattr(self, attrname)[i]
        def _get_size_list_arbitrary(self):
            return len(getattr(self, attrname))
        def _get_list_arbitrary(self):
            return getattr(self, attrname)
        def _set_arbitrary(self, i, val):
            if nonull:
                assert val is not None
            getattr(self, attrname)[i] = val
        def _init(self, elems, *args):
            debug.make_sure_not_resized(elems)
            setattr(self, attrname, elems)
            cls.__init__(self, *args)

        methods = {
            gettername     : _get_arbitrary,
            listsizename   : _get_size_list_arbitrary,
            listgettername : _get_list_arbitrary,
            settername     : _set_arbitrary,
            "__init__"     : _init,
        }

        cls_arbitrary = type(cls)("%sArbitrary" % cls.__name__, (cls, ), methods)

        if immutable:
            setattr(cls_arbitrary, "_immutable_fields_", ["%s[*]" % (attrname,)])
            cls_arbitrary = add_clone_method(cls_arbitrary)

        def make(elems, *args):
            if classes:
                if (elems is None or len(elems) == 0):
                    return make0(*args)
            else:
                if elems is None:
                    elems = []
            if sizemin <= len(elems) < sizemax:
                cls = classes[len(elems) - sizemin]
            else:
                cls = cls_arbitrary
            return cls(elems, *args)

        # XXX those could be done more nicely
        def make0(*args):
            if not classes: # no type specialization
                return make([], *args)
            result = objectmodel.instantiate(classes[0])
            cls.__init__(result, *args)
            return result
        def make1(elem, *args):
            if not classes: # no type specialization
                return make([elem], *args)
            result = objectmodel.instantiate(classes[1])
            result._set_list(0, elem)
            cls.__init__(result, *args)
            return result
        def make2(elem1, elem2, *args):
            if not classes: # no type specialization
                return make([elem1, elem2], *args)
            result = objectmodel.instantiate(classes[2])
            result._set_list(0, elem1)
            result._set_list(1, elem2)
            cls.__init__(result, *args)
            return result

        def make_n(size, *args):
            if sizemin <= size < sizemax:
                subcls = classes[size - sizemin]
            else:
                subcls = cls_arbitrary
            result = objectmodel.instantiate(subcls)
            if subcls is cls_arbitrary:
                assert isinstance(result, subcls)
                setattr(result, attrname, [None] * size)
            cls.__init__(result, *args)
            return result

        if unbox_num:
            assert immutable, "unboxing is only supported for immutable objects"
            make, make1, make2 = _add_num_classes(cls, make, make0, make1, make2)
        setattr(cls, factoryname, staticmethod(make))
        setattr(cls, factoryname + "0", staticmethod(make0))
        setattr(cls, factoryname + "1", staticmethod(make1))
        setattr(cls, factoryname + "2", staticmethod(make2))
        setattr(cls, factoryname + "_n", staticmethod(make_n))
        return cls
    return wrapper
dataset/ETHPy150Open samth/pycket/pycket/small_list.py/inline_small_list/swapped operands of `%`