Hello community,

here is the log from the commit of package python-ldap for openSUSE:Factory 
checked in at 2017-11-15 17:02:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-ldap (Old)
 and      /work/SRC/openSUSE:Factory/.python-ldap.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-ldap"

Wed Nov 15 17:02:32 2017 rev:46 rq:541892 version:2.5.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-ldap/python-ldap.changes  2017-10-10 
11:42:50.627848244 +0200
+++ /work/SRC/openSUSE:Factory/.python-ldap.new/python-ldap.changes     
2017-11-15 17:02:45.789129045 +0100
@@ -1,0 +2,36 @@
+Sun Nov 12 17:49:25 UTC 2017 - [email protected]
+
+- update to upstream release 2.5.1
+- adjusted BuildRequires to match upstream prerequisites
+
+Changes since 2.4.45:
+
+Mandatory prerequisites:
+- Python 2.7.x
+- pyasn1 0.3.7+ and pyasn1_modules 0.1.5+
+
+Modules/
+* removed unused code schema.c
+
+Lib/
+* ldap.__version__, ldap.__author__ and ldap.__license__ now
+  imported from new sub-module ldap.pkginfo also to setup.py
+* Added safety assertion when importing _ldap:
+  ldap.pkginfo.__version__ must match _ldap.__version__
+* removed stand-alone module dsml
+* slapdtest.SlapdObject.restart() just restarts slapd
+  without cleaning any data
+* Compability changes for pyasn1 0.3.x or newer
+  (thanks to Ilya Etingof and Christian Heimes)
+* The methods SSSResponseControl.decodeControlValue() and
+  VLVResponseControl.decodeControlValue() now follow the coding
+  convention to use camel-cased ASN.1 name as class attribute name.
+  The old class names are still set for back-ward compability
+  but should not be used in new code because they might be removed
+  in a later release.
+* removed SSSRequestControl from ldap.controls.KNOWN_RESPONSE_CONTROLS
+
+Tests/
+* added explicit reconnect tests for ReconnectLDAPObject
+
+-------------------------------------------------------------------

Old:
----
  python-ldap-2.4.45.tar.gz
  python-ldap-2.4.45.tar.gz.asc

New:
----
  python-ldap-2.5.1.tar.gz
  python-ldap-2.5.1.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-ldap.spec ++++++
--- /var/tmp/diff_new_pack.MujBPy/_old  2017-11-15 17:02:47.537065044 +0100
+++ /var/tmp/diff_new_pack.MujBPy/_new  2017-11-15 17:02:47.537065044 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           python-ldap
-Version:        2.4.45
+Version:        2.5.1
 Release:        0
 Summary:        Python LDAP interface
 License:        Python-2.0
@@ -33,11 +33,11 @@
 BuildRequires:  openldap2
 BuildRequires:  openldap2-client
 BuildRequires:  openldap2-devel >= 2.4.11
-BuildRequires:  python-devel >= 2.3
+BuildRequires:  python-devel >= 2.7
 BuildRequires:  python-setuptools
 Requires:       libldap-2_4-2 >= 2.4.11
