Skip to content

Commit 4056ea2

Browse files
committed
Remove Python 2 support
python-ldap 3.4 will require Python 3.6 or newer. Signed-off-by: Christian Heimes <cheimes@redhat.com>
1 parent e885b62 commit 4056ea2

27 files changed

+98
-931
lines changed

.travis.yml

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,13 @@ addons:
1414
# Note: when updating Python versions, also change setup.py and tox.ini
1515
matrix:
1616
include:
17-
- python: 2.7
18-
env:
19-
- TOXENV=py27
20-
- WITH_GCOV=1
21-
- python: 3.4
22-
env:
23-
- TOXENV=py34
24-
- WITH_GCOV=1
25-
- python: 3.5
26-
env:
27-
- TOXENV=py35
28-
- WITH_GCOV=1
2917
- python: 3.6
3018
env:
3119
- TOXENV=py36
3220
- WITH_GCOV=1
33-
- python: pypy
21+
- python: pypy3
3422
env:
35-
- TOXENV=pypy
23+
- TOXENV=pypy3
3624
- python: 3.7
3725
env:
3826
- TOXENV=py37
@@ -68,7 +56,7 @@ matrix:
6856
env: TOXENV=doc
6957
allow_failures:
7058
- env:
71-
- TOXENV=pypy
59+
- TOXENV=pypy35
7260

7361
env:
7462
global:

Doc/bytes_mode.rst

Lines changed: 1 addition & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ What's text, and what's bytes
2727

2828
The LDAP protocol states that some fields (distinguished names, relative
2929
distinguished names, attribute names, queries) be encoded in UTF-8.
30-
In python-ldap, these are represented as text (``str`` on Python 3,
31-
``unicode`` on Python 2).
30+
In python-ldap, these are represented as text (``str`` on Python 3).
3231

3332
Attribute *values*, on the other hand, **MAY**
3433
contain any type of data, including text.
@@ -44,96 +43,3 @@ The bytes mode
4443
--------------
4544

4645
In Python 3, text values are represented as ``str``, the Unicode text type.
47-
48-
In Python 2, the behavior of python-ldap 3.0 is influenced by a ``bytes_mode``
49-
argument to :func:`ldap.initialize`:
50-
51-
``bytes_mode=True`` (backwards compatible):
52-
Text values are represented as bytes (``str``) encoded using UTF-8.
53-
54-
``bytes_mode=False`` (future compatible):
55-
Text values are represented as ``unicode``.
56-
57-
If not given explicitly, python-ldap will default to ``bytes_mode=True``,
58-
but if a ``unicode`` value is supplied to it, it will warn and use that value.
59-
60-
Backwards-compatible behavior is not scheduled for removal until Python 2
61-
itself reaches end of life.
62-
63-
64-
Errors, warnings, and automatic encoding
65-
----------------------------------------
66-
67-
While the type of values *returned* from python-ldap is always given by
68-
``bytes_mode``, for Python 2 the behavior for “wrong-type” values *passed in*
69-
can be controlled by the ``bytes_strictness`` argument to
70-
:func:`ldap.initialize`:
71-
72-
``bytes_strictness='error'`` (default if ``bytes_mode`` is specified):
73-
A ``TypeError`` is raised.
74-
75-
``bytes_strictness='warn'`` (default when ``bytes_mode`` is not given explicitly):
76-
A warning is raised, and the value is encoded/decoded
77-
using the UTF-8 encoding.
78-
79-
The warnings are of type :class:`~ldap.LDAPBytesWarning`, which
80-
is a subclass of :class:`BytesWarning` designed to be easily
81-
:ref:`filtered out <filter-bytes-warning>` if needed.
82-
83-
``bytes_strictness='silent'``:
84-
The value is automatically encoded/decoded using the UTF-8 encoding.
85-
86-
On Python 3, ``bytes_strictness`` is ignored and a ``TypeError`` is always
87-
raised.
88-
89-
When setting ``bytes_strictness``, an explicit value for ``bytes_mode`` needs
90-
to be given as well.
91-
92-
93-
Porting recommendations
94-
-----------------------
95-
96-
Since end of life of Python 2 is coming in a few years, projects are strongly
97-
urged to make their code compatible with Python 3. General instructions for
98-
this are provided :ref:`in Python documentation <pyporting-howto>` and in the
99-
`Conservative porting guide`_.
100-
101-
.. _Conservative porting guide: https://portingguide.readthedocs.io/en/latest/
102-
103-
104-
When porting from python-ldap 2.x, users are advised to update their code
105-
to set ``bytes_mode=False``, and fix any resulting failures.
106-
107-
The typical usage is as follows.
108-
Note that only the result's *values* are of the ``bytes`` type:
109-
110-
.. code-block:: pycon
111-
112-
>>> import ldap
113-
>>> con = ldap.initialize('ldap://localhost:389', bytes_mode=False)
114-
>>> con.simple_bind_s(u'login', u'secret_password')
115-
>>> results = con.search_s(u'ou=people,dc=example,dc=org', ldap.SCOPE_SUBTREE, u"(cn=Raphaël)")
116-
>>> results
117-
[
118-
("cn=Raphaël,ou=people,dc=example,dc=org", {
119-
'cn': [b'Rapha\xc3\xabl'],
120-
'sn': [b'Barrois'],
121-
}),
122-
]
123-
124-
125-
.. _filter-bytes-warning:
126-
127-
Filtering warnings
128-
------------------
129-
130-
The bytes mode warnings can be filtered out and ignored with a
131-
simple filter.
132-
133-
.. code-block:: python
134-
135-
import warnings
136-
import ldap
137-
138-
if hasattr(ldap, 'LDAPBytesWarning'):
139-
warnings.simplefilter('ignore', ldap.LDAPBytesWarning)

