Commit 7b65b4e7 authored by Tres Seaver's avatar Tres Seaver

Merge py3k branch.

parents f70f5c92 bbd693c7
......@@ -6,3 +6,4 @@ nosetests.xml
coverage.xml
*.egg
docs/_build
__pycache__
This diff is collapsed.
......@@ -15,6 +15,7 @@
#include "Python.h"
/* include structmember.h for offsetof */
#include "structmember.h"
#include "bytesobject.h"
#ifdef PERSISTENT
#include "persistent/cPersistence.h"
......@@ -27,7 +28,7 @@
#define PER_ACCESSED(O) 1
#endif
#include "py24compat.h"
#include "_compat.h"
/* So sue me. This pair gets used all over the place, so much so that it
* interferes with understanding non-persistence parts of algorithms.
......@@ -65,7 +66,7 @@ static void PyVar_Assign(PyObject **v, PyObject *e) { Py_XDECREF(*v); *v=e;}
#define MAX_BTREE_SIZE(B) DEFAULT_MAX_BTREE_SIZE
#define MAX_BUCKET_SIZE(B) DEFAULT_MAX_BUCKET_SIZE
#define SameType_Check(O1, O2) ((O1)->ob_type==(O2)->ob_type)
#define SameType_Check(O1, O2) (Py_TYPE((O1))==Py_TYPE((O2)))
#define ASSERT(C, S, R) if (! (C)) { \
PyErr_SetString(PyExc_AssertionError, (S)); return (R); }
......@@ -81,7 +82,7 @@ static void PyVar_Assign(PyObject **v, PyObject *e) { Py_XDECREF(*v); *v=e;}
static int
longlong_check(PyObject *ob)
{
if (PyInt_Check(ob))
if (INT_CHECK(ob))
return 1;
if (PyLong_Check(ob)) {
......@@ -101,10 +102,52 @@ longlong_as_object(PY_LONG_LONG val)
static PY_LONG_LONG maxint = 0;
if (maxint == 0)
maxint = PyInt_GetMax();
maxint = INT_GETMAX();
if ((val > maxint) || (val < (-maxint-1)))
return PyLong_FromLongLong(val);
return PyInt_FromLong((long)val);
return INT_FROM_LONG((long)val);
}
#endif
#ifdef NEED_LONG_LONG_KEYS
static int
longlong_convert(PyObject *ob, PY_LONG_LONG *value)
{
#ifndef PY3K
if (PyInt_Check(ob))
{
(*value) = (PY_LONG_LONG)PyInt_AS_LONG(ob);
return 1;
}
#endif
if (!PyLong_Check(ob))
{
PyErr_SetString(PyExc_TypeError, "expected integer key");
return 0;
}
else
{
PY_LONG_LONG val;
#if PY_VERSION_HEX < 0x02070000
/* check magnitude */
val = PyLong_AsLongLong(ob);
if (val == -1 && PyErr_Occurred())
goto overflow;
#else
int overflow;
val = PyLong_AsLongLongAndOverflow(ob, &overflow);
if (overflow)
goto overflow;
#endif
(*value) = val;
return 1;
}
overflow:
PyErr_SetString(PyExc_ValueError, "long integer out of range");
return 0;
}
#endif
......@@ -291,7 +334,7 @@ IndexError(int i)
{
PyObject *v;
v = PyInt_FromLong(i);
v = INT_FROM_LONG(i);
if (!v) {
v = Py_None;
Py_INCREF(v);
......@@ -451,7 +494,11 @@ BTREEITEMSTEMPLATE_C
int
init_persist_type(PyTypeObject *type)
{
#ifdef PY3K
((PyObject*)type)->ob_type = &PyType_Type;
#else
type->ob_type = &PyType_Type;
#endif
type->tp_base = cPersistenceCAPI->pertype;
if (PyType_Ready(type) < 0)
......@@ -460,120 +507,167 @@ init_persist_type(PyTypeObject *type)
return 1;
}
void
INITMODULE (void)
#ifdef PY3K
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"_" MOD_NAME_PREFIX "BTree", /* m_name */
BTree_module_documentation, /* m_doc */
-1, /* m_size */
module_methods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
#endif
static PyObject*
module_init(void)
{
PyObject *m, *d, *c;
PyObject *module, *mod_dict, *interfaces, *conflicterr;
#ifdef KEY_TYPE_IS_PYOBJECT
object_ = PyTuple_GetItem(Py_None->ob_type->tp_bases, 0);
object_ = PyTuple_GetItem(Py_TYPE(Py_None)->tp_bases, 0);
if (object_ == NULL)
return;
return NULL;
#endif
sort_str = PyString_InternFromString("sort");
sort_str = INTERN("sort");
if (!sort_str)
return;
reverse_str = PyString_InternFromString("reverse");
return NULL;
reverse_str = INTERN("reverse");
if (!reverse_str)
return;
__setstate___str = PyString_InternFromString("__setstate__");
return NULL;
__setstate___str = INTERN("__setstate__");
if (!__setstate___str)
return;
_bucket_type_str = PyString_InternFromString("_bucket_type");
return NULL;
_bucket_type_str = INTERN("_bucket_type");
if (!_bucket_type_str)
return;
return NULL;
/* Grab the ConflictError class */
m = PyImport_ImportModule("BTrees.Interfaces");
if (m != NULL) {
c = PyObject_GetAttrString(m, "BTreesConflictError");
if (c != NULL)
ConflictError = c;
Py_DECREF(m);
interfaces = PyImport_ImportModule("BTrees.Interfaces");
if (interfaces != NULL)
{
conflicterr = PyObject_GetAttrString(interfaces, "BTreesConflictError");
if (conflicterr != NULL)
ConflictError = conflicterr;
Py_DECREF(interfaces);
}
if (ConflictError == NULL) {
if (ConflictError == NULL)
{
Py_INCREF(PyExc_ValueError);
ConflictError=PyExc_ValueError;
}
/* Initialize the PyPersist_C_API and the type objects. */
cPersistenceCAPI = PyCObject_Import("persistent.cPersistence", "CAPI");
#ifdef PY3K
cPersistenceCAPI = (cPersistenceCAPIstruct *)PyCapsule_Import(
"persistent.cPersistence.CAPI", 0);
#else
cPersistenceCAPI = (cPersistenceCAPIstruct *)PyCObject_Import(
"persistent.cPersistence", "CAPI");
#endif
if (cPersistenceCAPI == NULL)
return;
return NULL;
BTreeItemsType.ob_type = &PyType_Type;
BTreeIter_Type.ob_type = &PyType_Type;
#ifdef PY3K
#define _SET_TYPE(typ) ((PyObject*)(&typ))->ob_type = &PyType_Type
#else
#define _SET_TYPE(typ) (typ).ob_type = &PyType_Type
#endif
_SET_TYPE(BTreeItemsType);
_SET_TYPE(BTreeIter_Type);
BTreeIter_Type.tp_getattro = PyObject_GenericGetAttr;
BucketType.tp_new = PyType_GenericNew;
SetType.tp_new = PyType_GenericNew;
BTreeType.tp_new = PyType_GenericNew;
TreeSetType.tp_new = PyType_GenericNew;
if (!init_persist_type(&BucketType))
return;
return NULL;
if (!init_persist_type(&BTreeType))
return;
return NULL;
if (!init_persist_type(&SetType))
return;
return NULL;
if (!init_persist_type(&TreeSetType))
return;
return NULL;
if (PyDict_SetItem(BTreeType.tp_dict, _bucket_type_str,
(PyObject *)&BucketType) < 0) {
(PyObject *)&BucketType) < 0)
{
fprintf(stderr, "btree failed\n");
return;
return NULL;
}
if (PyDict_SetItem(TreeSetType.tp_dict, _bucket_type_str,
(PyObject *)&SetType) < 0) {
(PyObject *)&SetType) < 0)
{
fprintf(stderr, "bucket failed\n");
return;
return NULL;
}
/* Create the module and add the functions */
m = Py_InitModule4("_" MOD_NAME_PREFIX "BTree",
#ifdef PY3K
module = PyModule_Create(&moduledef);
#else
module = Py_InitModule4("_" MOD_NAME_PREFIX "BTree",
module_methods, BTree_module_documentation,
(PyObject *)NULL, PYTHON_API_VERSION);
#endif
/* Add some symbolic constants to the module */
d = PyModule_GetDict(m);
if (PyDict_SetItemString(d, MOD_NAME_PREFIX "Bucket",
mod_dict = PyModule_GetDict(module);
if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "Bucket",
(PyObject *)&BucketType) < 0)
return;
if (PyDict_SetItemString(d, MOD_NAME_PREFIX "BTree",
return NULL;
if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "BTree",
(PyObject *)&BTreeType) < 0)
return;
if (PyDict_SetItemString(d, MOD_NAME_PREFIX "Set",
return NULL;
if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "Set",
(PyObject *)&SetType) < 0)
return;
if (PyDict_SetItemString(d, MOD_NAME_PREFIX "TreeSet",
return NULL;
if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "TreeSet",
(PyObject *)&TreeSetType) < 0)
return;
if (PyDict_SetItemString(d, MOD_NAME_PREFIX "TreeIterator",
return NULL;
if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "TreeIterator",
(PyObject *)&BTreeIter_Type) < 0)
return;
return NULL;
/* We also want to be able to access these constants without the prefix
* so that code can more easily exchange modules (particularly the integer
* and long modules, but also others). The TreeIterator is only internal,
* so we don't bother to expose that.
*/
if (PyDict_SetItemString(d, "Bucket",
if (PyDict_SetItemString(mod_dict, "Bucket",
(PyObject *)&BucketType) < 0)
return;
if (PyDict_SetItemString(d, "BTree",
return NULL;
if (PyDict_SetItemString(mod_dict, "BTree",
(PyObject *)&BTreeType) < 0)
return;
if (PyDict_SetItemString(d, "Set",
return NULL;
if (PyDict_SetItemString(mod_dict, "Set",
(PyObject *)&SetType) < 0)
return;
if (PyDict_SetItemString(d, "TreeSet",
return NULL;
if (PyDict_SetItemString(mod_dict, "TreeSet",
(PyObject *)&TreeSetType) < 0)
return;
return NULL;
#if defined(ZODB_64BIT_INTS) && defined(NEED_LONG_LONG_SUPPORT)
if (PyDict_SetItemString(d, "using64bits", Py_True) < 0)
return;
if (PyDict_SetItemString(mod_dict, "using64bits", Py_True) < 0)
return NULL;
#else
if (PyDict_SetItemString(d, "using64bits", Py_False) < 0)
return;
if (PyDict_SetItemString(mod_dict, "using64bits", Py_False) < 0)
return NULL;
#endif
return module;
}
#ifdef PY3K
PyMODINIT_FUNC INITMODULE(void)
{
return module_init();
}
#else
PyMODINIT_FUNC INITMODULE(void)
{
module_init();
}
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -99,17 +99,8 @@ weightedUnionPy = _set_operation(_weightedUnion, IFSetPy)
weightedIntersectionPy = _set_operation(_weightedIntersection, IFSetPy)
try:
from _IFBTree import IFBucket
from _IFBTree import IFSet
from _IFBTree import IFBTree
from _IFBTree import IFTreeSet
from _IFBTree import difference
from _IFBTree import union
from _IFBTree import intersection
from _IFBTree import multiunion
from _OIBTree import weightedUnion
from _OIBTree import weightedIntersection
except ImportError: #pragma NO COVER
from ._IFBTree import IFBucket
except ImportError: #pragma NO COVER w/ C extensions
IFBucket = IFBucketPy
IFSet = IFSetPy
IFBTree = IFBTreePy
......@@ -120,6 +111,16 @@ except ImportError: #pragma NO COVER
multiunion = multiunionPy
weightedUnion = weightedUnionPy
weightedIntersection = weightedIntersectionPy
else: #pragma NO COVER w/o C extensions
from ._IFBTree import IFSet
from ._IFBTree import IFBTree
from ._IFBTree import IFTreeSet
from ._IFBTree import difference
from ._IFBTree import union
from ._IFBTree import intersection
from ._IFBTree import multiunion
from ._IFBTree import weightedUnion
from ._IFBTree import weightedIntersection
Bucket = IFBucket
Set = IFSet
......
......@@ -100,17 +100,8 @@ weightedUnionPy = _set_operation(_weightedUnion, IISetPy)
weightedIntersectionPy = _set_operation(_weightedIntersection, IISetPy)
try:
from _IIBTree import IIBucket
from _IIBTree import IISet
from _IIBTree import IIBTree
from _IIBTree import IITreeSet
from _IIBTree import difference
from _IIBTree import union
from _IIBTree import intersection
from _IIBTree import multiunion
from _IIBTree import weightedUnion
from _IIBTree import weightedIntersection
except ImportError: #pragma NO COVER
from ._IIBTree import IIBucket
except ImportError: #pragma NO COVER w/ C extensions
IIBucket = IIBucketPy
IISet = IISetPy
IIBTree = IIBTreePy
......@@ -121,6 +112,16 @@ except ImportError: #pragma NO COVER
multiunion = multiunionPy
weightedUnion = weightedUnionPy
weightedIntersection = weightedIntersectionPy
else: #pragma NO COVER w/o C extensions
from ._IIBTree import IISet
from ._IIBTree import IIBTree
from ._IIBTree import IITreeSet
from ._IIBTree import difference
from ._IIBTree import union
from ._IIBTree import intersection
from ._IIBTree import multiunion
from ._IIBTree import weightedUnion
from ._IIBTree import weightedIntersection
Bucket = IIBucket
Set = IISet
......
......@@ -83,15 +83,8 @@ intersectionPy = _set_operation(_intersection, IOSetPy)
multiunionPy = _set_operation(_multiunion, IOSetPy)
try:
from _IOBTree import IOBucket
from _IOBTree import IOSet
from _IOBTree import IOBTree
from _IOBTree import IOTreeSet
from _IOBTree import difference
from _IOBTree import union
from _IOBTree import intersection
from _IOBTree import multiunion
except ImportError: #pragma NO COVER
from ._IOBTree import IOBucket
except ImportError: #pragma NO COVER w/ C extensions
IOBucket = IOBucketPy
IOSet = IOSetPy
IOBTree = IOBTreePy
......@@ -100,6 +93,14 @@ except ImportError: #pragma NO COVER
union = unionPy
intersection = intersectionPy
multiunion = multiunionPy
else: #pragma NO COVER w/o C extensions
from ._IOBTree import IOSet
from ._IOBTree import IOBTree
from ._IOBTree import IOTreeSet
from ._IOBTree import difference
from ._IOBTree import union
from ._IOBTree import intersection
from ._IOBTree import multiunion
Bucket = IOBucket
Set = IOSet
......
......@@ -100,17 +100,8 @@ weightedUnionPy = _set_operation(_weightedUnion, LFSetPy)
weightedIntersectionPy = _set_operation(_weightedIntersection, LFSetPy)
try:
from _LFBTree import LFBucket
from _LFBTree import LFSet
from _LFBTree import LFBTree
from _LFBTree import LFTreeSet
from _LFBTree import difference
from _LFBTree import union
from _LFBTree import intersection
from _LFBTree import multiunion
from _OIBTree import weightedUnion
from _OIBTree import weightedIntersection
except ImportError: #pragma NO COVER
from ._LFBTree import LFBucket
except ImportError: #pragma NO COVER w/ C extensions
LFBucket = LFBucketPy
LFSet = LFSetPy
LFBTree = LFBTreePy
......@@ -121,6 +112,16 @@ except ImportError: #pragma NO COVER
multiunion = multiunionPy
weightedUnion = weightedUnionPy
weightedIntersection = weightedIntersectionPy
else: #pragma NO COVER w/o C extensions
from ._LFBTree import LFSet
from ._LFBTree import LFBTree
from ._LFBTree import LFTreeSet
from ._LFBTree import difference
from ._LFBTree import union
from ._LFBTree import intersection
from ._LFBTree import multiunion
from ._LFBTree import weightedUnion
from ._LFBTree import weightedIntersection
Bucket = LFBucket
Set = LFSet
......
......@@ -100,17 +100,8 @@ weightedUnionPy = _set_operation(_weightedUnion, LLSetPy)
weightedIntersectionPy = _set_operation(_weightedIntersection, LLSetPy)
try:
from _LLBTree import LLBucket
from _LLBTree import LLSet
from _LLBTree import LLBTree
from _LLBTree import LLTreeSet
from _LLBTree import difference
from _LLBTree import union
from _LLBTree import intersection
from _LLBTree import multiunion
from _LLBTree import weightedUnion
from _LLBTree import weightedIntersection
except ImportError: #pragma NO COVER
from ._LLBTree import LLBucket
except ImportError: #pragma NO COVER w/ C extensions
LLBucket = LLBucketPy
LLSet = LLSetPy
LLBTree = LLBTreePy
......@@ -121,6 +112,16 @@ except ImportError: #pragma NO COVER
multiunion = multiunionPy
weightedUnion = weightedUnionPy
weightedIntersection = weightedIntersectionPy
else: #pragma NO COVER w/o C extensions
from ._LLBTree import LLSet
from ._LLBTree import LLBTree
from ._LLBTree import LLTreeSet
from ._LLBTree import difference
from ._LLBTree import union
from ._LLBTree import intersection
from ._LLBTree import multiunion
from ._LLBTree import weightedUnion
from ._LLBTree import weightedIntersection
Bucket = LLBucket
Set = LLSet
......
......@@ -83,15 +83,8 @@ intersectionPy = _set_operation(_intersection, LOSetPy)
multiunionPy = _set_operation(_multiunion, LOSetPy)
try:
from _LOBTree import LOBucket
from _LOBTree import LOSet
from _LOBTree import LOBTree
from _LOBTree import LOTreeSet
from _LOBTree import difference
from _LOBTree import union
from _LOBTree import intersection
from _LOBTree import multiunion
except ImportError: #pragma NO COVER
from ._LOBTree import LOBucket
except ImportError: #pragma NO COVER w/ C extensions
LOBucket = LOBucketPy
LOSet = LOSetPy
LOBTree = LOBTreePy
......@@ -100,6 +93,14 @@ except ImportError: #pragma NO COVER
union = unionPy
intersection = intersectionPy
multiunion = multiunionPy
else: #pragma NO COVER w/o C extensions
from ._LOBTree import LOSet
from ._LOBTree import LOBTree
from ._LOBTree import LOTreeSet
from ._LOBTree import difference
from ._LOBTree import union
from ._LOBTree import intersection
from ._LOBTree import multiunion
Bucket = LOBucket
Set = LOSet
......
......@@ -97,16 +97,8 @@ weightedUnionPy = _set_operation(_weightedUnion, OISetPy)
weightedIntersectionPy = _set_operation(_weightedIntersection, OISetPy)
try:
from _OIBTree import OIBucket
from _OIBTree import OISet
from _OIBTree import OIBTree
from _OIBTree import OITreeSet
from _OIBTree import difference
from _OIBTree import union
from _OIBTree import intersection
from _OIBTree import weightedUnion
from _OIBTree import weightedIntersection
except ImportError: #pragma NO COVER
from ._OIBTree import OIBucket
except ImportError: #pragma NO COVER w/ C extensions
OIBucket = OIBucketPy
OISet = OISetPy
OIBTree = OIBTreePy
......@@ -116,6 +108,15 @@ except ImportError: #pragma NO COVER
intersection = intersectionPy
weightedUnion = weightedUnionPy
weightedIntersection = weightedIntersectionPy
else: #pragma NO COVER w/o C extensions
from ._OIBTree import OISet
from ._OIBTree import OIBTree
from ._OIBTree import OITreeSet
from ._OIBTree import difference
from ._OIBTree import union
from ._OIBTree import intersection
from ._OIBTree import weightedUnion
from ._OIBTree import weightedIntersection
Bucket = OIBucket
......
......@@ -98,16 +98,8 @@ weightedUnionPy = _set_operation(_weightedUnion, OLSetPy)
weightedIntersectionPy = _set_operation(_weightedIntersection, OLSetPy)
try:
from _OLBTree import OLBucket
from _OLBTree import OLSet
from _OLBTree import OLBTree
from _OLBTree import OLTreeSet
from _OLBTree import difference
from _OLBTree import union
from _OLBTree import intersection
from _OLBTree import weightedUnion
from _OLBTree import weightedIntersection
except ImportError: #pragma NO COVER
from ._OLBTree import OLBucket
except ImportError: #pragma NO COVER w/ C extensions
OLBucket = OLBucketPy
OLSet = OLSetPy
OLBTree = OLBTreePy
......@@ -117,6 +109,15 @@ except ImportError: #pragma NO COVER
intersection = intersectionPy
weightedUnion = weightedUnionPy
weightedIntersection = weightedIntersectionPy
else: #pragma NO COVER w/o C extensions
from ._OLBTree import OLSet
from ._OLBTree import OLBTree
from ._OLBTree import OLTreeSet
from ._OLBTree import difference
from ._OLBTree import union
from ._OLBTree import intersection
from ._OLBTree import weightedUnion
from ._OLBTree import weightedIntersection
Bucket = OLBucket
Set = OLSet
......
......@@ -78,14 +78,8 @@ unionPy = _set_operation(_union, OOSetPy)
intersectionPy = _set_operation(_intersection, OOSetPy)
try:
from _OOBTree import OOBucket
from _OOBTree import OOSet
from _OOBTree import OOBTree
from _OOBTree import OOTreeSet
from _OOBTree import difference
from _OOBTree import union
from _OOBTree import intersection
except ImportError: #pragma NO COVER
from ._OOBTree import OOBucket
except ImportError as e: #pragma NO COVER w/ C extensions
OOBucket = OOBucketPy
OOSet = OOSetPy
OOBTree = OOBTreePy
......@@ -93,6 +87,13 @@ except ImportError: #pragma NO COVER
difference = differencePy
union = unionPy
intersection = intersectionPy
else: #pragma NO COVER w/o C extensions
from ._OOBTree import OOSet
from ._OOBTree import OOBTree
from ._OOBTree import OOTreeSet
from ._OOBTree import difference
from ._OOBTree import union
from ._OOBTree import intersection
Bucket = OOBucket
Set = OOSet
......
......@@ -11,6 +11,7 @@
FOR A PARTICULAR PURPOSE
****************************************************************************/
#include "_compat.h"
#define SETTEMPLATE_C "$Id$\n"
......@@ -20,9 +21,11 @@ Set_insert(Bucket *self, PyObject *args)
PyObject *key;
int i;
UNLESS (PyArg_ParseTuple(args, "O", &key)) return NULL;
if ( (i=_bucket_set(self, key, Py_None, 1, 1, 0)) < 0) return NULL;
return PyInt_FromLong(i);
UNLESS (PyArg_ParseTuple(args, "O", &key))
return NULL;
if ( (i=_bucket_set(self, key, Py_None, 1, 1, 0)) < 0)
return NULL;
return INT_FROM_LONG(i);
}
/* _Set_update and _TreeSet_update are identical except for the
......@@ -55,7 +58,7 @@ _Set_update(Bucket *self, PyObject *seq)
n += ind;
}
err:
err:
Py_DECREF(iter);
if (ind < 0)
return -1;
......@@ -77,7 +80,7 @@ Set_update(Bucket *self, PyObject *args)
return NULL;
}
return PyInt_FromLong(n);
return INT_FROM_LONG(n);
}
static PyObject *
......@@ -85,8 +88,10 @@ Set_remove(Bucket *self, PyObject *args)
{
PyObject *key;
UNLESS (PyArg_ParseTuple(args, "O", &key)) return NULL;
if (_bucket_set(self, key, NULL, 0, 1, 0) < 0) return NULL;
UNLESS (PyArg_ParseTuple(args, "O", &key))
return NULL;
if (_bucket_set(self, key, NULL, 0, 1, 0) < 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
......@@ -109,7 +114,8 @@ _set_setstate(Bucket *self, PyObject *args)
return -1;
}
if ((l=PyTuple_Size(items)) < 0) return -1;
if ((l=PyTuple_Size(items)) < 0)
return -1;
for (i=self->len; --i >= 0; )
{
......@@ -125,7 +131,8 @@ _set_setstate(Bucket *self, PyObject *args)
if (l > self->size)
{
UNLESS (keys=BTree_Realloc(self->keys, sizeof(KEY_TYPE)*l)) return -1;
UNLESS (keys=BTree_Realloc(self->keys, sizeof(KEY_TYPE)*l))
return -1;
self->keys=keys;
self->size=l;
}
......@@ -134,7 +141,8 @@ _set_setstate(Bucket *self, PyObject *args)
{
k=PyTuple_GET_ITEM(items, i);
COPY_KEY_FROM_ARG(self->keys[i], k, copied);
UNLESS (copied) return -1;
UNLESS (copied)
return -1;
INCREF_KEY(self->keys[i]);
}
......@@ -154,13 +162,15 @@ set_setstate(Bucket *self, PyObject *args)
{
int r;
UNLESS (PyArg_ParseTuple(args, "O", &args)) return NULL;
UNLESS (PyArg_ParseTuple(args, "O", &args))
return NULL;
PER_PREVENT_DEACTIVATION(self);
r=_set_setstate(self, args);
PER_UNUSE(self);
if (r < 0) return NULL;
if (r < 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
......@@ -172,7 +182,7 @@ static struct PyMethodDef Set_methods[] = {
{"__setstate__", (PyCFunction) set_setstate, METH_VARARGS,
"__setstate__() -- Set the state of the object"},
{"keys", (PyCFunction) bucket_keys, METH_KEYWORDS,
{"keys", (PyCFunction) bucket_keys, METH_VARARGS | METH_KEYWORDS,
"keys() -- Return the keys"},
{"has_key", (PyCFunction) bucket_has_key, METH_O,
......@@ -190,10 +200,12 @@ static struct PyMethodDef Set_methods[] = {
"If an argument is given, find the minimum >= the argument"},
#ifdef PERSISTENT
{"_p_resolveConflict", (PyCFunction) bucket__p_resolveConflict, METH_VARARGS,
{"_p_resolveConflict",
(PyCFunction) bucket__p_resolveConflict, METH_VARARGS,
"_p_resolveConflict() -- Reinitialize from a newly created copy"},
{"_p_deactivate", (PyCFunction) bucket__p_deactivate, METH_KEYWORDS,
{"_p_deactivate",
(PyCFunction) bucket__p_deactivate, METH_VARARGS | METH_KEYWORDS,
"_p_deactivate() -- Reinitialize from a newly created copy"},
#endif
......@@ -235,12 +247,14 @@ set_repr(Bucket *self)
PyObject *r, *t;
if (!format)
format = PyString_FromString(MOD_NAME_PREFIX "Set(%s)");
UNLESS (t = PyTuple_New(1)) return NULL;
UNLESS (r = bucket_keys(self, NULL, NULL)) goto err;
format = TEXT_FROM_STRING(MOD_NAME_PREFIX "Set(%s)");
UNLESS (t = PyTuple_New(1))
return NULL;
UNLESS (r = bucket_keys(self, NULL, NULL))
goto err;
PyTuple_SET_ITEM(t, 0, r);
r = t;
ASSIGN(r, PyString_Format(format, r));
ASSIGN(r, TEXT_FORMAT(format, r));
return r;
err:
Py_DECREF(t);
......@@ -291,8 +305,7 @@ static PySequenceMethods set_as_sequence = {
};
static PyTypeObject SetType = {
PyObject_HEAD_INIT(NULL) /* PyPersist_Type */
0, /* ob_size */
PyVarObject_HEAD_INIT(NULL, 0) /* PyPersist_Type */
MODULE_NAME MOD_NAME_PREFIX "Set", /* tp_name */
sizeof(Bucket), /* tp_basicsize */
0, /* tp_itemsize */
......@@ -311,7 +324,8 @@ static PyTypeObject SetType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
(traverseproc)bucket_traverse, /* tp_traverse */
......@@ -339,7 +353,8 @@ nextSet(SetIteration *i)
if (i->position >= 0)
{
UNLESS(PER_USE(BUCKET(i->set))) return -1;
UNLESS(PER_USE(BUCKET(i->set)))
return -1;
if (i->position)
{
......
......@@ -11,6 +11,7 @@
FOR A PARTICULAR PURPOSE
****************************************************************************/
#include "_compat.h"
#define TREESETTEMPLATE_C "$Id$\n"
......@@ -25,7 +26,7 @@ TreeSet_insert(BTree *self, PyObject *args)
i = _BTree_set(self, key, Py_None, 1, 1);
if (i < 0)
return NULL;
return PyInt_FromLong(i);
return INT_FROM_LONG(i);
}
/* _Set_update and _TreeSet_update are identical except for the
......@@ -42,9 +43,11 @@ _TreeSet_update(BTree *self, PyObject *seq)
if (iter == NULL)
return -1;
while (1) {
while (1)
{
v = PyIter_Next(iter);
if (v == NULL) {
if (v == NULL)
{
if (PyErr_Occurred())
goto err;
else
......@@ -58,7 +61,7 @@ _TreeSet_update(BTree *self, PyObject *seq)
n += ind;
}
err:
err:
Py_DECREF(iter);
if (ind < 0)
return -1;
......@@ -74,13 +77,14 @@ TreeSet_update(BTree *self, PyObject *args)
if (!PyArg_ParseTuple(args, "|O:update", &seq))
return NULL;
if (seq) {
if (seq)
{
n = _TreeSet_update(self, seq);
if (n < 0)
return NULL;
}
return PyInt_FromLong(n);
return INT_FROM_LONG(n);
}
......@@ -89,8 +93,10 @@ TreeSet_remove(BTree *self, PyObject *args)
{
PyObject *key;
UNLESS (PyArg_ParseTuple(args, "O", &key)) return NULL;
if (_BTree_set(self, key, NULL, 0, 1) < 0) return NULL;
UNLESS (PyArg_ParseTuple(args, "O", &key))
return NULL;
if (_BTree_set(self, key, NULL, 0, 1) < 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
......@@ -100,18 +106,21 @@ TreeSet_setstate(BTree *self, PyObject *args)
{
int r;
if (!PyArg_ParseTuple(args,"O",&args)) return NULL;
if (!PyArg_ParseTuple(args,"O",&args))
return NULL;
PER_PREVENT_DEACTIVATION(self);
r=_BTree_setstate(self, args, 1);
PER_UNUSE(self);
if (r < 0) return NULL;
if (r < 0)
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
static struct PyMethodDef TreeSet_methods[] = {
static struct PyMethodDef TreeSet_methods[] =
{
{"__getstate__", (PyCFunction) BTree_getstate, METH_NOARGS,
"__getstate__() -> state\n\n"
"Return the picklable state of the TreeSet."},
......@@ -124,7 +133,7 @@ static struct PyMethodDef TreeSet_methods[] = {
"has_key(key)\n\n"
"Return true if the TreeSet contains the given key."},
{"keys", (PyCFunction) BTree_keys, METH_KEYWORDS,
{"keys", (PyCFunction) BTree_keys, METH_VARARGS | METH_KEYWORDS,
"keys([min, max]) -> list of keys\n\n"
"Returns the keys of the TreeSet. If min and max are supplied, only\n"
"keys greater than min and less than max are returned."},
......@@ -158,10 +167,12 @@ static struct PyMethodDef TreeSet_methods[] = {
"Perform sanity check on TreeSet, and raise exception if flawed."},
#ifdef PERSISTENT
{"_p_resolveConflict", (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
{"_p_resolveConflict",
(PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
"_p_resolveConflict() -- Reinitialize from a newly created copy"},
{"_p_deactivate", (PyCFunction) BTree__p_deactivate, METH_KEYWORDS,
{"_p_deactivate",
(PyCFunction) BTree__p_deactivate, METH_VARARGS | METH_KEYWORDS,
"_p_deactivate()\n\nReinitialize from a newly created copy."},
#endif
{NULL, NULL} /* sentinel */
......@@ -198,10 +209,10 @@ TreeSet_init(PyObject *self, PyObject *args, PyObject *kwds)
return 0;
}
static PyTypeObject TreeSetType = {
PyObject_HEAD_INIT(NULL) /* PyPersist_Type */
0, /* ob_size */
MODULE_NAME MOD_NAME_PREFIX "TreeSet",/* tp_name */
static PyTypeObject TreeSetType =
{
PyVarObject_HEAD_INIT(NULL, 0)
MODULE_NAME MOD_NAME_PREFIX "TreeSet", /* tp_name */
sizeof(BTree), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)BTree_dealloc, /* tp_dealloc */
......@@ -219,7 +230,8 @@ static PyTypeObject TreeSetType = {
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
(traverseproc)BTree_traverse, /* tp_traverse */
......
......@@ -25,10 +25,17 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "IF"
#define INITMODULE init_IFBTree
#define DEFAULT_MAX_BUCKET_SIZE 120
#define DEFAULT_MAX_BTREE_SIZE 500
#include "_compat.h"
#include "intkeymacros.h"
#include "floatvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__IFBTree
#else
#define INITMODULE init_IFBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -25,10 +25,17 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "II"
#define INITMODULE init_IIBTree
#define DEFAULT_MAX_BUCKET_SIZE 120
#define DEFAULT_MAX_BTREE_SIZE 500
#include "_compat.h"
#include "intkeymacros.h"
#include "intvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__IIBTree
#else
#define INITMODULE init_IIBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -23,10 +23,17 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "IO"
#define DEFAULT_MAX_BUCKET_SIZE 60
#define DEFAULT_MAX_BTREE_SIZE 500
#define INITMODULE init_IOBTree
#include "_compat.h"
#include "intkeymacros.h"
#include "objectvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__IOBTree
#else
#define INITMODULE init_IOBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -25,12 +25,19 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "LF"
#define INITMODULE init_LFBTree
#define DEFAULT_MAX_BUCKET_SIZE 120
#define DEFAULT_MAX_BTREE_SIZE 500
#define ZODB_64BIT_INTS
#include "_compat.h"
#include "intkeymacros.h"
#include "floatvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__LFBTree
#else
#define INITMODULE init_LFBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -25,12 +25,19 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "LL"
#define INITMODULE init_LLBTree
#define DEFAULT_MAX_BUCKET_SIZE 120
#define DEFAULT_MAX_BTREE_SIZE 500
#define ZODB_64BIT_INTS
#include "_compat.h"
#include "intkeymacros.h"
#include "intvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__LLBTree
#else
#define INITMODULE init_LLBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -23,12 +23,19 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "LO"
#define DEFAULT_MAX_BUCKET_SIZE 60
#define DEFAULT_MAX_BTREE_SIZE 500
#define INITMODULE init_LOBTree
#define ZODB_64BIT_INTS
#include "_compat.h"
#include "intkeymacros.h"
#include "objectvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__LOBTree
#else
#define INITMODULE init_LOBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -23,10 +23,17 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "OI"
#define INITMODULE init_OIBTree
#define DEFAULT_MAX_BUCKET_SIZE 60
#define DEFAULT_MAX_BTREE_SIZE 250
#include "_compat.h"
#include "objectkeymacros.h"
#include "intvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__OIBTree
#else
#define INITMODULE init_OIBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -23,12 +23,19 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "OL"
#define INITMODULE init_OLBTree
#define DEFAULT_MAX_BUCKET_SIZE 60
#define DEFAULT_MAX_BTREE_SIZE 250
#define ZODB_64BIT_INTS
#include "_compat.h"
#include "objectkeymacros.h"
#include "intvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__OLBTree
#else
#define INITMODULE init_OLBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -23,10 +23,17 @@
#define PERSISTENT
#define MOD_NAME_PREFIX "OO"
#define INITMODULE init_OOBTree
#define DEFAULT_MAX_BUCKET_SIZE 30
#define DEFAULT_MAX_BTREE_SIZE 250
#include "_compat.h"
#include "objectkeymacros.h"
#include "objectvaluemacros.h"
#ifdef PY3K
#define INITMODULE PyInit__OOBTree
#else
#define INITMODULE init_OOBTree
#endif
#include "BTreeModuleTemplate.c"
......@@ -21,6 +21,10 @@ from struct import error as struct_error
from persistent import Persistent
from .Interfaces import BTreesConflictError
from ._compat import PY3
from ._compat import cmp
from ._compat import int_types
from ._compat import xrange
_marker = object()
......@@ -156,7 +160,7 @@ class _SetIteration(object):
__slots__ = ('to_iterate',
'useValues',
'_next',
'_iter',
'active',
'position',
'key',
......@@ -172,6 +176,9 @@ class _SetIteration(object):
try:
itmeth = to_iterate.iteritems
except AttributeError:
if PY3 and isinstance(to_iterate, dict): #pragma NO COVER Py3k
itmeth = to_iterate.items().__iter__
else:
itmeth = to_iterate.__iter__
useValues = False
else:
......@@ -180,7 +187,7 @@ class _SetIteration(object):
itmeth = to_iterate.__iter__
self.useValues = useValues
self._next = itmeth().next
self._iter = itmeth()
self.active = True
self.position = 0
self.key = _marker
......@@ -190,9 +197,9 @@ class _SetIteration(object):
def advance(self):
try:
if self.useValues:
self.key, self.value = self._next()
self.key, self.value = next(self._iter)
else:
self.key = self._next()
self.key = next(self._iter)
self.position += 1
except StopIteration:
self.active = False
......@@ -200,6 +207,15 @@ class _SetIteration(object):
return self
def _no_default_comparison(key):
# Enforce test that key has non-default comparison.
lt = getattr(key, '__lt__', None)
if lt is not None:
if getattr(lt, '__objclass__', None) is object: #pragma NO COVER Py3k
lt = None
if (lt is None and
getattr(key, '__cmp__', None) is None):
raise TypeError("Can't use default __cmp__")
class Bucket(_BucketBase):
......@@ -237,10 +253,7 @@ class Bucket(_BucketBase):
raise TypeError('items must be a sequence of 2-tuples')
def __setitem__(self, key, value):
# Enforce test that key has non-default comparison.
if ( getattr(key, '__lt__', None) is None and
getattr(key, '__cmp__', None) is None):
raise TypeError("Can't use default __cmp__")
_no_default_comparison(key)
self._set(self._to_key(key), self._to_value(value))
def __delitem__(self, key):
......@@ -298,7 +311,7 @@ class Bucket(_BucketBase):
def _split(self, index=-1):
if index < 0 or index >= len(self._keys):
index = len(self._keys) / 2
index = len(self._keys) // 2
new_instance = self.__class__()
new_instance._keys = self._keys[index:]
new_instance._values = self._values[index:]
......@@ -553,7 +566,7 @@ class Set(_BucketBase):
def _split(self, index=-1):
if index < 0 or index >= len(self._keys):
index = len(self._keys) / 2
index = len(self._keys) // 2
new_instance = self.__class__()
new_instance._keys = self._keys[index:]
del self._keys[index:]
......@@ -727,10 +740,7 @@ class _Tree(_Base):
set(*i)
def __setitem__(self, key, value):
# Enforce test that key has non-default comparison.
if ( getattr(key, '__lt__', None) is None and
getattr(key, '__cmp__', None) is None):
raise TypeError("Can't use default __cmp__")
_no_default_comparison(key)
self._set(self._to_key(key), self._to_value(value))
def __delitem__(self, key):
......@@ -742,6 +752,7 @@ class _Tree(_Base):
def __nonzero__(self):
return bool(self._data)
__bool__ = __nonzero__ #Py3k rename
def __len__(self):
l = 0
......@@ -760,7 +771,7 @@ class _Tree(_Base):
if data:
lo = 0
hi = len(data)
i = hi//2
i = hi // 2
while i > lo:
cmp_ = cmp(data[i].key, key)
if cmp_ < 0:
......@@ -769,7 +780,7 @@ class _Tree(_Base):
hi = i
else:
break
i = (lo+hi)//2
i = (lo + hi) // 2
return i
return -1
......@@ -882,7 +893,7 @@ class _Tree(_Base):
def _split(self, index=None):
data = self._data
if index is None:
index = len(data)//2
index = len(data) // 2
next = self.__class__()
next._data = data[index:]
......@@ -1083,7 +1094,7 @@ class _TreeItems(object):
while i > self.index:
try:
self.v = self.it.next()
self.v = next(self.it)
except StopIteration:
raise IndexError(i)
else:
......@@ -1158,7 +1169,6 @@ class TreeSet(_Tree):
__slots__ = ()
#_next = None
def add(self, key):
return self._set(self._to_key(key))[0]
......@@ -1270,6 +1280,14 @@ def intersection(set_type, o1, o2):
i2.advance()
return result
def _prepMergeIterators(o1, o2):
MERGE_DEFAULT = getattr(o1, 'MERGE_DEFAULT', None)
if MERGE_DEFAULT is None:
raise TypeError("invalid set operation")
i1 = _SetIteration(o1, True, MERGE_DEFAULT)
i2 = _SetIteration(o2, True, MERGE_DEFAULT)
return i1, i2
def weightedUnion(set_type, o1, o2, w1=1, w2=1):
if o1 is None:
if o2 is None:
......@@ -1277,9 +1295,7 @@ def weightedUnion(set_type, o1, o2, w1=1, w2=1):
return w2, o2
if o2 is None:
return w1, o1
MERGE_DEFAULT = getattr(o1, 'MERGE_DEFAULT', None)
i1 = _SetIteration(o1, True, MERGE_DEFAULT)
i2 = _SetIteration(o2, True, MERGE_DEFAULT)
i1, i2 = _prepMergeIterators(o1, o2)
MERGE = getattr(o1, 'MERGE', None)
if MERGE is None and i1.useValues and i2.useValues:
raise TypeError("invalid set operation")
......@@ -1287,12 +1303,6 @@ def weightedUnion(set_type, o1, o2, w1=1, w2=1):
if (not i1.useValues) and i2.useValues:
i1, i2 = i2, i1
w1, w2 = w2, w1
if MERGE_DEFAULT is None:
if i1.useValues:
if (not i2.useValues):
raise TypeError("invalid set operation")
else:
raise TypeError("invalid set operation")
_merging = i1.useValues or i2.useValues
if _merging:
result = o1._mapping_type()
......@@ -1333,22 +1343,13 @@ def weightedIntersection(set_type, o1, o2, w1=1, w2=1):
return w2, o2
if o2 is None:
return w1, o1
MERGE_DEFAULT = getattr(o1, 'MERGE_DEFAULT', None)
i1 = _SetIteration(o1, True, MERGE_DEFAULT)
i2 = _SetIteration(o2, True, MERGE_DEFAULT)
i1, i2 = _prepMergeIterators(o1, o2)
MERGE = getattr(o1, 'MERGE', None)
if MERGE is None and i1.useValues and i2.useValues:
raise TypeError("invalid set operation")
MERGE_WEIGHT = getattr(o1, 'MERGE_WEIGHT')
if (not i1.useValues) and i2.useValues:
i1, i2 = i2, i1
w1, w2 = w2, w1
if MERGE_DEFAULT is None:
if i1.useValues:
if (not i2.useValues):
raise TypeError("invalid set operation")
else:
raise TypeError("invalid set operation")
_merging = i1.useValues or i2.useValues
if _merging:
result = o1._mapping_type()
......@@ -1384,7 +1385,6 @@ def multiunion(set_type, seqs):
def to_ob(self, v):
return v
int_types = int, long
def to_int(self, v):
try:
# XXX Python 2.6 doesn't truncate, it spews a warning.
......@@ -1420,10 +1420,10 @@ def to_long(self, v):
return int(v)
def to_str(l):
def to_bytes(l):
def to(self, v):
if not (isinstance(v, str) and len(v) == l):
raise TypeError("%s-character string expected" % l)
if not (isinstance(v, bytes) and len(v) == l):
raise TypeError("%s-byte array expected" % l)
return v
return to
......
/* Straddle Python 2 / 3 */
#ifndef BTREES__COMPAT_H
#define BTREES__COMPAT_H
#include "Python.h"
#ifdef INTERN
#undef INTERN
#endif
#ifdef INT_FROM_LONG
#undef INT_FROM_LONG
#endif
#ifdef INT_CHECK
#undef INT_CHECK
#endif
#if PY_MAJOR_VERSION >= 3
#define PY3K
#define INTERN PyUnicode_InternFromString
#define INT_FROM_LONG(x) PyLong_FromLong(x)
#define INT_CHECK(x) PyLong_Check(x)
#define INT_AS_LONG(x) PyLong_AS_LONG(x)
#define INT_GETMAX(x) 2<<31
#define TEXT_FROM_STRING PyUnicode_FromString
#define TEXT_FORMAT PyUnicode_Format
#define COMPARE(lhs, rhs) \
PyObject_RichCompareBool((lhs), (rhs), Py_LT) > 0 ? -1 : \
(PyObject_RichCompareBool((lhs), (rhs), Py_EQ) > 0 ? 0 : 1)
#else
#define INTERN PyString_InternFromString
#define INT_FROM_LONG(x) PyInt_FromLong(x)
#define INT_CHECK(x) PyInt_Check(x)
#define INT_AS_LONG(x) PyInt_AS_LONG(x)
#define INT_GETMAX(x) PyInt_GetMax(x)
#define TEXT_FROM_STRING PyString_FromString
#define TEXT_FORMAT PyString_Format
#define COMPARE(lhs, rhs) PyObject_Compare((lhs), (rhs))
#endif
#endif /* BTREES__COMPAT_H */
##############################################################################
#
# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import sys
if sys.version_info[0] < 3: #pragma NO COVER Python2
PY2 = True
PY3 = False
from StringIO import StringIO
BytesIO = StringIO
int_types = int, long
xrange = xrange
cmp = cmp
_bytes = str
def _ascii(x):
return bytes(x)
def _u(s, encoding='unicode_escape'):
return unicode(s, encoding)
else: #pragma NO COVER Python3
PY2 = False
PY3 = True
from io import StringIO
from io import BytesIO
int_types = int,
xrange = range
def cmp(x, y):
return (x > y) - (y > x)
_bytes = bytes
def _ascii(x):
return bytes(x, 'ascii')
def _u(s, encoding=None):
if encoding is None:
return s
return str(s, encoding)
......@@ -31,23 +31,24 @@ typedef unsigned char char6[6];
#define PERSISTENT
#define MOD_NAME_PREFIX "fs"
#define INITMODULE init_fsBTree
#define DEFAULT_MAX_BUCKET_SIZE 500
#define DEFAULT_MAX_BTREE_SIZE 500
#include "_compat.h"
/*#include "intkeymacros.h"*/
#define KEYMACROS_H "$Id$\n"
#define KEY_TYPE char2
#undef KEY_TYPE_IS_PYOBJECT
#define KEY_CHECK(K) (PyString_Check(K) && PyString_GET_SIZE(K)==2)
#define KEY_CHECK(K) (PyBytes_Check(K) && PyBytes_GET_SIZE(K)==2)
#define TEST_KEY_SET_OR(V, K, T) if ( ( (V) = ((*(K) < *(T) || (*(K) == *(T) && (K)[1] < (T)[1])) ? -1 : ((*(K) == *(T) && (K)[1] == (T)[1]) ? 0 : 1)) ), 0 )
#define DECREF_KEY(KEY)
#define INCREF_KEY(k)
#define COPY_KEY(KEY, E) (*(KEY)=*(E), (KEY)[1]=(E)[1])
#define COPY_KEY_TO_OBJECT(O, K) O=PyString_FromStringAndSize((const char*)K,2)
#define COPY_KEY_TO_OBJECT(O, K) O=PyBytes_FromStringAndSize((const char*)K,2)
#define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) \
if (KEY_CHECK(ARG)) memcpy(TARGET, PyString_AS_STRING(ARG), 2); else { \
if (KEY_CHECK(ARG)) memcpy(TARGET, PyBytes_AS_STRING(ARG), 2); else { \
PyErr_SetString(PyExc_TypeError, "expected two-character string key"); \
(STATUS)=0; }
......@@ -59,10 +60,10 @@ typedef unsigned char char6[6];
#define DECREF_VALUE(k)
#define INCREF_VALUE(k)
#define COPY_VALUE(V, E) (memcpy(V, E, 6))
#define COPY_VALUE_TO_OBJECT(O, K) O=PyString_FromStringAndSize((const char*)K,6)
#define COPY_VALUE_TO_OBJECT(O, K) O=PyBytes_FromStringAndSize((const char*)K,6)
#define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
if ((PyString_Check(ARG) && PyString_GET_SIZE(ARG)==6)) \
memcpy(TARGET, PyString_AS_STRING(ARG), 6); else { \
if ((PyBytes_Check(ARG) && PyBytes_GET_SIZE(ARG)==6)) \
memcpy(TARGET, PyBytes_AS_STRING(ARG), 6); else { \
PyErr_SetString(PyExc_TypeError, "expected six-character string key"); \
(STATUS)=0; }
......@@ -70,20 +71,29 @@ typedef unsigned char char6[6];
#include "Python.h"
static PyObject *bucket_toString(PyObject *self);
static PyObject *bucket_toBytes(PyObject *self);
static PyObject *bucket_fromString(PyObject *self, PyObject *state);
static PyObject *bucket_fromBytes(PyObject *self, PyObject *state);
#define EXTRA_BUCKET_METHODS \
{"toString", (PyCFunction) bucket_toString, METH_NOARGS, \
"toString() -- Return the state as a string"}, \
{"fromString", (PyCFunction) bucket_fromString, METH_O, \
"fromString(s) -- Set the state of the object from a string"}, \
{"toBytes", (PyCFunction) bucket_toBytes, METH_NOARGS, \
"toBytes() -- Return the state as a bytes array"}, \
{"fromBytes", (PyCFunction) bucket_fromBytes, METH_O, \
"fromSBytes(s) -- Set the state of the object from a bytes array"}, \
{"toString", (PyCFunction) bucket_toBytes, METH_NOARGS, \
"toString() -- Deprecated alias for 'toBytes'"}, \
{"fromString", (PyCFunction) bucket_fromBytes, METH_O, \
"fromString(s) -- Deprecated alias for 'fromBytes'"}, \
#ifdef PY3K
#define INITMODULE PyInit__fsBTree
#else
#define INITMODULE init_fsBTree
#endif
#include "BTreeModuleTemplate.c"
static PyObject *
bucket_toString(PyObject *oself)
bucket_toBytes(PyObject *oself)
{
Bucket *self = (Bucket *)oself;
PyObject *items = NULL;
......@@ -93,11 +103,11 @@ bucket_toString(PyObject *oself)
len = self->len;
items = PyString_FromStringAndSize(NULL, len*8);
items = PyBytes_FromStringAndSize(NULL, len*8);
if (items == NULL)
goto err;
memcpy(PyString_AS_STRING(items), self->keys, len*2);
memcpy(PyString_AS_STRING(items)+len*2, self->values, len*6);
memcpy(PyBytes_AS_STRING(items), self->keys, len*2);
memcpy(PyBytes_AS_STRING(items)+len*2, self->values, len*6);
PER_UNUSE(self);
return items;
......@@ -109,14 +119,14 @@ bucket_toString(PyObject *oself)
}
static PyObject *
bucket_fromString(PyObject *oself, PyObject *state)
bucket_fromBytes(PyObject *oself, PyObject *state)
{
Bucket *self = (Bucket *)oself;
int len;
KEY_TYPE *keys;
VALUE_TYPE *values;
len = PyString_Size(state);
len = PyBytes_Size(state);
if (len < 0)
return NULL;
......@@ -144,8 +154,8 @@ bucket_fromString(PyObject *oself, PyObject *state)
self->size = len;
}
memcpy(self->keys, PyString_AS_STRING(state), len*2);
memcpy(self->values, PyString_AS_STRING(state)+len*2, len*6);
memcpy(self->keys, PyBytes_AS_STRING(state), len*2);
memcpy(self->values, PyBytes_AS_STRING(state)+len*2, len*6);
self->len = len;
......
......@@ -378,30 +378,30 @@ class Printer(Walker): #pragma NO COVER
def visit_btree(self, obj, path, parent, is_mapping,
keys, kids, lo, hi):
indent = " " * len(path)
print "%s%s %s with %d children" % (
print("%s%s %s with %d children" % (
indent,
".".join(map(str, path)),
type_and_adr(obj),
len(kids))
len(kids)))
indent += " "
n = len(keys)
for i in range(n):
print "%skey %d: %r" % (indent, i, keys[i])
print("%skey %d: %r" % (indent, i, keys[i]))
def visit_bucket(self, obj, path, parent, is_mapping,
keys, values, lo, hi):
indent = " " * len(path)
print "%s%s %s with %d keys" % (
print("%s%s %s with %d keys" % (
indent,
".".join(map(str, path)),
type_and_adr(obj),
len(keys))
len(keys)))
indent += " "
n = len(keys)
for i in range(n):
print "%skey %d: %r" % (indent, i, keys[i]),
print("%skey %d: %r" % (indent, i, keys[i]),)
if is_mapping:
print "value %r" % (values[i],)
print("value %r" % (values[i],))
def check(btree):
"""Check internal value-based invariants in a BTree or TreeSet.
......
......@@ -13,7 +13,7 @@
#define COPY_VALUE_TO_OBJECT(O, K) O=PyFloat_FromDouble(K)
#define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
if (PyFloat_Check(ARG)) TARGET = (float)PyFloat_AsDouble(ARG); \
else if (PyInt_Check(ARG)) TARGET = (float)PyInt_AsLong(ARG); \
else if (INT_CHECK(ARG)) TARGET = (float)INT_AS_LONG(ARG); \
else { \
PyErr_SetString(PyExc_TypeError, "expected float or int value"); \
(STATUS)=0; (TARGET)=0; }
......
......@@ -14,10 +14,11 @@
# fsBTrees are data structures used for ZODB FileStorage. They are not
# expected to be "public" excpect to FileStorage.
# Each item in an fsBTree maps a two-byte key to a six-byte value.
__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
'fsBucket', 'fsSet', 'fsBTree', 'fsTreeSet',
'union', 'intersection', 'difference', 'multiunion',
'union', 'intersection', 'difference',
)
......@@ -30,16 +31,15 @@ from ._base import Tree as BTree
from ._base import TreeSet
from ._base import difference as _difference
from ._base import intersection as _intersection
from ._base import multiunion as _multiunion
from ._base import set_operation as _set_operation
from ._base import to_str as _to_str
from ._base import to_bytes as _to_bytes
from ._base import union as _union
_BUCKET_SIZE = 500
_TREE_SIZE = 500
using64bits = False
_to_key = _to_str(2)
_to_value = _to_str(6)
_to_key = _to_bytes(2)
_to_value = _to_bytes(6)
class fsBucketPy(Bucket):
......@@ -47,11 +47,8 @@ class fsBucketPy(Bucket):
_to_key = _to_key
_to_value = _to_value
def MERGE_WEIGHT(self, value, weight):
return value
def toString(self):
return ''.join(self._keys) + ''.join(self._values)
return b''.join(self._keys) + b''.join(self._values)
def fromString(self, v):
length = len(v)
......@@ -77,8 +74,6 @@ class fsBTreePy(BTree):
MAX_SIZE = _TREE_SIZE
_to_key = _to_key
_to_value = _to_value
def MERGE_WEIGHT(self, value, weight):
return value
class fsTreeSetPy(TreeSet):
......@@ -104,18 +99,10 @@ fsTreeSetPy._set_type = fsTreeSetPy._bucket_type = fsSetPy
differencePy = _set_operation(_difference, fsSetPy)
unionPy = _set_operation(_union, fsSetPy)
intersectionPy = _set_operation(_intersection, fsSetPy)
multiunionPy = _set_operation(_multiunion, fsSetPy)
try:
from _fsBTree import fsBucket
from _fsBTree import fsSet
from _fsBTree import fsBTree
from _fsBTree import fsTreeSet
from _fsBTree import difference
from _fsBTree import union
from _fsBTree import intersection
from _fsBTree import multiunion
except ImportError: #pragma NO COVER
from ._fsBTree import fsBucket
except ImportError: #pragma NO COVER w/ C extensions
fsBucket = fsBucketPy
fsSet = fsSetPy
fsBTree = fsBTreePy
......@@ -123,7 +110,13 @@ except ImportError: #pragma NO COVER
difference = differencePy
union = unionPy
intersection = intersectionPy
multiunion = multiunionPy
else: #pragma NO COVER w/o C extensions
from ._fsBTree import fsSet
from ._fsBTree import fsBTree
from ._fsBTree import fsTreeSet
from ._fsBTree import difference
from ._fsBTree import union
from ._fsBTree import intersection
Bucket = fsBucket
Set = fsSet
......
......@@ -4,26 +4,23 @@
#ifdef ZODB_64BIT_INTS
/* PY_LONG_LONG as key */
#define NEED_LONG_LONG_SUPPORT
#define NEED_LONG_LONG_KEYS
#define KEY_TYPE PY_LONG_LONG
#define KEY_CHECK longlong_check
#define COPY_KEY_TO_OBJECT(O, K) O=longlong_as_object(K)
#define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) \
if (PyInt_Check(ARG)) TARGET=PyInt_AS_LONG(ARG); else \
if (longlong_check(ARG)) TARGET=PyLong_AsLongLong(ARG); else \
if (PyLong_Check(ARG)) { \
PyErr_SetString(PyExc_ValueError, "long integer out of range"); \
(STATUS)=0; (TARGET)=0; } \
else { \
PyErr_SetString(PyExc_TypeError, "expected integer key"); \
(STATUS)=0; (TARGET)=0; }
if (!longlong_convert((ARG), &TARGET)) \
{ \
(STATUS)=0; (TARGET)=0; \
}
#else
/* C int as key */
#define KEY_TYPE int
#define KEY_CHECK PyInt_Check
#define COPY_KEY_TO_OBJECT(O, K) O=PyInt_FromLong(K)
#define KEY_CHECK INT_CHECK
#define COPY_KEY_TO_OBJECT(O, K) O=INT_FROM_LONG(K)
#define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) \
if (PyInt_Check(ARG)) { \
long vcopy = PyInt_AS_LONG(ARG); \
if (INT_CHECK(ARG)) { \
long vcopy = INT_AS_LONG(ARG); \
if ((int)vcopy != vcopy) { \
PyErr_SetString(PyExc_TypeError, "integer out of range"); \
(STATUS)=0; (TARGET)=0; \
......
......@@ -7,7 +7,7 @@
#define VALUE_PARSE "L"
#define COPY_VALUE_TO_OBJECT(O, K) O=longlong_as_object(K)
#define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
if (PyInt_Check(ARG)) TARGET=PyInt_AS_LONG(ARG); else \
if (INT_CHECK(ARG)) TARGET=INT_AS_LONG(ARG); else \
if (longlong_check(ARG)) TARGET=PyLong_AsLongLong(ARG); else \
if (PyLong_Check(ARG)) { \
PyErr_SetString(PyExc_ValueError, "long integer out of range"); \
......@@ -18,11 +18,11 @@
#else
#define VALUE_TYPE int
#define VALUE_PARSE "i"
#define COPY_VALUE_TO_OBJECT(O, K) O=PyInt_FromLong(K)
#define COPY_VALUE_TO_OBJECT(O, K) O=INT_FROM_LONG(K)
#define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
if (PyInt_Check(ARG)) { \
long vcopy = PyInt_AS_LONG(ARG); \
if (INT_CHECK(ARG)) { \
long vcopy = INT_AS_LONG(ARG); \
if ((int)vcopy != vcopy) { \
PyErr_SetString(PyExc_TypeError, "integer out of range"); \
(STATUS)=0; (TARGET)=0; \
......
......@@ -3,8 +3,9 @@
#define KEY_TYPE_IS_PYOBJECT
#include "Python.h"
#include "_compat.h"
static PyObject *object_;
static PyObject *object_; /* initialized in BTreeModuleTemplate init */
static int
check_argument_cmp(PyObject *arg)
......@@ -15,15 +16,12 @@ check_argument_cmp(PyObject *arg)
/* arg->ob_type->tp_compare, */
/* ((PyTypeObject *)object_)->ob_type->tp_compare); */
if (arg->ob_type->tp_richcompare == NULL
&&
#if PY_MAJOR_VERSION==2 && PY_MINOR_VERSION < 6
arg->ob_type->tp_compare == NULL
#ifdef PY3K
if (Py_TYPE(arg)->tp_richcompare == Py_TYPE(object_)->tp_richcompare)
#else
arg->ob_type->tp_compare ==
((PyTypeObject *)object_)->ob_type->tp_compare
if (Py_TYPE(arg)->tp_richcompare == NULL
&& Py_TYPE(arg)->tp_compare == Py_TYPE(object_)->tp_compare)
#endif
)
{
PyErr_SetString(PyExc_TypeError, "Object has default comparison");
return 0;
......@@ -31,7 +29,8 @@ check_argument_cmp(PyObject *arg)
return 1;
}
#define TEST_KEY_SET_OR(V, KEY, TARGET) if ( ( (V) = PyObject_Compare((KEY),(TARGET)) ), PyErr_Occurred() )
#define TEST_KEY_SET_OR(V, KEY, TARGET) \
if ( ( (V) = COMPARE((KEY),(TARGET)) ), PyErr_Occurred() )
#define INCREF_KEY(k) Py_INCREF(k)
#define DECREF_KEY(KEY) Py_DECREF(KEY)
#define COPY_KEY(KEY, E) KEY=(E)
......
#define VALUEMACROS_H "$Id$\n"
#define VALUE_TYPE PyObject *
#define VALUE_TYPE_IS_PYOBJECT
#define TEST_VALUE(VALUE, TARGET) PyObject_Compare((VALUE),(TARGET))
#define TEST_VALUE(VALUE, TARGET) COMPARE((VALUE),(TARGET))
#define DECLARE_VALUE(NAME) VALUE_TYPE NAME
#define INCREF_VALUE(k) Py_INCREF(k)
#define DECREF_VALUE(k) Py_DECREF(k)
......
/* Backport type definitions from Python 2.5's object.h */
#ifndef BTREE_PY24COMPATH_H
#define BTREE_PY24COMPAT_H
#if PY_VERSION_HEX < 0x02050000
typedef Py_ssize_t (*lenfunc)(PyObject *);
typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
#endif /* PY_VERSION_HEX */
#endif /* BTREE_PY24COMPAT_H */
This diff is collapsed.
......@@ -121,7 +121,7 @@ class DegenerateBTree(unittest.TestCase):
self.assertEqual(t.has_key(7), 5)
self.assertEqual(t.has_key(11), 5)
for i in 0, 2, 4, 6, 8, 9, 10, 12:
self.assert_(i not in t)
self.assertTrue(i not in t)
def _checkRanges(self, tree, keys):
self.assertEqual(len(tree), len(keys))
......@@ -129,7 +129,7 @@ class DegenerateBTree(unittest.TestCase):
sorted_keys.sort()
self.assertEqual(list(tree.keys()), sorted_keys)
for k in keys:
self.assert_(k in tree)
self.assertTrue(k in tree)
if keys:
lokey = sorted_keys[0]
hikey = sorted_keys[-1]
......@@ -206,6 +206,24 @@ class ToBeDeleted(object):
def __cmp__(self, other):
return cmp(self.id, other.id)
def __le__(self, other):
return self.id <= other.id
def __lt__(self, other):
return self.id < other.id
def __eq__(self, other):
return self.id == other.id
def __ne__(self, other):
return self.id != other.id
def __gt__(self, other):
return self.id > other.id
def __ge__(self, other):
return self.id >= other.id
def __hash__(self):
return hash(self.id)
......@@ -236,6 +254,8 @@ class BugFixes(unittest.TestCase):
import gc
import random
from BTrees.OOBTree import OOBTree
from .._compat import _u
from .._compat import xrange
t = OOBTree()
......@@ -257,12 +277,12 @@ class BugFixes(unittest.TestCase):
t[id] = ToBeDeleted(id)
else:
#del
id = trandom.choice(ids.keys())
id = trandom.choice(list(ids.keys()))
del t[id]
del ids[id]
ids = ids.keys()
trandom.shuffle(ids)
trandom.shuffle(list(ids))
for id in ids:
del t[id]
ids = None
......@@ -287,15 +307,15 @@ class BugFixes(unittest.TestCase):
id = trandom.randint(0,1000000)
ids[id] = 1
t[id] = (id, ToBeDeleted(id), u'somename')
t[id] = (id, ToBeDeleted(id), _u('somename'))
else:
#del
id = trandom.choice(ids.keys())
id = trandom.choice(list(ids.keys()))
del t[id]
del ids[id]
ids = ids.keys()
trandom.shuffle(ids)
trandom.shuffle(list(ids))
for id in ids:
del t[id]
ids = None
......@@ -325,12 +345,12 @@ class BugFixes(unittest.TestCase):
t[id] = 1
else:
#del
id = trandom.choice(ids.keys())
id = trandom.choice(list(ids.keys()))
del ids[id]
del t[id]
ids = ids.keys()
trandom.shuffle(ids)
trandom.shuffle(list(ids))
for id in ids:
del t[id]
#release all refs
......@@ -354,18 +374,18 @@ class BugFixes(unittest.TestCase):
id = None
while id is None or id in ids:
id = trandom.randint(0,1000000)
id = (id, ToBeDeleted(id), u'somename')
id = (id, ToBeDeleted(id), _u('somename'))
ids[id] = 1
t[id] = 1
else:
#del
id = trandom.choice(ids.keys())
id = trandom.choice(list(ids.keys()))
del ids[id]
del t[id]
ids = ids.keys()
trandom.shuffle(ids)
trandom.shuffle(list(ids))
for id in ids:
del t[id]
#release all refs
......@@ -387,7 +407,7 @@ class DoesntLikeBeingCompared:
def __cmp__(self,other):
raise ValueError('incomparable')
__lt__ = __le__ = __eq__ = __ne__ = __ge__ = __gt__ = __cmp__
class TestCmpError(unittest.TestCase):
......@@ -397,7 +417,7 @@ class TestCmpError(unittest.TestCase):
t['hello world'] = None
try:
t[DoesntLikeBeingCompared()] = None
except ValueError,e:
except ValueError as e:
self.assertEqual(str(e), 'incomparable')
else:
self.fail('incomarable objects should not be allowed into '
......@@ -410,22 +430,22 @@ class FamilyTest(unittest.TestCase):
import BTrees
from BTrees.IOBTree import IOTreeSet
verifyObject(BTrees.Interfaces.IBTreeFamily, BTrees.family32)
self.assertEquals(
self.assertEqual(
BTrees.family32.IO, BTrees.IOBTree)
self.assertEquals(
self.assertEqual(
BTrees.family32.OI, BTrees.OIBTree)
self.assertEquals(
self.assertEqual(
BTrees.family32.II, BTrees.IIBTree)
self.assertEquals(
self.assertEqual(
BTrees.family32.IF, BTrees.IFBTree)
self.assertEquals(
self.assertEqual(
BTrees.family32.OO, BTrees.OOBTree)
s = IOTreeSet()
s.insert(BTrees.family32.maxint)
self.assert_(BTrees.family32.maxint in s)
self.assertTrue(BTrees.family32.maxint in s)
s = IOTreeSet()
s.insert(BTrees.family32.minint)
self.assert_(BTrees.family32.minint in s)
self.assertTrue(BTrees.family32.minint in s)
s = IOTreeSet()
# this next bit illustrates an, um, "interesting feature". If
# the characteristics change to match the 64 bit version, please
......@@ -440,22 +460,22 @@ class FamilyTest(unittest.TestCase):
import BTrees
from BTrees.LOBTree import LOTreeSet
verifyObject(BTrees.Interfaces.IBTreeFamily, BTrees.family64)
self.assertEquals(
self.assertEqual(
BTrees.family64.IO, BTrees.LOBTree)
self.assertEquals(
self.assertEqual(
BTrees.family64.OI, BTrees.OLBTree)
self.assertEquals(
self.assertEqual(
BTrees.family64.II, BTrees.LLBTree)
self.assertEquals(
self.assertEqual(
BTrees.family64.IF, BTrees.LFBTree)
self.assertEquals(
self.assertEqual(
BTrees.family64.OO, BTrees.OOBTree)
s = LOTreeSet()
s.insert(BTrees.family64.maxint)
self.assert_(BTrees.family64.maxint in s)
self.assertTrue(BTrees.family64.maxint in s)
s = LOTreeSet()
s.insert(BTrees.family64.minint)
self.assert_(BTrees.family64.minint in s)
self.assertTrue(BTrees.family64.minint in s)
s = LOTreeSet()
# XXX why oh why do we expect ValueError here, but TypeError in test32?
self.assertRaises(ValueError, s.insert, BTrees.family64.maxint + 1)
......@@ -468,35 +488,35 @@ class FamilyTest(unittest.TestCase):
# unpickling, whether from the same unpickler or different
# unpicklers.
import pickle
import StringIO
from .._compat import BytesIO
s = pickle.dumps((family, family))
(f1, f2) = pickle.loads(s)
self.failUnless(f1 is family)
self.failUnless(f2 is family)
self.assertTrue(f1 is family)
self.assertTrue(f2 is family)
# Using a single memo across multiple pickles:
sio = StringIO.StringIO()
sio = BytesIO()
p = pickle.Pickler(sio)
p.dump(family)
p.dump([family])
u = pickle.Unpickler(StringIO.StringIO(sio.getvalue()))
u = pickle.Unpickler(BytesIO(sio.getvalue()))
f1 = u.load()
f2, = u.load()
self.failUnless(f1 is family)
self.failUnless(f2 is family)
self.assertTrue(f1 is family)
self.assertTrue(f2 is family)
# Using separate memos for each pickle:
sio = StringIO.StringIO()
sio = BytesIO()
p = pickle.Pickler(sio)
p.dump(family)
p.clear_memo()
p.dump([family])
u = pickle.Unpickler(StringIO.StringIO(sio.getvalue()))
u = pickle.Unpickler(BytesIO(sio.getvalue()))
f1 = u.load()
f2, = u.load()
self.failUnless(f1 is family)
self.failUnless(f2 is family)
self.assertTrue(f1 is family)
self.assertTrue(f2 is family)
def test_suite():
......
......@@ -13,7 +13,7 @@
##############################################################################
import unittest
from BTrees.OOBTree import OOBTree
from .common import _skip_under_Py3k
# When an OOBtree contains unicode strings as keys,
# it is neccessary accessing non-unicode strings are
......@@ -26,33 +26,40 @@ class TestBTreesUnicode(unittest.TestCase):
""" test unicode"""
def setUp(self):
"""setup an OOBTree with some unicode strings"""
#setup an OOBTree with some unicode strings
from BTrees.OOBTree import OOBTree
from BTrees._compat import _bytes
from BTrees._compat import _u
self.s = unicode('dreit\xe4gigen', 'latin1')
self.s = _u(b'dreit\xe4gigen', 'latin1')
self.data = [('alien', 1),
('k\xf6nnten', 2),
('fox', 3),
('future', 4),
('quick', 5),
('zerst\xf6rt', 6),
(unicode('dreit\xe4gigen','latin1'), 7),
self.data = [(b'alien', 1),
(b'k\xf6nnten', 2),
(b'fox', 3),
(b'future', 4),
(b'quick', 5),
(b'zerst\xf6rt', 6),
(_u(b'dreit\xe4gigen','latin1'), 7),
]
self.tree = OOBTree()
for k, v in self.data:
if isinstance(k, str):
k = unicode(k, 'latin1')
if isinstance(k, _bytes):
k = _u(k, 'latin1')
self.tree[k] = v
@_skip_under_Py3k
def testAllKeys(self):
# check every item of the tree
from BTrees._compat import _u
from BTrees._compat import _bytes
for k, v in self.data:
if isinstance(k, str):
k = unicode(k, encoding)
self.assert_(self.tree.has_key(k))
if isinstance(k, _bytes):
k = _u(k, encoding)
self.assertTrue(k in self.tree)
self.assertEqual(self.tree[k], v)
@_skip_under_Py3k
def testUnicodeKeys(self):
# try to access unicode keys in tree
k, v = self.data[-1]
......@@ -60,10 +67,11 @@ class TestBTreesUnicode(unittest.TestCase):
self.assertEqual(self.tree[k], v)
self.assertEqual(self.tree[self.s], v)
@_skip_under_Py3k
def testAsciiKeys(self):
# try to access some "plain ASCII" keys in the tree
for k, v in self.data[0], self.data[2]:
self.assert_(isinstance(k, str))
self.assertTrue(isinstance(k, str))
self.assertEqual(self.tree[k], v)
def test_suite():
......
......@@ -136,7 +136,7 @@ class NastyConfictFunctionalTests(ConflictTestBase, unittest.TestCase):
numtoadd = 16
candidate = 60
while numtoadd:
if not b.has_key(candidate):
if candidate not in b:
b[candidate] = candidate
numtoadd -= 1
candidate += 1
......@@ -332,10 +332,10 @@ class NastyConfictFunctionalTests(ConflictTestBase, unittest.TestCase):
state1 = bucket.__getstate__()
state2 = bucket.__getstate__()
state3 = bucket.__getstate__()
self.assert_(state2 is not state1 and
self.assertTrue(state2 is not state1 and
state2 is not state3 and
state3 is not state1)
self.assert_(state2 == state1 and
self.assertTrue(state2 == state1 and
state3 == state1)
self.assertRaises(BTreesConflictError, bucket._p_resolveConflict,
state1, state2, state3)
......
......@@ -53,24 +53,42 @@ class LengthTestCase(unittest.TestCase):
length = self._makeOne()
self.assertEqual(length._p_resolveConflict(5, 7, 9), 11)
def test_change_w_positive_delta(self):
length = self._makeOne()
length.change(3)
self.assertEqual(length.value, 3)
def test_change_w_negative_delta(self):
length = self._makeOne()
length.change(-3)
self.assertEqual(length.value, -3)
def test_change_overflows_to_long(self):
import sys
try:
length = self._makeOne(sys.maxint)
except AttributeError: #pragma NO COVER Py3k
return
else: #pragma NO COVER Py2
self.assertEqual(length(), sys.maxint)
self.assert_(type(length()) is int)
self.assertTrue(type(length()) is int)
length.change(+1)
self.assertEqual(length(), sys.maxint + 1)
self.assert_(type(length()) is long)
self.assertTrue(type(length()) is long)
def test_change_underflows_to_long(self):
import sys
try:
minint = (-sys.maxint) - 1
except AttributeError: #pragma NO COVER Py3k
return
else: #pragma NO COVER Py2
length = self._makeOne(minint)
self.assertEqual(length(), minint)
self.assert_(type(length()) is int)
self.assertTrue(type(length()) is int)
length.change(-1)
self.assertEqual(length(), minint - 1)
self.assert_(type(length()) is long)
self.assertTrue(type(length()) is long)
def test___call___no_args(self):
length = self._makeOne(42)
......
......@@ -143,6 +143,7 @@ class _TestOIBTreesBase(TypeTest):
self._makeOne()[1] = None
def testEmptyFirstBucketReportedByGuido(self):
from .._compat import xrange
b = self._makeOne()
for i in xrange(29972): # reduce to 29971 and it works
b[i] = i
......
......@@ -112,6 +112,7 @@ class OOBTreeTest(BTreeTests, unittest.TestCase):
# used in a function that's used in lots of places.
# Otherwise, there are many permutations that would have to be
# checked.
from .._compat import PY2
t = self._makeOne()
class C(object):
......@@ -119,30 +120,31 @@ class OOBTreeTest(BTreeTests, unittest.TestCase):
self.assertRaises(TypeError, lambda : t.__setitem__(C(), 1))
class C(object):
if PY2: # we only check for __cmp__ on Python2
class With___cmp__(object):
def __cmp__(*args):
return 1
c = C()
c = With___cmp__()
t[c] = 1
t.clear()
class C(object):
class With___lt__(object):
def __lt__(*args):
return 1
c = C()
c = With___lt__()
t[c] = 1
t.clear()
#class OOBTreePyTest(OOBTreeTest):
class OOBTreePyTest(OOBTreeTest):
#
# Right now, we can't match the C extension's test / prohibition of the
# default 'object' comparison semantics.
class OOBTreePyTest(BTreeTests, unittest.TestCase):
#class OOBTreePyTest(BTreeTests, unittest.TestCase):
def _makeOne(self):
from BTrees.OOBTree import OOBTreePy
......
This diff is collapsed.
......@@ -38,7 +38,7 @@ class SubclassTest(unittest.TestCase):
t[i] = i
state = t.__getstate__()
self.assert_(state[0][0].__class__ is B)
self.assertTrue(state[0][0].__class__ is B)
def test_suite():
return unittest.makeSuite(SubclassTest)
......@@ -149,10 +149,10 @@ class Test_type_and_adr(unittest.TestCase):
def test_type_and_adr_w_oid(self):
from BTrees.utils import oid_repr
class WithOid(object):
_p_oid = 'DEADBEEF'
_p_oid = b'DEADBEEF'
t_and_a = self._callFUT(WithOid())
self.assertTrue(t_and_a.startswith('WithOid (0x'))
self.assertTrue(t_and_a.endswith('oid=%s)' % oid_repr('DEADBEEF')))
self.assertTrue(t_and_a.endswith('oid=%s)' % oid_repr(b'DEADBEEF')))
def test_type_and_adr_wo_oid(self):
class WithoutOid(object):
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -5,6 +5,9 @@
4.0.2 (unreleased)
------------------
- Added explicit support for Python 3.2, Python 3.3, and PyPy.
Note that the C extensions are not (yet) available on PyPy.
- Python reference implementations now tested separately from the C
verions on all platforms.
......
This diff is collapsed.
......@@ -3,7 +3,7 @@ envlist =
# Jython support pending 2.7 support, due 2012-07-15 or so. See:
# http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html
# py26,py27,py32,jython,pypy,coverage,docs
py26,py27,pypy,w_zodb,coverage,docs
py26,py27,pypy,py32,py33,w_zodb,coverage,docs
[testenv]
deps =
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment