Skip to content

Commit 4c9c526

Browse files
committed
Merge Python 3 porting (and infrastructure improvements) from pyldap
The full history of the pyldap fork can be found at https://github.com/pyldap/pyldap/
2 parents fc020d0 + 3138957 commit 4c9c526

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1478
-586
lines changed

.gitignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
2+
# Auto-generated
3+
.*.swp
4+
*.pyc
5+
__pycache__/
6+
.tox
7+
8+
# shared libs installed by 'setup.py test'
9+
/Lib/*.so*
10+
/Lib/*.dylib
11+
/Lib/*.pyd
12+
13+
# Build related
14+
*.egg-info
15+
build/
16+
dist/
17+
PKG-INFO

.travis.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
language: python
2+
3+
python:
4+
- '2.7'
5+
- '3.3'
6+
- '3.4'
7+
- '3.5'
8+
- '3.6'
9+
# Note: when updating Python versions, also change setup.py and tox.ini
10+
11+
sudo: false
12+
13+
cache: pip
14+
15+
addons:
16+
apt:
17+
packages:
18+
- ldap-utils
19+
- slapd
20+
21+
install:
22+
- pip install "pip>=7.1.0"
23+
- pip install tox-travis tox
24+
25+
script: tox

CHANGES

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,30 @@
11
----------------------------------------------------------------
2-
Released 2.5.2 2017-11-20
3-
4-
Changes since 2.5.1:
5-
6-
Modules/
7-
* PyBytes_ instead of PyString_ and added PyInt_FromLong compat macro
8-
* moved code from version.c to ldapmodule.c
9-
* removed obsolete back-ward compability constants from common.h
10-
* build checks whether LDAP_API_VERSION is OpenLDAP 2.4.x
11-
* _ldap.__author__ and _ldap.__license__ also set from ldap.pkginfo
12-
* assume C extension API for Python 2.7+
13-
14-
Lib/
15-
* removed all dependencies on modules string and types
16-
* removed use of .has_key()
17-
* removed class ldap.ldapobject.NonblockingLDAPObject
18-
* new global constant ldap.LIBLDAP_API_INFO
19-
* right after importing _ldap there is a call into libldap to initialize it
20-
* method .decodeControlValue() of SSSResponseControl and VLVResponseControl
21-
does not set class attribute result_code anymore
22-
* always use bytes() for UUID() constructor in ldap.syncrepl
23-
* module ldif now uses functions b64encode() and b64decode()
24-
* fixed pickling and restoring of ReconnectLDAPObject
25-
26-
Tests/
27-
* scripts do not directly call SlapdTestCase.setUpClass() anymore
28-
* added LDIF test with folded, base64-encoded attribute
29-
* added more tests for sub-module ldap.dn
30-
* added tests for ldap.syncrepl (thanks to Karl Kornel)
31-
32-
----------------------------------------------------------------
33-
Released 2.5.1 2017-11-12
2+
Released 3.0.0 xxxx-xx-xx
343

354
Changes since 2.4.45:
365

376
Mandatory prerequisites:
38-
- Python 2.7.x
7+
- Python 2.7.x or 3.3+
398
- pyasn1 0.3.7+ and pyasn1_modules 0.1.5+
409

10+
Python 3 support is merged from the pyldap fork (https://github.com/pyldap)
11+
12+
Infrastructure:
13+
- Add .gitignore
14+
- Re-format README to ReStructured Text
15+
- Setup for automatic testing using Travis CI
16+
4117
Modules/
18+
(thanks to Michael Ströder)
4219
* removed unused code schema.c
20+
* moved code from version.c to ldapmodule.c
21+
* removed obsolete back-ward compability constants from common.h
22+
* build checks whether LDAP_API_VERSION is OpenLDAP 2.4.x
23+
* _ldap.__author__ and _ldap.__license__ also set from ldap.pkginfo
24+
* assume C extension API for Python 2.7+
4325

4426
Lib/
27+
(thanks to Michael Ströder)
4528
* ldap.__version__, ldap.__author__ and ldap.__license__ now
4629
imported from new sub-module ldap.pkginfo also to setup.py
4730
* Added safety assertion when importing _ldap:
@@ -58,9 +41,35 @@ Lib/
5841
but should not be used in new code because they might be removed
5942
in a later release.
6043
* removed SSSRequestControl from ldap.controls.KNOWN_RESPONSE_CONTROLS
44+
* removed all dependencies on modules string and types
45+
* removed use of .has_key()
46+
* removed class ldap.ldapobject.NonblockingLDAPObject
47+
* new global constant ldap.LIBLDAP_API_INFO
48+
* right after importing _ldap there is a call into libldap to initialize it
49+
* method .decodeControlValue() of SSSResponseControl and VLVResponseControl
50+
does not set class attribute result_code anymore
51+
* always use bytes() for UUID() constructor in ldap.syncrepl
52+
* module ldif now uses functions b64encode() and b64decode()
53+
* fixed pickling and restoring of ReconnectLDAPObject
54+
55+
Lib/slapdtest.py
56+
* Automatically try some common locations for SCHEMADIR
57+
* Ensure server is stopped when the process exits
6158

6259
Tests/
60+
(thanks to Michael Ströder)
6361
* added explicit reconnect tests for ReconnectLDAPObject
62+
* scripts do not directly call SlapdTestCase.setUpClass() anymore
63+
* added LDIF test with folded, base64-encoded attribute
64+
* added more tests for sub-module ldap.dn
65+
* added tests for ldap.syncrepl (thanks to Karl Kornel)
66+
67+
Tests/
68+
(thanks to pyldap contributors):
69+
* Expand cidict membership test
70+
* Add test suite for binds
71+
* Add test suite for edits
72+
* Add a smoke-check for listall() and attribute_types()
6473

6574
----------------------------------------------------------------
6675
Released 2.4.45 2017-10-09

Demo/Lib/ldap/async/deltree.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import print_function
2+
13
import ldap,ldap.async
24

35
class DeleteLeafs(ldap.async.AsyncSearchHandler):
@@ -15,7 +17,7 @@ def __init__(self,l):
1517

1618
def startSearch(self,searchRoot,searchScope):
1719
if not searchScope in [ldap.SCOPE_ONELEVEL,ldap.SCOPE_SUBTREE]:
18-
raise ValueError, "Parameter searchScope must be either ldap.SCOPE_ONELEVEL or ldap.SCOPE_SUBTREE."
20+
raise ValueError("Parameter searchScope must be either ldap.SCOPE_ONELEVEL or ldap.SCOPE_SUBTREE.")
1921
self.nonLeafEntries = []
2022
self.deletedEntries = 0
2123
ldap.async.AsyncSearchHandler.startSearch(
@@ -28,7 +30,7 @@ def startSearch(self,searchRoot,searchScope):
2830
)
2931

3032
def _processSingleResult(self,resultType,resultItem):
31-
if self._entryResultTypes.has_key(resultType):
33+
if resultType in self._entryResultTypes:
3234
# Don't process search references
3335
dn,entry = resultItem
3436
hasSubordinates = entry.get(
@@ -45,7 +47,7 @@ def _processSingleResult(self,resultType,resultItem):
4547
else:
4648
try:
4749
self._l.delete_s(dn)
48-
except ldap.NOT_ALLOWED_ON_NONLEAF,e:
50+
except ldap.NOT_ALLOWED_ON_NONLEAF as e:
4951
self.nonLeafEntries.append(dn)
5052
else:
5153
self.deletedEntries = self.deletedEntries+1
@@ -62,7 +64,7 @@ def DelTree(l,dn,scope=ldap.SCOPE_ONELEVEL):
6264
non_leaf_entries = leafs_deleter.nonLeafEntries[:]
6365
while non_leaf_entries:
6466
dn = non_leaf_entries.pop()
65-
print deleted_entries,len(non_leaf_entries),dn
67+
print(deleted_entries,len(non_leaf_entries),dn)
6668
leafs_deleter.startSearch(dn,ldap.SCOPE_SUBTREE)
6769
leafs_deleter.processResults()
6870
deleted_entries = deleted_entries+leafs_deleter.deletedEntries

Demo/Lib/ldapurl/urlsearch.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,30 @@
33
44
No output of LDAP data is produced except trace output.
55
"""
6-
6+
from __future__ import print_function
77
import sys,getpass,ldap,ldapurl
88

99
try:
1010
ldapUrl = ldapurl.LDAPUrl(ldapUrl=sys.argv[1])
1111
except IndexError:
12-
print 'Usage: %s [LDAP URL]' % (sys.argv[0])
12+
print('Usage: %s [LDAP URL]' % (sys.argv[0]))
1313
sys.exit(1)
1414

1515
for a in [
1616
'urlscheme','hostport','dn','attrs','scope',
1717
'filterstr','extensions','who','cred'
1818
]:
19-
print a,repr(getattr(ldapUrl,a))
19+
print(a,repr(getattr(ldapUrl,a)))
2020

2121
l = ldap.initialize(ldapUrl.initializeUrl(),trace_level=1)
2222
if ldapUrl.who!=None:
2323
if ldapUrl.cred!=None:
2424
cred=ldapUrl.cred
2525
else:
26-
print 'Enter password for simple bind with',repr(ldapUrl.who)
26+
print('Enter password for simple bind with',repr(ldapUrl.who))
2727
cred=getpass.getpass()
2828
l.simple_bind_s(ldapUrl.who,cred)
2929

3030
res = l.search_s(ldapUrl.dn,ldapUrl.scope,ldapUrl.filterstr,ldapUrl.attrs)
3131

32-
print len(res),'search results'
32+
print(len(res),'search results')

Demo/initialize.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
ldaps://localhost:1391 (LDAP over SSL)
88
ldapi://%2ftmp%2fopenldap2 (domain socket /tmp/openldap2)
99
"""
10+
from __future__ import print_function
1011

1112
import sys,os,ldap
1213

@@ -23,10 +24,10 @@
2324
# Complete path name of the file containing all trusted CA certs
2425
CACERTFILE='/etc/ssl/ca-bundle.pem'
2526

26-
print """##################################################################
27+
print("""##################################################################
2728
# LDAPv3 connection with StartTLS ext. op.
2829
##################################################################
29-
"""
30+
""")
3031

3132
# Create LDAPObject instance
3233
l = ldap.initialize('ldap://localhost:1390',trace_level=ldapmodule_trace_level,trace_file=ldapmodule_trace_file)
@@ -44,19 +45,19 @@
4445
# Now try StartTLS extended operation
4546
l.start_tls_s()
4647

47-
print '***ldap.OPT_X_TLS_VERSION',l.get_option(ldap.OPT_X_TLS_VERSION)
48-
print '***ldap.OPT_X_TLS_CIPHER',l.get_option(ldap.OPT_X_TLS_CIPHER)
48+
print('***ldap.OPT_X_TLS_VERSION',l.get_option(ldap.OPT_X_TLS_VERSION))
49+
print('***ldap.OPT_X_TLS_CIPHER',l.get_option(ldap.OPT_X_TLS_CIPHER))
4950

5051
# Try an explicit anon bind to provoke failure
5152
l.simple_bind_s('','')
5253

5354
# Close connection
5455
l.unbind_s()
5556

56-
print """##################################################################
57+
print("""##################################################################
5758
# LDAPv3 connection over SSL
5859
##################################################################
59-
"""
60+
""")
6061

6162
# Create LDAPObject instance
6263
l = ldap.initialize('ldaps://localhost:1391',trace_level=ldapmodule_trace_level,trace_file=ldapmodule_trace_file)
@@ -74,16 +75,16 @@
7475
# Try an explicit anon bind to provoke failure
7576
l.simple_bind_s('','')
7677

77-
print '***ldap.OPT_X_TLS_VERSION',l.get_option(ldap.OPT_X_TLS_VERSION)
78-
print '***ldap.OPT_X_TLS_CIPHER',l.get_option(ldap.OPT_X_TLS_CIPHER)
78+
print('***ldap.OPT_X_TLS_VERSION',l.get_option(ldap.OPT_X_TLS_VERSION))
79+
print('***ldap.OPT_X_TLS_CIPHER',l.get_option(ldap.OPT_X_TLS_CIPHER))
7980

8081
# Close connection
8182
l.unbind_s()
8283

83-
print """##################################################################
84+
print("""##################################################################
8485
# LDAPv3 connection over Unix domain socket
8586
##################################################################
86-
"""
87+
""")
8788

8889
# Create LDAPObject instance
8990
l = ldap.initialize('ldapi://%2ftmp%2fopenldap-socket',trace_level=ldapmodule_trace_level,trace_file=ldapmodule_trace_file)

Demo/ldapcontrols.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1+
from __future__ import print_function
12
import ldap,ldapurl,pprint
23

34
from ldap.controls import LDAPControl,BooleanControl
45

56
l = ldap.initialize('ldap://localhost:1390',trace_level=2)
67

7-
print 60*'#'
8+
print(60*'#')
89

910
pprint.pprint(l.get_option(ldap.OPT_SERVER_CONTROLS))
1011
l.manage_dsa_it(1,1)
1112
pprint.pprint(l.get_option(ldap.OPT_SERVER_CONTROLS))
12-
print 60*'#'
13+
print(60*'#')
1314

1415
# Search with ManageDsaIT control (which has no value)
1516
pprint.pprint(l.search_ext_s(
@@ -19,7 +20,7 @@
1920
['*','+'],
2021
serverctrls = [ LDAPControl('2.16.840.1.113730.3.4.2',1,None) ],
2122
))
22-
print 60*'#'
23+
print(60*'#')
2324

2425
# Search with Subentries control (which has boolean value)
2526
pprint.pprint(l.search_ext_s(
@@ -30,4 +31,4 @@
3031
serverctrls = [ BooleanControl('1.3.6.1.4.1.4203.1.10.1',1,1) ],
3132
))
3233

33-
print 60*'#'
34+
print(60*'#')

Demo/ldapurl_search.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import print_function
2+
13
import sys,pprint,ldap
24

35
from ldap.ldapobject import LDAPObject
@@ -15,7 +17,7 @@ class MyLDAPUrl(LDAPUrl):
1517
ldap_url = MyLDAPUrl(sys.argv[1])
1618
trace_level = int(ldap_url.trace_level or '0')
1719

18-
print '***trace_level',trace_level
20+
print('***trace_level',trace_level)
1921

2022
ldap.trace_level = trace_level
2123

@@ -37,6 +39,6 @@ class MyLDAPUrl(LDAPUrl):
3739

3840
pprint.pprint(result)
3941

40-
print '***DIAGNOSTIC_MESSAGE',repr(l.get_option(ldap.OPT_DIAGNOSTIC_MESSAGE))
42+
print('***DIAGNOSTIC_MESSAGE',repr(l.get_option(ldap.OPT_DIAGNOSTIC_MESSAGE)))
4143

4244
l.unbind_s()

Demo/matchedvalues.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,17 @@
2727
# Matched values control: (mail=*@example.org)
2828
# dn: uid=jsmith,ou=People,dc=example,dc=com
2929
# mail: jsmith@example.org
30+
from __future__ import print_function
3031

3132
import ldap
3233
from ldap.controls import MatchedValuesControl
3334

3435
def print_result(search_result):
3536
for n in range(len(search_result)):
36-
print "dn: %s" % search_result[n][0]
37+
print("dn: %s" % search_result[n][0])
3738
for attr in search_result[n][1].keys():
3839
for i in range(len(search_result[n][1][attr])):
39-
print "%s: %s" % (attr, search_result[n][1][attr][i])
40+
print("%s: %s" % (attr, search_result[n][1][attr][i]))
4041
print
4142

4243

@@ -51,13 +52,13 @@ def print_result(search_result):
5152
mv = MatchedValuesControl(criticality=True, controlValue=control_filter)
5253

5354
res = ld.search_ext_s(base, scope, filter, attrlist = ['mail'])
54-
print "LDAP filter used: %s" % filter
55-
print "Requesting 'mail' attribute back"
55+
print("LDAP filter used: %s" % filter)
56+
print("Requesting 'mail' attribute back")
5657
print
57-
print "No matched values control:"
58+
print("No matched values control:")
5859
print_result(res)
5960

6061
res = ld.search_ext_s(base, scope, filter, attrlist = ['mail'], serverctrls = [mv])
61-
print "Matched values control: %s" % control_filter
62+
print("Matched values control: %s" % control_filter)
6263
print_result(res)
6364

0 commit comments

Comments
 (0)