Doc/faq.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Usage
2929
.. _pyldap: https://pypi.org/project/pyldap/
3030

3131

32-
**Q**: Does it work with Python 2.6? (1.5|2.0|2.1|2.2|2.3|2.4|2.5)?
32+
**Q**: Does it work with Python 2.7? (1.5|2.0|2.1|2.2|2.3|2.4|2.5|2.6|2.7)?
3333

3434
**A**: No. Old versions of python-ldap are still available from PyPI, though.
3535

Doc/reference/ldap.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,8 @@ This module defines the following functions:
6363
*trace_file* specifies a file-like object as target of the debug log and
6464
*trace_stack_limit* specifies the stack limit of tracebacks in debug log.
6565

66-
The *bytes_mode* and *bytes_strictness* arguments specify text/bytes
67-
behavior under Python 2.
68-
See :ref:`text-bytes` for a complete documentation.
66+
The *bytes_mode* and *bytes_strictness* arguments are deprecated and
67+
ignored.
6968

7069
Possible values for *trace_level* are
7170
:py:const:`0` for no logging,
@@ -86,6 +85,10 @@ This module defines the following functions:
8685

8786
The *fileno* argument was added.
8887

88+
.. deprecated:: 3.4
89+
90+
*bytes_mode* and *bytes_strictness* arguments are deprecated.
91+
8992

9093
.. py:function:: get_option(option) -> int|string
9194

Doc/reference/ldapurl.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
This module parses and generates LDAP URLs. It is implemented in pure Python
1111
and does not rely on any non-standard modules. Therefore it can be used stand-
12-
alone without the rest of the python-ldap package. Compatibility note: This
13-
module has been solely tested on Python 2.x and above.
12+
alone without the rest of the python-ldap package.
1413

1514
.. seealso::
1615

Doc/sample_workflow.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ python-ldap won't affect the rest of your system::
3131

3232
$ python3 -m venv __venv__
3333

34-
(For Python 2, install `virtualenv`_ and use it instead of ``python3 -m venv``.)
35-
3634
.. _git: https://git-scm.com/
3735
.. _virtualenv: https://virtualenv.pypa.io/en/stable/
3836

