Add __repr__ implementations for ldb.Message, ldb.MessageElement and ldb.Dn.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 19 May 2008 21:07:04 +0000 (23:07 +0200)
committerJelmer Vernooij <jelmer@samba.org>
Mon, 19 May 2008 21:07:04 +0000 (23:07 +0200)
(This used to be commit b9119c0f0f524d43ff09825dffb24a5e77a240f4)

source4/lib/ldb/ldb.i
source4/lib/ldb/ldb.py
source4/lib/ldb/ldb_wrap.c
source4/lib/ldb/tests/python/api.py

index 6b94f19cb5b565f68e07cb87abc68f9e63ba618e..75482011fb08f286620a4a5fd7611d51c774bb84 100644 (file)
@@ -229,6 +229,14 @@ fail:
             return ldb_dn_canonical_ex_string($self, $self);
         }
 #ifdef SWIGPYTHON
+        char *__repr__(void)
+        {
+            char *dn = ldb_dn_get_linearized($self), *ret;
+            asprintf(&ret, "Dn('%s')", dn);
+            talloc_free(dn);
+            return ret;
+        }
+
         ldb_dn *__add__(ldb_dn *other)
         {
             ldb_dn *ret = ldb_dn_copy(NULL, $self);
@@ -376,6 +384,9 @@ typedef struct ldb_message_element {
                 raise KeyError("no such value")
             return ret
 
+        def __repr__(self):
+            return "MessageElement([%s])" % (",".join(repr(x) for x in self.__set__()))
+
         def __eq__(self, other):
             if (len(self) == 1 and self.get(0) == other):
                 return True
@@ -400,17 +411,22 @@ typedef struct ldb_message_element {
     else
         $result = SWIG_NewPointerObj($1, SWIGTYPE_p_ldb_message_element, 0);
 }
-%rename(__getitem__) ldb_message::find_element;
 //%typemap(out) ldb_msg_element *;
 
 
 %inline {
     PyObject *ldb_msg_list_elements(ldb_msg *msg)
     {
-        int i;
-        PyObject *obj = PyList_New(msg->num_elements);
-        for (i = 0; i < msg->num_elements; i++)
-            PyList_SetItem(obj, i, PyString_FromString(msg->elements[i].name));
+        int i, j = 0;
+        PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
+        if (msg->dn != NULL) {
+            PyList_SetItem(obj, j, PyString_FromString("dn"));
+            j++;
+        }
+        for (i = 0; i < msg->num_elements; i++) {
+            PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
+            j++;
+        }
         return obj;
     }
 }
@@ -466,6 +482,28 @@ typedef struct ldb_message {
         }
 #endif
         void remove_attr(const char *name);
+%pythoncode {
+    def get(self, key, default=None):
+        if key == "dn":
+            return self.dn
+        return self.find_element(key)
+
+    def __getitem__(self, key):
+        ret = self.get(key, None)
+        if ret is None:
+            raise KeyError("No such element")
+        return ret
+
+    def iteritems(self):
+        for k in self.keys():
+            yield k, self[k]
+    
+    def items(self):
+        return list(self.iteritems())
+
+    def __repr__(self):
+        return "Message(%s)" % repr(dict(self.iteritems()))
+}
     }
 } ldb_msg;
 
@@ -753,6 +791,8 @@ typedef struct ldb_context {
 
         def search(self, base=None, scope=SCOPE_DEFAULT, expression=None, 
                    attrs=None, controls=None):
+            if not (attrs is None or isinstance(attrs, list)):
+                raise TypeError("attributes not a list")
             parsed_controls = None
             if controls is not None:
                 parsed_controls = self.parse_control_strings(controls)
index b148782c63aac297bfc286f193f1cb3e6b2bb601..60644d352cdde7e8c4e9776fc968e3302ee8d7fd 100644 (file)
@@ -68,7 +68,6 @@ CHANGETYPE_MODIFY = _ldb.CHANGETYPE_MODIFY
 ldb_val_to_py_object = _ldb.ldb_val_to_py_object
 class Dn(object):
     thisown = _swig_property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc='The membership flag')
