Skip to content

Commit 587460a

Browse files
pyldap contributorsencukou
authored andcommitted
py3: Add and use the ldap.compat module
Add a module providing common things that differ between Python 2 and 3. (This is really a limited approximation of the six library)
1 parent 17b4000 commit 587460a

10 files changed

Lines changed: 73 additions & 22 deletions

File tree

Lib/ldap/cidict.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from ldap import __version__
1010

11-
from UserDict import IterableUserDict
11+
from ldap.compat import IterableUserDict
1212

1313

1414
class cidict(IterableUserDict):

Lib/ldap/compat.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""Compatibility wrappers for Py2/Py3."""
2+
3+
import sys
4+
5+
if sys.version_info[0] < 3:
6+
from UserDict import UserDict, IterableUserDict
7+
from urllib import quote
8+
from urllib import quote_plus
9+
from urllib import unquote as urllib_unquote
10+
from urllib import urlopen
11+
from urlparse import urlparse
12+
13+
def unquote(uri):
14+
"""Specialized unquote that uses UTF-8 for parsing."""
15+
uri = uri.encode('ascii')
16+
unquoted = urllib_unquote(uri)
17+
return unquoted.decode('utf-8')
18+
19+
# Old-style of re-raising an exception is SyntaxError in Python 3,
20+
# so hide behind exec() so the Python 3 parser doesn't see it
21+
exec('''def reraise(exc_type, exc_value, exc_traceback):
22+
"""Re-raise an exception given information from sys.exc_info()
23+
24+
Note that unlike six.reraise, this does not support replacing the
25+
traceback. All arguments must come from a single sys.exc_info() call.
26+
"""
27+
raise exc_type, exc_value, exc_traceback
28+
''')
29+
30+
else:
31+
from collections import UserDict
32+
IterableUserDict = UserDict
33+
from urllib.parse import quote, quote_plus, unquote, urlparse
34+
from urllib.request import urlopen
35+
36+
def reraise(exc_type, exc_value, exc_traceback):
37+
"""Re-raise an exception given information from sys.exc_info()
38+
39+
Note that unlike six.reraise, this does not support replacing the
40+
traceback. All arguments must come from a single sys.exc_info() call.
41+
"""
42+
# In Python 3, all exception info is contained in one object.
43+
raise exc_value

Lib/ldap/ldapobject.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from ldap.schema import SCHEMA_ATTRS
2525
from ldap.controls import LDAPControl,DecodeControlTuples,RequestControlTuples
2626
from ldap.extop import ExtendedRequest,ExtendedResponse
27+
from ldap.compat import reraise
2728

2829
from ldap import LDAPError
2930

@@ -105,7 +106,10 @@ def _ldap_call(self,func,*args,**kwargs):
105106
pass
106107
if __debug__ and self._trace_level>=2:
107108
self._trace_file.write('=> LDAPError - %s: %s\n' % (e.__class__.__name__,str(e)))
108-
raise exc_type,exc_value,exc_traceback
109+
try:
110+
reraise(exc_type, exc_value, exc_traceback)
111+
finally:
112+
exc_type = exc_value = exc_traceback = None
109113
else:
110114
if __debug__ and self._trace_level>=2:
111115
if not diagnostic_message_success is None:

Lib/ldap/schema/models.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
See https://www.python-ldap.org/ for details.
55
"""
66

7-
import UserDict,ldap.cidict
7+
import sys
8+
9+
import ldap.cidict
10+
from ldap.compat import IterableUserDict
811

912
from ldap.schema.tokenizer import split_tokens,extract_tokens
1013

@@ -615,7 +618,7 @@ def __str__(self):
615618
return '( %s )' % ''.join(result)
616619

617620

618-
class Entry(UserDict.IterableUserDict):
621+
class Entry(IterableUserDict):
619622
"""
620623
Schema-aware implementation of an LDAP entry class.
621624
@@ -628,7 +631,7 @@ def __init__(self,schema,dn,entry):
628631
self._attrtype2keytuple = {}
629632
self._s = schema
630633
self.dn = dn
631-
UserDict.UserDict.__init__(self,{})
634+
IterableUserDict.IterableUserDict.__init__(self,{})
632635
self.update(entry)
633636

634637
def _at2key(self,nameoroid):

Lib/ldap/schema/subentry.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,9 @@ def urlfetch(uri,trace_level=0):
473473
l.unbind_s()
474474
del l
475475
else:
476-
import urllib,ldif
477-
ldif_file = urllib.urlopen(uri)
476+
import ldif
477+
from ldap.compat import urlopen
478+
ldif_file = urlopen(uri)
478479
ldif_parser = ldif.LDIFRecordList(ldif_file,max_entries=1)
479480
ldif_parser.parse()
480481
subschemasubentry_dn,s_temp = ldif_parser.all_records[0]

Lib/ldapurl.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616
'LDAPUrlExtension','LDAPUrlExtensions','LDAPUrl'
1717
]
1818

19-
import UserDict
20-
21-
from urllib import quote,unquote
19+
from ldap.compat import UserDict, quote, unquote
2220

2321
LDAP_SCOPE_BASE = 0
2422
LDAP_SCOPE_ONELEVEL = 1
@@ -132,14 +130,14 @@ def __ne__(self,other):
132130
return not self.__eq__(other)
133131

134132

135-
class LDAPUrlExtensions(UserDict.UserDict):
133+
class LDAPUrlExtensions(UserDict):
136134
"""
137135
Models a collection of LDAP URL extensions as
138136
dictionary type
139137
"""
140138

141139
def __init__(self,default=None):
142-
UserDict.UserDict.__init__(self)
140+
UserDict.__init__(self)
143141
for k,v in (default or {}).items():
144142
self[k]=v
145143

Lib/ldif.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
'LDIFCopy',
1919
]
2020

21-
import urlparse
22-
import urllib
2321
import re
2422
from base64 import b64encode, b64decode
2523

@@ -28,6 +26,8 @@
2826
except ImportError:
2927
from StringIO import StringIO
3028

29+
from ldap.compat import urlparse, urlopen
30+
3131
attrtype_pattern = r'[\w;.-]+(;[\w_-]+)*'
3232
attrvalue_pattern = r'(([^,]|\\,)+|".*?")'
3333
attrtypeandvalue_pattern = attrtype_pattern + r'[ ]*=[ ]*' + attrvalue_pattern
@@ -350,9 +350,9 @@ def _next_key_and_value(self):
350350
url = unfolded_line[colon_pos+2:].strip()
351351
attr_value = None
352352
if self._process_url_schemes:
353-
u = urlparse.urlparse(url)
353+
u = urlparse(url)
354354
if u[0] in self._process_url_schemes:
355-
attr_value = urllib.urlopen(url).read()
355+
attr_value = urlopen(url).read()
356356
else:
357357
attr_value = unfolded_line[colon_pos+1:]
358358
return attr_type,attr_value

Lib/slapdtest.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
import logging
1515
from logging.handlers import SysLogHandler
1616
import unittest
17-
import urllib
17+
18+
from ldap.compat import quote_plus
1819

1920
# a template string for generating simple slapd.conf file
2021
SLAPD_CONF_TEMPLATE = r"""
@@ -125,7 +126,7 @@ def __init__(self):
125126
self._db_directory = os.path.join(self.testrundir, "openldap-data")
126127
self.ldap_uri = "ldap://%s:%d/" % (LOCALHOST, self._port)
127128
ldapi_path = os.path.join(self.testrundir, 'ldapi')
128-
self.ldapi_uri = "ldapi://%s" % urllib.quote_plus(ldapi_path)
129+
self.ldapi_uri = "ldapi://%s" % quote_plus(ldapi_path)
129130

130131
def setup_rundir(self):
131132
"""

Tests/t_ldapurl.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"""
77

88
import unittest
9-
import urllib
9+
from ldap.compat import quote
1010

1111
import ldapurl
1212
from ldapurl import LDAPUrl
@@ -185,9 +185,9 @@ def test_combo(self):
185185
"ldap://127.0.0.1:1234/dc=example,dc=com"
186186
+ "?attr1,attr2,attr3"
187187
+ "?sub"
188-
+ "?" + urllib.quote("(objectClass=*)")
189-
+ "?bindname=" + urllib.quote("cn=d,c=au")
190-
+ ",X-BINDPW=" + urllib.quote("???")
188+
+ "?" + quote("(objectClass=*)")
189+
+ "?bindname=" + quote("cn=d,c=au")
190+
+ ",X-BINDPW=" + quote("???")
191191
+ ",trace=8"
192192
)
193193
self.assertEqual(u.urlscheme, "ldap")

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class OpenLDAP2:
137137
'ldap',
138138
'slapdtest',
139139
'ldap.async',
140+
'ldap.compat',
140141
'ldap.controls',
141142
'ldap.controls.deref',
142143
'ldap.controls.libldap',

0 commit comments

Comments
 (0)