1995-07-18 11:12:02 -03:00
|
|
|
/* Abstract Object Interface (many thanks to Jim Fulton) */
|
1998-05-21 21:47:05 -03:00
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
#include "Python.h"
|
1998-05-22 12:23:36 -03:00
|
|
|
#include <ctype.h>
|
2001-01-03 21:39:06 -04:00
|
|
|
#include "structmember.h" /* we need the offsetof() macro from there */
|
2001-09-10 17:52:51 -03:00
|
|
|
#include "longintrepr.h"
|
2001-01-03 21:39:06 -04:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Shorthands to return certain errors */
|
1995-07-18 11:12:02 -03:00
|
|
|
|
|
|
|
static PyObject *
|
2000-07-09 01:34:13 -03:00
|
|
|
type_error(const char *msg)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyErr_SetString(PyExc_TypeError, msg);
|
|
|
|
return NULL;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1996-11-11 11:08:19 -04:00
|
|
|
static PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
null_error(void)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
if (!PyErr_Occurred())
|
|
|
|
PyErr_SetString(PyExc_SystemError,
|
|
|
|
"null argument to internal routine");
|
|
|
|
return NULL;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Operations on any object */
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyObject_Cmp(PyObject *o1, PyObject *o2, int *result)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
int r;
|
|
|
|
|
|
|
|
if (o1 == NULL || o2 == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
r = PyObject_Compare(o1, o2);
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
return -1;
|
|
|
|
*result = r;
|
1995-07-18 11:12:02 -03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyObject_Type(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
|
|
|
PyObject *v;
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
1995-07-18 11:12:02 -03:00
|
|
|
v = (PyObject *)o->ob_type;
|
|
|
|
Py_INCREF(v);
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t
|
2000-07-12 09:56:19 -03:00
|
|
|
PyObject_Size(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = o->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_length)
|
|
|
|
return m->sq_length(o);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2000-07-12 09:56:19 -03:00
|
|
|
return PyMapping_Size(o);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2000-07-17 06:22:55 -03:00
|
|
|
#undef PyObject_Length
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t
|
2000-07-17 06:22:55 -03:00
|
|
|
PyObject_Length(PyObject *o)
|
|
|
|
{
|
|
|
|
return PyObject_Size(o);
|
|
|
|
}
|
|
|
|
#define PyObject_Length PyObject_Size
|
|
|
|
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t
|
2006-02-11 17:32:43 -04:00
|
|
|
_PyObject_LengthHint(PyObject *o)
|
2005-09-24 18:23:05 -03:00
|
|
|
{
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t rv = PyObject_Size(o);
|
2005-09-24 18:23:05 -03:00
|
|
|
if (rv != -1)
|
|
|
|
return rv;
|
|
|
|
if (PyErr_ExceptionMatches(PyExc_TypeError) ||
|
|
|
|
PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
|
|
|
PyObject *err_type, *err_value, *err_tb, *ro;
|
|
|
|
|
|
|
|
PyErr_Fetch(&err_type, &err_value, &err_tb);
|
2006-02-11 17:32:43 -04:00
|
|
|
ro = PyObject_CallMethod(o, "__length_hint__", NULL);
|
2005-09-24 18:23:05 -03:00
|
|
|
if (ro != NULL) {
|
2006-02-15 13:27:45 -04:00
|
|
|
rv = PyInt_AsLong(ro);
|
2005-09-24 18:23:05 -03:00
|
|
|
Py_DECREF(ro);
|
|
|
|
Py_XDECREF(err_type);
|
|
|
|
Py_XDECREF(err_value);
|
|
|
|
Py_XDECREF(err_tb);
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
PyErr_Restore(err_type, err_value, err_tb);
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyObject_GetItem(PyObject *o, PyObject *key)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyMappingMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL || key == NULL)
|
|
|
|
return null_error();
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = o->ob_type->tp_as_mapping;
|
|
|
|
if (m && m->mp_subscript)
|
|
|
|
return m->mp_subscript(o, key);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-08-13 13:44:44 -03:00
|
|
|
if (o->ob_type->tp_as_sequence) {
|
2006-03-07 14:50:55 -04:00
|
|
|
PyNumberMethods *nb = key->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (nb != NULL && nb->nb_index != NULL) {
|
2006-03-07 14:50:55 -04:00
|
|
|
Py_ssize_t key_value = nb->nb_index(key);
|
2000-02-23 18:21:50 -04:00
|
|
|
if (key_value == -1 && PyErr_Occurred())
|
|
|
|
return NULL;
|
|
|
|
return PySequence_GetItem(o, key_value);
|
|
|
|
}
|
2001-11-24 14:24:47 -04:00
|
|
|
else if (o->ob_type->tp_as_sequence->sq_item)
|
|
|
|
return type_error("sequence index must be integer");
|
1998-08-13 13:44:44 -03:00
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
|
|
|
|
return type_error("unsubscriptable object");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyObject_SetItem(PyObject *o, PyObject *key, PyObject *value)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyMappingMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL || key == NULL || value == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
m = o->ob_type->tp_as_mapping;
|
|
|
|
if (m && m->mp_ass_subscript)
|
|
|
|
return m->mp_ass_subscript(o, key, value);
|
|
|
|
|
1998-08-13 13:44:44 -03:00
|
|
|
if (o->ob_type->tp_as_sequence) {
|
2006-03-07 14:50:55 -04:00
|
|
|
PyNumberMethods *nb = key->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (nb != NULL && nb->nb_index != NULL) {
|
2006-03-07 14:50:55 -04:00
|
|
|
Py_ssize_t key_value = nb->nb_index(key);
|
2000-02-23 18:21:50 -04:00
|
|
|
if (key_value == -1 && PyErr_Occurred())
|
|
|
|
return -1;
|
|
|
|
return PySequence_SetItem(o, key_value, value);
|
|
|
|
}
|
2001-11-24 14:24:47 -04:00
|
|
|
else if (o->ob_type->tp_as_sequence->sq_ass_item) {
|
|
|
|
type_error("sequence index must be integer");
|
|
|
|
return -1;
|
|
|
|
}
|
1998-08-13 13:44:44 -03:00
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
type_error("object does not support item assignment");
|
|
|
|
return -1;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1996-08-21 14:41:54 -03:00
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyObject_DelItem(PyObject *o, PyObject *key)
|
1996-08-21 14:41:54 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyMappingMethods *m;
|
|
|
|
|
|
|
|
if (o == NULL || key == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
m = o->ob_type->tp_as_mapping;
|
|
|
|
if (m && m->mp_ass_subscript)
|
|
|
|
return m->mp_ass_subscript(o, key, (PyObject*)NULL);
|
1996-08-21 14:41:54 -03:00
|
|
|
|
1998-08-13 13:44:44 -03:00
|
|
|
if (o->ob_type->tp_as_sequence) {
|
2006-03-07 14:50:55 -04:00
|
|
|
PyNumberMethods *nb = key->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (nb != NULL && nb->nb_index != NULL) {
|
2006-03-07 14:50:55 -04:00
|
|
|
Py_ssize_t key_value = nb->nb_index(key);
|
2000-02-23 18:21:50 -04:00
|
|
|
if (key_value == -1 && PyErr_Occurred())
|
|
|
|
return -1;
|
|
|
|
return PySequence_DelItem(o, key_value);
|
|
|
|
}
|
2001-11-24 14:24:47 -04:00
|
|
|
else if (o->ob_type->tp_as_sequence->sq_ass_item) {
|
|
|
|
type_error("sequence index must be integer");
|
|
|
|
return -1;
|
|
|
|
}
|
1998-08-13 13:44:44 -03:00
|
|
|
}
|
1996-08-21 14:41:54 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
type_error("object does not support item deletion");
|
|
|
|
return -1;
|
1996-08-21 14:41:54 -03:00
|
|
|
}
|
|
|
|
|
2002-01-05 06:50:30 -04:00
|
|
|
int
|
|
|
|
PyObject_DelItemString(PyObject *o, char *key)
|
|
|
|
{
|
|
|
|
PyObject *okey;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (o == NULL || key == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
okey = PyString_FromString(key);
|
|
|
|
if (okey == NULL)
|
|
|
|
return -1;
|
|
|
|
ret = PyObject_DelItem(o, okey);
|
|
|
|
Py_DECREF(okey);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
Merge the rest of the trunk.
Merged revisions 46490-46494,46496,46498,46500,46506,46521,46538,46558,46563-46567,46570-46571,46583,46593,46595-46598,46604,46606,46609-46753 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r46610 | martin.v.loewis | 2006-06-03 09:42:26 +0200 (Sat, 03 Jun 2006) | 2 lines
Updated version (win32-icons2.zip) from #1490384.
........
r46612 | andrew.kuchling | 2006-06-03 20:09:41 +0200 (Sat, 03 Jun 2006) | 1 line
[Bug #1472084] Fix description of do_tag
........
r46614 | andrew.kuchling | 2006-06-03 20:33:35 +0200 (Sat, 03 Jun 2006) | 1 line
[Bug #1475554] Strengthen text to say 'must' instead of 'should'
........
r46616 | andrew.kuchling | 2006-06-03 20:41:28 +0200 (Sat, 03 Jun 2006) | 1 line
[Bug #1441864] Clarify description of 'data' argument
........
r46617 | andrew.kuchling | 2006-06-03 20:43:24 +0200 (Sat, 03 Jun 2006) | 1 line
Minor rewording
........
r46619 | andrew.kuchling | 2006-06-03 21:02:35 +0200 (Sat, 03 Jun 2006) | 9 lines
[Bug #1497414] _self is a reserved word in the WATCOM 10.6 C compiler.
Fix by renaming the variable.
In a different module, Neal fixed it by renaming _self to self. There's
already a variable named 'self' here, so I used selfptr.
(I'm committing this on a Mac without Tk, but it's a simple search-and-replace.
<crosses fingers>, so I'll watch the buildbots and see what happens.)
........
r46621 | fredrik.lundh | 2006-06-03 23:56:05 +0200 (Sat, 03 Jun 2006) | 5 lines
"_self" is a said to be a reserved word in Watcom C 10.6. I'm
not sure that's really standard compliant behaviour, but I guess
we have to fix that anyway...
........
r46622 | andrew.kuchling | 2006-06-04 00:44:42 +0200 (Sun, 04 Jun 2006) | 1 line
Update readme
........
r46623 | andrew.kuchling | 2006-06-04 00:59:23 +0200 (Sun, 04 Jun 2006) | 1 line
Drop 0 parameter
........
r46624 | andrew.kuchling | 2006-06-04 00:59:59 +0200 (Sun, 04 Jun 2006) | 1 line
Some code tidying; use curses.wrapper
........
r46625 | andrew.kuchling | 2006-06-04 01:02:15 +0200 (Sun, 04 Jun 2006) | 1 line
Use True; value returned from main is unused
........
r46626 | andrew.kuchling | 2006-06-04 01:07:21 +0200 (Sun, 04 Jun 2006) | 1 line
Use true division, and the True value
........
r46627 | andrew.kuchling | 2006-06-04 01:09:58 +0200 (Sun, 04 Jun 2006) | 1 line
Docstring fix; use True
........
r46628 | andrew.kuchling | 2006-06-04 01:15:56 +0200 (Sun, 04 Jun 2006) | 1 line
Put code in a main() function; loosen up the spacing to match current code style
........
r46629 | andrew.kuchling | 2006-06-04 01:39:07 +0200 (Sun, 04 Jun 2006) | 1 line
Use functions; modernize code
........
r46630 | andrew.kuchling | 2006-06-04 01:43:22 +0200 (Sun, 04 Jun 2006) | 1 line
This demo requires Medusa (not just asyncore); remove it
........
r46631 | andrew.kuchling | 2006-06-04 01:46:36 +0200 (Sun, 04 Jun 2006) | 2 lines
Remove xmlrpc demo -- it duplicates the SimpleXMLRPCServer module.
........
r46632 | andrew.kuchling | 2006-06-04 01:47:22 +0200 (Sun, 04 Jun 2006) | 1 line
Remove xmlrpc/ directory
........
r46633 | andrew.kuchling | 2006-06-04 01:51:21 +0200 (Sun, 04 Jun 2006) | 1 line
Remove dangling reference
........
r46634 | andrew.kuchling | 2006-06-04 01:59:36 +0200 (Sun, 04 Jun 2006) | 1 line
Add more whitespace; use a better socket name
........
r46635 | tim.peters | 2006-06-04 03:22:53 +0200 (Sun, 04 Jun 2006) | 2 lines
Whitespace normalization.
........
r46637 | tim.peters | 2006-06-04 05:26:02 +0200 (Sun, 04 Jun 2006) | 16 lines
In a PYMALLOC_DEBUG build obmalloc adds extra debugging info
to each allocated block. This was using 4 bytes for each such
piece of info regardless of platform. This didn't really matter
before (proof: no bug reports, and the debug-build obmalloc would
have assert-failed if it was ever asked for a chunk of memory
>= 2**32 bytes), since container indices were plain ints. But after
the Py_ssize_t changes, it's at least theoretically possible to
allocate a list or string whose guts exceed 2**32 bytes, and the
PYMALLOC_DEBUG routines would fail then (having only 4 bytes
to record the originally requested size).
Now we use sizeof(size_t) bytes for each of a PYMALLOC_DEBUG
build's extra debugging fields. This won't make any difference
on 32-bit boxes, but will add 16 bytes to each allocation in
a debug build on a 64-bit box.
........
r46638 | tim.peters | 2006-06-04 05:38:04 +0200 (Sun, 04 Jun 2006) | 4 lines
_PyObject_DebugMalloc(): The return value should add
2*sizeof(size_t) now, not 8. This probably accounts for
current disasters on the 64-bit buildbot slaves.
........
r46639 | neal.norwitz | 2006-06-04 08:19:31 +0200 (Sun, 04 Jun 2006) | 1 line
SF #1499797, Fix for memory leak in WindowsError_str
........
r46640 | andrew.macintyre | 2006-06-04 14:31:09 +0200 (Sun, 04 Jun 2006) | 2 lines
Patch #1454481: Make thread stack size runtime tunable.
........
r46641 | andrew.macintyre | 2006-06-04 14:59:59 +0200 (Sun, 04 Jun 2006) | 2 lines
clean up function declarations to conform to PEP-7 style.
........
r46642 | martin.blais | 2006-06-04 15:49:49 +0200 (Sun, 04 Jun 2006) | 15 lines
Fixes in struct and socket from merge reviews.
- Following Guido's comments, renamed
* pack_to -> pack_into
* recv_buf -> recv_into
* recvfrom_buf -> recvfrom_into
- Made fixes to _struct.c according to Neal Norwitz comments on the checkins
list.
- Converted some ints into the appropriate -- I hope -- ssize_t and size_t.
........
r46643 | ronald.oussoren | 2006-06-04 16:05:28 +0200 (Sun, 04 Jun 2006) | 3 lines
"Import" LDFLAGS in Mac/OSX/Makefile.in to ensure pythonw gets build with
the right compiler flags.
........
r46644 | ronald.oussoren | 2006-06-04 16:24:59 +0200 (Sun, 04 Jun 2006) | 2 lines
Drop Mac wrappers for the WASTE library.
........
r46645 | tim.peters | 2006-06-04 17:49:07 +0200 (Sun, 04 Jun 2006) | 3 lines
s_methods[]: Stop compiler warnings by casting
s_unpack_from to PyCFunction.
........
r46646 | george.yoshida | 2006-06-04 19:04:12 +0200 (Sun, 04 Jun 2006) | 2 lines
Remove a redundant word
........
r46647 | george.yoshida | 2006-06-04 19:17:25 +0200 (Sun, 04 Jun 2006) | 2 lines
Markup fix
........
r46648 | martin.v.loewis | 2006-06-04 21:36:28 +0200 (Sun, 04 Jun 2006) | 2 lines
Patch #1359618: Speed-up charmap encoder.
........
r46649 | georg.brandl | 2006-06-04 23:46:16 +0200 (Sun, 04 Jun 2006) | 3 lines
Repair refleaks in unicodeobject.
........
r46650 | georg.brandl | 2006-06-04 23:56:52 +0200 (Sun, 04 Jun 2006) | 4 lines
Patch #1346214: correctly optimize away "if 0"-style stmts
(thanks to Neal for review)
........
r46651 | georg.brandl | 2006-06-05 00:15:37 +0200 (Mon, 05 Jun 2006) | 2 lines
Bug #1500293: fix memory leaks in _subprocess module.
........
r46654 | tim.peters | 2006-06-05 01:43:53 +0200 (Mon, 05 Jun 2006) | 2 lines
Whitespace normalization.
........
r46655 | tim.peters | 2006-06-05 01:52:47 +0200 (Mon, 05 Jun 2006) | 16 lines
Revert revisions:
46640 Patch #1454481: Make thread stack size runtime tunable.
46647 Markup fix
The first is causing many buildbots to fail test runs, and there
are multiple causes with seemingly no immediate prospects for
repairing them. See python-dev discussion.
Note that a branch can (and should) be created for resolving these
problems, like
svn copy svn+ssh://svn.python.org/python/trunk -r46640 svn+ssh://svn.python.org/python/branches/NEW_BRANCH
followed by merging rev 46647 to the new branch.
........
r46656 | andrew.kuchling | 2006-06-05 02:08:09 +0200 (Mon, 05 Jun 2006) | 1 line
Mention second encoding speedup
........
r46657 | gregory.p.smith | 2006-06-05 02:31:01 +0200 (Mon, 05 Jun 2006) | 7 lines
bugfix: when log_archive was called with the DB_ARCH_REMOVE flag present
in BerkeleyDB >= 4.2 it tried to construct a list out of an uninitialized
char **log_list.
feature: export the DB_ARCH_REMOVE flag by name in the module on BerkeleyDB >= 4.2.
........
r46658 | gregory.p.smith | 2006-06-05 02:33:35 +0200 (Mon, 05 Jun 2006) | 5 lines
fix a bug in the previous commit. don't leak empty list on error return and
fix the additional rare (out of memory only) bug that it was supposed to fix
of not freeing log_list when the python allocator failed.
........
r46660 | tim.peters | 2006-06-05 02:55:26 +0200 (Mon, 05 Jun 2006) | 9 lines
"Flat is better than nested."
Move the long-winded, multiply-nested -R support out
of runtest() and into some module-level helper functions.
This makes runtest() and the -R code easier to follow.
That in turn allowed seeing some opportunities for code
simplification, and made it obvious that reglog.txt
never got closed.
........
r46661 | hyeshik.chang | 2006-06-05 02:59:54 +0200 (Mon, 05 Jun 2006) | 3 lines
Fix a potentially invalid memory access of CJKCodecs' shift-jis
decoder. (found by Neal Norwitz)
........
r46663 | gregory.p.smith | 2006-06-05 03:39:52 +0200 (Mon, 05 Jun 2006) | 3 lines
* support DBEnv.log_stat() method on BerkeleyDB >= 4.0 [patch #1494885]
........
r46664 | tim.peters | 2006-06-05 03:43:03 +0200 (Mon, 05 Jun 2006) | 3 lines
Remove doctest.testmod's deprecated (in 2.4) `isprivate`
argument. A lot of hair went into supporting that!
........
r46665 | tim.peters | 2006-06-05 03:47:24 +0200 (Mon, 05 Jun 2006) | 2 lines
Whitespace normalization.
........
r46666 | tim.peters | 2006-06-05 03:48:21 +0200 (Mon, 05 Jun 2006) | 2 lines
Make doctest news more accurate.
........
r46667 | gregory.p.smith | 2006-06-05 03:56:15 +0200 (Mon, 05 Jun 2006) | 3 lines
* support DBEnv.lsn_reset() method on BerkeleyDB >= 4.4 [patch #1494902]
........
r46668 | gregory.p.smith | 2006-06-05 04:02:25 +0200 (Mon, 05 Jun 2006) | 3 lines
mention the just committed bsddb changes
........
r46671 | gregory.p.smith | 2006-06-05 19:38:04 +0200 (Mon, 05 Jun 2006) | 3 lines
* add support for DBSequence objects [patch #1466734]
........
r46672 | gregory.p.smith | 2006-06-05 20:20:07 +0200 (Mon, 05 Jun 2006) | 3 lines
forgot to add this file in previous commit
........
r46673 | tim.peters | 2006-06-05 20:36:12 +0200 (Mon, 05 Jun 2006) | 2 lines
Whitespace normalization.
........
r46674 | tim.peters | 2006-06-05 20:36:54 +0200 (Mon, 05 Jun 2006) | 2 lines
Add missing svn:eol-style property to text files.
........
r46675 | gregory.p.smith | 2006-06-05 20:48:21 +0200 (Mon, 05 Jun 2006) | 4 lines
* fix DBCursor.pget() bug with keyword argument names when no data= is
supplied [SF pybsddb bug #1477863]
........
r46676 | andrew.kuchling | 2006-06-05 21:05:32 +0200 (Mon, 05 Jun 2006) | 1 line
Remove use of Trove name, which isn't very helpful to users
........
r46677 | andrew.kuchling | 2006-06-05 21:08:25 +0200 (Mon, 05 Jun 2006) | 1 line
[Bug #1470026] Include link to list of classifiers
........
r46679 | tim.peters | 2006-06-05 22:48:49 +0200 (Mon, 05 Jun 2006) | 10 lines
Access _struct attributes directly instead of mucking with getattr.
string_reverse(): Simplify.
assertRaises(): Raise TestFailed on failure.
test_unpack_from(), test_pack_into(), test_pack_into_fn(): never
use `assert` to test for an expected result (it doesn't test anything
when Python is run with -O).
........
r46680 | tim.peters | 2006-06-05 22:49:27 +0200 (Mon, 05 Jun 2006) | 2 lines
Add missing svn:eol-style property to text files.
........
r46681 | gregory.p.smith | 2006-06-06 01:38:06 +0200 (Tue, 06 Jun 2006) | 3 lines
add depends = ['md5.h'] to the _md5 module extension for correctness sake.
........
r46682 | brett.cannon | 2006-06-06 01:51:55 +0200 (Tue, 06 Jun 2006) | 4 lines
Add 3 more bytes to a buffer to cover constants in string and null byte on top of 10 possible digits for an int.
Closes bug #1501223.
........
r46684 | gregory.p.smith | 2006-06-06 01:59:37 +0200 (Tue, 06 Jun 2006) | 5 lines
- bsddb: the __len__ method of a DB object has been fixed to return correct
results. It could previously incorrectly return 0 in some cases.
Fixes SF bug 1493322 (pybsddb bug 1184012).
........
r46686 | tim.peters | 2006-06-06 02:25:07 +0200 (Tue, 06 Jun 2006) | 7 lines
_PySys_Init(): It's rarely a good idea to size a buffer to the
exact maximum size someone guesses is needed. In this case, if
we're really worried about extreme integers, then "cp%d" can
actually need 14 bytes (2 for "cp" + 1 for \0 at the end +
11 for -(2**31-1)). So reserve 128 bytes instead -- nothing is
actually saved by making a stack-local buffer tiny.
........
r46687 | neal.norwitz | 2006-06-06 09:22:08 +0200 (Tue, 06 Jun 2006) | 1 line
Remove unused variable (and stop compiler warning)
........
r46688 | neal.norwitz | 2006-06-06 09:23:01 +0200 (Tue, 06 Jun 2006) | 1 line
Fix a bunch of parameter strings
........
r46689 | thomas.heller | 2006-06-06 13:34:33 +0200 (Tue, 06 Jun 2006) | 6 lines
Convert CFieldObject tp_members to tp_getset, since there is no
structmember typecode for Py_ssize_t fields. This should fix some of
the errors on the PPC64 debian machine (64-bit, big endian).
Assigning to readonly fields now raises AttributeError instead of
TypeError, so the testcase has to be changed as well.
........
r46690 | thomas.heller | 2006-06-06 13:54:32 +0200 (Tue, 06 Jun 2006) | 1 line
Damn - the sentinel was missing. And fix another silly mistake.
........
r46691 | martin.blais | 2006-06-06 14:46:55 +0200 (Tue, 06 Jun 2006) | 13 lines
Normalized a few cases of whitespace in function declarations.
Found them using::
find . -name '*.py' | while read i ; do grep 'def[^(]*( ' $i /dev/null ; done
find . -name '*.py' | while read i ; do grep ' ):' $i /dev/null ; done
(I was doing this all over my own code anyway, because I'd been using spaces in
all defs, so I thought I'd make a run on the Python code as well. If you need
to do such fixes in your own code, you can use xx-rename or parenregu.el within
emacs.)
........
r46693 | thomas.heller | 2006-06-06 17:34:18 +0200 (Tue, 06 Jun 2006) | 1 line
Specify argtypes for all test functions. Maybe that helps on strange ;-) architectures
........
r46694 | tim.peters | 2006-06-06 17:50:17 +0200 (Tue, 06 Jun 2006) | 5 lines
BSequence_set_range(): Rev 46688 ("Fix a bunch of
parameter strings") changed this function's signature
seemingly by mistake, which is causing buildbots to fail
test_bsddb3. Restored the pre-46688 signature.
........
r46695 | tim.peters | 2006-06-06 17:52:35 +0200 (Tue, 06 Jun 2006) | 4 lines
On python-dev Thomas Heller said these were committed
by mistake in rev 46693, so reverting this part of
rev 46693.
........
r46696 | andrew.kuchling | 2006-06-06 19:10:41 +0200 (Tue, 06 Jun 2006) | 1 line
Fix comment typo
........
r46697 | brett.cannon | 2006-06-06 20:08:16 +0200 (Tue, 06 Jun 2006) | 2 lines
Fix coding style guide bug.
........
r46698 | thomas.heller | 2006-06-06 20:50:46 +0200 (Tue, 06 Jun 2006) | 2 lines
Add a hack so that foreign functions returning float now do work on 64-bit
big endian platforms.
........
r46699 | thomas.heller | 2006-06-06 21:25:13 +0200 (Tue, 06 Jun 2006) | 3 lines
Use the same big-endian hack as in _ctypes/callproc.c for callback functions.
This fixes the callback function tests that return float.
........
r46700 | ronald.oussoren | 2006-06-06 21:50:24 +0200 (Tue, 06 Jun 2006) | 5 lines
* Ensure that "make altinstall" works when the tree was configured
with --enable-framework
* Also for --enable-framework: allow users to use --prefix to specify
the location of the compatibility symlinks (such as /usr/local/bin/python)
........
r46701 | ronald.oussoren | 2006-06-06 21:56:00 +0200 (Tue, 06 Jun 2006) | 3 lines
A quick hack to ensure the right key-bindings for IDLE on osx: install patched
configuration files during a framework install.
........
r46702 | tim.peters | 2006-06-07 03:04:59 +0200 (Wed, 07 Jun 2006) | 4 lines
dash_R_cleanup(): Clear filecmp._cache. This accounts for
different results across -R runs (at least on Windows) of
test_filecmp.
........
r46705 | tim.peters | 2006-06-07 08:57:51 +0200 (Wed, 07 Jun 2006) | 17 lines
SF patch 1501987: Remove randomness from test_exceptions,
from ?iga Seilnacht (sorry about the name, but Firefox
on my box can't display the first character of the name --
the SF "Unix name" is zseil).
This appears to cure the oddball intermittent leaks across
runs when running test_exceptions under -R. I'm not sure
why, but I'm too sleepy to care ;-)
The thrust of the SF patch was to remove randomness in the
pickle protocol used. I changed the patch to use
range(pickle.HIGHEST_PROTOCOL + 1), to try both pickle and
cPickle, and randomly mucked with other test lines to put
statements on their own lines.
Not a bugfix candidate (this is fiddling new-in-2.5 code).
........
r46706 | andrew.kuchling | 2006-06-07 15:55:33 +0200 (Wed, 07 Jun 2006) | 1 line
Add an SQLite introduction, taken from the 'What's New' text
........
r46708 | andrew.kuchling | 2006-06-07 19:02:52 +0200 (Wed, 07 Jun 2006) | 1 line
Mention other placeholders
........
r46709 | andrew.kuchling | 2006-06-07 19:03:46 +0200 (Wed, 07 Jun 2006) | 1 line
Add an item; also, escape %
........
r46710 | andrew.kuchling | 2006-06-07 19:04:01 +0200 (Wed, 07 Jun 2006) | 1 line
Mention other placeholders
........
r46716 | ronald.oussoren | 2006-06-07 20:57:44 +0200 (Wed, 07 Jun 2006) | 2 lines
Move Mac/OSX/Tools one level up
........
r46717 | ronald.oussoren | 2006-06-07 20:58:01 +0200 (Wed, 07 Jun 2006) | 2 lines
Move Mac/OSX/PythonLauncher one level up
........
r46718 | ronald.oussoren | 2006-06-07 20:58:42 +0200 (Wed, 07 Jun 2006) | 2 lines
mv Mac/OSX/BuildScript one level up
........
r46719 | ronald.oussoren | 2006-06-07 21:02:03 +0200 (Wed, 07 Jun 2006) | 2 lines
Move Mac/OSX/* one level up
........
r46720 | ronald.oussoren | 2006-06-07 21:06:01 +0200 (Wed, 07 Jun 2006) | 2 lines
And the last bit: move IDLE one level up and adjust makefiles
........
r46723 | ronald.oussoren | 2006-06-07 21:38:53 +0200 (Wed, 07 Jun 2006) | 4 lines
- Patch the correct version of python in the Info.plists at build time, instead
of relying on a maintainer to update them before releases.
- Remove the now empty Mac/OSX directory
........
r46727 | ronald.oussoren | 2006-06-07 22:18:44 +0200 (Wed, 07 Jun 2006) | 7 lines
* If BuildApplet.py is used as an applet it starts with a version of
sys.exutable that isn't usuable on an #!-line. That results in generated
applets that don't actually work. Work around this problem by resetting
sys.executable.
* argvemulator.py didn't work on intel macs. This patch fixes this
(bug #1491468)
........
r46728 | tim.peters | 2006-06-07 22:40:06 +0200 (Wed, 07 Jun 2006) | 2 lines
Whitespace normalization.
........
r46729 | tim.peters | 2006-06-07 22:40:54 +0200 (Wed, 07 Jun 2006) | 2 lines
Add missing svn:eol-style property to text files.
........
r46730 | thomas.heller | 2006-06-07 22:43:06 +0200 (Wed, 07 Jun 2006) | 7 lines
Fix for foreign functions returning small structures on 64-bit big
endian machines. Should fix the remaininf failure in the PPC64
Debian buildbot.
Thanks to Matthias Klose for providing access to a machine to debug
and test this.
........
r46731 | brett.cannon | 2006-06-07 23:48:17 +0200 (Wed, 07 Jun 2006) | 2 lines
Clarify documentation for bf_getcharbuffer.
........
r46735 | neal.norwitz | 2006-06-08 07:12:45 +0200 (Thu, 08 Jun 2006) | 1 line
Fix a refleak in recvfrom_into
........
r46736 | gregory.p.smith | 2006-06-08 07:17:08 +0200 (Thu, 08 Jun 2006) | 9 lines
- bsddb: the bsddb.dbtables Modify method now raises the proper error and
aborts the db transaction safely when a modifier callback fails.
Fixes SF python patch/bug #1408584.
Also cleans up the bsddb.dbtables docstrings since thats the only
documentation that exists for that unadvertised module. (people
really should really just use sqlite3)
........
r46737 | gregory.p.smith | 2006-06-08 07:38:11 +0200 (Thu, 08 Jun 2006) | 4 lines
* Turn the deadlock situation described in SF bug #775414 into a
DBDeadLockError exception.
* add the test case for my previous dbtables commit.
........
r46738 | gregory.p.smith | 2006-06-08 07:39:54 +0200 (Thu, 08 Jun 2006) | 2 lines
pasted set_lk_detect line in wrong spot in previous commit. fixed. passes tests this time.
........
r46739 | armin.rigo | 2006-06-08 12:56:24 +0200 (Thu, 08 Jun 2006) | 6 lines
(arre, arigo) SF bug #1350060
Give a consistent behavior for comparison and hashing of method objects
(both user- and built-in methods). Now compares the 'self' recursively.
The hash was already asking for the hash of 'self'.
........
r46740 | andrew.kuchling | 2006-06-08 13:56:44 +0200 (Thu, 08 Jun 2006) | 1 line
Typo fix
........
r46741 | georg.brandl | 2006-06-08 14:45:01 +0200 (Thu, 08 Jun 2006) | 2 lines
Bug #1502750: Fix getargs "i" format to use LONG_MIN and LONG_MAX for bounds checking.
........
r46743 | georg.brandl | 2006-06-08 14:54:13 +0200 (Thu, 08 Jun 2006) | 2 lines
Bug #1502728: Correctly link against librt library on HP-UX.
........
r46745 | georg.brandl | 2006-06-08 14:55:47 +0200 (Thu, 08 Jun 2006) | 3 lines
Add news for recent bugfix.
........
r46746 | georg.brandl | 2006-06-08 15:31:07 +0200 (Thu, 08 Jun 2006) | 4 lines
Argh. "integer" is a very confusing word ;)
Actually, checking for INT_MAX and INT_MIN is correct since
the format code explicitly handles a C "int".
........
r46748 | nick.coghlan | 2006-06-08 15:54:49 +0200 (Thu, 08 Jun 2006) | 1 line
Add functools.update_wrapper() and functools.wraps() as described in PEP 356
........
r46751 | georg.brandl | 2006-06-08 16:50:21 +0200 (Thu, 08 Jun 2006) | 4 lines
Bug #1502805: don't alias file.__exit__ to file.close since the
latter can return something that's true.
........
r46752 | georg.brandl | 2006-06-08 16:50:53 +0200 (Thu, 08 Jun 2006) | 3 lines
Convert test_file to unittest.
........
2006-06-08 12:35:45 -03:00
|
|
|
int
|
|
|
|
PyObject_AsCharBuffer(PyObject *obj,
|
2000-03-10 18:55:18 -04:00
|
|
|
const char **buffer,
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t *buffer_len)
|
2000-03-10 18:55:18 -04:00
|
|
|
{
|
|
|
|
PyBufferProcs *pb;
|
2006-02-27 12:46:16 -04:00
|
|
|
char *pp;
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t len;
|
2000-03-10 18:55:18 -04:00
|
|
|
|
|
|
|
if (obj == NULL || buffer == NULL || buffer_len == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
pb = obj->ob_type->tp_as_buffer;
|
2001-11-09 17:59:42 -04:00
|
|
|
if (pb == NULL ||
|
2000-03-10 18:55:18 -04:00
|
|
|
pb->bf_getcharbuffer == NULL ||
|
2001-11-09 17:59:42 -04:00
|
|
|
pb->bf_getsegcount == NULL) {
|
2000-03-10 18:55:18 -04:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"expected a character buffer object");
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
}
|
2001-11-09 17:59:42 -04:00
|
|
|
if ((*pb->bf_getsegcount)(obj,NULL) != 1) {
|
2000-03-10 18:55:18 -04:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"expected a single-segment buffer object");
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
}
|
2001-11-09 17:59:42 -04:00
|
|
|
len = (*pb->bf_getcharbuffer)(obj, 0, &pp);
|
2000-03-10 18:55:18 -04:00
|
|
|
if (len < 0)
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
*buffer = pp;
|
|
|
|
*buffer_len = len;
|
|
|
|
return 0;
|
2001-11-09 17:59:42 -04:00
|
|
|
}
|
2000-03-10 18:55:18 -04:00
|
|
|
|
2001-11-09 17:59:42 -04:00
|
|
|
int
|
|
|
|
PyObject_CheckReadBuffer(PyObject *obj)
|
|
|
|
{
|
|
|
|
PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
|
|
|
|
|
|
|
|
if (pb == NULL ||
|
|
|
|
pb->bf_getreadbuffer == NULL ||
|
|
|
|
pb->bf_getsegcount == NULL ||
|
|
|
|
(*pb->bf_getsegcount)(obj, NULL) != 1)
|
|
|
|
return 0;
|
|
|
|
return 1;
|
2000-03-10 18:55:18 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
int PyObject_AsReadBuffer(PyObject *obj,
|
|
|
|
const void **buffer,
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t *buffer_len)
|
2000-03-10 18:55:18 -04:00
|
|
|
{
|
|
|
|
PyBufferProcs *pb;
|
|
|
|
void *pp;
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t len;
|
2000-03-10 18:55:18 -04:00
|
|
|
|
|
|
|
if (obj == NULL || buffer == NULL || buffer_len == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
pb = obj->ob_type->tp_as_buffer;
|
2001-11-09 17:59:42 -04:00
|
|
|
if (pb == NULL ||
|
2000-03-10 18:55:18 -04:00
|
|
|
pb->bf_getreadbuffer == NULL ||
|
2001-11-09 17:59:42 -04:00
|
|
|
pb->bf_getsegcount == NULL) {
|
2000-03-10 18:55:18 -04:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"expected a readable buffer object");
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
}
|
2001-11-09 17:59:42 -04:00
|
|
|
if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
|
2000-03-10 18:55:18 -04:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"expected a single-segment buffer object");
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
}
|
2001-11-09 17:59:42 -04:00
|
|
|
len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
|
2000-03-10 18:55:18 -04:00
|
|
|
if (len < 0)
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
*buffer = pp;
|
|
|
|
*buffer_len = len;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int PyObject_AsWriteBuffer(PyObject *obj,
|
|
|
|
void **buffer,
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t *buffer_len)
|
2000-03-10 18:55:18 -04:00
|
|
|
{
|
|
|
|
PyBufferProcs *pb;
|
|
|
|
void*pp;
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t len;
|
2000-03-10 18:55:18 -04:00
|
|
|
|
|
|
|
if (obj == NULL || buffer == NULL || buffer_len == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
pb = obj->ob_type->tp_as_buffer;
|
2001-11-09 17:59:42 -04:00
|
|
|
if (pb == NULL ||
|
2000-03-10 18:55:18 -04:00
|
|
|
pb->bf_getwritebuffer == NULL ||
|
2001-11-09 17:59:42 -04:00
|
|
|
pb->bf_getsegcount == NULL) {
|
2000-03-10 18:55:18 -04:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"expected a writeable buffer object");
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
}
|
2001-11-09 17:59:42 -04:00
|
|
|
if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
|
2000-03-10 18:55:18 -04:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
|
|
|
"expected a single-segment buffer object");
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
}
|
|
|
|
len = (*pb->bf_getwritebuffer)(obj,0,&pp);
|
|
|
|
if (len < 0)
|
2001-11-09 17:59:42 -04:00
|
|
|
return -1;
|
2000-03-10 18:55:18 -04:00
|
|
|
*buffer = pp;
|
|
|
|
*buffer_len = len;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Operations on numbers */
|
|
|
|
|
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Check(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2003-02-18 12:36:28 -04:00
|
|
|
return o && o->ob_type->tp_as_number &&
|
|
|
|
(o->ob_type->tp_as_number->nb_int ||
|
|
|
|
o->ob_type->tp_as_number->nb_float);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Binary operators */
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
/* New style number protocol support */
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
#define NB_SLOT(x) offsetof(PyNumberMethods, x)
|
|
|
|
#define NB_BINOP(nb_methods, slot) \
|
2002-11-23 21:34:49 -04:00
|
|
|
(*(binaryfunc*)(& ((char*)nb_methods)[slot]))
|
2001-01-03 21:39:06 -04:00
|
|
|
#define NB_TERNOP(nb_methods, slot) \
|
2002-11-23 21:34:49 -04:00
|
|
|
(*(ternaryfunc*)(& ((char*)nb_methods)[slot]))
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
/*
|
|
|
|
Calling scheme used for binary operations:
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
v w Action
|
|
|
|
-------------------------------------------------------------------
|
2001-09-28 20:49:48 -03:00
|
|
|
new new w.op(v,w)[*], v.op(v,w), w.op(v,w)
|
2001-01-03 21:39:06 -04:00
|
|
|
new old v.op(v,w), coerce(v,w), v.op(v,w)
|
|
|
|
old new w.op(v,w), coerce(v,w), v.op(v,w)
|
|
|
|
old old coerce(v,w), v.op(v,w)
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-09-28 20:49:48 -03:00
|
|
|
[*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of
|
|
|
|
v->ob_type
|
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
Legend:
|
|
|
|
-------
|
|
|
|
* new == new style number
|
|
|
|
* old == old style number
|
|
|
|
* Action indicates the order in which operations are tried until either
|
|
|
|
a valid result is produced or an error occurs.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
binary_op1(PyObject *v, PyObject *w, const int op_slot)
|
|
|
|
{
|
|
|
|
PyObject *x;
|
2001-09-28 20:49:48 -03:00
|
|
|
binaryfunc slotv = NULL;
|
|
|
|
binaryfunc slotw = NULL;
|
|
|
|
|
2006-07-27 18:53:35 -03:00
|
|
|
if (v->ob_type->tp_as_number != NULL)
|
2002-11-23 21:34:49 -04:00
|
|
|
slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot);
|
2001-09-28 20:49:48 -03:00
|
|
|
if (w->ob_type != v->ob_type &&
|
2006-07-27 18:53:35 -03:00
|
|
|
w->ob_type->tp_as_number != NULL) {
|
2002-11-23 21:34:49 -04:00
|
|
|
slotw = NB_BINOP(w->ob_type->tp_as_number, op_slot);
|
2001-09-28 20:49:48 -03:00
|
|
|
if (slotw == slotv)
|
|
|
|
slotw = NULL;
|
2001-01-03 21:39:06 -04:00
|
|
|
}
|
2001-09-28 20:49:48 -03:00
|
|
|
if (slotv) {
|
2001-10-01 14:10:18 -03:00
|
|
|
if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
|
|
|
|
x = slotw(v, w);
|
|
|
|
if (x != Py_NotImplemented)
|
|
|
|
return x;
|
|
|
|
Py_DECREF(x); /* can't do it */
|
|
|
|
slotw = NULL;
|
|
|
|
}
|
2001-09-28 20:49:48 -03:00
|
|
|
x = slotv(v, w);
|
|
|
|
if (x != Py_NotImplemented)
|
|
|
|
return x;
|
|
|
|
Py_DECREF(x); /* can't do it */
|
|
|
|
}
|
|
|
|
if (slotw) {
|
|
|
|
x = slotw(v, w);
|
|
|
|
if (x != Py_NotImplemented)
|
|
|
|
return x;
|
|
|
|
Py_DECREF(x); /* can't do it */
|
2001-01-03 21:39:06 -04:00
|
|
|
}
|
|
|
|
Py_INCREF(Py_NotImplemented);
|
|
|
|
return Py_NotImplemented;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
2002-04-16 13:32:50 -03:00
|
|
|
|
2002-12-30 16:18:15 -04:00
|
|
|
static PyObject *
|
|
|
|
binop_type_error(PyObject *v, PyObject *w, const char *op_name)
|
|
|
|
{
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"unsupported operand type(s) for %s: '%s' and '%s'",
|
|
|
|
op_name,
|
|
|
|
v->ob_type->tp_name,
|
|
|
|
w->ob_type->tp_name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
static PyObject *
|
|
|
|
binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-01-03 21:39:06 -04:00
|
|
|
PyObject *result = binary_op1(v, w, op_slot);
|
|
|
|
if (result == Py_NotImplemented) {
|
2002-12-30 16:18:15 -04:00
|
|
|
Py_DECREF(result);
|
|
|
|
return binop_type_error(v, w, op_name);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
2001-01-03 21:39:06 -04:00
|
|
|
return result;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
/*
|
|
|
|
Calling scheme used for ternary operations:
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-09-28 22:05:03 -03:00
|
|
|
*** In some cases, w.op is called before v.op; see binary_op1. ***
|
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
v w z Action
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
new new new v.op(v,w,z), w.op(v,w,z), z.op(v,w,z)
|
|
|
|
new old new v.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
|
|
|
|
old new new w.op(v,w,z), z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
|
|
|
|
old old new z.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
|
|
|
|
new new old v.op(v,w,z), w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
|
|
|
|
new old old v.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
|
|
|
|
old new old w.op(v,w,z), coerce(v,w,z), v.op(v,w,z)
|
|
|
|
old old old coerce(v,w,z), v.op(v,w,z)
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
Legend:
|
|
|
|
-------
|
|
|
|
* new == new style number
|
|
|
|
* old == old style number
|
|
|
|
* Action indicates the order in which operations are tried until either
|
|
|
|
a valid result is produced or an error occurs.
|
|
|
|
* coerce(v,w,z) actually does: coerce(v,w), coerce(v,z), coerce(w,z) and
|
|
|
|
only if z != Py_None; if z == Py_None, then it is treated as absent
|
|
|
|
variable and only coerce(v,w) is tried.
|
|
|
|
|
|
|
|
*/
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
static PyObject *
|
|
|
|
ternary_op(PyObject *v,
|
|
|
|
PyObject *w,
|
|
|
|
PyObject *z,
|
|
|
|
const int op_slot,
|
|
|
|
const char *op_name)
|
|
|
|
{
|
|
|
|
PyNumberMethods *mv, *mw, *mz;
|
2001-09-28 22:05:03 -03:00
|
|
|
PyObject *x = NULL;
|
|
|
|
ternaryfunc slotv = NULL;
|
|
|
|
ternaryfunc slotw = NULL;
|
|
|
|
ternaryfunc slotz = NULL;
|
2002-04-16 13:32:50 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
mv = v->ob_type->tp_as_number;
|
2001-09-28 20:49:48 -03:00
|
|
|
mw = w->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (mv != NULL)
|
2002-11-23 21:34:49 -04:00
|
|
|
slotv = NB_TERNOP(mv, op_slot);
|
2001-09-28 22:05:03 -03:00
|
|
|
if (w->ob_type != v->ob_type &&
|
2006-07-27 18:53:35 -03:00
|
|
|
mw != NULL) {
|
2002-11-23 21:34:49 -04:00
|
|
|
slotw = NB_TERNOP(mw, op_slot);
|
2001-09-28 22:05:03 -03:00
|
|
|
if (slotw == slotv)
|
|
|
|
slotw = NULL;
|
2001-09-28 20:49:48 -03:00
|
|
|
}
|
2001-09-28 22:05:03 -03:00
|
|
|
if (slotv) {
|
2001-10-01 14:10:18 -03:00
|
|
|
if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) {
|
|
|
|
x = slotw(v, w, z);
|
|
|
|
if (x != Py_NotImplemented)
|
|
|
|
return x;
|
|
|
|
Py_DECREF(x); /* can't do it */
|
|
|
|
slotw = NULL;
|
|
|
|
}
|
2001-09-28 22:05:03 -03:00
|
|
|
x = slotv(v, w, z);
|
|
|
|
if (x != Py_NotImplemented)
|
|
|
|
return x;
|
|
|
|
Py_DECREF(x); /* can't do it */
|
|
|
|
}
|
|
|
|
if (slotw) {
|
|
|
|
x = slotw(v, w, z);
|
|
|
|
if (x != Py_NotImplemented)
|
|
|
|
return x;
|
|
|
|
Py_DECREF(x); /* can't do it */
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
2001-01-03 21:39:06 -04:00
|
|
|
mz = z->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (mz != NULL) {
|
2002-11-23 21:34:49 -04:00
|
|
|
slotz = NB_TERNOP(mz, op_slot);
|
2001-09-28 22:05:03 -03:00
|
|
|
if (slotz == slotv || slotz == slotw)
|
|
|
|
slotz = NULL;
|
|
|
|
if (slotz) {
|
|
|
|
x = slotz(v, w, z);
|
2001-01-03 21:39:06 -04:00
|
|
|
if (x != Py_NotImplemented)
|
|
|
|
return x;
|
2001-09-28 22:05:03 -03:00
|
|
|
Py_DECREF(x); /* can't do it */
|
2000-02-14 18:22:04 -04:00
|
|
|
}
|
2001-01-03 21:39:06 -04:00
|
|
|
}
|
|
|
|
|
2001-10-22 01:12:44 -03:00
|
|
|
if (z == Py_None)
|
|
|
|
PyErr_Format(
|
|
|
|
PyExc_TypeError,
|
|
|
|
"unsupported operand type(s) for ** or pow(): "
|
|
|
|
"'%s' and '%s'",
|
|
|
|
v->ob_type->tp_name,
|
|
|
|
w->ob_type->tp_name);
|
|
|
|
else
|
|
|
|
PyErr_Format(
|
|
|
|
PyExc_TypeError,
|
|
|
|
"unsupported operand type(s) for pow(): "
|
|
|
|
"'%s', '%s', '%s'",
|
|
|
|
v->ob_type->tp_name,
|
|
|
|
w->ob_type->tp_name,
|
|
|
|
z->ob_type->tp_name);
|
2001-01-03 21:39:06 -04:00
|
|
|
return NULL;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
#define BINARY_FUNC(func, op, op_name) \
|
|
|
|
PyObject * \
|
|
|
|
func(PyObject *v, PyObject *w) { \
|
|
|
|
return binary_op(v, w, NB_SLOT(op), op_name); \
|
|
|
|
}
|
|
|
|
|
|
|
|
BINARY_FUNC(PyNumber_Or, nb_or, "|")
|
|
|
|
BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
|
|
|
|
BINARY_FUNC(PyNumber_And, nb_and, "&")
|
|
|
|
BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
|
|
|
|
BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
|
|
|
|
BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
|
|
|
|
BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2001-01-03 21:39:06 -04:00
|
|
|
PyNumber_Add(PyObject *v, PyObject *w)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-01-03 21:39:06 -04:00
|
|
|
PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
|
|
|
|
if (result == Py_NotImplemented) {
|
|
|
|
PySequenceMethods *m = v->ob_type->tp_as_sequence;
|
2005-12-29 11:59:19 -04:00
|
|
|
Py_DECREF(result);
|
2002-03-08 17:28:54 -04:00
|
|
|
if (m && m->sq_concat) {
|
2005-12-29 11:59:19 -04:00
|
|
|
return (*m->sq_concat)(v, w);
|
2002-03-08 17:28:54 -04:00
|
|
|
}
|
2005-12-29 11:59:19 -04:00
|
|
|
result = binop_type_error(v, w, "+");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
2001-01-03 21:39:06 -04:00
|
|
|
return result;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2002-12-30 16:18:15 -04:00
|
|
|
static PyObject *
|
2006-02-15 13:27:45 -04:00
|
|
|
sequence_repeat(ssizeargfunc repeatfunc, PyObject *seq, PyObject *n)
|
2002-12-30 16:18:15 -04:00
|
|
|
{
|
2006-03-07 14:50:55 -04:00
|
|
|
Py_ssize_t count;
|
|
|
|
PyNumberMethods *nb = n->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (nb != NULL && nb->nb_index != NULL) {
|
2006-03-07 14:50:55 -04:00
|
|
|
count = nb->nb_index(n);
|
2002-12-30 16:18:15 -04:00
|
|
|
if (count == -1 && PyErr_Occurred())
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return type_error(
|
2004-05-12 18:35:06 -03:00
|
|
|
"can't multiply sequence by non-int");
|
2002-12-30 16:18:15 -04:00
|
|
|
}
|
2006-03-07 14:50:55 -04:00
|
|
|
return (*repeatfunc)(seq, count);
|
2002-12-30 16:18:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
PyNumber_Multiply(PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
PyObject *result = binary_op1(v, w, NB_SLOT(nb_multiply));
|
|
|
|
if (result == Py_NotImplemented) {
|
|
|
|
PySequenceMethods *mv = v->ob_type->tp_as_sequence;
|
|
|
|
PySequenceMethods *mw = w->ob_type->tp_as_sequence;
|
2002-12-31 15:50:03 -04:00
|
|
|
Py_DECREF(result);
|
2002-12-30 16:18:15 -04:00
|
|
|
if (mv && mv->sq_repeat) {
|
|
|
|
return sequence_repeat(mv->sq_repeat, v, w);
|
|
|
|
}
|
|
|
|
else if (mw && mw->sq_repeat) {
|
|
|
|
return sequence_repeat(mw->sq_repeat, w, v);
|
|
|
|
}
|
|
|
|
result = binop_type_error(v, w, "*");
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2001-08-08 02:00:18 -03:00
|
|
|
PyObject *
|
|
|
|
PyNumber_FloorDivide(PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
/* XXX tp_flags test */
|
|
|
|
return binary_op(v, w, NB_SLOT(nb_floor_divide), "//");
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
PyNumber_TrueDivide(PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
/* XXX tp_flags test */
|
|
|
|
return binary_op(v, w, NB_SLOT(nb_true_divide), "/");
|
|
|
|
}
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Remainder(PyObject *v, PyObject *w)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-01-03 21:39:06 -04:00
|
|
|
return binary_op(v, w, NB_SLOT(nb_remainder), "%");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-01-03 21:39:06 -04:00
|
|
|
return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2000-08-24 17:08:19 -03:00
|
|
|
/* Binary in-place operators */
|
|
|
|
|
|
|
|
/* The in-place operators are defined to fall back to the 'normal',
|
2001-01-03 21:39:06 -04:00
|
|
|
non in-place operations, if the in-place methods are not in place.
|
2000-08-24 17:08:19 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
- If the left hand object has the appropriate struct members, and
|
|
|
|
they are filled, call the appropriate function and return the
|
|
|
|
result. No coercion is done on the arguments; the left-hand object
|
|
|
|
is the one the operation is performed on, and it's up to the
|
|
|
|
function to deal with the right-hand object.
|
2002-04-16 13:32:50 -03:00
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
- Otherwise, in-place modification is not supported. Handle it exactly as
|
|
|
|
a non in-place operation of the same kind.
|
2000-08-24 17:08:19 -03:00
|
|
|
|
|
|
|
*/
|
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
static PyObject *
|
2002-12-30 16:18:15 -04:00
|
|
|
binary_iop1(PyObject *v, PyObject *w, const int iop_slot, const int op_slot)
|
2001-01-03 21:39:06 -04:00
|
|
|
{
|
|
|
|
PyNumberMethods *mv = v->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (mv != NULL) {
|
2002-11-23 21:34:49 -04:00
|
|
|
binaryfunc slot = NB_BINOP(mv, iop_slot);
|
|
|
|
if (slot) {
|
|
|
|
PyObject *x = (slot)(v, w);
|
2001-01-03 21:39:06 -04:00
|
|
|
if (x != Py_NotImplemented) {
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
Py_DECREF(x);
|
|
|
|
}
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
2002-12-30 16:18:15 -04:00
|
|
|
return binary_op1(v, w, op_slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *
|
|
|
|
binary_iop(PyObject *v, PyObject *w, const int iop_slot, const int op_slot,
|
|
|
|
const char *op_name)
|
|
|
|
{
|
|
|
|
PyObject *result = binary_iop1(v, w, iop_slot, op_slot);
|
|
|
|
if (result == Py_NotImplemented) {
|
|
|
|
Py_DECREF(result);
|
|
|
|
return binop_type_error(v, w, op_name);
|
|
|
|
}
|
|
|
|
return result;
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
#define INPLACE_BINOP(func, iop, op, op_name) \
|
|
|
|
PyObject * \
|
|
|
|
func(PyObject *v, PyObject *w) { \
|
|
|
|
return binary_iop(v, w, NB_SLOT(iop), NB_SLOT(op), op_name); \
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
|
|
|
|
2001-01-03 21:39:06 -04:00
|
|
|
INPLACE_BINOP(PyNumber_InPlaceOr, nb_inplace_or, nb_or, "|=")
|
|
|
|
INPLACE_BINOP(PyNumber_InPlaceXor, nb_inplace_xor, nb_xor, "^=")
|
|
|
|
INPLACE_BINOP(PyNumber_InPlaceAnd, nb_inplace_and, nb_and, "&=")
|
|
|
|
INPLACE_BINOP(PyNumber_InPlaceLshift, nb_inplace_lshift, nb_lshift, "<<=")
|
|
|
|
INPLACE_BINOP(PyNumber_InPlaceRshift, nb_inplace_rshift, nb_rshift, ">>=")
|
|
|
|
INPLACE_BINOP(PyNumber_InPlaceSubtract, nb_inplace_subtract, nb_subtract, "-=")
|
2000-08-24 17:08:19 -03:00
|
|
|
|
2001-08-08 02:00:18 -03:00
|
|
|
PyObject *
|
|
|
|
PyNumber_InPlaceFloorDivide(PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
/* XXX tp_flags test */
|
|
|
|
return binary_iop(v, w, NB_SLOT(nb_inplace_floor_divide),
|
|
|
|
NB_SLOT(nb_floor_divide), "//=");
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
PyNumber_InPlaceTrueDivide(PyObject *v, PyObject *w)
|
|
|
|
{
|
|
|
|
/* XXX tp_flags test */
|
|
|
|
return binary_iop(v, w, NB_SLOT(nb_inplace_true_divide),
|
|
|
|
NB_SLOT(nb_true_divide), "/=");
|
|
|
|
}
|
|
|
|
|
2000-08-24 17:08:19 -03:00
|
|
|
PyObject *
|
|
|
|
PyNumber_InPlaceAdd(PyObject *v, PyObject *w)
|
|
|
|
{
|
2002-12-30 16:18:15 -04:00
|
|
|
PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_add),
|
|
|
|
NB_SLOT(nb_add));
|
|
|
|
if (result == Py_NotImplemented) {
|
|
|
|
PySequenceMethods *m = v->ob_type->tp_as_sequence;
|
|
|
|
Py_DECREF(result);
|
|
|
|
if (m != NULL) {
|
|
|
|
binaryfunc f = NULL;
|
2006-07-27 18:53:35 -03:00
|
|
|
f = m->sq_inplace_concat;
|
2002-12-30 16:18:15 -04:00
|
|
|
if (f == NULL)
|
|
|
|
f = m->sq_concat;
|
|
|
|
if (f != NULL)
|
|
|
|
return (*f)(v, w);
|
|
|
|
}
|
|
|
|
result = binop_type_error(v, w, "+=");
|
2000-09-01 20:27:32 -03:00
|
|
|
}
|
2002-12-30 16:18:15 -04:00
|
|
|
return result;
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
PyNumber_InPlaceMultiply(PyObject *v, PyObject *w)
|
|
|
|
{
|
2002-12-30 16:18:15 -04:00
|
|
|
PyObject *result = binary_iop1(v, w, NB_SLOT(nb_inplace_multiply),
|
|
|
|
NB_SLOT(nb_multiply));
|
|
|
|
if (result == Py_NotImplemented) {
|
2006-02-15 13:27:45 -04:00
|
|
|
ssizeargfunc f = NULL;
|
2002-12-30 16:18:15 -04:00
|
|
|
PySequenceMethods *mv = v->ob_type->tp_as_sequence;
|
|
|
|
PySequenceMethods *mw = w->ob_type->tp_as_sequence;
|
|
|
|
Py_DECREF(result);
|
|
|
|
if (mv != NULL) {
|
2006-07-27 18:53:35 -03:00
|
|
|
f = mv->sq_inplace_repeat;
|
2002-12-30 16:18:15 -04:00
|
|
|
if (f == NULL)
|
|
|
|
f = mv->sq_repeat;
|
|
|
|
if (f != NULL)
|
|
|
|
return sequence_repeat(f, v, w);
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
2002-12-30 16:18:15 -04:00
|
|
|
else if (mw != NULL) {
|
|
|
|
/* Note that the right hand operand should not be
|
|
|
|
* mutated in this case so sq_inplace_repeat is not
|
|
|
|
* used. */
|
|
|
|
if (mw->sq_repeat)
|
|
|
|
return sequence_repeat(mw->sq_repeat, w, v);
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
2002-12-30 16:18:15 -04:00
|
|
|
result = binop_type_error(v, w, "*=");
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
2002-12-30 16:18:15 -04:00
|
|
|
return result;
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
PyNumber_InPlaceRemainder(PyObject *v, PyObject *w)
|
|
|
|
{
|
2002-11-23 21:07:42 -04:00
|
|
|
return binary_iop(v, w, NB_SLOT(nb_inplace_remainder),
|
|
|
|
NB_SLOT(nb_remainder), "%=");
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
|
|
|
|
{
|
2006-07-27 18:53:35 -03:00
|
|
|
if (v->ob_type->tp_as_number &&
|
2001-01-03 21:39:06 -04:00
|
|
|
v->ob_type->tp_as_number->nb_inplace_power != NULL) {
|
|
|
|
return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**=");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return ternary_op(v, w, z, NB_SLOT(nb_power), "**=");
|
2000-08-24 17:08:19 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Unary operators and functions */
|
1995-07-18 11:12:02 -03:00
|
|
|
|
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Negative(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyNumberMethods *m;
|
|
|
|
|
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
|
|
|
m = o->ob_type->tp_as_number;
|
|
|
|
if (m && m->nb_negative)
|
|
|
|
return (*m->nb_negative)(o);
|
|
|
|
|
|
|
|
return type_error("bad operand type for unary -");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Positive(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyNumberMethods *m;
|
|
|
|
|
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
|
|
|
m = o->ob_type->tp_as_number;
|
|
|
|
if (m && m->nb_positive)
|
|
|
|
return (*m->nb_positive)(o);
|
|
|
|
|
|
|
|
return type_error("bad operand type for unary +");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Invert(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyNumberMethods *m;
|
|
|
|
|
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
|
|
|
m = o->ob_type->tp_as_number;
|
|
|
|
if (m && m->nb_invert)
|
|
|
|
return (*m->nb_invert)(o);
|
|
|
|
|
|
|
|
return type_error("bad operand type for unary ~");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Absolute(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyNumberMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
|
|
|
m = o->ob_type->tp_as_number;
|
|
|
|
if (m && m->nb_absolute)
|
|
|
|
return m->nb_absolute(o);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
return type_error("bad operand type for abs()");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2000-04-05 17:11:21 -03:00
|
|
|
/* Add a check for embedded NULL-bytes in the argument. */
|
|
|
|
static PyObject *
|
2006-02-15 13:27:45 -04:00
|
|
|
int_from_string(const char *s, Py_ssize_t len)
|
2000-04-05 17:11:21 -03:00
|
|
|
{
|
|
|
|
char *end;
|
|
|
|
PyObject *x;
|
|
|
|
|
|
|
|
x = PyInt_FromString((char*)s, &end, 10);
|
|
|
|
if (x == NULL)
|
|
|
|
return NULL;
|
|
|
|
if (end != s + len) {
|
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"null byte in argument for int()");
|
|
|
|
Py_DECREF(x);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
2006-03-07 14:50:55 -04:00
|
|
|
/* Return a Py_ssize_t integer from the object item */
|
|
|
|
Py_ssize_t
|
|
|
|
PyNumber_Index(PyObject *item)
|
|
|
|
{
|
|
|
|
Py_ssize_t value = -1;
|
|
|
|
PyNumberMethods *nb = item->ob_type->tp_as_number;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (nb != NULL && nb->nb_index != NULL) {
|
2006-03-07 14:50:55 -04:00
|
|
|
value = nb->nb_index(item);
|
|
|
|
}
|
|
|
|
else {
|
2006-04-21 07:40:58 -03:00
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"'%.200s' object cannot be interpreted "
|
|
|
|
"as an index", item->ob_type->tp_name);
|
2006-03-07 14:50:55 -04:00
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Int(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyNumberMethods *m;
|
2000-03-10 18:55:18 -04:00
|
|
|
const char *buffer;
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t buffer_len;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
2001-09-10 17:52:51 -03:00
|
|
|
if (PyInt_CheckExact(o)) {
|
2000-04-05 17:11:21 -03:00
|
|
|
Py_INCREF(o);
|
|
|
|
return o;
|
|
|
|
}
|
2005-04-26 00:45:26 -03:00
|
|
|
m = o->ob_type->tp_as_number;
|
|
|
|
if (m && m->nb_int) { /* This should include subclasses of int */
|
|
|
|
PyObject *res = m->nb_int(o);
|
|
|
|
if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"__int__ returned non-int (type %.200s)",
|
|
|
|
res->ob_type->tp_name);
|
|
|
|
Py_DECREF(res);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
if (PyInt_Check(o)) { /* A int subclass without nb_int */
|
2001-09-10 17:52:51 -03:00
|
|
|
PyIntObject *io = (PyIntObject*)o;
|
|
|
|
return PyInt_FromLong(io->ob_ival);
|
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
if (PyString_Check(o))
|
2002-04-16 13:32:50 -03:00
|
|
|
return int_from_string(PyString_AS_STRING(o),
|
2000-04-05 17:11:21 -03:00
|
|
|
PyString_GET_SIZE(o));
|
2001-08-17 15:39:25 -03:00
|
|
|
#ifdef Py_USING_UNICODE
|
2000-04-05 17:11:21 -03:00
|
|
|
if (PyUnicode_Check(o))
|
|
|
|
return PyInt_FromUnicode(PyUnicode_AS_UNICODE(o),
|
|
|
|
PyUnicode_GET_SIZE(o),
|
|
|
|
10);
|
2001-08-17 15:39:25 -03:00
|
|
|
#endif
|
2000-03-10 18:55:18 -04:00
|
|
|
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
|
2000-04-05 17:11:21 -03:00
|
|
|
return int_from_string((char*)buffer, buffer_len);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2002-06-06 12:45:38 -03:00
|
|
|
return type_error("int() argument must be a string or a number");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2000-04-05 17:11:21 -03:00
|
|
|
/* Add a check for embedded NULL-bytes in the argument. */
|
1999-10-12 16:54:53 -03:00
|
|
|
static PyObject *
|
2006-02-15 13:27:45 -04:00
|
|
|
long_from_string(const char *s, Py_ssize_t len)
|
1999-10-12 16:54:53 -03:00
|
|
|
{
|
2000-03-10 18:55:18 -04:00
|
|
|
char *end;
|
1999-10-12 16:54:53 -03:00
|
|
|
PyObject *x;
|
|
|
|
|
2000-03-10 18:55:18 -04:00
|
|
|
x = PyLong_FromString((char*)s, &end, 10);
|
2000-04-05 17:11:21 -03:00
|
|
|
if (x == NULL)
|
1999-10-12 16:54:53 -03:00
|
|
|
return NULL;
|
2000-04-05 17:11:21 -03:00
|
|
|
if (end != s + len) {
|
1999-10-12 16:54:53 -03:00
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"null byte in argument for long()");
|
2000-04-05 17:11:21 -03:00
|
|
|
Py_DECREF(x);
|
1999-10-12 16:54:53 -03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Long(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyNumberMethods *m;
|
2000-03-10 18:55:18 -04:00
|
|
|
const char *buffer;
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t buffer_len;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
2005-04-26 00:45:26 -03:00
|
|
|
m = o->ob_type->tp_as_number;
|
|
|
|
if (m && m->nb_long) { /* This should include subclasses of long */
|
|
|
|
PyObject *res = m->nb_long(o);
|
|
|
|
if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"__long__ returned non-long (type %.200s)",
|
|
|
|
res->ob_type->tp_name);
|
|
|
|
Py_DECREF(res);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return res;
|
2000-04-05 17:11:21 -03:00
|
|
|
}
|
2005-04-26 00:45:26 -03:00
|
|
|
if (PyLong_Check(o)) /* A long subclass without nb_long */
|
2002-03-02 00:14:21 -04:00
|
|
|
return _PyLong_Copy((PyLongObject *)o);
|
1998-05-21 21:47:05 -03:00
|
|
|
if (PyString_Check(o))
|
2002-04-16 13:32:50 -03:00
|
|
|
/* need to do extra error checking that PyLong_FromString()
|
1999-10-12 16:54:53 -03:00
|
|
|
* doesn't do. In particular long('9.5') must raise an
|
|
|
|
* exception, not truncate the float.
|
|
|
|
*/
|
2000-03-10 18:55:18 -04:00
|
|
|
return long_from_string(PyString_AS_STRING(o),
|
|
|
|
PyString_GET_SIZE(o));
|
2001-08-17 15:39:25 -03:00
|
|
|
#ifdef Py_USING_UNICODE
|
2000-04-05 17:11:21 -03:00
|
|
|
if (PyUnicode_Check(o))
|
|
|
|
/* The above check is done in PyLong_FromUnicode(). */
|
|
|
|
return PyLong_FromUnicode(PyUnicode_AS_UNICODE(o),
|
|
|
|
PyUnicode_GET_SIZE(o),
|
|
|
|
10);
|
2001-08-17 15:39:25 -03:00
|
|
|
#endif
|
2000-03-10 18:55:18 -04:00
|
|
|
if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len))
|
|
|
|
return long_from_string(buffer, buffer_len);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2002-06-06 12:45:38 -03:00
|
|
|
return type_error("long() argument must be a string or a number");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyNumber_Float(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyNumberMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
2005-04-26 00:45:26 -03:00
|
|
|
m = o->ob_type->tp_as_number;
|
|
|
|
if (m && m->nb_float) { /* This should include subclasses of float */
|
|
|
|
PyObject *res = m->nb_float(o);
|
|
|
|
if (res && !PyFloat_Check(res)) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"__float__ returned non-float (type %.200s)",
|
|
|
|
res->ob_type->tp_name);
|
|
|
|
Py_DECREF(res);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return res;
|
2000-04-05 17:11:21 -03:00
|
|
|
}
|
2005-04-26 00:45:26 -03:00
|
|
|
if (PyFloat_Check(o)) { /* A float subclass with nb_float == NULL */
|
2001-09-10 18:28:20 -03:00
|
|
|
PyFloatObject *po = (PyFloatObject *)o;
|
|
|
|
return PyFloat_FromDouble(po->ob_fval);
|
|
|
|
}
|
2000-03-10 18:55:18 -04:00
|
|
|
return PyFloat_FromString(o, NULL);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Operations on sequences */
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PySequence_Check(PyObject *s)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2004-09-19 03:00:15 -03:00
|
|
|
if (s && PyInstance_Check(s))
|
2004-04-04 05:51:41 -03:00
|
|
|
return PyObject_HasAttrString(s, "__getitem__");
|
2001-09-07 17:20:11 -03:00
|
|
|
return s != NULL && s->ob_type->tp_as_sequence &&
|
|
|
|
s->ob_type->tp_as_sequence->sq_item != NULL;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t
|
2000-07-12 09:56:19 -03:00
|
|
|
PySequence_Size(PyObject *s)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (s == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_length)
|
|
|
|
return m->sq_length(s);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
type_error("len() of unsized object");
|
|
|
|
return -1;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2000-07-17 06:22:55 -03:00
|
|
|
#undef PySequence_Length
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t
|
2000-07-17 06:22:55 -03:00
|
|
|
PySequence_Length(PyObject *s)
|
|
|
|
{
|
|
|
|
return PySequence_Size(s);
|
|
|
|
}
|
|
|
|
#define PySequence_Length PySequence_Size
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PySequence_Concat(PyObject *s, PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
|
|
|
|
|
|
|
if (s == NULL || o == NULL)
|
|
|
|
return null_error();
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_concat)
|
|
|
|
return m->sq_concat(s, o);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2005-12-29 11:59:19 -04:00
|
|
|
/* Instances of user classes defining an __add__() method only
|
|
|
|
have an nb_add slot, not an sq_concat slot. So we fall back
|
|
|
|
to nb_add if both arguments appear to be sequences. */
|
|
|
|
if (PySequence_Check(s) && PySequence_Check(o)) {
|
|
|
|
PyObject *result = binary_op1(s, o, NB_SLOT(nb_add));
|
|
|
|
if (result != Py_NotImplemented)
|
|
|
|
return result;
|
|
|
|
Py_DECREF(result);
|
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
return type_error("object can't be concatenated");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_Repeat(PyObject *o, Py_ssize_t count)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = o->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_repeat)
|
|
|
|
return m->sq_repeat(o, count);
|
|
|
|
|
2005-12-29 11:59:19 -04:00
|
|
|
/* Instances of user classes defining a __mul__() method only
|
|
|
|
have an nb_multiply slot, not an sq_repeat slot. so we fall back
|
|
|
|
to nb_multiply if o appears to be a sequence. */
|
|
|
|
if (PySequence_Check(o)) {
|
|
|
|
PyObject *n, *result;
|
2006-02-16 10:32:27 -04:00
|
|
|
n = PyInt_FromSsize_t(count);
|
2005-12-29 11:59:19 -04:00
|
|
|
if (n == NULL)
|
|
|
|
return NULL;
|
|
|
|
result = binary_op1(o, n, NB_SLOT(nb_multiply));
|
|
|
|
Py_DECREF(n);
|
|
|
|
if (result != Py_NotImplemented)
|
|
|
|
return result;
|
|
|
|
Py_DECREF(result);
|
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
return type_error("object can't be repeated");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2000-08-24 17:08:19 -03:00
|
|
|
PyObject *
|
|
|
|
PySequence_InPlaceConcat(PyObject *s, PyObject *o)
|
|
|
|
{
|
|
|
|
PySequenceMethods *m;
|
|
|
|
|
|
|
|
if (s == NULL || o == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
|
|
|
m = s->ob_type->tp_as_sequence;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (m && m->sq_inplace_concat)
|
2000-08-24 17:08:19 -03:00
|
|
|
return m->sq_inplace_concat(s, o);
|
|
|
|
if (m && m->sq_concat)
|
|
|
|
return m->sq_concat(s, o);
|
|
|
|
|
2005-12-29 11:59:19 -04:00
|
|
|
if (PySequence_Check(s) && PySequence_Check(o)) {
|
|
|
|
PyObject *result = binary_iop1(s, o, NB_SLOT(nb_inplace_add),
|
|
|
|
NB_SLOT(nb_add));
|
|
|
|
if (result != Py_NotImplemented)
|
|
|
|
return result;
|
|
|
|
Py_DECREF(result);
|
|
|
|
}
|
2000-08-24 17:08:19 -03:00
|
|
|
return type_error("object can't be concatenated");
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_InPlaceRepeat(PyObject *o, Py_ssize_t count)
|
2000-08-24 17:08:19 -03:00
|
|
|
{
|
|
|
|
PySequenceMethods *m;
|
|
|
|
|
|
|
|
if (o == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
|
|
|
m = o->ob_type->tp_as_sequence;
|
2006-07-27 18:53:35 -03:00
|
|
|
if (m && m->sq_inplace_repeat)
|
2000-08-24 17:08:19 -03:00
|
|
|
return m->sq_inplace_repeat(o, count);
|
|
|
|
if (m && m->sq_repeat)
|
|
|
|
return m->sq_repeat(o, count);
|
|
|
|
|
2005-12-29 11:59:19 -04:00
|
|
|
if (PySequence_Check(o)) {
|
|
|
|
PyObject *n, *result;
|
2006-02-16 10:32:27 -04:00
|
|
|
n = PyInt_FromSsize_t(count);
|
2005-12-29 11:59:19 -04:00
|
|
|
if (n == NULL)
|
|
|
|
return NULL;
|
|
|
|
result = binary_iop1(o, n, NB_SLOT(nb_inplace_multiply),
|
|
|
|
NB_SLOT(nb_multiply));
|
|
|
|
Py_DECREF(n);
|
|
|
|
if (result != Py_NotImplemented)
|
|
|
|
return result;
|
|
|
|
Py_DECREF(result);
|
|
|
|
}
|
2000-08-24 17:08:19 -03:00
|
|
|
return type_error("object can't be repeated");
|
|
|
|
}
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_GetItem(PyObject *s, Py_ssize_t i)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
|
|
|
|
|
|
|
if (s == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_item) {
|
|
|
|
if (i < 0) {
|
|
|
|
if (m->sq_length) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t l = (*m->sq_length)(s);
|
1998-05-21 21:47:05 -03:00
|
|
|
if (l < 0)
|
|
|
|
return NULL;
|
|
|
|
i += l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m->sq_item(s, i);
|
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
return type_error("unindexable object");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_GetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
2000-08-17 19:37:32 -03:00
|
|
|
PyMappingMethods *mp;
|
1998-05-21 21:47:05 -03:00
|
|
|
|
|
|
|
if (!s) return null_error();
|
|
|
|
|
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_slice) {
|
|
|
|
if (i1 < 0 || i2 < 0) {
|
|
|
|
if (m->sq_length) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t l = (*m->sq_length)(s);
|
1998-05-21 21:47:05 -03:00
|
|
|
if (l < 0)
|
|
|
|
return NULL;
|
|
|
|
if (i1 < 0)
|
|
|
|
i1 += l;
|
|
|
|
if (i2 < 0)
|
|
|
|
i2 += l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m->sq_slice(s, i1, i2);
|
2000-08-17 19:37:32 -03:00
|
|
|
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_subscript) {
|
|
|
|
PyObject *res;
|
2006-04-21 07:40:58 -03:00
|
|
|
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
2000-08-17 19:37:32 -03:00
|
|
|
if (!slice)
|
|
|
|
return NULL;
|
|
|
|
res = mp->mp_subscript(s, slice);
|
|
|
|
Py_DECREF(slice);
|
|
|
|
return res;
|
1998-05-21 21:47:05 -03:00
|
|
|
}
|
1997-04-02 01:31:09 -04:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
return type_error("unsliceable object");
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_SetItem(PyObject *s, Py_ssize_t i, PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
|
|
|
|
|
|
|
if (s == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_ass_item) {
|
|
|
|
if (i < 0) {
|
|
|
|
if (m->sq_length) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t l = (*m->sq_length)(s);
|
1998-05-21 21:47:05 -03:00
|
|
|
if (l < 0)
|
1998-05-28 23:59:33 -03:00
|
|
|
return -1;
|
1998-05-21 21:47:05 -03:00
|
|
|
i += l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m->sq_ass_item(s, i, o);
|
|
|
|
}
|
|
|
|
|
2003-10-27 05:22:16 -04:00
|
|
|
type_error("object does not support item assignment");
|
1998-05-21 21:47:05 -03:00
|
|
|
return -1;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1996-08-21 14:41:54 -03:00
|
|
|
int
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_DelItem(PyObject *s, Py_ssize_t i)
|
1996-08-21 14:41:54 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
|
|
|
|
|
|
|
if (s == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_ass_item) {
|
|
|
|
if (i < 0) {
|
|
|
|
if (m->sq_length) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t l = (*m->sq_length)(s);
|
1998-05-21 21:47:05 -03:00
|
|
|
if (l < 0)
|
1998-05-28 23:59:33 -03:00
|
|
|
return -1;
|
1998-05-21 21:47:05 -03:00
|
|
|
i += l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m->sq_ass_item(s, i, (PyObject *)NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
type_error("object doesn't support item deletion");
|
|
|
|
return -1;
|
1996-08-21 14:41:54 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
int
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_SetSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2, PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
2000-08-17 19:37:32 -03:00
|
|
|
PyMappingMethods *mp;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (s == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_ass_slice) {
|
|
|
|
if (i1 < 0 || i2 < 0) {
|
|
|
|
if (m->sq_length) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t l = (*m->sq_length)(s);
|
1998-05-21 21:47:05 -03:00
|
|
|
if (l < 0)
|
1998-05-28 23:59:33 -03:00
|
|
|
return -1;
|
1998-05-21 21:47:05 -03:00
|
|
|
if (i1 < 0)
|
|
|
|
i1 += l;
|
|
|
|
if (i2 < 0)
|
|
|
|
i2 += l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m->sq_ass_slice(s, i1, i2, o);
|
2000-08-17 19:37:32 -03:00
|
|
|
} else if ((mp = s->ob_type->tp_as_mapping) && mp->mp_ass_subscript) {
|
|
|
|
int res;
|
2006-04-21 07:40:58 -03:00
|
|
|
PyObject *slice = _PySlice_FromIndices(i1, i2);
|
2000-08-17 19:37:32 -03:00
|
|
|
if (!slice)
|
|
|
|
return -1;
|
|
|
|
res = mp->mp_ass_subscript(s, slice, o);
|
|
|
|
Py_DECREF(slice);
|
|
|
|
return res;
|
1998-05-21 21:47:05 -03:00
|
|
|
}
|
2000-08-17 19:37:32 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
type_error("object doesn't support slice assignment");
|
|
|
|
return -1;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
int
|
2006-02-15 13:27:45 -04:00
|
|
|
PySequence_DelSlice(PyObject *s, Py_ssize_t i1, Py_ssize_t i2)
|
1996-08-21 14:41:54 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PySequenceMethods *m;
|
1996-08-21 14:41:54 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (s == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
1996-08-21 14:41:54 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = s->ob_type->tp_as_sequence;
|
|
|
|
if (m && m->sq_ass_slice) {
|
|
|
|
if (i1 < 0 || i2 < 0) {
|
|
|
|
if (m->sq_length) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t l = (*m->sq_length)(s);
|
1998-05-21 21:47:05 -03:00
|
|
|
if (l < 0)
|
1998-05-28 23:59:33 -03:00
|
|
|
return -1;
|
1998-05-21 21:47:05 -03:00
|
|
|
if (i1 < 0)
|
|
|
|
i1 += l;
|
|
|
|
if (i2 < 0)
|
|
|
|
i2 += l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return m->sq_ass_slice(s, i1, i2, (PyObject *)NULL);
|
|
|
|
}
|
|
|
|
type_error("object doesn't support slice deletion");
|
|
|
|
return -1;
|
1996-08-21 14:41:54 -03:00
|
|
|
}
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PySequence_Tuple(PyObject *v)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-05-05 00:56:37 -03:00
|
|
|
PyObject *it; /* iter(v) */
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t n; /* guess for result tuple size */
|
2001-05-05 00:56:37 -03:00
|
|
|
PyObject *result;
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t j;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (v == NULL)
|
|
|
|
return null_error();
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-05-05 00:56:37 -03:00
|
|
|
/* Special-case the common tuple and list cases, for efficiency. */
|
2001-09-10 20:37:46 -03:00
|
|
|
if (PyTuple_CheckExact(v)) {
|
|
|
|
/* Note that we can't know whether it's safe to return
|
|
|
|
a tuple *subclass* instance as-is, hence the restriction
|
2001-09-10 20:53:53 -03:00
|
|
|
to exact tuples here. In contrast, lists always make
|
|
|
|
a copy, so there's no need for exactness below. */
|
1998-05-21 21:47:05 -03:00
|
|
|
Py_INCREF(v);
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
if (PyList_Check(v))
|
|
|
|
return PyList_AsTuple(v);
|
|
|
|
|
2001-05-05 00:56:37 -03:00
|
|
|
/* Get iterator. */
|
|
|
|
it = PyObject_GetIter(v);
|
|
|
|
if (it == NULL)
|
Generalize dictionary() to accept a sequence of 2-sequences. At the
outer level, the iterator protocol is used for memory-efficiency (the
outer sequence may be very large if fully materialized); at the inner
level, PySequence_Fast() is used for time-efficiency (these should
always be sequences of length 2).
dictobject.c, new functions PyDict_{Merge,Update}FromSeq2. These are
wholly analogous to PyDict_{Merge,Update}, but process a sequence-of-2-
sequences argument instead of a mapping object. For now, I left these
functions file static, so no corresponding doc changes. It's tempting
to change dict.update() to allow a sequence-of-2-seqs argument too.
Also changed the name of dictionary's keyword argument from "mapping"
to "x". Got a better name? "mapping_or_sequence_of_pairs" isn't
attractive, although more so than "mosop" <wink>.
abstract.h, abstract.tex: Added new PySequence_Fast_GET_SIZE function,
much faster than going thru the all-purpose PySequence_Size.
libfuncs.tex:
- Document dictionary().
- Fiddle tuple() and list() to admit that their argument is optional.
- The long-winded repetitions of "a sequence, a container that supports
iteration, or an iterator object" is getting to be a PITA. Many
months ago I suggested factoring this out into "iterable object",
where the definition of that could include being explicit about
generators too (as is, I'm not sure a reader outside of PythonLabs
could guess that "an iterator object" includes a generator call).
- Please check my curly braces -- I'm going blind <0.9 wink>.
abstract.c, PySequence_Tuple(): When PyObject_GetIter() fails, leave
its error msg alone now (the msg it produces has improved since
PySequence_Tuple was generalized to accept iterable objects, and
PySequence_Tuple was also stomping on the msg in cases it shouldn't
have even before PyObject_GetIter grew a better msg).
2001-10-26 02:06:50 -03:00
|
|
|
return NULL;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-05-05 00:56:37 -03:00
|
|
|
/* Guess result size and allocate space. */
|
2006-02-11 17:32:43 -04:00
|
|
|
n = _PyObject_LengthHint(v);
|
2001-05-05 00:56:37 -03:00
|
|
|
if (n < 0) {
|
2005-08-21 08:03:59 -03:00
|
|
|
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
|
|
|
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
|
|
|
Py_DECREF(it);
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-05-05 00:56:37 -03:00
|
|
|
PyErr_Clear();
|
|
|
|
n = 10; /* arbitrary */
|
|
|
|
}
|
|
|
|
result = PyTuple_New(n);
|
|
|
|
if (result == NULL)
|
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
/* Fill the tuple. */
|
|
|
|
for (j = 0; ; ++j) {
|
|
|
|
PyObject *item = PyIter_Next(it);
|
|
|
|
if (item == NULL) {
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
goto Fail;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (j >= n) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t oldn = n;
|
2004-12-16 06:38:38 -04:00
|
|
|
/* The over-allocation strategy can grow a bit faster
|
|
|
|
than for lists because unlike lists the
|
|
|
|
over-allocation isn't permanent -- we reclaim
|
|
|
|
the excess before the end of this routine.
|
|
|
|
So, grow by ten and then add 25%.
|
|
|
|
*/
|
|
|
|
n += 10;
|
|
|
|
n += n >> 2;
|
|
|
|
if (n < oldn) {
|
|
|
|
/* Check for overflow */
|
|
|
|
PyErr_NoMemory();
|
2004-12-16 11:10:21 -04:00
|
|
|
Py_DECREF(item);
|
2004-12-16 06:38:38 -04:00
|
|
|
goto Fail;
|
|
|
|
}
|
2001-05-28 19:30:08 -03:00
|
|
|
if (_PyTuple_Resize(&result, n) != 0) {
|
2001-05-05 01:10:25 -03:00
|
|
|
Py_DECREF(item);
|
2001-05-05 00:56:37 -03:00
|
|
|
goto Fail;
|
2001-05-05 01:10:25 -03:00
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
}
|
2001-05-05 00:56:37 -03:00
|
|
|
PyTuple_SET_ITEM(result, j, item);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2001-05-05 00:56:37 -03:00
|
|
|
/* Cut tuple back if guess was too large. */
|
|
|
|
if (j < n &&
|
2001-05-28 19:30:08 -03:00
|
|
|
_PyTuple_Resize(&result, j) != 0)
|
2001-05-05 00:56:37 -03:00
|
|
|
goto Fail;
|
|
|
|
|
|
|
|
Py_DECREF(it);
|
|
|
|
return result;
|
|
|
|
|
|
|
|
Fail:
|
|
|
|
Py_XDECREF(result);
|
|
|
|
Py_DECREF(it);
|
|
|
|
return NULL;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1996-12-05 17:51:24 -04:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PySequence_List(PyObject *v)
|
1996-12-05 17:51:24 -04:00
|
|
|
{
|
2001-05-01 17:45:31 -03:00
|
|
|
PyObject *result; /* result list */
|
2004-03-11 05:13:12 -04:00
|
|
|
PyObject *rv; /* return value from PyList_Extend */
|
1998-05-21 21:47:05 -03:00
|
|
|
|
1998-07-10 15:03:50 -03:00
|
|
|
if (v == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
2004-03-11 05:13:12 -04:00
|
|
|
result = PyList_New(0);
|
|
|
|
if (result == NULL)
|
2001-05-01 17:45:31 -03:00
|
|
|
return NULL;
|
|
|
|
|
2004-03-11 05:13:12 -04:00
|
|
|
rv = _PyList_Extend((PyListObject *)result, v);
|
|
|
|
if (rv == NULL) {
|
|
|
|
Py_DECREF(result);
|
2001-05-01 17:45:31 -03:00
|
|
|
return NULL;
|
|
|
|
}
|
2004-03-17 01:24:23 -04:00
|
|
|
Py_DECREF(rv);
|
2001-05-01 17:45:31 -03:00
|
|
|
return result;
|
1998-05-21 21:47:05 -03:00
|
|
|
}
|
1997-04-02 01:31:09 -04:00
|
|
|
|
2000-06-18 15:43:14 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PySequence_Fast(PyObject *v, const char *m)
|
2000-06-18 15:43:14 -03:00
|
|
|
{
|
2004-01-11 19:26:51 -04:00
|
|
|
PyObject *it;
|
|
|
|
|
2000-06-18 15:43:14 -03:00
|
|
|
if (v == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
2002-11-05 14:05:49 -04:00
|
|
|
if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) {
|
2000-06-18 15:43:14 -03:00
|
|
|
Py_INCREF(v);
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2004-01-11 19:26:51 -04:00
|
|
|
it = PyObject_GetIter(v);
|
|
|
|
if (it == NULL) {
|
|
|
|
if (PyErr_ExceptionMatches(PyExc_TypeError))
|
|
|
|
return type_error(m);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2004-12-18 15:00:59 -04:00
|
|
|
v = PySequence_List(it);
|
2004-01-11 19:26:51 -04:00
|
|
|
Py_DECREF(it);
|
2000-06-18 15:43:14 -03:00
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2001-09-08 01:00:12 -03:00
|
|
|
/* Iterate over seq. Result depends on the operation:
|
|
|
|
PY_ITERSEARCH_COUNT: -1 if error, else # of times obj appears in seq.
|
|
|
|
PY_ITERSEARCH_INDEX: 0-based index of first occurence of obj in seq;
|
|
|
|
set ValueError and return -1 if none found; also return -1 on error.
|
|
|
|
Py_ITERSEARCH_CONTAINS: return 1 if obj in seq, else 0; -1 on error.
|
|
|
|
*/
|
2006-03-04 14:49:58 -04:00
|
|
|
Py_ssize_t
|
2001-09-08 01:00:12 -03:00
|
|
|
_PySequence_IterSearch(PyObject *seq, PyObject *obj, int operation)
|
1998-05-21 21:47:05 -03:00
|
|
|
{
|
2006-03-04 14:49:58 -04:00
|
|
|
Py_ssize_t n;
|
2001-09-08 01:00:12 -03:00
|
|
|
int wrapped; /* for PY_ITERSEARCH_INDEX, true iff n wrapped around */
|
|
|
|
PyObject *it; /* iter(seq) */
|
1997-04-02 01:31:09 -04:00
|
|
|
|
2001-09-08 01:00:12 -03:00
|
|
|
if (seq == NULL || obj == NULL) {
|
1998-05-21 21:47:05 -03:00
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
2001-05-05 08:33:43 -03:00
|
|
|
|
2001-09-08 01:00:12 -03:00
|
|
|
it = PyObject_GetIter(seq);
|
2001-05-05 08:33:43 -03:00
|
|
|
if (it == NULL) {
|
2001-09-08 01:00:12 -03:00
|
|
|
type_error("iterable argument required");
|
1998-05-21 21:47:05 -03:00
|
|
|
return -1;
|
2001-05-05 08:33:43 -03:00
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2001-09-08 01:00:12 -03:00
|
|
|
n = wrapped = 0;
|
2001-05-05 08:33:43 -03:00
|
|
|
for (;;) {
|
|
|
|
int cmp;
|
|
|
|
PyObject *item = PyIter_Next(it);
|
|
|
|
if (item == NULL) {
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
goto Fail;
|
|
|
|
break;
|
|
|
|
}
|
2001-09-08 01:00:12 -03:00
|
|
|
|
|
|
|
cmp = PyObject_RichCompareBool(obj, item, Py_EQ);
|
1998-05-21 21:47:05 -03:00
|
|
|
Py_DECREF(item);
|
2001-05-05 08:33:43 -03:00
|
|
|
if (cmp < 0)
|
|
|
|
goto Fail;
|
|
|
|
if (cmp > 0) {
|
2001-09-08 01:00:12 -03:00
|
|
|
switch (operation) {
|
|
|
|
case PY_ITERSEARCH_COUNT:
|
|
|
|
++n;
|
|
|
|
if (n <= 0) {
|
2006-03-04 14:49:58 -04:00
|
|
|
/* XXX(nnorwitz): int means ssize_t */
|
2001-09-08 01:00:12 -03:00
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
2001-05-05 08:33:43 -03:00
|
|
|
"count exceeds C int size");
|
2001-09-08 01:00:12 -03:00
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case PY_ITERSEARCH_INDEX:
|
|
|
|
if (wrapped) {
|
2006-03-04 14:49:58 -04:00
|
|
|
/* XXX(nnorwitz): int means ssize_t */
|
2001-09-08 01:00:12 -03:00
|
|
|
PyErr_SetString(PyExc_OverflowError,
|
|
|
|
"index exceeds C int size");
|
|
|
|
goto Fail;
|
|
|
|
}
|
|
|
|
goto Done;
|
|
|
|
|
|
|
|
case PY_ITERSEARCH_CONTAINS:
|
|
|
|
n = 1;
|
|
|
|
goto Done;
|
|
|
|
|
|
|
|
default:
|
|
|
|
assert(!"unknown operation");
|
2001-05-05 08:33:43 -03:00
|
|
|
}
|
2001-09-08 01:00:12 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (operation == PY_ITERSEARCH_INDEX) {
|
|
|
|
++n;
|
|
|
|
if (n <= 0)
|
|
|
|
wrapped = 1;
|
2001-05-05 08:33:43 -03:00
|
|
|
}
|
1997-04-02 01:31:09 -04:00
|
|
|
}
|
2001-05-05 08:33:43 -03:00
|
|
|
|
2001-09-08 01:00:12 -03:00
|
|
|
if (operation != PY_ITERSEARCH_INDEX)
|
|
|
|
goto Done;
|
|
|
|
|
|
|
|
PyErr_SetString(PyExc_ValueError,
|
|
|
|
"sequence.index(x): x not in sequence");
|
|
|
|
/* fall into failure code */
|
2001-05-05 08:33:43 -03:00
|
|
|
Fail:
|
2001-09-08 01:00:12 -03:00
|
|
|
n = -1;
|
|
|
|
/* fall through */
|
|
|
|
Done:
|
2001-05-05 08:33:43 -03:00
|
|
|
Py_DECREF(it);
|
2001-09-08 01:00:12 -03:00
|
|
|
return n;
|
|
|
|
|
1996-12-05 17:51:24 -04:00
|
|
|
}
|
|
|
|
|
2001-09-08 01:00:12 -03:00
|
|
|
/* Return # of times o appears in s. */
|
2006-03-04 14:49:58 -04:00
|
|
|
Py_ssize_t
|
2001-09-08 01:00:12 -03:00
|
|
|
PySequence_Count(PyObject *s, PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-09-08 01:00:12 -03:00
|
|
|
return _PySequence_IterSearch(s, o, PY_ITERSEARCH_COUNT);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2001-05-05 18:05:01 -03:00
|
|
|
/* Return -1 if error; 1 if ob in seq; 0 if ob not in seq.
|
2001-09-08 01:00:12 -03:00
|
|
|
* Use sq_contains if possible, else defer to _PySequence_IterSearch().
|
2001-05-05 18:05:01 -03:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
PySequence_Contains(PyObject *seq, PyObject *ob)
|
|
|
|
{
|
2006-03-04 14:49:58 -04:00
|
|
|
Py_ssize_t result;
|
2006-07-27 18:53:35 -03:00
|
|
|
PySequenceMethods *sqm = seq->ob_type->tp_as_sequence;
|
|
|
|
if (sqm != NULL && sqm->sq_contains != NULL)
|
|
|
|
return (*sqm->sq_contains)(seq, ob);
|
2006-03-04 14:49:58 -04:00
|
|
|
result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS);
|
|
|
|
return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);
|
2001-05-05 18:05:01 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Backwards compatibility */
|
|
|
|
#undef PySequence_In
|
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PySequence_In(PyObject *w, PyObject *v)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
return PySequence_Contains(w, v);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2006-03-04 14:49:58 -04:00
|
|
|
Py_ssize_t
|
2000-07-09 01:06:11 -03:00
|
|
|
PySequence_Index(PyObject *s, PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-09-08 01:00:12 -03:00
|
|
|
return _PySequence_IterSearch(s, o, PY_ITERSEARCH_INDEX);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Operations on mappings */
|
|
|
|
|
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyMapping_Check(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2004-09-19 03:00:15 -03:00
|
|
|
if (o && PyInstance_Check(o))
|
2004-04-04 05:51:41 -03:00
|
|
|
return PyObject_HasAttrString(o, "__getitem__");
|
|
|
|
|
|
|
|
return o && o->ob_type->tp_as_mapping &&
|
|
|
|
o->ob_type->tp_as_mapping->mp_subscript &&
|
2004-04-05 05:14:48 -03:00
|
|
|
!(o->ob_type->tp_as_sequence &&
|
|
|
|
o->ob_type->tp_as_sequence->sq_slice);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t
|
2000-07-12 09:56:19 -03:00
|
|
|
PyMapping_Size(PyObject *o)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyMappingMethods *m;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
if (o == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
m = o->ob_type->tp_as_mapping;
|
|
|
|
if (m && m->mp_length)
|
|
|
|
return m->mp_length(o);
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
type_error("len() of unsized object");
|
|
|
|
return -1;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
2000-07-17 06:22:55 -03:00
|
|
|
#undef PyMapping_Length
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t
|
2000-07-17 06:22:55 -03:00
|
|
|
PyMapping_Length(PyObject *o)
|
|
|
|
{
|
|
|
|
return PyMapping_Size(o);
|
|
|
|
}
|
|
|
|
#define PyMapping_Length PyMapping_Size
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyMapping_GetItemString(PyObject *o, char *key)
|
1998-05-21 21:47:05 -03:00
|
|
|
{
|
|
|
|
PyObject *okey, *r;
|
|
|
|
|
|
|
|
if (key == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
|
|
|
okey = PyString_FromString(key);
|
|
|
|
if (okey == NULL)
|
|
|
|
return NULL;
|
|
|
|
r = PyObject_GetItem(o, okey);
|
|
|
|
Py_DECREF(okey);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyMapping_SetItemString(PyObject *o, char *key, PyObject *value)
|
1998-05-21 21:47:05 -03:00
|
|
|
{
|
|
|
|
PyObject *okey;
|
|
|
|
int r;
|
|
|
|
|
|
|
|
if (key == NULL) {
|
|
|
|
null_error();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
okey = PyString_FromString(key);
|
|
|
|
if (okey == NULL)
|
1998-05-28 23:59:33 -03:00
|
|
|
return -1;
|
1998-05-21 21:47:05 -03:00
|
|
|
r = PyObject_SetItem(o, okey, value);
|
|
|
|
Py_DECREF(okey);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyMapping_HasKeyString(PyObject *o, char *key)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyObject *v;
|
|
|
|
|
|
|
|
v = PyMapping_GetItemString(o, key);
|
|
|
|
if (v) {
|
|
|
|
Py_DECREF(v);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
PyErr_Clear();
|
|
|
|
return 0;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
int
|
2000-07-09 01:06:11 -03:00
|
|
|
PyMapping_HasKey(PyObject *o, PyObject *key)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
PyObject *v;
|
|
|
|
|
|
|
|
v = PyObject_GetItem(o, key);
|
|
|
|
if (v) {
|
|
|
|
Py_DECREF(v);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
PyErr_Clear();
|
|
|
|
return 0;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
/* Operations on callable objects */
|
|
|
|
|
|
|
|
/* XXX PyCallable_Check() is in object.c */
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
2000-07-09 01:06:11 -03:00
|
|
|
PyObject_CallObject(PyObject *o, PyObject *a)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
2001-09-14 13:47:50 -03:00
|
|
|
return PyEval_CallObjectWithKeywords(o, a, NULL);
|
1998-05-21 21:47:05 -03:00
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-08-02 01:15:00 -03:00
|
|
|
PyObject *
|
|
|
|
PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw)
|
|
|
|
{
|
|
|
|
ternaryfunc call;
|
|
|
|
|
|
|
|
if ((call = func->ob_type->tp_call) != NULL) {
|
|
|
|
PyObject *result = (*call)(func, arg, kw);
|
|
|
|
if (result == NULL && !PyErr_Occurred())
|
|
|
|
PyErr_SetString(
|
|
|
|
PyExc_SystemError,
|
|
|
|
"NULL result without error in PyObject_Call");
|
|
|
|
return result;
|
|
|
|
}
|
2001-11-01 16:26:12 -04:00
|
|
|
PyErr_Format(PyExc_TypeError, "'%s' object is not callable",
|
|
|
|
func->ob_type->tp_name);
|
2001-08-02 01:15:00 -03:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
static PyObject*
|
|
|
|
call_function_tail(PyObject *callable, PyObject *args)
|
|
|
|
{
|
|
|
|
PyObject *retval;
|
|
|
|
|
|
|
|
if (args == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!PyTuple_Check(args)) {
|
|
|
|
PyObject *a;
|
|
|
|
|
|
|
|
a = PyTuple_New(1);
|
|
|
|
if (a == NULL) {
|
|
|
|
Py_DECREF(args);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
PyTuple_SET_ITEM(a, 0, args);
|
|
|
|
args = a;
|
|
|
|
}
|
|
|
|
retval = PyObject_Call(callable, args, NULL);
|
|
|
|
|
|
|
|
Py_DECREF(args);
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
1995-07-18 11:12:02 -03:00
|
|
|
PyObject *
|
1998-05-21 21:47:05 -03:00
|
|
|
PyObject_CallFunction(PyObject *callable, char *format, ...)
|
1995-07-18 11:12:02 -03:00
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
va_list va;
|
2006-04-21 07:40:58 -03:00
|
|
|
PyObject *args;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-10-27 03:16:31 -03:00
|
|
|
if (callable == NULL)
|
1998-05-21 21:47:05 -03:00
|
|
|
return null_error();
|
|
|
|
|
2001-10-27 03:16:31 -03:00
|
|
|
if (format && *format) {
|
|
|
|
va_start(va, format);
|
1998-05-21 21:47:05 -03:00
|
|
|
args = Py_VaBuildValue(format, va);
|
2001-10-27 03:16:31 -03:00
|
|
|
va_end(va);
|
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
else
|
|
|
|
args = PyTuple_New(0);
|
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
return call_function_tail(callable, args);
|
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
PyObject *
|
|
|
|
_PyObject_CallFunction_SizeT(PyObject *callable, char *format, ...)
|
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
PyObject *args;
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
if (callable == NULL)
|
|
|
|
return null_error();
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
if (format && *format) {
|
|
|
|
va_start(va, format);
|
|
|
|
args = _Py_VaBuildValue_SizeT(format, va);
|
|
|
|
va_end(va);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
args = PyTuple_New(0);
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
return call_function_tail(callable, args);
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
|
|
|
|
{
|
1998-05-21 21:47:05 -03:00
|
|
|
va_list va;
|
2006-04-21 07:40:58 -03:00
|
|
|
PyObject *args;
|
2005-07-12 07:21:19 -03:00
|
|
|
PyObject *func = NULL;
|
|
|
|
PyObject *retval = NULL;
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-10-27 03:16:31 -03:00
|
|
|
if (o == NULL || name == NULL)
|
1998-05-21 21:47:05 -03:00
|
|
|
return null_error();
|
1995-07-18 11:12:02 -03:00
|
|
|
|
1998-05-21 21:47:05 -03:00
|
|
|
func = PyObject_GetAttrString(o, name);
|
|
|
|
if (func == NULL) {
|
|
|
|
PyErr_SetString(PyExc_AttributeError, name);
|
|
|
|
return 0;
|
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2005-07-12 07:21:19 -03:00
|
|
|
if (!PyCallable_Check(func)) {
|
|
|
|
type_error("call of non-callable attribute");
|
|
|
|
goto exit;
|
|
|
|
}
|
1995-07-18 11:12:02 -03:00
|
|
|
|
2001-10-27 03:16:31 -03:00
|
|
|
if (format && *format) {
|
|
|
|
va_start(va, format);
|
1998-05-21 21:47:05 -03:00
|
|
|
args = Py_VaBuildValue(format, va);
|
2001-10-27 03:16:31 -03:00
|
|
|
va_end(va);
|
|
|
|
}
|
1998-05-21 21:47:05 -03:00
|
|
|
else
|
|
|
|
args = PyTuple_New(0);
|
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
retval = call_function_tail(func, args);
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
exit:
|
|
|
|
/* args gets consumed in call_function_tail */
|
|
|
|
Py_XDECREF(func);
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
|
|
|
_PyObject_CallMethod_SizeT(PyObject *o, char *name, char *format, ...)
|
|
|
|
{
|
|
|
|
va_list va;
|
|
|
|
PyObject *args;
|
|
|
|
PyObject *func = NULL;
|
|
|
|
PyObject *retval = NULL;
|
|
|
|
|
|
|
|
if (o == NULL || name == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
|
|
|
func = PyObject_GetAttrString(o, name);
|
|
|
|
if (func == NULL) {
|
|
|
|
PyErr_SetString(PyExc_AttributeError, name);
|
|
|
|
return 0;
|
1998-05-21 21:47:05 -03:00
|
|
|
}
|
|
|
|
|
2006-04-21 07:40:58 -03:00
|
|
|
if (!PyCallable_Check(func)) {
|
|
|
|
type_error("call of non-callable attribute");
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (format && *format) {
|
|
|
|
va_start(va, format);
|
|
|
|
args = _Py_VaBuildValue_SizeT(format, va);
|
|
|
|
va_end(va);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
args = PyTuple_New(0);
|
|
|
|
|
|
|
|
retval = call_function_tail(func, args);
|
1998-05-21 21:47:05 -03:00
|
|
|
|
2005-07-12 07:21:19 -03:00
|
|
|
exit:
|
2006-04-21 07:40:58 -03:00
|
|
|
/* args gets consumed in call_function_tail */
|
2005-07-12 07:21:19 -03:00
|
|
|
Py_XDECREF(func);
|
1998-05-21 21:47:05 -03:00
|
|
|
|
|
|
|
return retval;
|
1995-07-18 11:12:02 -03:00
|
|
|
}
|
2001-03-21 14:40:58 -04:00
|
|
|
|
|
|
|
|
2001-10-26 13:21:32 -03:00
|
|
|
static PyObject *
|
2001-10-27 23:39:03 -03:00
|
|
|
objargs_mktuple(va_list va)
|
2001-10-26 13:21:32 -03:00
|
|
|
{
|
|
|
|
int i, n = 0;
|
|
|
|
va_list countva;
|
|
|
|
PyObject *result, *tmp;
|
|
|
|
|
|
|
|
#ifdef VA_LIST_IS_ARRAY
|
|
|
|
memcpy(countva, va, sizeof(va_list));
|
2002-07-28 07:23:27 -03:00
|
|
|
#else
|
|
|
|
#ifdef __va_copy
|
|
|
|
__va_copy(countva, va);
|
2001-10-26 13:21:32 -03:00
|
|
|
#else
|
|
|
|
countva = va;
|
2002-07-28 07:23:27 -03:00
|
|
|
#endif
|
2001-10-26 13:21:32 -03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
|
|
|
|
++n;
|
|
|
|
result = PyTuple_New(n);
|
|
|
|
if (result != NULL && n > 0) {
|
|
|
|
for (i = 0; i < n; ++i) {
|
|
|
|
tmp = (PyObject *)va_arg(va, PyObject *);
|
|
|
|
PyTuple_SET_ITEM(result, i, tmp);
|
|
|
|
Py_INCREF(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2001-10-27 23:39:03 -03:00
|
|
|
PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
|
2001-10-26 13:21:32 -03:00
|
|
|
{
|
|
|
|
PyObject *args, *tmp;
|
|
|
|
va_list vargs;
|
|
|
|
|
|
|
|
if (callable == NULL || name == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
|
|
|
callable = PyObject_GetAttr(callable, name);
|
|
|
|
if (callable == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* count the args */
|
|
|
|
va_start(vargs, name);
|
2001-10-27 23:39:03 -03:00
|
|
|
args = objargs_mktuple(vargs);
|
2001-10-26 13:21:32 -03:00
|
|
|
va_end(vargs);
|
|
|
|
if (args == NULL) {
|
|
|
|
Py_DECREF(callable);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
tmp = PyObject_Call(callable, args, NULL);
|
|
|
|
Py_DECREF(args);
|
|
|
|
Py_DECREF(callable);
|
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
PyObject *
|
2001-10-27 23:39:03 -03:00
|
|
|
PyObject_CallFunctionObjArgs(PyObject *callable, ...)
|
2001-10-26 13:21:32 -03:00
|
|
|
{
|
|
|
|
PyObject *args, *tmp;
|
|
|
|
va_list vargs;
|
|
|
|
|
|
|
|
if (callable == NULL)
|
|
|
|
return null_error();
|
|
|
|
|
|
|
|
/* count the args */
|
|
|
|
va_start(vargs, callable);
|
2001-10-27 23:39:03 -03:00
|
|
|
args = objargs_mktuple(vargs);
|
2001-10-26 13:21:32 -03:00
|
|
|
va_end(vargs);
|
|
|
|
if (args == NULL)
|
|
|
|
return NULL;
|
|
|
|
tmp = PyObject_Call(callable, args, NULL);
|
|
|
|
Py_DECREF(args);
|
|
|
|
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-21 14:40:58 -04:00
|
|
|
/* isinstance(), issubclass() */
|
|
|
|
|
abstract_get_bases(): Clarify exactly what the return values and
states can be for this function, and ensure that only AttributeErrors
are masked. Any other exception raised via the equivalent of
getattr(cls, '__bases__') should be propagated up.
abstract_issubclass(): If abstract_get_bases() returns NULL, we must
call PyErr_Occurred() to see if an exception is being propagated, and
return -1 or 0 as appropriate. This is the specific fix for a problem
whereby if getattr(derived, '__bases__') raised an exception, an
"undetected error" would occur (under a debug build). This nasty
situation was uncovered when writing a security proxy extension type
for the Zope3 project, where the security proxy raised a Forbidden
exception on getattr of __bases__.
PyObject_IsInstance(), PyObject_IsSubclass(): After both calls to
abstract_get_bases(), where we're setting the TypeError if the return
value is NULL, we must first check to see if an exception occurred,
and /not/ mask an existing exception.
Neil Schemenauer should double check that these changes don't break
his ExtensionClass examples (there aren't any test cases for those
examples and abstract_get_bases() was added by him in response to
problems with ExtensionClass). Neil, please add test cases if
possible!
I belive this is a bug fix candidate for Python 2.2.2.
2002-04-23 19:45:44 -03:00
|
|
|
/* abstract_get_bases() has logically 4 return states, with a sort of 0th
|
|
|
|
* state that will almost never happen.
|
|
|
|
*
|
|
|
|
* 0. creating the __bases__ static string could get a MemoryError
|
|
|
|
* 1. getattr(cls, '__bases__') could raise an AttributeError
|
|
|
|
* 2. getattr(cls, '__bases__') could raise some other exception
|
|
|
|
* 3. getattr(cls, '__bases__') could return a tuple
|
|
|
|
* 4. getattr(cls, '__bases__') could return something other than a tuple
|
|
|
|
*
|
|
|
|
* Only state #3 is a non-error state and only it returns a non-NULL object
|
|
|
|
* (it returns the retrieved tuple).
|
|
|
|
*
|
|
|
|
* Any raised AttributeErrors are masked by clearing the exception and
|
|
|
|
* returning NULL. If an object other than a tuple comes out of __bases__,
|
|
|
|
* then again, the return value is NULL. So yes, these two situations
|
|
|
|
* produce exactly the same results: NULL is returned and no error is set.
|
|
|
|
*
|
|
|
|
* If some exception other than AttributeError is raised, then NULL is also
|
|
|
|
* returned, but the exception is not cleared. That's because we want the
|
|
|
|
* exception to be propagated along.
|
|
|
|
*
|
|
|
|
* Callers are expected to test for PyErr_Occurred() when the return value
|
|
|
|
* is NULL to decide whether a valid exception should be propagated or not.
|
|
|
|
* When there's no exception to propagate, it's customary for the caller to
|
|
|
|
* set a TypeError.
|
|
|
|
*/
|
2001-10-18 00:18:43 -03:00
|
|
|
static PyObject *
|
|
|
|
abstract_get_bases(PyObject *cls)
|
2001-03-21 14:40:58 -04:00
|
|
|
{
|
|
|
|
static PyObject *__bases__ = NULL;
|
|
|
|
PyObject *bases;
|
|
|
|
|
|
|
|
if (__bases__ == NULL) {
|
|
|
|
__bases__ = PyString_FromString("__bases__");
|
|
|
|
if (__bases__ == NULL)
|
2001-10-18 00:18:43 -03:00
|
|
|
return NULL;
|
2001-03-21 14:40:58 -04:00
|
|
|
}
|
2001-10-18 00:18:43 -03:00
|
|
|
bases = PyObject_GetAttr(cls, __bases__);
|
abstract_get_bases(): Clarify exactly what the return values and
states can be for this function, and ensure that only AttributeErrors
are masked. Any other exception raised via the equivalent of
getattr(cls, '__bases__') should be propagated up.
abstract_issubclass(): If abstract_get_bases() returns NULL, we must
call PyErr_Occurred() to see if an exception is being propagated, and
return -1 or 0 as appropriate. This is the specific fix for a problem
whereby if getattr(derived, '__bases__') raised an exception, an
"undetected error" would occur (under a debug build). This nasty
situation was uncovered when writing a security proxy extension type
for the Zope3 project, where the security proxy raised a Forbidden
exception on getattr of __bases__.
PyObject_IsInstance(), PyObject_IsSubclass(): After both calls to
abstract_get_bases(), where we're setting the TypeError if the return
value is NULL, we must first check to see if an exception occurred,
and /not/ mask an existing exception.
Neil Schemenauer should double check that these changes don't break
his ExtensionClass examples (there aren't any test cases for those
examples and abstract_get_bases() was added by him in response to
problems with ExtensionClass). Neil, please add test cases if
possible!
I belive this is a bug fix candidate for Python 2.2.2.
2002-04-23 19:45:44 -03:00
|
|
|
if (bases == NULL) {
|
|
|
|
if (PyErr_ExceptionMatches(PyExc_AttributeError))
|
|
|
|
PyErr_Clear();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (!PyTuple_Check(bases)) {
|
|
|
|
Py_DECREF(bases);
|
2001-10-18 00:18:43 -03:00
|
|
|
return NULL;
|
2001-03-21 14:40:58 -04:00
|
|
|
}
|
2001-10-18 00:18:43 -03:00
|
|
|
return bases;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
abstract_issubclass(PyObject *derived, PyObject *cls)
|
|
|
|
{
|
|
|
|
PyObject *bases;
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t i, n;
|
2001-10-18 00:18:43 -03:00
|
|
|
int r = 0;
|
|
|
|
|
|
|
|
|
2001-03-21 14:40:58 -04:00
|
|
|
if (derived == cls)
|
|
|
|
return 1;
|
|
|
|
|
2002-12-12 12:41:44 -04:00
|
|
|
if (PyTuple_Check(cls)) {
|
|
|
|
/* Not a general sequence -- that opens up the road to
|
|
|
|
recursion and stack overflow. */
|
|
|
|
n = PyTuple_GET_SIZE(cls);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
if (derived == PyTuple_GET_ITEM(cls, i))
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2001-10-18 00:18:43 -03:00
|
|
|
bases = abstract_get_bases(derived);
|
abstract_get_bases(): Clarify exactly what the return values and
states can be for this function, and ensure that only AttributeErrors
are masked. Any other exception raised via the equivalent of
getattr(cls, '__bases__') should be propagated up.
abstract_issubclass(): If abstract_get_bases() returns NULL, we must
call PyErr_Occurred() to see if an exception is being propagated, and
return -1 or 0 as appropriate. This is the specific fix for a problem
whereby if getattr(derived, '__bases__') raised an exception, an
"undetected error" would occur (under a debug build). This nasty
situation was uncovered when writing a security proxy extension type
for the Zope3 project, where the security proxy raised a Forbidden
exception on getattr of __bases__.
PyObject_IsInstance(), PyObject_IsSubclass(): After both calls to
abstract_get_bases(), where we're setting the TypeError if the return
value is NULL, we must first check to see if an exception occurred,
and /not/ mask an existing exception.
Neil Schemenauer should double check that these changes don't break
his ExtensionClass examples (there aren't any test cases for those
examples and abstract_get_bases() was added by him in response to
problems with ExtensionClass). Neil, please add test cases if
possible!
I belive this is a bug fix candidate for Python 2.2.2.
2002-04-23 19:45:44 -03:00
|
|
|
if (bases == NULL) {
|
|
|
|
if (PyErr_Occurred())
|
|
|
|
return -1;
|
2001-10-18 00:18:43 -03:00
|
|
|
return 0;
|
abstract_get_bases(): Clarify exactly what the return values and
states can be for this function, and ensure that only AttributeErrors
are masked. Any other exception raised via the equivalent of
getattr(cls, '__bases__') should be propagated up.
abstract_issubclass(): If abstract_get_bases() returns NULL, we must
call PyErr_Occurred() to see if an exception is being propagated, and
return -1 or 0 as appropriate. This is the specific fix for a problem
whereby if getattr(derived, '__bases__') raised an exception, an
"undetected error" would occur (under a debug build). This nasty
situation was uncovered when writing a security proxy extension type
for the Zope3 project, where the security proxy raised a Forbidden
exception on getattr of __bases__.
PyObject_IsInstance(), PyObject_IsSubclass(): After both calls to
abstract_get_bases(), where we're setting the TypeError if the return
value is NULL, we must first check to see if an exception occurred,
and /not/ mask an existing exception.
Neil Schemenauer should double check that these changes don't break
his ExtensionClass examples (there aren't any test cases for those
examples and abstract_get_bases() was added by him in response to
problems with ExtensionClass). Neil, please add test cases if
possible!
I belive this is a bug fix candidate for Python 2.2.2.
2002-04-23 19:45:44 -03:00
|
|
|
}
|
2001-03-21 14:40:58 -04:00
|
|
|
n = PyTuple_GET_SIZE(bases);
|
|
|
|
for (i = 0; i < n; i++) {
|
2001-10-18 00:18:43 -03:00
|
|
|
r = abstract_issubclass(PyTuple_GET_ITEM(bases, i), cls);
|
2001-03-21 14:40:58 -04:00
|
|
|
if (r != 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Py_DECREF(bases);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2002-12-12 12:41:44 -04:00
|
|
|
static int
|
|
|
|
check_class(PyObject *cls, const char *error)
|
|
|
|
{
|
|
|
|
PyObject *bases = abstract_get_bases(cls);
|
|
|
|
if (bases == NULL) {
|
|
|
|
/* Do not mask errors. */
|
|
|
|
if (!PyErr_Occurred())
|
|
|
|
PyErr_SetString(PyExc_TypeError, error);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
Py_DECREF(bases);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2004-03-20 18:52:14 -04:00
|
|
|
static int
|
|
|
|
recursive_isinstance(PyObject *inst, PyObject *cls, int recursion_depth)
|
2001-03-21 14:40:58 -04:00
|
|
|
{
|
|
|
|
PyObject *icls;
|
|
|
|
static PyObject *__class__ = NULL;
|
|
|
|
int retval = 0;
|
|
|
|
|
2003-02-11 23:32:58 -04:00
|
|
|
if (__class__ == NULL) {
|
|
|
|
__class__ = PyString_FromString("__class__");
|
|
|
|
if (__class__ == NULL)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-03-15 00:58:47 -04:00
|
|
|
if (PyType_Check(cls)) {
|
2001-08-02 01:15:00 -03:00
|
|
|
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
|
2003-02-11 23:32:58 -04:00
|
|
|
if (retval == 0) {
|
|
|
|
PyObject *c = PyObject_GetAttr(inst, __class__);
|
|
|
|
if (c == NULL) {
|
|
|
|
PyErr_Clear();
|
|
|
|
}
|
|
|
|
else {
|
2003-02-11 23:36:05 -04:00
|
|
|
if (c != (PyObject *)(inst->ob_type) &&
|
|
|
|
PyType_Check(c))
|
2003-02-11 23:32:58 -04:00
|
|
|
retval = PyType_IsSubtype(
|
|
|
|
(PyTypeObject *)c,
|
|
|
|
(PyTypeObject *)cls);
|
|
|
|
Py_DECREF(c);
|
|
|
|
}
|
|
|
|
}
|
2001-03-21 14:40:58 -04:00
|
|
|
}
|
2001-10-07 17:54:12 -03:00
|
|
|
else if (PyTuple_Check(cls)) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t i, n;
|
2001-10-07 17:54:12 -03:00
|
|
|
|
2004-03-20 18:52:14 -04:00
|
|
|
if (!recursion_depth) {
|
|
|
|
PyErr_SetString(PyExc_RuntimeError,
|
|
|
|
"nest level of tuple too deep");
|
2004-03-21 12:59:09 -04:00
|
|
|
return -1;
|
2004-03-20 18:52:14 -04:00
|
|
|
}
|
|
|
|
|
2001-10-07 17:54:12 -03:00
|
|
|
n = PyTuple_GET_SIZE(cls);
|
|
|
|
for (i = 0; i < n; i++) {
|
2004-03-20 18:52:14 -04:00
|
|
|
retval = recursive_isinstance(
|
|
|
|
inst,
|
|
|
|
PyTuple_GET_ITEM(cls, i),
|
|
|
|
recursion_depth-1);
|
2001-10-07 17:54:12 -03:00
|
|
|
if (retval != 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2001-10-18 00:18:43 -03:00
|
|
|
else {
|
2002-12-12 12:41:44 -04:00
|
|
|
if (!check_class(cls,
|
|
|
|
"isinstance() arg 2 must be a class, type,"
|
|
|
|
" or tuple of classes and types"))
|
2001-10-18 00:18:43 -03:00
|
|
|
return -1;
|
2001-03-21 14:40:58 -04:00
|
|
|
icls = PyObject_GetAttr(inst, __class__);
|
2001-10-18 00:18:43 -03:00
|
|
|
if (icls == NULL) {
|
|
|
|
PyErr_Clear();
|
|
|
|
retval = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
retval = abstract_issubclass(icls, cls);
|
2001-03-21 14:40:58 -04:00
|
|
|
Py_DECREF(icls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2004-03-20 18:52:14 -04:00
|
|
|
PyObject_IsInstance(PyObject *inst, PyObject *cls)
|
|
|
|
{
|
|
|
|
return recursive_isinstance(inst, cls, Py_GetRecursionLimit());
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
recursive_issubclass(PyObject *derived, PyObject *cls, int recursion_depth)
|
2001-03-21 14:40:58 -04:00
|
|
|
{
|
|
|
|
int retval;
|
|
|
|
|
2006-03-15 00:58:47 -04:00
|
|
|
{
|
2003-02-10 12:05:43 -04:00
|
|
|
if (!check_class(derived,
|
|
|
|
"issubclass() arg 1 must be a class"))
|
2001-10-18 00:18:43 -03:00
|
|
|
return -1;
|
2002-12-12 12:41:44 -04:00
|
|
|
|
|
|
|
if (PyTuple_Check(cls)) {
|
2006-02-15 13:27:45 -04:00
|
|
|
Py_ssize_t i;
|
|
|
|
Py_ssize_t n = PyTuple_GET_SIZE(cls);
|
2004-03-20 18:52:14 -04:00
|
|
|
|
|
|
|
if (!recursion_depth) {
|
|
|
|
PyErr_SetString(PyExc_RuntimeError,
|
|
|
|
"nest level of tuple too deep");
|
2004-03-21 12:59:09 -04:00
|
|
|
return -1;
|
2004-03-20 18:52:14 -04:00
|
|
|
}
|
2002-12-12 12:41:44 -04:00
|
|
|
for (i = 0; i < n; ++i) {
|
2004-03-20 18:52:14 -04:00
|
|
|
retval = recursive_issubclass(
|
|
|
|
derived,
|
|
|
|
PyTuple_GET_ITEM(cls, i),
|
|
|
|
recursion_depth-1);
|
2003-02-10 12:05:43 -04:00
|
|
|
if (retval != 0) {
|
|
|
|
/* either found it, or got an error */
|
2002-12-12 15:14:08 -04:00
|
|
|
return retval;
|
2003-02-10 12:05:43 -04:00
|
|
|
}
|
2002-12-12 12:41:44 -04:00
|
|
|
}
|
2002-12-12 15:14:08 -04:00
|
|
|
return 0;
|
2001-10-18 00:18:43 -03:00
|
|
|
}
|
2002-12-12 12:41:44 -04:00
|
|
|
else {
|
|
|
|
if (!check_class(cls,
|
|
|
|
"issubclass() arg 2 must be a class"
|
|
|
|
" or tuple of classes"))
|
|
|
|
return -1;
|
2001-10-18 00:18:43 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
retval = abstract_issubclass(derived, cls);
|
2001-03-21 14:40:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
2001-04-20 16:13:02 -03:00
|
|
|
|
2004-03-20 18:52:14 -04:00
|
|
|
int
|
|
|
|
PyObject_IsSubclass(PyObject *derived, PyObject *cls)
|
|
|
|
{
|
|
|
|
return recursive_issubclass(derived, cls, Py_GetRecursionLimit());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-04-20 16:13:02 -03:00
|
|
|
PyObject *
|
|
|
|
PyObject_GetIter(PyObject *o)
|
|
|
|
{
|
|
|
|
PyTypeObject *t = o->ob_type;
|
|
|
|
getiterfunc f = NULL;
|
2006-07-27 18:53:35 -03:00
|
|
|
f = t->tp_iter;
|
2001-04-20 16:13:02 -03:00
|
|
|
if (f == NULL) {
|
|
|
|
if (PySequence_Check(o))
|
2001-04-23 11:08:49 -03:00
|
|
|
return PySeqIter_New(o);
|
2002-04-16 13:32:50 -03:00
|
|
|
PyErr_SetString(PyExc_TypeError,
|
2001-11-09 17:59:42 -04:00
|
|
|
"iteration over non-sequence");
|
2001-04-20 16:13:02 -03:00
|
|
|
return NULL;
|
|
|
|
}
|
2001-04-23 11:08:49 -03:00
|
|
|
else {
|
|
|
|
PyObject *res = (*f)(o);
|
|
|
|
if (res != NULL && !PyIter_Check(res)) {
|
|
|
|
PyErr_Format(PyExc_TypeError,
|
|
|
|
"iter() returned non-iterator "
|
|
|
|
"of type '%.100s'",
|
|
|
|
res->ob_type->tp_name);
|
|
|
|
Py_DECREF(res);
|
|
|
|
res = NULL;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-05-04 21:14:56 -03:00
|
|
|
/* Return next item.
|
|
|
|
* If an error occurs, return NULL. PyErr_Occurred() will be true.
|
|
|
|
* If the iteration terminates normally, return NULL and clear the
|
|
|
|
* PyExc_StopIteration exception (if it was set). PyErr_Occurred()
|
|
|
|
* will be false.
|
|
|
|
* Else return the next object. PyErr_Occurred() will be false.
|
|
|
|
*/
|
2001-04-23 11:08:49 -03:00
|
|
|
PyObject *
|
|
|
|
PyIter_Next(PyObject *iter)
|
|
|
|
{
|
2001-05-04 21:14:56 -03:00
|
|
|
PyObject *result;
|
2003-02-28 21:44:32 -04:00
|
|
|
assert(PyIter_Check(iter));
|
2001-05-04 21:14:56 -03:00
|
|
|
result = (*iter->ob_type->tp_iternext)(iter);
|
|
|
|
if (result == NULL &&
|
|
|
|
PyErr_Occurred() &&
|
|
|
|
PyErr_ExceptionMatches(PyExc_StopIteration))
|
|
|
|
PyErr_Clear();
|
|
|
|
return result;
|
2001-04-20 16:13:02 -03:00
|
|
|
}
|