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

Merge py3k branch.

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