-    __repr__ = _swig_repr
     def __init__(self, *args, **kwargs): 
         _ldb.Dn_swiginit(self,_ldb.new_Dn(*args, **kwargs))
     __swig_destroy__ = _ldb.delete_Dn
@@ -93,6 +92,7 @@ Dn.add_child = new_instancemethod(_ldb.Dn_add_child,None,Dn)
 Dn.add_base = new_instancemethod(_ldb.Dn_add_base,None,Dn)
 Dn.canonical_str = new_instancemethod(_ldb.Dn_canonical_str,None,Dn)
 Dn.canonical_ex_str = new_instancemethod(_ldb.Dn_canonical_ex_str,None,Dn)
+Dn.__repr__ = new_instancemethod(_ldb.Dn___repr__,None,Dn)
 Dn.__add__ = new_instancemethod(_ldb.Dn___add__,None,Dn)
 Dn_swigregister = _ldb.Dn_swigregister
 Dn_swigregister(Dn)
@@ -108,6 +108,9 @@ class ldb_msg_element(object):
             raise KeyError("no such value")
         return ret
 
+    def __repr__(self):
+        return "MessageElement([%s])" % (",".join(repr(x) for x in self.__set__()))
+
     def __eq__(self, other):
         if (len(self) == 1 and self.get(0) == other):
             return True
@@ -139,7 +142,28 @@ class Message(object):
     def __init__(self, *args, **kwargs): 
         _ldb.Message_swiginit(self,_ldb.new_Message(*args, **kwargs))
     __swig_destroy__ = _ldb.delete_Message
-Message.__getitem__ = new_instancemethod(_ldb.Message___getitem__,None,Message)
+    def get(self, key, default=None):
+        if key == "dn":
+            return self.dn
+        return self.find_element(key)
+
+    def __getitem__(self, key):
+        ret = self.get(key, None)
+        if ret is None:
+            raise KeyError("No such element")
+        return ret
+
+    def iteritems(self):
+        for k in self.keys():
+            yield k, self[k]
+
+    def items(self):
+        return list(self.iteritems())
+
+    def __repr__(self):
+        return "Message(%s)" % repr(dict(self.iteritems()))
+
+Message.find_element = new_instancemethod(_ldb.Message_find_element,None,Message)
 Message.__setitem__ = new_instancemethod(_ldb.Message___setitem__,None,Message)
 Message.__len__ = new_instancemethod(_ldb.Message___len__,None,Message)
 Message.keys = new_instancemethod(_ldb.Message_keys,None,Message)
@@ -202,6 +226,8 @@ class Ldb(object):
 
     def search(self, base=None, scope=SCOPE_DEFAULT, expression=None, 
                attrs=None, controls=None):
+        if not (attrs is None or isinstance(attrs, list)):
+            raise TypeError("attributes not a list")
         parsed_controls = None
         if controls is not None:
             parsed_controls = self.parse_control_strings(controls)