-Requires:       python-pyasn1
-Requires:       python-pyasn1-modules
+Requires:       python-pyasn1 >= 0.3.7
+Requires:       python-pyasn1-modules >= 0.1.5
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 %if 0%{?suse_version} && 0%{?suse_version} <= 1110
 %{!?python_sitearch: %global python_sitearch %(python -c "from 
distutils.sysconfig import get_python_lib; print get_python_lib(1)")}

++++++ python-ldap-2.4.45.tar.gz -> python-ldap-2.5.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/CHANGES 
new/python-ldap-2.5.1/CHANGES
--- old/python-ldap-2.4.45/CHANGES      2017-10-09 17:10:02.000000000 +0200
+++ new/python-ldap-2.5.1/CHANGES       2017-11-12 18:32:33.000000000 +0100
@@ -1,4 +1,37 @@
 ----------------------------------------------------------------
+Released 2.5.1 2017-11-12
+
+Changes since 2.4.45:
+
+Mandatory prerequisites:
+- Python 2.7.x
+- pyasn1 0.3.7+ and pyasn1_modules 0.1.5+
+
+Modules/
+* removed unused code schema.c
+
+Lib/
+* ldap.__version__, ldap.__author__ and ldap.__license__ now
+  imported from new sub-module ldap.pkginfo also to setup.py
+* Added safety assertion when importing _ldap:
+  ldap.pkginfo.__version__ must match _ldap.__version__
+* removed stand-alone module dsml
+* slapdtest.SlapdObject.restart() just restarts slapd
+  without cleaning any data
+* Compability changes for pyasn1 0.3.x or newer
+  (thanks to Ilya Etingof and Christian Heimes)
+* The methods SSSResponseControl.decodeControlValue() and
+  VLVResponseControl.decodeControlValue() now follow the coding
+  convention to use camel-cased ASN.1 name as class attribute name.
+  The old class names are still set for back-ward compability
+  but should not be used in new code because they might be removed
+  in a later release.
+* removed SSSRequestControl from ldap.controls.KNOWN_RESPONSE_CONTROLS
+
+Tests/
+* added explicit reconnect tests for ReconnectLDAPObject
+
+----------------------------------------------------------------
 Released 2.4.45 2017-10-09
 
 Changes since 2.4.44:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/dsml.py 
new/python-ldap-2.5.1/Lib/dsml.py
--- old/python-ldap-2.4.45/Lib/dsml.py  2017-10-09 16:56:08.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/dsml.py   1970-01-01 01:00:00.000000000 +0100
@@ -1,295 +0,0 @@
-"""
-dsml - generate and parse DSMLv1 data
-(see http://www.oasis-open.org/committees/dsml/)
-
-See https://www.python-ldap.org/ for details.
-
-Python compability note:
-Tested with Python 2.0+.
-"""
-
-__version__ = '2.4.45'
-
-import string,base64
-
-
-special_entities = (
-  ('&','&amp;'),
-  ('<','&lt;'),
-  ('"','&quot;'),
-  ("'",'&apos;'),
-)
-
-
-def replace_char(s):
-  for char,entity in special_entities:
-    s = string.replace(s,char,entity)
-  return s
-
-
-class DSMLWriter:
-  """
-  Class for writing LDAP entry records to a DSMLv1 file.
-
-  Arguments:
-
-  f
-      File object for output.
-  base64_attrs
-      Attribute types to be base64-encoded.
-  dsml_comment
-      Text placed in comment lines behind <dsml:dsml>.
-  indent
-      String used for indentiation of next nested level.
-  """
-
-  def __init__(
-    self,f,base64_attrs=[],dsml_comment='',indent='    '
-  ):
-    self._output_file = f
-    self._base64_attrs = {}.fromkeys(map(string.lower,base64_attrs))
-    self._dsml_comment = dsml_comment
-    self._indent = indent
-
-  def _needs_base64_encoding(self,attr_type,attr_value):
-    if self._base64_attrs:
-      return self._base64_attrs.has_key(string.lower(attr_type))
-    else:
-      try:
-        unicode(attr_value,'utf-8')
-      except UnicodeError:
-        return 1
-      else:
-        return 0
-
-  def writeHeader(self):
-    """
-    Write the header
-    """
-    self._output_file.write('\n'.join([
-        '<?xml version="1.0" encoding="UTF-8"?>',
-        '<!DOCTYPE root PUBLIC "dsml.dtd" "http://www.dsml.org/1.0/dsml.dtd";>',
-        '<dsml:dsml xmlns:dsml="http://www.dsml.org/DSML";>',
-        '%s<dsml:directory-entries>\n' % (self._indent),
-      ])
-    )
-    if self._dsml_comment:
-      self._output_file.write('%s<!--\n' % (self._indent))
-      self._output_file.write('%s%s\n' % (self._indent,self._dsml_comment))
-      self._output_file.write('%s-->\n' % (self._indent))
-
-  def writeFooter(self):
-    """
-    Write the footer
-    """
-    self._output_file.write('%s</dsml:directory-entries>\n' % (self._indent))
-    self._output_file.write('</dsml:dsml>\n')
-
-  def unparse(self,dn,entry):
-    return self.writeRecord(dn,entry)
-
-  def writeRecord(self,dn,entry):
-    """
-    dn
-          string-representation of distinguished name
-    entry
-          dictionary holding the LDAP entry {attr:data}
-    """
-
-    # Write line dn: first
-    self._output_file.write(
-      '%s<dsml:entry dn="%s">\n' % (
-        self._indent*2,replace_char(dn)
-      )
-    )
-
-    objectclasses = entry.get('objectclass',entry.get('objectClass',[]))
-
-    self._output_file.write('%s<dsml:objectclass>\n' % (self._indent*3))
-    for oc in objectclasses:
-      self._output_file.write('%s<dsml:oc-value>%s</dsml:oc-value>\n' % 
(self._indent*4,oc))
-    self._output_file.write('%s</dsml:objectclass>\n' % (self._indent*3))
-
-    attr_types = entry.keys()[:]
-    try:
-      attr_types.remove('objectclass')
-      attr_types.remove('objectClass')
-    except ValueError:
-      pass
-    attr_types.sort()
-    for attr_type in attr_types:
-      self._output_file.write('%s<dsml:attr name="%s">\n' % 
(self._indent*3,attr_type))
-      for attr_value_item in entry[attr_type]:
-        needs_base64_encoding = self._needs_base64_encoding(
-          attr_type,attr_value_item
-        )
-        if needs_base64_encoding:
-          attr_value_item = base64.encodestring(attr_value_item)
-        else:
-          attr_value_item = replace_char(attr_value_item)
-        self._output_file.write('%s<dsml:value%s>\n' % (
-            self._indent*4,
-            ' encoding="base64"'*needs_base64_encoding
-          )
-        )
-        self._output_file.write('%s%s\n' % (
-            self._indent*5,
-            attr_value_item
-          )
-        )
-        self._output_file.write('%s</dsml:value>\n' % (
-            self._indent*4,
-          )
-        )
-      self._output_file.write('%s</dsml:attr>\n' % (self._indent*3))
-    self._output_file.write('%s</dsml:entry>\n' % (self._indent*2))
-    return
-
-
-try:
-
-  import xml.sax,xml.sax.handler
-
-except ImportError:
-  pass
-
-else:
-
-  class DSMLv1Handler(xml.sax.handler.ContentHandler):
-    """
-    Content handler class for DSMLv1
-    """
-
-    def __init__(self,parser_instance):
-      self._parser_instance = parser_instance
-      xml.sax.handler.ContentHandler.__init__(self)
-
-    def startDocument(self):
-      pass
-
-    def endDocument(self):
-      pass
-
-    def startElement(self,raw_name,attrs):
-      assert raw_name.startswith(''),'Illegal name'
-      name = raw_name[5:]
-      if name=='dsml':
-        pass
-      elif name=='directory-entries':
-        self._parsing_entries = 1
-      elif name=='entry':
-        self._dn = attrs['dn']
-        self._entry = {}
-      elif name=='attr':
-        self._attr_type = attrs['name'].encode('utf-8')
-        self._attr_values = []
-      elif name=='value':
-        self._attr_value = ''
-        self._base64_encoding = attrs.get('encoding','').lower()=='base64'
-      # Handle object class tags
-      elif name=='objectclass':
-        self._object_classes = []
-      elif name=='oc-value':
-        self._oc_value = ''
-      # Unhandled tags
-      else:
-        raise ValueError,'Unknown tag %s' % (raw_name)
-
-    def endElement(self,raw_name):
-      assert raw_name.startswith('dsml:'),'Illegal name'
-      name = raw_name[5:]
-      if name=='dsml':
-        pass
-      elif name=='directory-entries':
-        self._parsing_entries = 0
-      elif name=='entry':
-        self._parser_instance.handle(self._dn,self._entry)
-        del self._dn
-        del self._entry
-      elif name=='attr':
-        self._entry[self._attr_type] = self._attr_values
-        del self._attr_type
-        del self._attr_values
-      elif name=='value':
-        if self._base64_encoding:
-          attr_value = base64.decodestring(self._attr_value.strip())
-        else:
-          attr_value = self._attr_value.strip().encode('utf-8')
-        self._attr_values.append(attr_value)
-        del attr_value
-        del self._attr_value
-        del self._base64_encoding
-      # Handle object class tags
-      elif name=='objectclass':
-        self._entry['objectClass'] = self._object_classes
-        del self._object_classes
-      elif name=='oc-value':
-        self._object_classes.append(self._oc_value.strip().encode('utf-8'))
-        del self._oc_value
-      # Unhandled tags
-      else:
-        raise ValueError,'Unknown tag %s' % (raw_name)
-
-    def characters(self,ch):
-      if self.__dict__.has_key('_oc_value'):
-        self._oc_value = self._oc_value + ch
-      elif self.__dict__.has_key('_attr_value'):
-        self._attr_value = self._attr_value + ch
-      else:
-        pass
-
-
-  class DSMLParser:
-    """
-    Base class for a DSMLv1 parser. Applications should sub-class this
-    class and override method handle() to implement something meaningful.
-
-    Public class attributes:
-
-    records_read
-        Counter for records processed so far
-
-    Arguments:
-
-    input_file
-        File-object to read the DSMLv1 input from
-    ignored_attr_types
-        Attributes with these attribute type names will be ignored.
-    max_entries
-        If non-zero specifies the maximum number of entries to be
-        read from f.
-    line_sep
-        String used as line separator
-    """
-
-    def __init__(
-      self,
-      input_file,
-      ContentHandlerClass,
-      ignored_attr_types=None,
-      max_entries=0,
-    ):
-      self._input_file = input_file
-      self._max_entries = max_entries
-      self._ignored_attr_types = 
{}.fromkeys(map(string.lower,(ignored_attr_types or [])))
-      self._current_record = None,None
-      self.records_read = 0
-      self._parser = xml.sax.make_parser()
-      self._parser.setFeature(xml.sax.handler.feature_namespaces,0)
-      content_handler = ContentHandlerClass(self)
-      self._parser.setContentHandler(content_handler)
-
-    def handle(self,*args,**kwargs):
-      """
-      Process a single DSMLv1 entry record. This method should be
-      implemented by applications using DSMLParser.
-      """
-      import pprint
-      pprint.pprint(args)
-      pprint.pprint(kwargs)
-
-    def parse(self):
-      """
-      Continously read and parse DSML records
-      """
-      self._parser.parse(self._input_file)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/__init__.py 
new/python-ldap-2.5.1/Lib/ldap/__init__.py
--- old/python-ldap-2.4.45/Lib/ldap/__init__.py 2017-10-09 16:55:44.000000000 
+0200
+++ new/python-ldap-2.5.1/Lib/ldap/__init__.py  2017-11-12 18:30:19.000000000 
+0100
@@ -6,7 +6,7 @@
 
 # This is also the overall release version number
 
-__version__ = '2.4.45'
+from pkginfo import __version__, __author__, __license__
 
 import sys
 
@@ -17,7 +17,11 @@
   _trace_file = sys.stderr
   _trace_stack_limit = None
 
+from ldap.pkginfo import __version__
+
 import _ldap
+assert _ldap.__version__==__version__, \
+       ImportError('ldap %s and _ldap %s version mismatch!' % 
(__version__,_ldap.__version__))
 from _ldap import *
 
 OPT_NAMES_DICT = {}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/async.py 
new/python-ldap-2.5.1/Lib/ldap/async.py
--- old/python-ldap-2.4.45/Lib/ldap/async.py    2017-10-09 16:55:57.000000000 
+0200
+++ new/python-ldap-2.5.1/Lib/ldap/async.py     2017-11-12 14:00:28.000000000 
+0100
@@ -285,31 +285,3 @@
       # Search continuations are ignored
       dn,entry = resultItem
       self._ldif_writer.unparse(dn,entry)
-
-
-class DSMLWriter(FileWriter):
-  """
-  Class for writing a stream LDAP search results to a DSML file
-
-  Arguments:
-
-  l
-    LDAPObject instance
-  writer_obj
-    Either a file-like object or a dsml.DSMLWriter instance used for output
-  """
-
-  def __init__(self,l,writer_obj,headerStr='',footerStr=''):
-    import dsml
-    if isinstance(writer_obj,dsml.DSMLWriter):
-      self._dsml_writer = writer_obj
-    else:
-      self._dsml_writer = dsml.DSMLWriter(writer_obj)
-    
FileWriter.__init__(self,l,self._dsml_writer._output_file,headerStr,footerStr)
-
-  def _processSingleResult(self,resultType,resultItem):
-    if _entryResultTypes.has_key(resultType):
-      # Search continuations are ignored
-      dn,entry = resultItem
-      self._dsml_writer.unparse(dn,entry)
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/controls/__init__.py 
new/python-ldap-2.5.1/Lib/ldap/controls/__init__.py
--- old/python-ldap-2.4.45/Lib/ldap/controls/__init__.py        2017-10-09 
16:57:38.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/ldap/controls/__init__.py 2017-11-12 
17:24:06.000000000 +0100
@@ -9,7 +9,19 @@
 Each class provides support for a certain control.
 """
 
-from ldap import __version__
+from ldap.pkginfo import __version__
+
+import _ldap
+assert _ldap.__version__==__version__, \
+       ImportError('ldap %s and _ldap %s version mismatch!' % 
(__version__,_ldap.__version__))
+
+import ldap
+
+try:
+  from pyasn1.error import PyAsn1Error
+except ImportError:
+  PyAsn1Error = None
+
 
 __all__ = [
   'KNOWN_RESPONSE_CONTROLS',
@@ -32,13 +44,6 @@
 # response control OID to class registry
 KNOWN_RESPONSE_CONTROLS = {}
 
-import _ldap,ldap
-
-try:
-  from pyasn1.error import PyAsn1Error
-except ImportError:
-  PyAsn1Error = None
-
 
 class RequestControl:
   """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/controls/libldap.py 
new/python-ldap-2.5.1/Lib/ldap/controls/libldap.py
--- old/python-ldap-2.4.45/Lib/ldap/controls/libldap.py 2017-10-09 
16:57:35.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/ldap/controls/libldap.py  2017-11-12 
17:23:47.000000000 +0100
@@ -6,7 +6,14 @@
 See https://www.python-ldap.org/ for details.
 """
 
-import _ldap,ldap
+from ldap.pkginfo import __version__
+
+import _ldap
+assert _ldap.__version__==__version__, \
+       ImportError('ldap %s and _ldap %s version mismatch!' % 
(__version__,_ldap.__version__))
+
+import ldap
+
 from ldap.controls import RequestControl,LDAPControl,KNOWN_RESPONSE_CONTROLS
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/controls/ppolicy.py 
new/python-ldap-2.5.1/Lib/ldap/controls/ppolicy.py
--- old/python-ldap-2.4.45/Lib/ldap/controls/ppolicy.py 2017-10-09 
16:57:28.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/ldap/controls/ppolicy.py  2017-11-11 
21:18:23.000000000 +0100
@@ -71,24 +71,24 @@
   def decodeControlValue(self,encodedControlValue):
     ppolicyValue,_ = 
decoder.decode(encodedControlValue,asn1Spec=PasswordPolicyResponseValue())
     warning = ppolicyValue.getComponentByName('warning')
-    if warning is None:
+    if not warning.hasValue():
       self.timeBeforeExpiration,self.graceAuthNsRemaining = None,None
     else:
       timeBeforeExpiration = warning.getComponentByName('timeBeforeExpiration')
-      if timeBeforeExpiration!=None:
+      if timeBeforeExpiration.hasValue():
         self.timeBeforeExpiration = int(timeBeforeExpiration)
       else:
         self.timeBeforeExpiration = None
       graceAuthNsRemaining = warning.getComponentByName('graceAuthNsRemaining')
-      if graceAuthNsRemaining!=None:
+      if graceAuthNsRemaining.hasValue():
         self.graceAuthNsRemaining = int(graceAuthNsRemaining)
       else:
         self.graceAuthNsRemaining = None
     error = ppolicyValue.getComponentByName('error')
-    if error is None:
-      self.error = None
-    else:
+    if error.hasValue():
       self.error = int(error)
+    else:
+      self.error = None
 
 
 KNOWN_RESPONSE_CONTROLS[PasswordPolicyControl.controlType] = 
PasswordPolicyControl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/controls/psearch.py 
new/python-ldap-2.5.1/Lib/ldap/controls/psearch.py
--- old/python-ldap-2.4.45/Lib/ldap/controls/psearch.py 2017-10-09 
16:57:26.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/ldap/controls/psearch.py  2017-11-11 
21:00:39.000000000 +0100
@@ -115,18 +115,16 @@
   def decodeControlValue(self,encodedControlValue):
     ecncValue,_ = 
decoder.decode(encodedControlValue,asn1Spec=EntryChangeNotificationValue())
     self.changeType = int(ecncValue.getComponentByName('changeType'))
-    if len(ecncValue)==3:
-      self.previousDN = str(ecncValue.getComponentByName('previousDN'))
-      self.changeNumber = int(ecncValue.getComponentByName('changeNumber'))
-    elif len(ecncValue)==2:
-      if self.changeType==8:
-        self.previousDN = str(ecncValue.getComponentByName('previousDN'))
-        self.changeNumber = None
-      else:
-        self.previousDN = None
-        self.changeNumber = int(ecncValue.getComponentByName('changeNumber'))
+    previousDN = ecncValue.getComponentByName('previousDN')
+    if previousDN.hasValue():
+      self.previousDN = str(previousDN)
     else:
-      self.previousDN,self.changeNumber = None,None
+      self.previousDN = None
+    changeNumber = ecncValue.getComponentByName('changeNumber')
+    if changeNumber.hasValue():
+      self.changeNumber = int(changeNumber)
+    else:
+      self.changeNumber = None
     return (self.changeType,self.previousDN,self.changeNumber)
 
 KNOWN_RESPONSE_CONTROLS[EntryChangeNotificationControl.controlType] = 
EntryChangeNotificationControl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/controls/sss.py 
new/python-ldap-2.5.1/Lib/ldap/controls/sss.py
--- old/python-ldap-2.4.45/Lib/ldap/controls/sss.py     2017-10-09 
16:57:15.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/ldap/controls/sss.py      2017-11-12 
18:13:40.000000000 +0100
@@ -119,10 +119,17 @@
     def decodeControlValue(self, encoded):
         p, rest = decoder.decode(encoded, asn1Spec=SortResultType())
         assert not rest, 'all data could not be decoded'
-        self.result = int(p.getComponentByName('sortResult'))
-        self.result_code = 
p.getComponentByName('sortResult').prettyOut(self.result)
-        self.attribute_type_error = p.getComponentByName('attributeType')
+        sort_result = p.getComponentByName('sortResult')
+        self.sortResult = int(sort_result)
+        attribute_type = p.getComponentByName('attributeType')
+        if attribute_type.hasValue():
+            self.attributeType = attribute_type
+        else:
+            self.attributeType = None
+        # backward compability class attributes
+        self.result = self.sortResult
+        self.attribute_type_error = self.attributeType
+        # not sure whether to keep this
+        self.result_code = sort_result.prettyPrint()
 
-
-KNOWN_RESPONSE_CONTROLS[SSSRequestControl.controlType] = SSSRequestControl
 KNOWN_RESPONSE_CONTROLS[SSSResponseControl.controlType] = SSSResponseControl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/controls/vlv.py 
new/python-ldap-2.5.1/Lib/ldap/controls/vlv.py
--- old/python-ldap-2.4.45/Lib/ldap/controls/vlv.py     2017-10-09 
16:57:13.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/ldap/controls/vlv.py      2017-11-12 
17:11:00.000000000 +0100
@@ -125,13 +125,21 @@
     def decodeControlValue(self,encoded):
         p, rest = decoder.decode(encoded, 
asn1Spec=VirtualListViewResponseType())
         assert not rest, 'all data could not be decoded'
-        self.target_position = int(p.getComponentByName('targetPosition'))
-        self.content_count = int(p.getComponentByName('contentCount'))
-        self.result = int(p.getComponentByName('virtualListViewResult'))
-        self.result_code = p.getComponentByName('virtualListViewResult') \
-                .prettyOut(self.result)
-        self.context_id = p.getComponentByName('contextID')
-        if self.context_id:
-            self.context_id = str(self.context_id)
+        self.targetPosition = int(p.getComponentByName('targetPosition'))
+        self.contentCount = int(p.getComponentByName('contentCount'))
+        virtual_list_view_result = 
p.getComponentByName('virtualListViewResult')
+        self.virtualListViewResult = int(virtual_list_view_result)
+        context_id = p.getComponentByName('contextID')
+        if context_id.hasValue():
+            self.contextID = str(context_id)
+        else:
+            self.contextID = None
+        # backward compability class attributes
+        self.target_position = self.targetPosition
+        self.content_count = self.contentCount
+        self.result = self.virtualListViewResult
+        self.context_id = self.contextID
+        # not sure whether to keep this
+        self.result_code = virtual_list_view_result.prettyPrint()
 
 KNOWN_RESPONSE_CONTROLS[VLVResponseControl.controlType] = VLVResponseControl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/dn.py 
new/python-ldap-2.5.1/Lib/ldap/dn.py
--- old/python-ldap-2.4.45/Lib/ldap/dn.py       2017-10-09 16:55:51.000000000 
+0200
+++ new/python-ldap-2.5.1/Lib/ldap/dn.py        2017-11-12 17:24:18.000000000 
+0100
@@ -7,10 +7,11 @@
 - Tested with Python 2.0+
 """
 
-from ldap import __version__
-
+from ldap.pkginfo import __version__
 
 import _ldap
+assert _ldap.__version__==__version__, \
+       ImportError('ldap %s and _ldap %s version mismatch!' % 
(__version__,_ldap.__version__))
 
 import ldap.functions
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/pkginfo.py 
new/python-ldap-2.5.1/Lib/ldap/pkginfo.py
--- old/python-ldap-2.4.45/Lib/ldap/pkginfo.py  1970-01-01 01:00:00.000000000 
+0100
+++ new/python-ldap-2.5.1/Lib/ldap/pkginfo.py   2017-11-12 18:33:16.000000000 
+0100
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+"""
+meta attributes for packaging which does not import any dependencies
+"""
+__version__ = '2.5.1'
+__author__ = u'python-ldap project'
+__license__ = 'Python style'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldap/syncrepl.py 
new/python-ldap-2.5.1/Lib/ldap/syncrepl.py
--- old/python-ldap-2.4.45/Lib/ldap/syncrepl.py 2017-10-09 16:55:30.000000000 
+0200
+++ new/python-ldap-2.5.1/Lib/ldap/syncrepl.py  2017-11-11 21:03:41.000000000 
+0100
@@ -131,11 +131,13 @@
         d = decoder.decode(encodedControlValue, asn1Spec = syncStateValue())
         state = d[0].getComponentByName('state')
         uuid = UUID(bytes=d[0].getComponentByName('entryUUID'))
-        self.cookie = d[0].getComponentByName('cookie')
+        cookie = d[0].getComponentByName('cookie')
+        if cookie.hasValue():
+            self.cookie = str(self.cookie)
+        else:
+            self.cookie = None
         self.state = self.__class__.opnames[int(state)]
         self.entryUUID = str(uuid)
-        if self.cookie is not None:
-            self.cookie = str(self.cookie)
 
 KNOWN_RESPONSE_CONTROLS[SyncStateControl.controlType] = SyncStateControl
 
@@ -165,12 +167,16 @@
 
     def decodeControlValue(self, encodedControlValue):
         d = decoder.decode(encodedControlValue, asn1Spec = syncDoneValue())
-        self.cookie = d[0].getComponentByName('cookie')
-        self.refreshDeletes = d[0].getComponentByName('refreshDeletes')
-        if self.cookie is not None:
-            self.cookie = str(self.cookie)
-        if self.refreshDeletes is not None:
-            self.refreshDeletes = bool(self.refreshDeletes)
+        cookie = d[0].getComponentByName('cookie')
+        if cookie.hasValue():
+            self.cookie = str(cookie)
+        else:
+            self.cookie = None
+        refresh_deletes = d[0].getComponentByName('refreshDeletes')
+        if refresh_deletes.hasValue():
+            self.refreshDeletes = bool(refresh_deletes)
+        else:
+            self.refreshDeletes = None
 
 KNOWN_RESPONSE_CONTROLS[SyncDoneControl.controlType] = SyncDoneControl
 
@@ -263,7 +269,7 @@
         for attr in [ 'newcookie', 'refreshDelete', 'refreshPresent', 
'syncIdSet']:
             comp = d[0].getComponentByName(attr)
 
-            if comp is not None:
+            if comp.hasValue():
 
                 if attr == 'newcookie':
                     self.newcookie = str(comp)
@@ -272,7 +278,7 @@
                 val = dict()
 
                 cookie = comp.getComponentByName('cookie')
-                if cookie is not None:
+                if cookie.hasValue():
                     val['cookie'] = str(cookie)
 
                 if attr.startswith('refresh'):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldapurl.py 
new/python-ldap-2.5.1/Lib/ldapurl.py
--- old/python-ldap-2.4.45/Lib/ldapurl.py       2017-10-09 16:56:06.000000000 
+0200
+++ new/python-ldap-2.5.1/Lib/ldapurl.py        2017-11-12 18:33:31.000000000 
+0100
@@ -9,7 +9,7 @@
 2. list comprehensions are used.
 """
 
-__version__ = '2.4.45'
+__version__ = '2.5.1'
 
 __all__ = [
   # constants
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/ldif.py 
new/python-ldap-2.5.1/Lib/ldif.py
--- old/python-ldap-2.4.45/Lib/ldif.py  2017-10-09 16:56:04.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/ldif.py   2017-11-12 18:33:27.000000000 +0100
@@ -7,7 +7,7 @@
 Tested with Python 2.0+, but should work with Python 1.5.2+.
 """
 
-__version__ = '2.4.45'
+__version__ = '2.5.1'
 
 __all__ = [
   # constants
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/python_ldap.egg-info/PKG-INFO 
new/python-ldap-2.5.1/Lib/python_ldap.egg-info/PKG-INFO
--- old/python-ldap-2.4.45/Lib/python_ldap.egg-info/PKG-INFO    2017-10-09 
17:12:11.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/python_ldap.egg-info/PKG-INFO     2017-11-12 
18:34:36.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: python-ldap
-Version: 2.4.45
+Version: 2.5.1
 Summary: Python modules for implementing LDAP clients
 Home-page: https://www.python-ldap.org/
 Author: python-ldap project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-ldap-2.4.45/Lib/python_ldap.egg-info/SOURCES.txt 
new/python-ldap-2.5.1/Lib/python_ldap.egg-info/SOURCES.txt
--- old/python-ldap-2.4.45/Lib/python_ldap.egg-info/SOURCES.txt 2017-10-09 
17:12:11.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/python_ldap.egg-info/SOURCES.txt  2017-11-12 
18:34:36.000000000 +0100
@@ -43,7 +43,6 @@
 Demo/pyasn1/sessiontrack.py
 Demo/pyasn1/sss_highest_number.py
 Demo/pyasn1/syncrepl.py
-Lib/dsml.py
 Lib/ldapurl.py
 Lib/ldif.py
 Lib/slapdtest.py
@@ -56,6 +55,7 @@
 Lib/ldap/ldapobject.py
 Lib/ldap/logger.py
 Lib/ldap/modlist.py
+Lib/ldap/pkginfo.py
 Lib/ldap/resiter.py
 Lib/ldap/sasl.py
 Lib/ldap/syncrepl.py
@@ -103,8 +103,6 @@
 Modules/message.h
 Modules/options.c
 Modules/options.h
-Modules/schema.c
-Modules/schema.h
 Modules/version.c
 Modules/version.h
 Tests/__init__.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/python-ldap-2.4.45/Lib/python_ldap.egg-info/top_level.txt 
new/python-ldap-2.5.1/Lib/python_ldap.egg-info/top_level.txt
--- old/python-ldap-2.4.45/Lib/python_ldap.egg-info/top_level.txt       
2017-10-09 17:12:11.000000000 +0200
+++ new/python-ldap-2.5.1/Lib/python_ldap.egg-info/top_level.txt        
2017-11-12 18:34:36.000000000 +0100
@@ -1,5 +1,4 @@
 _ldap
-dsml
 ldap
 ldapurl
 ldif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Lib/slapdtest.py 
new/python-ldap-2.5.1/Lib/slapdtest.py
--- old/python-ldap-2.4.45/Lib/slapdtest.py     2017-10-09 16:56:01.000000000 
+0200
+++ new/python-ldap-2.5.1/Lib/slapdtest.py      2017-11-12 18:33:22.000000000 
+0100
@@ -8,7 +8,7 @@
 This module only works with Python 2.7.x since
 """
 
-__version__ = '2.4.45'
+__version__ = '2.5.1'
 
 import os
 import socket
@@ -285,7 +285,9 @@
             )
 
     def stop(self):
-        """Stops the slapd server, and waits for it to terminate"""
+        """
+        Stops the slapd server, and waits for it to terminate and cleans up
+        """
         if self._proc is not None:
             self._log.debug('stopping slapd with pid %d', self._proc.pid)
             self._proc.terminate()
@@ -294,11 +296,11 @@
 
     def restart(self):
         """
-        Restarts the slapd server; ERASING previous content.
-        Starts the server even it if isn't already running.
+        Restarts the slapd server with same data
         """
-        self.stop()
-        self.start()
+        self._proc.terminate()
+        self.wait()
+        self._start_slapd()
 
     def wait(self):
         """Waits for the slapd process to terminate by itself."""
@@ -309,7 +311,7 @@
     def _stopped(self):
         """Called when the slapd server is known to have terminated"""
         if self._proc is not None:
-            self._log.info('slapd terminated')
+            self._log.info('slapd[%d] terminated', self._proc.pid)
             self._proc = None
 
     def _cli_auth_args(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Modules/ldapmodule.c 
new/python-ldap-2.5.1/Modules/ldapmodule.c
--- old/python-ldap-2.4.45/Modules/ldapmodule.c 2017-10-09 16:59:09.000000000 
+0200
+++ new/python-ldap-2.5.1/Modules/ldapmodule.c  2017-11-12 14:45:08.000000000 
+0100
@@ -5,7 +5,6 @@
 #include "constants.h"
 #include "errors.h"
 #include "functions.h"
-#include "schema.h"
 #include "ldapcontrol.h"
 
 #include "LDAPObject.h"
@@ -39,7 +38,6 @@
        LDAPinit_constants(d);
        LDAPinit_errors(d);
        LDAPinit_functions(d);
-       LDAPinit_schema(d);
        LDAPinit_control(d);
 
        /* Check for errors */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Modules/schema.c 
new/python-ldap-2.5.1/Modules/schema.c
--- old/python-ldap-2.4.45/Modules/schema.c     2017-10-09 16:58:56.000000000 
+0200
+++ new/python-ldap-2.5.1/Modules/schema.c      1970-01-01 01:00:00.000000000 
+0100
@@ -1,282 +0,0 @@
-/* See https://www.python-ldap.org/ for details. */
-
-#include "common.h"
-
-#include "schema.h"
-#include "ldap_schema.h"
-
-/* 
-   This utility function takes a null delimited C array of (null
-   delimited) C strings, creates its python equivalent and returns a
-   new reference to it. If the array is empty or the pointer to it is
-   NULL, an empty python array is returned. 
-*/
-PyObject* c_string_array_to_python(char **string_array)
-{
-  Py_ssize_t count = 0;
-  char **s;
-  PyObject *py_list;
-  if (string_array) {
-    for (s=string_array; *s != 0; s++) count++;
-    py_list = PyList_New(count);
-    count = 0;
-    for (s=string_array; *s != 0; s++){
-      PyList_SetItem(py_list, count, PyString_FromString(*s));
-      count++;
-    }
-  } else py_list=PyList_New(0);
-  return py_list;
-}
-
-
-/*
-  This function returns a list of tuples. The first entry of each
-  tuple is a string (lsei_name), and the second is a lists built from
-  lsei_values.
-
-  Probably the C data structure is modeled along the lines of a
-  mapping "lsei_name -> (list of lsei_values)". However, there seems
-  to be no guarantee that a lsei_name is unique, so I dare not use a
-  python mapping for this beast...
- */
-PyObject* schema_extension_to_python(LDAPSchemaExtensionItem **extensions)
-{
-  Py_ssize_t count = 0;
-  LDAPSchemaExtensionItem **e;
-  PyObject *py_list, *item_tuple;
-  if (extensions) {
-    for (e = extensions; *e !=0; e++) count++;
-    py_list = PyList_New(count);
-    count = 0;
-    for (e = extensions; *e !=0; e++) {
-      item_tuple = PyTuple_New(2);
-      PyTuple_SetItem(item_tuple, 0, 
-                     PyString_FromString((*e)->lsei_name));
-      PyTuple_SetItem(item_tuple, 1, 
-                     c_string_array_to_python((*e)->lsei_values));
-      PyList_SetItem(py_list, count, item_tuple);
-      count++;
-      }
-    }
-  else py_list=PyList_New(0);
-  return py_list;
-}
-
-
-/*
-  The following four functions do the boring job: they take a python
-  string, feed it into the respective parser functions provided by
-  openldap, and build a python list from the data structure returned
-  by the C function.
- */
-
-static char doc_ldap_str2objectclass[] = 
-"";
-
-static PyObject*
-l_ldap_str2objectclass(PyObject* self, PyObject *args)
-{
-  int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
-  char *oc_string;
-  const char *errp;
-  LDAPObjectClass *o;
-  PyObject *oc_names, *oc_sup_oids, *oc_at_oids_must, 
-    *oc_at_oids_may, *py_ret;
- 
-
-  if (!PyArg_ParseTuple(args, "si", &oc_string, &flag))
-       return NULL;
-  o = ldap_str2objectclass( oc_string, &ret, &errp, flag);
-  if (ret) {
-    py_ret = PyInt_FromLong(ret);
-    return py_ret;
-  }
-
-  oc_sup_oids     = c_string_array_to_python(o->oc_sup_oids);
-  oc_names        = c_string_array_to_python(o->oc_names);
-  oc_at_oids_must = c_string_array_to_python(o->oc_at_oids_must);
-  oc_at_oids_may  = c_string_array_to_python(o->oc_at_oids_may);
-  py_ret = PyList_New(9);
-  PyList_SetItem(py_ret, 0, PyString_FromString(o->oc_oid));
-  PyList_SetItem(py_ret, 1, oc_names);
-  if (o->oc_desc) {
-    PyList_SetItem(py_ret, 2, PyString_FromString(o->oc_desc)); 
-  } else {
-    PyList_SetItem(py_ret, 2, PyString_FromString(""));
-  }
-  PyList_SetItem(py_ret, 3, PyInt_FromLong(o->oc_obsolete));
-  PyList_SetItem(py_ret, 4, oc_sup_oids);
-  PyList_SetItem(py_ret, 5, PyInt_FromLong(o->oc_kind));
-  PyList_SetItem(py_ret, 6, oc_at_oids_must);
-  PyList_SetItem(py_ret, 7, oc_at_oids_may);
-
-  PyList_SetItem(py_ret, 8, 
-                schema_extension_to_python(o->oc_extensions));
-
-  ldap_objectclass_free(o);
-  return py_ret;
-}
-
-
-static char doc_ldap_str2attributetype[] = 
-"";
-
-static PyObject*
-l_ldap_str2attributetype(PyObject* self, PyObject *args)
-{
-  int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
-  char *at_string;
-  const char *errp;
-  LDAPAttributeType *a;
-  PyObject *py_ret;
-  PyObject *at_names;
-  
-  if (!PyArg_ParseTuple(args, "si", &at_string,&flag))
-    return NULL;
-  a = ldap_str2attributetype( at_string, &ret, &errp, flag);
-  if (ret) {
-    py_ret = PyInt_FromLong(ret);
-    return py_ret;
-  }
-  
-  py_ret = PyList_New(15);
-  PyList_SetItem(py_ret, 0, PyString_FromString(a->at_oid));
-  at_names = c_string_array_to_python(a->at_names);
-  PyList_SetItem(py_ret, 1, at_names);
-  if (a->at_desc) {
-    PyList_SetItem(py_ret, 2, PyString_FromString(a->at_desc)); 
-  } else {
-    PyList_SetItem(py_ret, 2, PyString_FromString(""));
-  }
-  PyList_SetItem(py_ret, 3, PyInt_FromLong(a->at_obsolete));
-  if (a->at_sup_oid) {
-    PyList_SetItem(py_ret, 4, PyString_FromString(a->at_sup_oid)); 
-  } else {
-    PyList_SetItem(py_ret, 4, PyString_FromString(""));
-  }
-  if (a->at_equality_oid) {
-    PyList_SetItem(py_ret, 5, PyString_FromString(a->at_equality_oid)); 
-  } else {
-    PyList_SetItem(py_ret, 5, PyString_FromString(""));
-  }
-  if (a->at_ordering_oid) {
-    PyList_SetItem(py_ret, 6, PyString_FromString(a->at_ordering_oid)); 
-  } else {
-    PyList_SetItem(py_ret, 6, PyString_FromString(""));
-  }
-  if (a->at_substr_oid) {
-    PyList_SetItem(py_ret, 7, PyString_FromString(a->at_substr_oid)); 
-  } else {
-    PyList_SetItem(py_ret, 7, PyString_FromString(""));
-  }
-  if (a->at_syntax_oid) {
-    PyList_SetItem(py_ret, 8, PyString_FromString(a->at_syntax_oid)); 
-  } else {
-    PyList_SetItem(py_ret, 8, PyString_FromString(""));
-  }
-  PyList_SetItem(py_ret, 9, PyInt_FromLong(a->at_syntax_len));
-  PyList_SetItem(py_ret,10, PyInt_FromLong(a->at_single_value));
-  PyList_SetItem(py_ret,11, PyInt_FromLong(a->at_collective));
-  PyList_SetItem(py_ret,12, PyInt_FromLong(a->at_no_user_mod));
-  PyList_SetItem(py_ret,13, PyInt_FromLong(a->at_usage));
-  
-  PyList_SetItem(py_ret, 14, 
-                schema_extension_to_python(a->at_extensions));
-  ldap_attributetype_free(a);
-  return py_ret;
-}
-
-static char doc_ldap_str2syntax[] = 
-"";
-
-
-static PyObject*
-l_ldap_str2syntax(PyObject* self, PyObject *args)
-{
-  LDAPSyntax *s;
-  int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
-  const char *errp;
-  char *syn_string;
-  PyObject *py_ret, *syn_names;
-  
-  if (!PyArg_ParseTuple(args, "si", &syn_string,&flag))
-    return NULL;
-  s = ldap_str2syntax(syn_string, &ret, &errp, flag);
-  if (ret) {
-    py_ret = PyInt_FromLong(ret);
-    return py_ret;
-  }
-  py_ret = PyList_New(4);
-  PyList_SetItem(py_ret, 0, PyString_FromString(s->syn_oid));
-  syn_names = c_string_array_to_python(s->syn_names);
-  PyList_SetItem(py_ret, 1, syn_names);
-  if (s->syn_desc) {
-    PyList_SetItem(py_ret, 2, PyString_FromString(s->syn_desc)); 
-  } else {
-    PyList_SetItem(py_ret, 2, PyString_FromString(""));
-  }
-  PyList_SetItem(py_ret, 3, 
-                schema_extension_to_python(s->syn_extensions));
-  ldap_syntax_free(s);
-  return py_ret;
-}
-
-static char doc_ldap_str2matchingrule[] = 
-"";
-
-static PyObject*
-l_ldap_str2matchingrule(PyObject* self, PyObject *args)
-{
-  LDAPMatchingRule *m;
-  int ret=0, flag = LDAP_SCHEMA_ALLOW_NONE;
-  const char *errp;
-  char *mr_string;
-  PyObject *py_ret, *mr_names;
-  
-  if (!PyArg_ParseTuple(args, "si", &mr_string,&flag))
-    return NULL;
-  m = ldap_str2matchingrule(mr_string, &ret, &errp, flag);
-  if (ret) {
-    py_ret = PyInt_FromLong(ret);
-    return py_ret;
-  }
-  py_ret = PyList_New(6);
-  PyList_SetItem(py_ret, 0, PyString_FromString(m->mr_oid));
-  mr_names = c_string_array_to_python(m->mr_names);
-  PyList_SetItem(py_ret, 1, mr_names);
-  if (m->mr_desc) {
-    PyList_SetItem(py_ret, 2, PyString_FromString(m->mr_desc)); 
-  } else {
-    PyList_SetItem(py_ret, 2, PyString_FromString(""));
-  }
-  PyList_SetItem(py_ret, 3, PyInt_FromLong(m->mr_obsolete));
-  if (m->mr_syntax_oid) {
-    PyList_SetItem(py_ret, 4, PyString_FromString(m->mr_syntax_oid)); 
-  } else {
-    PyList_SetItem(py_ret, 4, PyString_FromString(""));
-  }  
-  PyList_SetItem(py_ret, 5, 
-                schema_extension_to_python(m->mr_extensions));
-  ldap_matchingrule_free(m);
-  return py_ret;
-}
-
-/* methods */
-
-static PyMethodDef methods[] = {
-    { "str2objectclass", (PyCFunction)l_ldap_str2objectclass,  METH_VARARGS,
-       doc_ldap_str2objectclass },
-    { "str2attributetype", (PyCFunction)l_ldap_str2attributetype,      
-      METH_VARARGS, doc_ldap_str2attributetype },
-    { "str2syntax", (PyCFunction)l_ldap_str2syntax, 
-      METH_VARARGS, doc_ldap_str2syntax },
-    { "str2matchingrule", (PyCFunction)l_ldap_str2matchingrule, 
-      METH_VARARGS, doc_ldap_str2matchingrule },
-    { NULL, NULL }
-};
-
-
-void
-LDAPinit_schema( PyObject* d ) {
-    LDAPadd_methods( d, methods );
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Modules/schema.h 
new/python-ldap-2.5.1/Modules/schema.h
--- old/python-ldap-2.4.45/Modules/schema.h     2017-10-09 16:58:07.000000000 
+0200
+++ new/python-ldap-2.5.1/Modules/schema.h      1970-01-01 01:00:00.000000000 
+0100
@@ -1,13 +0,0 @@
-/* See https://www.python-ldap.org/ for details. */
-
-#ifndef __h_schema_
-#define __h_schema_
-
-
-
-#include "common.h"
-extern void LDAPinit_schema( PyObject* );
-
-
-#endif /* __h_schema_ */
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/PKG-INFO 
new/python-ldap-2.5.1/PKG-INFO
--- old/python-ldap-2.4.45/PKG-INFO     2017-10-09 17:12:12.000000000 +0200
+++ new/python-ldap-2.5.1/PKG-INFO      2017-11-12 18:34:36.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: python-ldap
-Version: 2.4.45
+Version: 2.5.1
 Summary: Python modules for implementing LDAP clients
 Home-page: https://www.python-ldap.org/
 Author: python-ldap project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/TODO new/python-ldap-2.5.1/TODO
--- old/python-ldap-2.4.45/TODO 2017-10-09 17:00:21.000000000 +0200
+++ new/python-ldap-2.5.1/TODO  2017-11-12 14:24:24.000000000 +0100
@@ -20,7 +20,6 @@
 (Everybody asking for the latter should check the mailing list archive first.)
 - Caching of search requests for each LDAPObject instance
 - LDIF parser for replication logs and change records
-- DSMLv2 support
 
 Tests/
 - Clean up and finish the mess of small test scripts started.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/Tests/t_ldapobject.py 
new/python-ldap-2.5.1/Tests/t_ldapobject.py
--- old/python-ldap-2.4.45/Tests/t_ldapobject.py        2017-10-09 
16:56:21.000000000 +0200
+++ new/python-ldap-2.5.1/Tests/t_ldapobject.py 2017-11-12 18:15:54.000000000 
+0100
@@ -27,6 +27,12 @@
 cn: %(rootcn)s
 userPassword: %(rootpw)s
 
+dn: cn=user1,%(suffix)s
+objectClass: applicationProcess
+objectClass: simpleSecurityObject
+cn: user1
+userPassword: user1_pw
+
 dn: cn=Foo1,%(suffix)s
 objectClass: organizationalRole
 cn: Foo1
@@ -185,11 +191,27 @@
 
 class Test02_ReconnectLDAPObject(Test01_SimpleLDAPObject):
     """
-    test LDAP search operations
+    test ReconnectLDAPObject by restarting slapd
     """
 
     ldap_object_class = ReconnectLDAPObject
 
+    def test_reconnect_sasl_external(self):
+        l = self.ldap_object_class(self.server.ldapi_uri)
+        l.sasl_external_bind_s()
+        authz_id = l.whoami_s()
+        self.assertEqual(authz_id, 'dn:'+self.server.root_dn.lower())
+        self.server.restart()
+        self.assertEqual(l.whoami_s(), authz_id)
+
+    def test_reconnect_simple_bind(self):
+        l = self.ldap_object_class(self.server.ldapi_uri)
+        bind_dn = 'cn=user1,'+self.server.suffix
+        l.simple_bind_s(bind_dn, 'user1_pw')
+        self.assertEqual(l.whoami_s(), 'dn:'+bind_dn)
+        self.server.restart()
+        self.assertEqual(l.whoami_s(), 'dn:'+bind_dn)
+
 
 if __name__ == '__main__':
     unittest.main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/python-ldap-2.4.45/setup.py 
new/python-ldap-2.5.1/setup.py
--- old/python-ldap-2.4.45/setup.py     2017-10-09 16:56:38.000000000 +0200
+++ new/python-ldap-2.5.1/setup.py      2017-11-12 18:30:12.000000000 +0100
@@ -14,20 +14,8 @@
 from ConfigParser import ConfigParser
 import sys,os,string,time
 
-##################################################################
-# Weird Hack to grab release version of python-ldap from local dir
-##################################################################
-exec_startdir = os.path.dirname(os.path.abspath(sys.argv[0]))
-package_init_file_name = 
reduce(os.path.join,[exec_startdir,'Lib','ldap','__init__.py'])
-f = open(package_init_file_name,'r')
-s = f.readline()
-while s:
-  s = string.strip(s)
-  if s[0:11]=='__version__':
-    version = eval(string.split(s,'=')[1])
-    break
-  s = f.readline()
-f.close()
+sys.path.insert(0, os.path.join(os.getcwd(), 'Lib/ldap'))
+import pkginfo
 
 #-- A class describing the features and requirements of OpenLDAP 2.0
 class OpenLDAP2:
@@ -78,7 +66,8 @@
 setup(
   #-- Package description
   name = name,
-  version = version,
+  license=pkginfo.__license__,
+  version=pkginfo.__version__,
   description = 'Python modules for implementing LDAP clients',
   long_description = """python-ldap:
   python-ldap provides an object-oriented API to access LDAP directory servers
@@ -87,7 +76,7 @@
   (e.g. processing LDIF, LDAPURLs, LDAPv3 schema, LDAPv3 extended operations
   and controls, etc.). 
   """,
-  author = 'python-ldap project',
+  author = pkginfo.__author__,
   author_email = '[email protected]',
   url = 'https://www.python-ldap.org/',
   download_url = 'https://pypi.python.org/pypi/python-ldap/',
@@ -108,7 +97,6 @@
     'Topic :: System :: Systems Administration :: Authentication/Directory :: 
LDAP',
     'License :: OSI Approved :: Python Software Foundation License',
   ],
-  license = 'Python style',
   #-- C extension modules
   ext_modules = [
     Extension(
@@ -120,7 +108,6 @@
         'Modules/constants.c',
         'Modules/errors.c',
         'Modules/functions.c',
-        'Modules/schema.c',
         'Modules/ldapmodule.c',
         'Modules/message.c',
         'Modules/version.c',
@@ -138,14 +125,13 @@
         ('ldap_r' in LDAP_CLASS.libs or 'oldap_r' in 
LDAP_CLASS.libs)*[('HAVE_LIBLDAP_R',None)] + \
         ('sasl' in LDAP_CLASS.libs or 'sasl2' in LDAP_CLASS.libs or 'libsasl' 
in LDAP_CLASS.libs)*[('HAVE_SASL',None)] + \
         ('ssl' in LDAP_CLASS.libs and 'crypto' in 
LDAP_CLASS.libs)*[('HAVE_TLS',None)] + \
-        [('LDAPMODULE_VERSION', version)]
+        [('LDAPMODULE_VERSION', pkginfo.__version__)]
     ),
   ],
   #-- Python "stand alone" modules
   py_modules = [
     'ldapurl',
     'ldif',
-    'dsml',
     'ldap',
     'slapdtest',
     'ldap.async',
@@ -169,6 +155,7 @@
     'ldap.ldapobject',
     'ldap.logger',
     'ldap.modlist',
+    'ldap.pkginfo',
     'ldap.resiter',
     'ldap.sasl',
     'ldap.schema',


Reply via email to