1
/* Copyright (C) 2009, 2010 Canonical Ltd
1
/* Copyright (C) 2009 Canonical Ltd
3
3
* This program is free software; you can redistribute it and/or modify
4
4
* it under the terms of the GNU General Public License as published by
140
140
StaticTuple_New(Py_ssize_t size)
142
142
StaticTuple *stuple;
144
if (size < 0 || size > 255) {
145
/* Too big or too small */
146
PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
147
" takes from 0 to 255 items");
144
PyErr_BadInternalCall();
150
148
if (size == 0 && _empty_tuple != NULL) {
151
149
Py_INCREF(_empty_tuple);
152
150
return _empty_tuple;
180
StaticTuple_FromSequence(PyObject *sequence)
182
StaticTuple *new = NULL;
183
PyObject *as_tuple = NULL;
187
if (StaticTuple_CheckExact(sequence)) {
189
return (StaticTuple *)sequence;
191
if (!PySequence_Check(sequence)) {
192
as_tuple = PySequence_Tuple(sequence);
193
if (as_tuple == NULL)
197
size = PySequence_Size(sequence);
201
new = StaticTuple_New(size);
205
for (i = 0; i < size; ++i) {
206
// This returns a new reference, which we then 'steal' with
207
// StaticTuple_SET_ITEM
208
item = PySequence_GetItem(sequence, i);
214
StaticTuple_SET_ITEM(new, i, item);
217
Py_XDECREF(as_tuple);
218
return (StaticTuple *)new;
222
StaticTuple_from_sequence(PyObject *self, PyObject *args, PyObject *kwargs)
225
if (!PyArg_ParseTuple(args, "O", &sequence))
227
return StaticTuple_FromSequence(sequence);
231
/* Check that all items we point to are 'valid' */
233
StaticTuple_check_items(StaticTuple *self)
238
for (i = 0; i < self->size; ++i) {
239
obj = self->items[i];
241
PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
242
" should not have a NULL entry.");
245
if (PyString_CheckExact(obj)
246
|| StaticTuple_CheckExact(obj)
249
|| PyInt_CheckExact(obj)
250
|| PyLong_CheckExact(obj)
251
|| PyFloat_CheckExact(obj)
252
|| PyUnicode_CheckExact(obj)
254
PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
255
" requires that all items are one of"
256
" str, StaticTuple, None, bool, int, long, float, or unicode"
257
" not %s.", Py_TYPE(obj)->tp_name);
263
177
static PyObject *
264
178
StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
278
192
len = PyTuple_GET_SIZE(args);
279
193
if (len < 0 || len > 255) {
280
/* Check the length here so we can raise a TypeError instead of
281
* StaticTuple_New's ValueError.
283
PyErr_SetString(PyExc_TypeError, "StaticTuple(...)"
194
/* Too big or too small */
195
PyErr_SetString(PyExc_ValueError, "StaticTuple.__init__(...)"
284
196
" takes from 0 to 255 items");
291
203
for (i = 0; i < len; ++i) {
292
204
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);
294
214
self->items[i] = obj;
296
if (!StaticTuple_check_items(self)) {
297
type->tp_dealloc((PyObject *)self);
300
216
return (PyObject *)self;
314
230
if (tuple_repr == NULL) {
317
result = PyString_FromFormat("StaticTuple%s",
318
PyString_AsString(tuple_repr));
233
result = PyString_FromFormat("%s%s", Py_TYPE(self)->tp_name,
234
PyString_AsString(tuple_repr));
495
411
/* Both are StaticTuple types, so recurse */
496
412
result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
498
/* Fall back to generic richcompare */
499
result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
414
/* Not the same type, obviously they won't compare equal */
501
417
if (result == NULL) {
502
418
return NULL; /* There seems to be an error */
420
if (result == Py_NotImplemented) {
421
PyErr_BadInternalCall();
504
425
if (result == Py_False) {
505
// This entry is not identical, Shortcut for Py_EQ
426
/* This entry is not identical
506
429
if (op == Py_EQ) {
556
479
/* Both are StaticTuple types, so recurse */
557
480
return StaticTuple_richcompare(v_obj, w_obj, op);
559
return PyObject_RichCompare(v_obj, w_obj, op);
482
Py_INCREF(Py_NotImplemented);
483
return Py_NotImplemented;
586
510
static PyObject *
587
StaticTuple_reduce(StaticTuple *self)
589
PyObject *result = NULL, *as_tuple = NULL;
591
result = PyTuple_New(2);
595
as_tuple = StaticTuple_as_tuple(self);
596
if (as_tuple == NULL) {
600
Py_INCREF(&StaticTuple_Type);
601
PyTuple_SET_ITEM(result, 0, (PyObject *)&StaticTuple_Type);
602
PyTuple_SET_ITEM(result, 1, as_tuple);
606
static char StaticTuple_reduce_doc[] = "__reduce__() => tuple\n";
610
StaticTuple_add(PyObject *v, PyObject *w)
612
Py_ssize_t i, len_v, len_w;
615
/* StaticTuples and plain tuples may be added (concatenated) to
618
if (StaticTuple_CheckExact(v)) {
619
len_v = ((StaticTuple*)v)->size;
620
} else if (PyTuple_Check(v)) {
621
len_v = PyTuple_GET_SIZE(v);
623
Py_INCREF(Py_NotImplemented);
624
return Py_NotImplemented;
626
if (StaticTuple_CheckExact(w)) {
627
len_w = ((StaticTuple*)w)->size;
628
} else if (PyTuple_Check(w)) {
629
len_w = PyTuple_GET_SIZE(w);
631
Py_INCREF(Py_NotImplemented);
632
return Py_NotImplemented;
634
result = StaticTuple_New(len_v + len_w);
637
for (i = 0; i < len_v; ++i) {
638
// This returns a new reference, which we then 'steal' with
639
// StaticTuple_SET_ITEM
640
item = PySequence_GetItem(v, i);
645
StaticTuple_SET_ITEM(result, i, item);
647
for (i = 0; i < len_w; ++i) {
648
item = PySequence_GetItem(w, i);
653
StaticTuple_SET_ITEM(result, i+len_v, item);
655
if (!StaticTuple_check_items(result)) {
659
return (PyObject *)result;
663
511
StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
708
StaticTuple_sizeof(StaticTuple *self)
712
res = _PyObject_SIZE(&StaticTuple_Type) + (int)self->size * sizeof(void*);
713
return PyInt_FromSsize_t(res);
718
554
static char StaticTuple_doc[] =
719
555
"C implementation of a StaticTuple structure."
720
556
"\n This is used as StaticTuple(item1, item2, item3)"
729
565
{"intern", (PyCFunction)StaticTuple_Intern, METH_NOARGS, StaticTuple_Intern_doc},
730
566
{"_is_interned", (PyCFunction)StaticTuple__is_interned, METH_NOARGS,
731
567
StaticTuple__is_interned_doc},
732
{"from_sequence", (PyCFunction)StaticTuple_from_sequence,
733
METH_STATIC | METH_VARARGS,
734
"Create a StaticTuple from a given sequence. This functions"
735
" the same as the tuple() constructor."},
736
{"__reduce__", (PyCFunction)StaticTuple_reduce, METH_NOARGS, StaticTuple_reduce_doc},
737
{"__sizeof__", (PyCFunction)StaticTuple_sizeof, METH_NOARGS},
738
568
{NULL, NULL} /* sentinel */
742
static PyNumberMethods StaticTuple_as_number = {
743
(binaryfunc) StaticTuple_add, /* nb_add */
747
0, /* nb_remainder */
764
571
static PySequenceMethods StaticTuple_as_sequence = {
765
572
(lenfunc)StaticTuple_length, /* sq_length */
766
573
0, /* sq_concat */
782
589
PyTypeObject StaticTuple_Type = {
783
590
PyObject_HEAD_INIT(NULL)
785
"bzrlib._static_tuple_c.StaticTuple", /* tp_name */
592
"StaticTuple", /* tp_name */
786
593
sizeof(StaticTuple), /* tp_basicsize */
787
594
sizeof(PyObject *), /* tp_itemsize */
788
595
(destructor)StaticTuple_dealloc, /* tp_dealloc */
791
598
0, /* tp_setattr */
792
599
0, /* tp_compare */
793
600
(reprfunc)StaticTuple_repr, /* tp_repr */
794
&StaticTuple_as_number, /* tp_as_number */
601
0, /* tp_as_number */
795
602
&StaticTuple_as_sequence, /* tp_as_sequence */
796
603
0, /* tp_as_mapping */
797
604
(hashfunc)StaticTuple_hash, /* tp_hash */
607
PyObject_GenericGetAttr, /* tp_getattro */
801
608
0, /* tp_setattro */
802
609
0, /* tp_as_buffer */
803
/* Py_TPFLAGS_CHECKTYPES tells the number operations that they shouldn't
804
* try to 'coerce' but instead stuff like 'add' will check it arguments.
806
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES, /* tp_flags*/
610
Py_TPFLAGS_DEFAULT, /* tp_flags*/
807
611
StaticTuple_doc, /* tp_doc */
808
612
/* gc.get_referents checks the IS_GC flag before it calls tp_traverse
809
613
* And we don't include this object in the garbage collector because we
880
684
"StaticTuple *(Py_ssize_t)");
881
685
_export_function(m, "StaticTuple_Intern", StaticTuple_Intern,
882
686
"StaticTuple *(StaticTuple *)");
883
_export_function(m, "StaticTuple_FromSequence", StaticTuple_FromSequence,
884
"StaticTuple *(PyObject *)");
885
687
_export_function(m, "_StaticTuple_CheckExact", _StaticTuple_CheckExact,
886
688
"int(PyObject *)");
908
710
set_module = PyImport_ImportModule("bzrlib._simple_set_pyx");
909
711
if (set_module == NULL) {
712
// fprintf(stderr, "Failed to import bzrlib._simple_set_pyx\n");
912
715
/* Add the _simple_set_pyx into sys.modules at the appropriate location. */
913
716
sys_module = PyImport_ImportModule("sys");
914
717
if (sys_module == NULL) {
718
// fprintf(stderr, "Failed to import sys\n");
917
721
modules = PyObject_GetAttrString(sys_module, "modules");
918
722
if (modules == NULL || !PyDict_Check(modules)) {
723
// fprintf(stderr, "Failed to find sys.modules\n");
921
726
PyDict_SetItemString(modules, "_simple_set_pyx", set_module);