index 390652eebe60db8ac125fe04109276fee106ed17..f13ed4dc3b91219c430cb2325a45e83fe083a274 100644 (file)
@@ -2719,6 +2719,12 @@ SWIGINTERN char const *ldb_dn_canonical_str(ldb_dn *self){
 SWIGINTERN char const *ldb_dn_canonical_ex_str(ldb_dn *self){
             return ldb_dn_canonical_ex_string(self, self);
         }
+SWIGINTERN char *ldb_dn___repr__(ldb_dn *self){
+            char *dn = ldb_dn_get_linearized(self), *ret;
+            asprintf(&ret, "Dn('%s')", dn);
+            talloc_free(dn);
+            return ret;
+        }
 SWIGINTERN ldb_dn *ldb_dn___add__(ldb_dn *self,ldb_dn *other){
             ldb_dn *ret = ldb_dn_copy(NULL, self);
             ldb_dn_add_child(ret, other);
@@ -2970,10 +2976,16 @@ SWIGINTERN void delete_ldb_msg_element(ldb_msg_element *self){ talloc_free(self)
 
     PyObject *ldb_msg_list_elements(ldb_msg *msg)
     {
-        int i;
-        PyObject *obj = PyList_New(msg->num_elements);
-        for (i = 0; i < msg->num_elements; i++)
-            PyList_SetItem(obj, i, PyString_FromString(msg->elements[i].name));
+        int i, j = 0;
+        PyObject *obj = PyList_New(msg->num_elements+(msg->dn != NULL?1:0));
+        if (msg->dn != NULL) {
+            PyList_SetItem(obj, j, PyString_FromString("dn"));
+            j++;
+        }
+        for (i = 0; i < msg->num_elements; i++) {
+            PyList_SetItem(obj, j, PyString_FromString(msg->elements[i].name));
+            j++;
+        }
         return obj;
     }
 
@@ -3678,6 +3690,29 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Dn___repr__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  ldb_dn *arg1 = (ldb_dn *) 0 ;
+  char *result = 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  PyObject *swig_obj[1] ;
+  
+  if (!args) SWIG_fail;
+  swig_obj[0] = args;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ldb_dn, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Dn___repr__" "', argument " "1"" of type '" "ldb_dn *""'"); 
+  }
+  arg1 = (ldb_dn *)(argp1);
+  result = (char *)ldb_dn___repr__(arg1);
+  resultobj = SWIG_FromCharPtr((const char *)result);
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_Dn___add__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
   PyObject *resultobj = 0;
   ldb_dn *arg1 = (ldb_dn *) 0 ;
@@ -4074,7 +4109,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_Message___getitem__(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
+SWIGINTERN PyObject *_wrap_Message_find_element(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
   PyObject *resultobj = 0;
   ldb_msg *arg1 = (ldb_msg *) 0 ;
   char *arg2 = (char *) 0 ;
@@ -4090,15 +4125,15 @@ SWIGINTERN PyObject *_wrap_Message___getitem__(PyObject *SWIGUNUSEDPARM(self), P
     (char *) "self",(char *) "name", NULL 
   };
   
-  if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Message___getitem__",kwnames,&obj0,&obj1)) SWIG_fail;
+  if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Message_find_element",kwnames,&obj0,&obj1)) SWIG_fail;
   res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_message, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message___getitem__" "', argument " "1"" of type '" "ldb_msg *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_find_element" "', argument " "1"" of type '" "ldb_msg *""'"); 
   }
   arg1 = (ldb_msg *)(argp1);
   res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
   if (!SWIG_IsOK(res2)) {
-    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message___getitem__" "', argument " "2"" of type '" "char const *""'");
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message_find_element" "', argument " "2"" of type '" "char const *""'");
   }
   arg2 = (char *)(buf2);
   if (arg1 == NULL)
@@ -5673,6 +5708,7 @@ static PyMethodDef SwigMethods[] = {
         { (char *)"Dn_add_base", (PyCFunction) _wrap_Dn_add_base, METH_VARARGS | METH_KEYWORDS, NULL},
         { (char *)"Dn_canonical_str", (PyCFunction)_wrap_Dn_canonical_str, METH_O, NULL},
         { (char *)"Dn_canonical_ex_str", (PyCFunction)_wrap_Dn_canonical_ex_str, METH_O, NULL},
+        { (char *)"Dn___repr__", (PyCFunction)_wrap_Dn___repr__, METH_O, NULL},
         { (char *)"Dn___add__", (PyCFunction) _wrap_Dn___add__, METH_VARARGS | METH_KEYWORDS, NULL},
         { (char *)"Dn_swigregister", Dn_swigregister, METH_VARARGS, NULL},
         { (char *)"Dn_swiginit", Dn_swiginit, METH_VARARGS, NULL},
@@ -5689,7 +5725,7 @@ static PyMethodDef SwigMethods[] = {
         { (char *)"Message_dn_get", (PyCFunction)_wrap_Message_dn_get, METH_O, NULL},
         { (char *)"new_Message", (PyCFunction) _wrap_new_Message, METH_VARARGS | METH_KEYWORDS, NULL},
         { (char *)"delete_Message", (PyCFunction)_wrap_delete_Message, METH_O, NULL},
-        { (char *)"Message___getitem__", (PyCFunction) _wrap_Message___getitem__, METH_VARARGS | METH_KEYWORDS, NULL},
+        { (char *)"Message_find_element", (PyCFunction) _wrap_Message_find_element, METH_VARARGS | METH_KEYWORDS, NULL},
         { (char *)"Message___setitem__", _wrap_Message___setitem__, METH_VARARGS, NULL},
         { (char *)"Message___len__", (PyCFunction)_wrap_Message___len__, METH_O, NULL},
         { (char *)"Message_keys", (PyCFunction)_wrap_Message_keys, METH_O, NULL},
index 5f3f727b5d18694a3cb75b6b8791d9e44c20fc7e..6f073f79a84259bb6a67bed6e97bb64e2b93117c 100755 (executable)
@@ -60,6 +60,10 @@ class SimpleLdb(unittest.TestCase):
         l = ldb.Ldb("foo.tdb")
         self.assertEquals(len(l.search("", ldb.SCOPE_SUBTREE, "(dc=*)", ["dc"])), 0)
 
+    def test_search_attr_string(self):
+        l = ldb.Ldb("foo.tdb")
+        self.assertRaises(TypeError, l.search, attrs="dc")
+
     def test_opaque(self):
         l = ldb.Ldb("foo.tdb")
         l.set_opaque("my_opaque", l)
@@ -257,6 +261,10 @@ class DnTests(unittest.TestCase):
         x = ldb.Dn(self.ldb, "dc=foo,bar=bloe")
         self.assertEquals(x.__str__(), "dc=foo,bar=bloe")
 
+    def test_repr(self):
+        x = ldb.Dn(self.ldb, "dc=foo,bla=blie")
+        self.assertEquals(x.__repr__(), "Dn('dc=foo,bla=blie')")
+
     def test_get_casefold(self):
         x = ldb.Dn(self.ldb, "dc=foo,bar=bloe")
         self.assertEquals(x.get_casefold(), "DC=FOO,BAR=bloe")
@@ -347,6 +355,16 @@ class LdbMsgTests(unittest.TestCase):
         self.msg = ldb.Message(ldb.Dn(ldb.Ldb(), "dc=foo"))
         self.assertEquals("dc=foo", str(self.msg.dn))
 
+    def test_iter_items(self):
+        self.assertEquals(0, len(self.msg.items()))
+        self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo")
+        self.assertEquals(1, len(self.msg.items()))
+
+    def test_repr(self):
+        self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "dc=foo")
+        self.msg["dc"] = "foo"
+        self.assertEquals("Message({'dn': Dn('dc=foo'), 'dc': MessageElement(['foo'])})", repr(self.msg))
+
     def test_len(self):
         self.assertEquals(0, len(self.msg))
 
@@ -374,14 +392,26 @@ class LdbMsgTests(unittest.TestCase):
         self.assertEquals(["bar"], list(self.msg["foo"]))
 
     def test_keys(self):
+        self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
         self.msg["foo"] = ["bla"]
         self.msg["bar"] = ["bla"]
-        self.assertEquals(["foo", "bar"], self.msg.keys())
+        self.assertEquals(["dn", "foo", "bar"], self.msg.keys())
 
     def test_dn(self):
         self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
         self.assertEquals("@BASEINFO", self.msg.dn.__str__())
 
+    def test_get_dn(self):
+        self.msg.dn = ldb.Dn(ldb.Ldb("foo.tdb"), "@BASEINFO")
+        self.assertEquals("@BASEINFO", self.msg.get("dn").__str__())
+
+    def test_get_other(self):
+        self.msg["foo"] = ["bar"]
+        self.assertEquals("bar", self.msg.get("foo")[0])
+
+    def test_get_unknown(self):
+        self.assertRaises(KeyError, self.msg.get, "lalalala")
+
 
 class MessageElementTests(unittest.TestCase):
     def test_cmp_element(self):
@@ -395,6 +425,12 @@ class MessageElementTests(unittest.TestCase):
         x = ldb.MessageElement(["foo"])
         self.assertEquals(["foo"], list(x))
 
+    def test_repr(self):
+        x = ldb.MessageElement(["foo"])
+        self.assertEquals("MessageElement(['foo'])", repr(x))
+        x = ldb.MessageElement(["foo", "bla"])
+        self.assertEquals("MessageElement(['foo','bla'])", repr(x))
+
     def test_get_item(self):
         x = ldb.MessageElement(["foo", "bar"])
         self.assertEquals("foo", x[0])