Lib/ldap/cidict.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"""
88
import warnings
99

10-
from ldap.compat import MutableMapping
10+
from collections.abc import MutableMapping
1111
from ldap import __version__
1212

1313

Lib/ldap/compat.py

Lines changed: 22 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,23 @@
11
"""Compatibility wrappers for Py2/Py3."""
2-
3-
import sys
4-
import os
5-
6-
if sys.version_info[0] < 3:
7-
from UserDict import UserDict, IterableUserDict
8-
from urllib import quote
9-
from urllib import quote_plus
10-
from urllib import unquote as urllib_unquote
11-
from urllib import urlopen
12-
from urlparse import urlparse
13-
from collections import MutableMapping
14-
15-
def unquote(uri):
16-
"""Specialized unquote that uses UTF-8 for parsing."""
17-
uri = uri.encode('ascii')
18-
unquoted = urllib_unquote(uri)
19-
return unquoted.decode('utf-8')
20-
21-
# Old-style of re-raising an exception is SyntaxError in Python 3,
22-
# so hide behind exec() so the Python 3 parser doesn't see it
23-
exec('''def reraise(exc_type, exc_value, exc_traceback):
24-
"""Re-raise an exception given information from sys.exc_info()
25-
26-
Note that unlike six.reraise, this does not support replacing the
27-
traceback. All arguments must come from a single sys.exc_info() call.
28-
"""
29-
raise exc_type, exc_value, exc_traceback
30-
''')
31-
32-
else:
33-
from collections import UserDict
34-
IterableUserDict = UserDict
35-
from urllib.parse import quote, quote_plus, unquote, urlparse
36-
from urllib.request import urlopen
37-
from collections.abc import MutableMapping
38-
39-
def reraise(exc_type, exc_value, exc_traceback):
40-
"""Re-raise an exception given information from sys.exc_info()
41-
42-
Note that unlike six.reraise, this does not support replacing the
43-
traceback. All arguments must come from a single sys.exc_info() call.
44-
"""
45-
# In Python 3, all exception info is contained in one object.
46-
raise exc_value
47-
48-
try:
49-
from shutil import which
50-
except ImportError:
51-
# shutil.which() from Python 3.6
52-
# "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
53-
# 2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation;
54-
# All Rights Reserved"
55-
def which(cmd, mode=os.F_OK | os.X_OK, path=None):
56-
"""Given a command, mode, and a PATH string, return the path which
57-
conforms to the given mode on the PATH, or None if there is no such
58-
file.
59-
60-
`mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
61-
of os.environ.get("PATH"), or can be overridden with a custom search
62-
path.
63-
64-
"""
65-
# Check that a given file can be accessed with the correct mode.
66-
# Additionally check that `file` is not a directory, as on Windows
67-
# directories pass the os.access check.
68-
def _access_check(fn, mode):
69-
return (os.path.exists(fn) and os.access(fn, mode)
70-
and not os.path.isdir(fn))
71-
72-
# If we're given a path with a directory part, look it up directly rather
73-
# than referring to PATH directories. This includes checking relative to the
74-
# current directory, e.g. ./script
75-
if os.path.dirname(cmd):
76-
if _access_check(cmd, mode):
77-
return cmd
78-
return None
79-
80-
if path is None:
81-
path = os.environ.get("PATH", os.defpath)
82-
if not path:
83-
return None
84-
path = path.split(os.pathsep)
85-
86-
if sys.platform == "win32":
87-
# The current directory takes precedence on Windows.
88-
if not os.curdir in path:
89-
path.insert(0, os.curdir)
90-
91-
# PATHEXT is necessary to check on Windows.
92-
pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
93-
# See if the given file matches any of the expected path extensions.
94-
# This will allow us to short circuit when given "python.exe".
95-
# If it does match, only test that one, otherwise we have to try
96-
# others.
97-
if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
98-
files = [cmd]
99-
else:
100-
files = [cmd + ext for ext in pathext]
101-
else:
102-
# On other platforms you don't have things like PATHEXT to tell you
103-
# what file suffixes are executable, so just pass on cmd as-is.
104-
files = [cmd]
105-
106-
seen = set()
107-
for dir in path:
108-
normdir = os.path.normcase(dir)
109-
if not normdir in seen:
110-
seen.add(normdir)
111-
for thefile in files:
112-
name = os.path.join(dir, thefile)
113-
if _access_check(name, mode):
114-
return name
115-
return None
2+
import warnings
3+
4+
warnings.warn(
5+
DeprecationWarning,
6+
"The ldap.compat module is deprecated and will be removed in the future"
7+
)
8+
9+
from collections import UserDict
10+
IterableUserDict = UserDict
11+
from urllib.parse import quote, quote_plus, unquote, urlparse
12+
from urllib.request import urlopen
13+
from collections.abc import MutableMapping
14+
from shutil import which
15+
16+
def reraise(exc_type, exc_value, exc_traceback):
17+
"""Re-raise an exception given information from sys.exc_info()
18+
19+
Note that unlike six.reraise, this does not support replacing the
20+
traceback. All arguments must come from a single sys.exc_info() call.
21+
"""
22+
# In Python 3, all exception info is contained in one object.
23+
raise exc_value

Lib/ldap/controls/sss.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
from pyasn1.type import univ, namedtype, tag, namedval, constraint
2323
from pyasn1.codec.ber import encoder, decoder
2424

25-
PY2 = sys.version_info[0] <= 2
26-
if not PY2:
27-
basestring = str
28-
2925

3026
# SortKeyList ::= SEQUENCE OF SEQUENCE {
3127
# attributeType AttributeDescription,
@@ -63,7 +59,7 @@ def __init__(
6359
):
6460
RequestControl.__init__(self,self.controlType,criticality)
6561
self.ordering_rules = ordering_rules
66-
if isinstance(ordering_rules, basestring):
62+
if isinstance(ordering_rules, str):
6763
ordering_rules = [ordering_rules]
6864
for rule in ordering_rules:
6965
rule = rule.split(':')

Lib/ldap/dn.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
44
See https://www.python-ldap.org/ for details.
55
"""
6-
7-
import sys
86
from ldap.pkginfo import __version__
97

108
import _ldap
@@ -47,8 +45,6 @@ def str2dn(dn,flags=0):
4745
"""
4846
if not dn:
4947
return []
50-
if sys.version_info[0] < 3 and isinstance(dn, unicode):
51-
dn = dn.encode('utf-8')
5248
return ldap.functions._ldap_function_call(None,_ldap.str2dn,dn,flags)
5349

5450

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy