Skip to content

Commit e716349

Browse files
authored
Doc: Add dedicated page for bytes_mode
1 parent 9752c96 commit e716349

File tree

5 files changed

+121
-42
lines changed

5 files changed

+121
-42
lines changed

CHANGES

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@ Released 3.0.0 xxxx-xx-xx
33

44
Changes since 2.4.45:
55

6-
Mandatory prerequisites:
7-
- Python 2.7.x or 3.3+
8-
- pyasn1 0.3.7+ and pyasn1_modules 0.1.5+
6+
New dependencies (automatically installed when using pip):
7+
- pyasn1 0.3.7+
8+
- pyasn1_modules 0.1.5+
99

10-
Python 3 support is merged from the pyldap fork (https://github.com/pyldap)
10+
Removed support for Python 2.6.
11+
12+
Python 3 support and bytes_mode:
13+
- merged from the pyldap fork (https://github.com/pyldap)
14+
- please see documentation on bytes_mode and text/bytes handling:
15+
https://python-ldap.readthedocs.io/en/latest/bytes_mode.html
1116

1217
Infrastructure:
1318
- Add .gitignore

Doc/bytes_mode.rst

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
.. _text-bytes:
2+
3+
Bytes/text management
4+
=====================
5+
6+
Python 3 introduces a hard distinction between *text* (``str``) – sequences of
7+
characters (formally, *Unicode codepoints*) – and ``bytes`` – sequences of
8+
8-bit values used to encode *any* kind of data for storage or transmission.
9+
10+
Python 2 has the same distinction between ``str`` (bytes) and
11+
``unicode`` (text).
12+
However, values can be implicitly converted between these types as needed,
13+
e.g. when comparing or writing to disk or the network.
14+
The implicit encoding and decoding can be a source of subtle bugs when not
15+
designed and tested adequately.
16+
17+
In python-ldap 2.x (for Python 2), bytes were used for all fields,
18+
including those guaranteed to be text.
19+
20+
From version 3.0, python-ldap uses text where appropriate.
21+
On Python 2, the `bytes mode <bytes_mode>`_ setting influences how text is
22+
handled.
23+
24+
25+
What's text, and what's bytes
26+
-----------------------------
27+
28+
The LDAP protocol states that some fields (distinguished names, relative
29+
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).
32+
33+
Attribute *values*, on the other hand, **MAY**
34+
contain any type of data, including text.
35+
To know what type of data is represented, python-ldap would need access to the
36+
schema, which is not always available (nor always correct).
37+
Thus, attribute values are *always* treated as ``bytes``.
38+
Encoding/decoding to other formats – text, images, etc. – is left to the caller.
39+
40+
41+
.. _bytes_mode:
42+
43+
The bytes mode
44+
--------------
45+
46+
The behavior of python-ldap 3.0 in Python 2 is influenced by a ``bytes_mode``
47+
argument to :func:`ldap.initialize`.
48+
The argument can take these values:
49+
50+
``bytes_mode=True``: backwards-compatible
51+
52+
Text values returned from python-ldap are always bytes (``str``).
53+
Text values supplied to python-ldap may be either bytes or Unicode.
54+
The encoding for bytes is always assumed to be UTF-8.
55+
56+
Not available in Python 3.
57+
58+
``bytes_mode=False``: strictly future-compatible
59+
60+
Text values must be represented as ``unicode``.
61+
An error is raised if python-ldap receives a text value as bytes (``str``).
62+
63+
Unspecified: relaxed mode with warnings
64+
65+
Causes a warning on Python 2.
66+
67+
Text values returned from python-ldap are always ``unicode``.
68+
Text values supplied to python-ldap should be ``unicode``;
69+
warnings are emitted when they are not.
70+
71+
Backwards-compatible behavior is not scheduled for removal until Python 2
72+
itself reaches end of life.
73+
74+
75+
Porting recommendations
76+
-----------------------
77+
78+
Since end of life of Python 2 is coming in a few years,
79+
projects are strongly urged to make their code compatible with Python 3.
80+
General instructions for this are provided `in Python documentation`_ and in
81+
the `Conservative porting guide`_.
82+
83+
.. _in Python documentation: https://docs.python.org/3/howto/pyporting.html
84+
.. _Conservative porting guide: http://portingguide.readthedocs.io/en/latest/
85+
86+
87+
When porting from python-ldap 2.x, users are advised to update their code
88+
to set ``bytes_mode=False``, and fix any resulting failures.
89+
90+
The typical usage is as follows.
91+
Note that only the result's *values* are of the ``bytes`` type:
92+
93+
.. code-block:: pycon
94+
95+
>>> import ldap
96+
>>> con = ldap.initialize('ldap://localhost:389', bytes_mode=False)
97+
>>> con.simple_bind_s(u'login', u'secret_password')
98+
>>> results = con.search_s(u'ou=people,dc=example,dc=org', ldap.SCOPE_SUBTREE, u"(cn=Raphaël)")
99+
>>> results
100+
[
101+
("cn=Raphaël,ou=people,dc=example,dc=org", {
102+
'cn': [b'Rapha\xc3\xabl'],
103+
'sn': [b'Barrois'],
104+
}),
105+
]

Doc/index.rst

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -68,47 +68,13 @@ Contents
6868
:maxdepth: 2
6969

7070
installing.rst
71+
bytes_mode.rst
7172
reference/index.rst
7273
resources.rst
7374
contributing.rst
7475
faq.rst
7576

7677

77-
Bytes/text management
78-
---------------------
79-
80-
The LDAP protocol states that some fields (distinguished names, relative distinguished names,
81-
attribute names, queries) be encoded in UTF-8; some other (mostly attribute *values*) **MAY**
82-
contain any type of data, and thus be treated as bytes.
83-
84-
In Python 2, ``python-ldap`` used bytes for all fields, including those guaranteed to be text.
85-
In order to support Python 3, this distinction is made explicit. This is done
86-
through the ``bytes_mode`` flag to ``ldap.initialize()``.
87-
88-
When porting from ``python-ldap`` 2.x, users are advised to update their code to set ``bytes_mode=False``
89-
on calls to these methods.
90-
Under Python 2, ``python-pyldap`` aggressively checks the type of provided arguments, and will raise a ``TypeError``
91-
for any invalid parameter.
92-
However, if the ``bytes_mode`` kwarg isn't provided, ``pyldap`` will only
93-
raise warnings.
94-
95-
The typical usage is as follows; note that only the result's *values* are of the bytes type:
96-
97-
.. code-block:: pycon
98-
99-
>>> import ldap
100-
>>> con = ldap.initialize('ldap://localhost:389', bytes_mode=False)
101-
>>> con.simple_bind_s('login', 'secret_password')
102-
>>> results = con.search_s('ou=people,dc=example,dc=org', ldap.SCOPE_SUBTREE, "(cn=Raphaël)")
103-
>>> results
104-
[
105-
("cn=Raphaël,ou=people,dc=example,dc=org", {
106-
'cn': [b'Rapha\xc3\xabl'],
107-
'sn': [b'Barrois'],
108-
}),
109-
]
110-
111-
11278
Indices and tables
11379
------------------
11480

Doc/reference/ldap.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Functions
2929

3030
This module defines the following functions:
3131

32-
.. py:function:: initialize(uri [, trace_level=0 [, trace_file=sys.stdout [, trace_stack_limit=None]]]) -> LDAPObject object
32+
.. py:function:: initialize(uri [, trace_level=0 [, trace_file=sys.stdout [, trace_stack_limit=None, [bytes_mode=None]]]]) -> LDAPObject object
3333
3434
Initializes a new connection object for accessing the given LDAP server,
3535
and return an LDAP object (see :ref:`ldap-objects`) used to perform operations
@@ -48,11 +48,14 @@ This module defines the following functions:
4848
that nothing is sent on the wire. The error handling in the calling
4949
application has to correctly handle this behaviour.
5050

51-
The optional arguments are for generating debug log information:
51+
Three optional arguments are for generating debug log information:
5252
*trace_level* specifies the amount of information being logged,
5353
*trace_file* specifies a file-like object as target of the debug log and
5454
*trace_stack_limit* specifies the stack limit of tracebacks in debug log.
5555

56+
The *bytes_mode* argument specifies text/bytes behavior under Python 2.
57+
See :ref:`text-bytes` for a complete documentation.
58+
5659
Possible values for *trace_level* are
5760
:py:const:`0` for no logging,
5861
:py:const:`1` for only logging the method calls with arguments,

Lib/ldap/functions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def initialize(uri,trace_level=0,trace_file=sys.stdout,trace_stack_limit=None, b
7777
File object where to write the trace output to.
7878
Default is to use stdout.
7979
bytes_mode
80-
Whether to enable "bytes_mode" for backwards compatibility under Py2.
80+
Whether to enable :ref:`bytes_mode` for backwards compatibility under Py2.
8181
"""
8282
return LDAPObject(uri,trace_level,trace_file,trace_stack_limit,bytes_mode)
8383

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