PyObject *arg, PyObject *kw)
{
static const char *const kwlist[] = { "default", "min", "max", "mod", 0 };
- int dfl, min = 0, max = 0, mod = 1;
+ int dfl, min = 0, max, mod = 1;
+ PyObject *maxobj = Py_None;
keyszrange_pyobj *o;
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "i|iii:new", KWLIST,
- &dfl, &min, &max, &mod))
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "i|iOi:new", KWLIST,
+ &dfl, &min, &maxobj, &mod))
goto end;
- if (dfl < 0 || min < 0) VALERR("key size cannot be negative");
+ if (maxobj == Py_None)
+ max = 0;
+ else {
+ max = PyInt_AsLong(maxobj);
+ if (max == -1 && PyErr_Occurred()) goto end;
+ }
+ if (dfl < 0 || min < 0 || max < 0) VALERR("key size cannot be negative");
if (min > dfl || (max && dfl > max)) VALERR("bad key size bounds");
if (mod <= 0 || dfl%mod || min%mod || max%mod)
VALERR("bad key size modulus");
static PyObject *kaget_min(PyObject *me, void *hunoz)
{ return (PyInt_FromLong(0)); }
-#define kaget_max kaget_min
+static PyObject *kaget_max(PyObject *me, void *hunoz)
+ { RETURN_NONE; }
+
+static PyObject *krget_max(PyObject *me, void *hunoz)
+{
+ int max = ((keyszrange_pyobj *)me)->max;
+ if (max) return (PyInt_FromLong(max));
+ else RETURN_NONE;
+}
static PyObject *ksget_min(PyObject *me, void *hunoz)
{
static const PyMemberDef keyszrange_pymembers[] = {
#define MEMBERSTRUCT keyszrange_pyobj
MEMBER(min, T_INT, READONLY, "KSZ.min -> smallest allowed key size")
- MEMBER(max, T_INT, READONLY, "KSZ.max -> largest allowed key size")
MEMBER(mod, T_INT, READONLY,
"KSZ.mod -> key size must be a multiple of this")
#undef MEMBERSTRUCT
{ 0 }
};
+static const PyGetSetDef keyszrange_pygetset[] = {
+#define GETSETNAME(op, name) kr##op##_##name
+ GET (max, "KSZ.max -> largest allowed key size")
+#undef GETSETNAME
+ { 0 }
+};
+
static const PyGetSetDef keyszset_pygetset[] = {
#define GETSETNAME(op, name) ks##op##_##name
GET (min, "KSZ.min -> smallest allowed key size")
0, /* @tp_iternext@ */
0, /* @tp_methods@ */
PYMEMBERS(keyszrange), /* @tp_members@ */
- 0, /* @tp_getset@ */
+ PYGETSET(keyszrange), /* @tp_getset@ */
0, /* @tp_base@ */
0, /* @tp_dict@ */
0, /* @tp_descr_get@ */
if isinstance(ksz, C.KeySZAny): return None
elif isinstance(ksz, C.KeySZRange):
if ksz.mod != 1: return ksz.min + 1
- elif ksz.max != 0: return ksz.max + 1
+ elif ksz.max is not None: return ksz.max + 1
elif ksz.min != 0: return ksz.min - 1
else: return None
elif isinstance(ksz, C.KeySZSet):
if isinstance(ksz, C.KeySZAny): return sz + 1
elif isinstance(ksz, C.KeySZRange):
if sz > ksz.min: return sz - ksz.mod
- elif ksz.max == 0 or sz < ksz.max: return sz + ksz.mod
+ elif ksz.max is None or sz < ksz.max: return sz + ksz.mod
else: return None
elif isinstance(ksz, C.KeySZSet):
for sz1 in sorted(ksz.set):
me.assertEqual(type(ksz), C.KeySZAny)
me.assertEqual(ksz.default, 20)
me.assertEqual(ksz.min, 0)
- me.assertEqual(ksz.max, 0)
+ me.assertEqual(ksz.max, None)
for n in [0, 12, 20, 5000]:
me.assertTrue(ksz.check(n))
me.assertEqual(ksz.best(n), n)
me.assertEqual(type(ksz), C.KeySZAny)
me.assertEqual(ksz.default, 32)
me.assertEqual(ksz.min, 0)
- me.assertEqual(ksz.max, 0)
+ me.assertEqual(ksz.max, None)
for n in [0, 12, 20, 5000]:
me.assertTrue(ksz.check(n))
me.assertEqual(ksz.best(n), n)
ksz = C.KeySZAny(15)
me.assertEqual(ksz.default, 15)
me.assertEqual(ksz.min, 0)
- me.assertEqual(ksz.max, 0)
+ me.assertEqual(ksz.max, None)
me.assertRaises(ValueError, lambda: C.KeySZAny(-8))
me.assertEqual(C.KeySZAny(0).default, 0)
me.assertEqual(ksz.min, 21)
me.assertEqual(ksz.max, 35)
me.assertEqual(ksz.mod, 7)
+ ksz = C.KeySZRange(28, 21, None, 7)
+ me.assertEqual(ksz.min, 21)
+ me.assertEqual(ksz.max, None)
+ me.assertEqual(ksz.mod, 7)
+ me.assertEqual(ksz.pad(36), 42)
me.assertRaises(ValueError, C.KeySZRange, 29, 21, 35, 7)
me.assertRaises(ValueError, C.KeySZRange, 28, 20, 35, 7)
me.assertRaises(ValueError, C.KeySZRange, 28, 21, 34, 7)