148
if (size < 0 || size > 255) {
149
/* Too big or too small */
150
PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
151
" takes from 0 to 255 items");
148
154
if (size == 0 && _empty_tuple != NULL) {
149
155
Py_INCREF(_empty_tuple);
150
156
return _empty_tuple;
184
StaticTuple_FromSequence(PyObject *sequence)
186
StaticTuple *new = NULL;
187
PyObject *as_tuple = NULL;
191
if (StaticTuple_CheckExact(sequence)) {
193
return (StaticTuple *)sequence;
195
if (!PySequence_Check(sequence)) {
196
as_tuple = PySequence_Tuple(sequence);
197
if (as_tuple == NULL)
201
size = PySequence_Size(sequence);
205
new = StaticTuple_New(size);
209
for (i = 0; i < size; ++i) {
210
// This returns a new reference, which we then 'steal' with
211
// StaticTuple_SET_ITEM
212
item = PySequence_GetItem(sequence, i);
218
StaticTuple_SET_ITEM(new, i, item);
221
Py_XDECREF(as_tuple);
222
return (StaticTuple *)new;
226
StaticTuple_from_sequence(PyObject *self, PyObject *args, PyObject *kwargs)
229
if (!PyArg_ParseTuple(args, "O", &sequence))
231
return StaticTuple_FromSequence(sequence);
235
/* Check that all items we point to are 'valid' */
237
StaticTuple_check_items(StaticTuple *self)
242
for (i = 0; i < self->size; ++i) {
243
obj = self->items[i];
245
PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
246
" should not have a NULL entry.");
249
if (PyString_CheckExact(obj)
250
|| StaticTuple_CheckExact(obj)
253
|| PyInt_CheckExact(obj)
254
|| PyLong_CheckExact(obj)
255
|| PyFloat_CheckExact(obj)
256
|| PyUnicode_CheckExact(obj)
258
PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
259
" requires that all items are one of"
260
" str, StaticTuple, None, bool, int, long, float, or unicode"
261
" not %s.", Py_TYPE(obj)->tp_name);
177
267
static PyObject *
178
268
StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
192
282
len = PyTuple_GET_SIZE(args);
193
if (len < 0 || len > 255) {
194
/* Too big or too small */
195
PyErr_SetString(PyExc_ValueError, "StaticTuple.__init__(...)"
196
" takes from 0 to 255 items");
199
283
self = (StaticTuple *)StaticTuple_New(len);
200
284
if (self == NULL) {
203
287
for (i = 0; i < len; ++i) {
204
288
obj = PyTuple_GET_ITEM(args, i);
205
if (!PyString_CheckExact(obj)) {
206
if (!StaticTuple_CheckExact(obj)) {
207
PyErr_SetString(PyExc_TypeError, "StaticTuple.__init__(...)"
208
" requires that all items are strings or StaticTuple.");
209
type->tp_dealloc((PyObject *)self);
214
290
self->items[i] = obj;
292
if (!StaticTuple_check_items(self)) {
293
type->tp_dealloc((PyObject *)self);
216
296
return (PyObject *)self;
230
310
if (tuple_repr == NULL) {
233
result = PyString_FromFormat("%s%s", Py_TYPE(self)->tp_name,
234
PyString_AsString(tuple_repr));
313
result = PyString_FromFormat("StaticTuple%s",
314
PyString_AsString(tuple_repr));
411
491
/* Both are StaticTuple types, so recurse */
412
492
result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
414
/* Not the same type, obviously they won't compare equal */
494
/* Fall back to generic richcompare */
495
result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
417
497
if (result == NULL) {
418
498
return NULL; /* There seems to be an error */
420
if (result == Py_NotImplemented) {
421
PyErr_BadInternalCall();
425
500
if (result == Py_False) {
426
/* This entry is not identical
501
// This entry is not identical, Shortcut for Py_EQ
429
502
if (op == Py_EQ) {
479
552
/* Both are StaticTuple types, so recurse */
480
553
return StaticTuple_richcompare(v_obj, w_obj, op);
482
Py_INCREF(Py_NotImplemented);
483
return Py_NotImplemented;
555
return PyObject_RichCompare(v_obj, w_obj, op);
510
582
static PyObject *
583
StaticTuple_reduce(StaticTuple *self)
585
PyObject *result = NULL, *as_tuple = NULL;
587
result = PyTuple_New(2);
591
as_tuple = StaticTuple_as_tuple(self);
592
if (as_tuple == NULL) {
596
Py_INCREF(&StaticTuple_Type);
597
PyTuple_SET_ITEM(result, 0, (PyObject *)&StaticTuple_Type);
598
PyTuple_SET_ITEM(result, 1, as_tuple);
602
static char StaticTuple_reduce_doc[] = "__reduce__() => tuple\n";
606
StaticTuple_add(PyObject *v, PyObject *w)
608
Py_ssize_t i, len_v, len_w;
611
/* StaticTuples and plain tuples may be added (concatenated) to
614
if (StaticTuple_CheckExact(v)) {
615
len_v = ((StaticTuple*)v)->size;
616
} else if (PyTuple_Check(v)) {
617
len_v = PyTuple_GET_SIZE(v);
619
Py_INCREF(Py_NotImplemented);
620
return Py_NotImplemented;
622
if (StaticTuple_CheckExact(w)) {
623
len_w = ((StaticTuple*)w)->size;
624
} else if (PyTuple_Check(w)) {
625
len_w = PyTuple_GET_SIZE(w);
627
Py_INCREF(Py_NotImplemented);
628
return Py_NotImplemented;
630
result = StaticTuple_New(len_v + len_w);
633
for (i = 0; i < len_v; ++i) {
634
// This returns a new reference, which we then 'steal' with
635
// StaticTuple_SET_ITEM
636
item = PySequence_GetItem(v, i);
641
StaticTuple_SET_ITEM(result, i, item);
643
for (i = 0; i < len_w; ++i) {
644
item = PySequence_GetItem(w, i);
649
StaticTuple_SET_ITEM(result, i+len_v, item);
651
if (!StaticTuple_check_items(result)) {
655
return (PyObject *)result;
511
659
StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
565
713
{"intern", (PyCFunction)StaticTuple_Intern, METH_NOARGS, StaticTuple_Intern_doc},
566
714
{"_is_interned", (PyCFunction)StaticTuple__is_interned, METH_NOARGS,
567
715
StaticTuple__is_interned_doc},
716
{"from_sequence", (PyCFunction)StaticTuple_from_sequence,
717
METH_STATIC | METH_VARARGS,
718
"Create a StaticTuple from a given sequence. This functions"
719
" the same as the tuple() constructor."},
720
{"__reduce__", (PyCFunction)StaticTuple_reduce, METH_NOARGS, StaticTuple_reduce_doc},
568
721
{NULL, NULL} /* sentinel */
725
static PyNumberMethods StaticTuple_as_number = {
726
(binaryfunc) StaticTuple_add, /* nb_add */
730
0, /* nb_remainder */
571
747
static PySequenceMethods StaticTuple_as_sequence = {
572
748
(lenfunc)StaticTuple_length, /* sq_length */
573
749
0, /* sq_concat */
589
765
PyTypeObject StaticTuple_Type = {
590
766
PyObject_HEAD_INIT(NULL)
592
"StaticTuple", /* tp_name */
768
"bzrlib._static_tuple_c.StaticTuple", /* tp_name */
593
769
sizeof(StaticTuple), /* tp_basicsize */
594
770
sizeof(PyObject *), /* tp_itemsize */
595
771
(destructor)StaticTuple_dealloc, /* tp_dealloc */
598
774
0, /* tp_setattr */
599
775
0, /* tp_compare */
600
776
(reprfunc)StaticTuple_repr, /* tp_repr */
601
0, /* tp_as_number */
777
&StaticTuple_as_number, /* tp_as_number */
602
778
&StaticTuple_as_sequence, /* tp_as_sequence */
603
779
0, /* tp_as_mapping */
604
780
(hashfunc)StaticTuple_hash, /* tp_hash */
607
PyObject_GenericGetAttr, /* tp_getattro */
608
784
0, /* tp_setattro */
609
785
0, /* tp_as_buffer */
610
Py_TPFLAGS_DEFAULT, /* tp_flags*/
786
/* Py_TPFLAGS_CHECKTYPES tells the number operations that they shouldn't
787
* try to 'coerce' but instead stuff like 'add' will check it arguments.
789
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags*/
611
790
StaticTuple_doc, /* tp_doc */
612
791
/* gc.get_referents checks the IS_GC flag before it calls tp_traverse
613
792
* And we don't include this object in the garbage collector because we
684
863
"StaticTuple *(Py_ssize_t)");
685
864
_export_function(m, "StaticTuple_Intern", StaticTuple_Intern,
686
865
"StaticTuple *(StaticTuple *)");
866
_export_function(m, "StaticTuple_FromSequence", StaticTuple_FromSequence,
867
"StaticTuple *(PyObject *)");
687
868
_export_function(m, "_StaticTuple_CheckExact", _StaticTuple_CheckExact,
688
869
"int(PyObject *)");
710
891
set_module = PyImport_ImportModule("bzrlib._simple_set_pyx");
711
892
if (set_module == NULL) {
712
// fprintf(stderr, "Failed to import bzrlib._simple_set_pyx\n");
715
895
/* Add the _simple_set_pyx into sys.modules at the appropriate location. */
716
896
sys_module = PyImport_ImportModule("sys");
717
897
if (sys_module == NULL) {
718
// fprintf(stderr, "Failed to import sys\n");
721
900
modules = PyObject_GetAttrString(sys_module, "modules");
722
901
if (modules == NULL || !PyDict_Check(modules)) {
723
// fprintf(stderr, "Failed to find sys.modules\n");
726
904
PyDict_SetItemString(modules, "_simple_set_pyx", set_module);