Lichen

Annotated lib/__builtins__/tuple.py

902:dc210430ce4c
2019-05-27 Paul Boddie Updated copyright statement years.
paul@6 1
#!/usr/bin/env python
paul@6 2
paul@6 3
"""
paul@6 4
Tuple objects.
paul@6 5
paul@857 6
Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
paul@6 7
paul@6 8
This program is free software; you can redistribute it and/or modify it under
paul@6 9
the terms of the GNU General Public License as published by the Free Software
paul@6 10
Foundation; either version 3 of the License, or (at your option) any later
paul@6 11
version.
paul@6 12
paul@6 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@6 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@6 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@6 16
details.
paul@6 17
paul@6 18
You should have received a copy of the GNU General Public License along with
paul@6 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@6 20
"""
paul@6 21
paul@528 22
from __builtins__.iteration.iterator import itemiterator
paul@837 23
from __builtins__.sequence import hashable, unpackable
paul@773 24
from native import tuple_init, \
paul@857 25
                   list_element, list_len, list_setsize, list_setelement, \
paul@857 26
                   isinstance as _isinstance
paul@6 27
paul@837 28
class tuple(unpackable, hashable):
paul@6 29
paul@6 30
    "Implementation of tuple."
paul@6 31
paul@159 32
    def __init__(self, args=None):
paul@159 33
paul@159 34
        "Initialise the tuple."
paul@159 35
paul@227 36
        # Reserve an attribute for a fragment reference along with some space
paul@227 37
        # for elements.
paul@227 38
paul@773 39
        if args is None:
paul@773 40
            size = 0
paul@773 41
        else:
paul@773 42
            size = args.__len__()
paul@782 43
paul@782 44
        self.__data__ = tuple_init(size)
paul@782 45
paul@782 46
        if size:
paul@773 47
            list_setsize(self.__data__, size)
paul@227 48
paul@773 49
            # Populate the tuple.
paul@773 50
paul@227 51
            i = 0
paul@773 52
            while i < size:
paul@773 53
                list_setelement(self.__data__, i, args[i])
paul@227 54
                i += 1
paul@6 55
paul@459 56
    def __hash__(self):
paul@459 57
paul@459 58
        "Return a hashable value for the tuple."
paul@459 59
paul@459 60
        return self._hashvalue(hash)
paul@459 61
paul@551 62
    def __getslice__(self, start, end=None, step=1):
paul@6 63
paul@551 64
        """
paul@551 65
        Return a slice starting from 'start', with the optional 'end' and
paul@551 66
        'step'.
paul@551 67
        """
paul@6 68
paul@837 69
        return tuple(get_using(unpackable.__getslice__, self)(start, end, step))
paul@159 70
paul@159 71
    def __len__(self):
paul@6 72
paul@159 73
        "Return the length of the tuple."
paul@159 74
paul@356 75
        return list_len(self.__data__)
paul@159 76
paul@857 77
    def __add__(self, other):
paul@857 78
paul@857 79
        "Add this tuple to 'other'."
paul@857 80
paul@857 81
        if not _isinstance(other, tuple):
paul@857 82
            raise TypeError
paul@857 83
        return tuple(tuplepair(self, other))
paul@159 84
paul@227 85
    def __str__(self):
paul@227 86
paul@227 87
        "Return a string representation."
paul@227 88
paul@227 89
        return self._str("(", ")")
paul@6 90
paul@224 91
    __repr__ = __str__
paul@224 92
paul@6 93
    def __bool__(self):
paul@6 94
paul@6 95
        "Tuples are true if non-empty."
paul@6 96
paul@6 97
        return self.__len__() != 0
paul@6 98
paul@6 99
    def __iter__(self):
paul@6 100
paul@6 101
        "Return an iterator."
paul@6 102
paul@290 103
        return itemiterator(self)
paul@6 104
paul@6 105
    # Special implementation methods.
paul@6 106
paul@159 107
    def __get_single_item__(self, index):
paul@227 108
paul@227 109
        "Return the item at the normalised (positive) 'index'."
paul@227 110
paul@265 111
        self._check_index(index)
paul@356 112
        return list_element(self.__data__, index)
paul@227 113
paul@227 114
    def __set_single_item__(self, index, value):
paul@227 115
paul@227 116
        "Set at the normalised (positive) 'index' the given 'value'."
paul@227 117
paul@665 118
        raise TypeError
paul@6 119
paul@857 120
class tuplepair:
paul@857 121
paul@857 122
    "A combination of tuples."
paul@857 123
paul@857 124
    def __init__(self, a, b):
paul@857 125
        self.a = a
paul@857 126
        self.b = b
paul@857 127
paul@857 128
    def __len__(self):
paul@857 129
paul@857 130
        "Return the combined length of the tuples."
paul@857 131
paul@857 132
        return len(self.a) + len(self.b)
paul@857 133
paul@857 134
    def __getitem__(self, index):
paul@857 135
paul@857 136
        "Return the value from 'index' in the combined tuple."
paul@857 137
paul@857 138
        asize = len(self.a)
paul@857 139
        if index < asize:
paul@857 140
            return self.a.__get_single_item__(index)
paul@857 141
        else:
paul@857 142
            return self.b.__get_single_item__(index - asize)
paul@857 143
paul@6 144
# vim: tabstop=4 expandtab shiftwidth=4