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)
190
if (StaticTuple_CheckExact(sequence)) {
192
return (StaticTuple *)sequence;
194
if (!PySequence_Check(sequence)) {
195
PyErr_Format(PyExc_TypeError, "Type %s is not a sequence type",
196
Py_TYPE(sequence)->tp_name);
199
size = PySequence_Size(sequence);
202
new = StaticTuple_New(size);
206
for (i = 0; i < size; ++i) {
207
// This returns a new reference, which we then 'steal' with
208
// StaticTuple_SET_ITEM
209
item = PySequence_GetItem(sequence, i);
214
StaticTuple_SET_ITEM(new, i, item);
216
return (StaticTuple *)new;
220
StaticTuple_from_sequence(PyObject *self, PyObject *args, PyObject *kwargs)
223
if (!PyArg_ParseTuple(args, "O", &sequence))
225
return StaticTuple_FromSequence(sequence);
229
/* Check that all items we point to are 'valid' */
231
StaticTuple_check_items(StaticTuple *self)
236
for (i = 0; i < self->size; ++i) {
237
obj = self->items[i];
239
PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
240
" should not have a NULL entry.");
243
if (PyString_CheckExact(obj)
244
|| StaticTuple_CheckExact(obj)
247
|| PyInt_CheckExact(obj)
248
|| PyLong_CheckExact(obj)
249
|| PyFloat_CheckExact(obj)
250
|| PyUnicode_CheckExact(obj)
252
PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
253
" requires that all items are one of"
254
" str, StaticTuple, None, bool, int, long, float, or unicode"
255
" not %s.", Py_TYPE(obj)->tp_name);
177
261
static PyObject *
178
262
StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
192
276
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
277
self = (StaticTuple *)StaticTuple_New(len);
200
278
if (self == NULL) {
203
281
for (i = 0; i < len; ++i) {
204
282
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
284
self->items[i] = obj;
286
if (!StaticTuple_check_items(self)) {
287
type->tp_dealloc((PyObject *)self);
216
290
return (PyObject *)self;
230
304
if (tuple_repr == NULL) {
233
result = PyString_FromFormat("%s%s", Py_TYPE(self)->tp_name,
234
PyString_AsString(tuple_repr));
307
result = PyString_FromFormat("StaticTuple%s",
308
PyString_AsString(tuple_repr));
411
485
/* Both are StaticTuple types, so recurse */
412
486
result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
414
/* Not the same type, obviously they won't compare equal */
488
/* Fall back to generic richcompare */
489
result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
417
491
if (result == NULL) {
418
492
return NULL; /* There seems to be an error */
420
if (result == Py_NotImplemented) {
421
PyErr_BadInternalCall();
425
494
if (result == Py_False) {
426
/* This entry is not identical
495
// This entry is not identical, Shortcut for Py_EQ
429
496
if (op == Py_EQ) {
479
546
/* Both are StaticTuple types, so recurse */
480
547
return StaticTuple_richcompare(v_obj, w_obj, op);
482
Py_INCREF(Py_NotImplemented);
483
return Py_NotImplemented;
549
return PyObject_RichCompare(v_obj, w_obj, op);
510
576
static PyObject *
577
StaticTuple_reduce(StaticTuple *self)
579
PyObject *result = NULL, *as_tuple = NULL;
581
result = PyTuple_New(2);
585
as_tuple = StaticTuple_as_tuple(self);
586
if (as_tuple == NULL) {
590
Py_INCREF(&StaticTuple_Type);
591
PyTuple_SET_ITEM(result, 0, (PyObject *)&StaticTuple_Type);
592
PyTuple_SET_ITEM(result, 1, as_tuple);
596
static char StaticTuple_reduce_doc[] = "__reduce__() => tuple\n";
600
StaticTuple_add(PyObject *v, PyObject *w)
602
Py_ssize_t i, len_v, len_w;
605
/* StaticTuples and plain tuples may be added (concatenated) to
608
if (StaticTuple_CheckExact(v)) {
609
len_v = ((StaticTuple*)v)->size;
610
} else if (PyTuple_Check(v)) {
611
len_v = PyTuple_GET_SIZE(v);
613
Py_INCREF(Py_NotImplemented);
614
return Py_NotImplemented;
616
if (StaticTuple_CheckExact(w)) {
617
len_w = ((StaticTuple*)w)->size;
618
} else if (PyTuple_Check(w)) {
619
len_w = PyTuple_GET_SIZE(w);
621
Py_INCREF(Py_NotImplemented);
622
return Py_NotImplemented;
624
result = StaticTuple_New(len_v + len_w);
627
for (i = 0; i < len_v; ++i) {
628
// This returns a new reference, which we then 'steal' with
629
// StaticTuple_SET_ITEM
630
item = PySequence_GetItem(v, i);
635
StaticTuple_SET_ITEM(result, i, item);
637
for (i = 0; i < len_w; ++i) {
638
item = PySequence_GetItem(w, i);
643
StaticTuple_SET_ITEM(result, i+len_v, item);
645
if (!StaticTuple_check_items(result)) {
649
return (PyObject *)result;
511
653
StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
565
707
{"intern", (PyCFunction)StaticTuple_Intern, METH_NOARGS, StaticTuple_Intern_doc},
566
708
{"_is_interned", (PyCFunction)StaticTuple__is_interned, METH_NOARGS,
567
709
StaticTuple__is_interned_doc},
710
{"from_sequence", (PyCFunction)StaticTuple_from_sequence,
711
METH_STATIC | METH_VARARGS,
712
"Create a StaticTuple from a given sequence. This functions"
713
" the same as the tuple() constructor."},
714
{"__reduce__", (PyCFunction)StaticTuple_reduce, METH_NOARGS, StaticTuple_reduce_doc},
568
715
{NULL, NULL} /* sentinel */
719
static PyNumberMethods StaticTuple_as_number = {
720
(binaryfunc) StaticTuple_add, /* nb_add */
724
0, /* nb_remainder */
571
741
static PySequenceMethods StaticTuple_as_sequence = {
572
742
(lenfunc)StaticTuple_length, /* sq_length */
573
743
0, /* sq_concat */
589
759
PyTypeObject StaticTuple_Type = {
590
760
PyObject_HEAD_INIT(NULL)
592
"StaticTuple", /* tp_name */
762
"bzrlib._static_tuple_c.StaticTuple", /* tp_name */
593
763
sizeof(StaticTuple), /* tp_basicsize */
594
764
sizeof(PyObject *), /* tp_itemsize */
595
765
(destructor)StaticTuple_dealloc, /* tp_dealloc */
598
768
0, /* tp_setattr */
599
769
0, /* tp_compare */
600
770
(reprfunc)StaticTuple_repr, /* tp_repr */
601
0, /* tp_as_number */
771
&StaticTuple_as_number, /* tp_as_number */
602
772
&StaticTuple_as_sequence, /* tp_as_sequence */
603
773
0, /* tp_as_mapping */
604
774
(hashfunc)StaticTuple_hash, /* tp_hash */
607
PyObject_GenericGetAttr, /* tp_getattro */
608
778
0, /* tp_setattro */
609
779
0, /* tp_as_buffer */
610
Py_TPFLAGS_DEFAULT, /* tp_flags*/
780
/* Py_TPFLAGS_CHECKTYPES tells the number operations that they shouldn't
781
* try to 'coerce' but instead stuff like 'add' will check it arguments.
783
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags*/
611
784
StaticTuple_doc, /* tp_doc */
612
785
/* gc.get_referents checks the IS_GC flag before it calls tp_traverse
613
786
* And we don't include this object in the garbage collector because we
684
857
"StaticTuple *(Py_ssize_t)");
685
858
_export_function(m, "StaticTuple_Intern", StaticTuple_Intern,
686
859
"StaticTuple *(StaticTuple *)");
860
_export_function(m, "StaticTuple_FromSequence", StaticTuple_FromSequence,
861
"StaticTuple *(PyObject *)");
687
862
_export_function(m, "_StaticTuple_CheckExact", _StaticTuple_CheckExact,
688
863
"int(PyObject *)");
710
885
set_module = PyImport_ImportModule("bzrlib._simple_set_pyx");
711
886
if (set_module == NULL) {
712
// fprintf(stderr, "Failed to import bzrlib._simple_set_pyx\n");
715
889
/* Add the _simple_set_pyx into sys.modules at the appropriate location. */
716
890
sys_module = PyImport_ImportModule("sys");
717
891
if (sys_module == NULL) {
718
// fprintf(stderr, "Failed to import sys\n");
721
894
modules = PyObject_GetAttrString(sys_module, "modules");
722
895
if (modules == NULL || !PyDict_Check(modules)) {
723
// fprintf(stderr, "Failed to find sys.modules\n");
726
898
PyDict_SetItemString(modules, "_simple_set_pyx", set_module);