Skip to content
Snippets Groups Projects
Commit 6bd4fb2b authored by Willem van den Akker's avatar Willem van den Akker
Browse files

New upstream version 3.2.0

parent 39bbd687
Branches
Tags upstream/3.2.0
No related merge requests found
Showing with 200 additions and 124 deletions
----------------------------------------------------------------
Released 3.2.0 2019-03-13
Lib/
* Add support for X-ORIGIN in ldap.schema's ObjectClass
* Make initialize() pass extra keyword arguments to LDAPObject
* ldap.controls.sss: use str instead of basestring on Python 3
* Provide ldap._trace_* atributes in non-debug mode
Doc/
* Fix ReST syntax for links to set_option and get_option
Tests/
* Use intersphinx to link to Python documentation
* Correct type of some attribute values to bytes
* Use system-specific ENOTCONN value
Infrastructure:
* Add testing and document support for Python 3.7
* Add Python 3.8-dev to Tox and CI configuration
* Add Doc/requirements.txt for building on Read the Docs
----------------------------------------------------------------
Released 3.1.0 2018-05-25
......
......@@ -93,12 +93,11 @@ to be given as well.
Porting recommendations
-----------------------
Since end of life of Python 2 is coming in a few years,
projects are strongly urged to make their code compatible with Python 3.
General instructions for this are provided `in Python documentation`_ and in
the `Conservative porting guide`_.
Since end of life of Python 2 is coming in a few years, projects are strongly
urged to make their code compatible with Python 3. General instructions for
this are provided :ref:`in Python documentation <pyporting-howto>` and in the
`Conservative porting guide`_.
.. _in Python documentation: https://docs.python.org/3/howto/pyporting.html
.. _Conservative porting guide: https://portingguide.readthedocs.io/en/latest/
......
......@@ -31,7 +31,10 @@ from ldap import __version__
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc']
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
]
try:
import sphinxcontrib.spelling
......@@ -148,3 +151,5 @@ latex_documents = [('index', 'python-ldap.tex', 'python-ldap Documentation',
# If false, no module index is generated.
latex_use_modindex = True
intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
......@@ -99,10 +99,8 @@ From a source repository::
If you have more than one Python interpreter installed locally, you should
use the same one you plan to use python-ldap with.
Further instructions can be found in `Setuptools documentation`_.
.. _Setuptools documentation: https://docs.python.org/3/distributing/index.html
Further instructions can be found in :ref:`Setuptools documentation
<distributing-index>`.
.. _build prerequisites:
......@@ -169,11 +167,10 @@ Packages for building and testing::
setup.cfg
=========
The file setup.cfg allows to set some build and installation
parameters for reflecting the local installation of required
software packages. Only section ``[_ldap]`` is described here.
More information about other sections can be found in
`Setuptools documentation`_.
The file setup.cfg allows to set some build and installation parameters for
reflecting the local installation of required software packages. Only section
``[_ldap]`` is described here. More information about other sections can be
found in :ref:`Setuptools documentation <distributing-index>`.
.. data:: library_dirs
......
......@@ -63,6 +63,8 @@ This module defines the following functions:
:py:const:`2` for logging the method calls with arguments and the complete results and
:py:const:`9` for also logging the traceback of method calls.
Additional keyword arguments are passed to :class:`LDAPObject`.
.. seealso::
:rfc:`4516` - Lightweight Directory Access Protocol (LDAP): Uniform Resource Locator
......@@ -121,9 +123,9 @@ Options
:manpage:`ldap.conf(5)` and :manpage:`ldap_get_option(3)`
For use with functions :py:func:set_option() and :py:func:get_option()
and methods :py:method:LDAPObject.set_option() and :py:method:LDAPObject.get_option() the
following option identifiers are defined as constants:
For use with functions :py:func:`set_option` and :py:func:`get_option` and
methods :py:meth:`LDAPObject.set_option` and :py:meth:`LDAPObject.get_option`
the following option identifiers are defined as constants:
.. py:data:: OPT_API_FEATURE_INFO
......@@ -579,33 +581,16 @@ LDAPObject classes
.. py:class:: LDAPObject
Instances of :py:class:`LDAPObject` are returned by :py:func:`initialize()`
and :py:func:`open()` (deprecated). The connection is automatically unbound
Instances of :py:class:`LDAPObject` are returned by :py:func:`initialize()`.
The connection is automatically unbound
and closed when the LDAP object is deleted.
Internally :py:class:`LDAPObject` is set to :py:class:`SimpleLDAPObject`
by default.
.. py:class:: SimpleLDAPObject(uri [, trace_level=0 [, trace_file=sys.stdout [, trace_stack_limit=5]]])
This basic class wraps all methods of the underlying C API object.
The arguments are same like for function :py:func:`initialize()`.
.. py:class:: ReconnectLDAPObject(uri [, trace_level=0 [, trace_file=sys.stdout [, trace_stack_limit=5] [, retry_max=1 [, retry_delay=60.0]]]])
This class is derived from :py:class:`SimpleLDAPObject` and used for automatic
reconnects when using the synchronous request methods (see below). This class
also implements the pickle protocol.
The first arguments are same like for function :py:func:`initialize()`.
For automatic reconnects it has additional arguments:
Internally :py:class:`LDAPObject` is set to
:py:class:`~ldap.ldapobject.SimpleLDAPObject` by default.
*retry_max* specifies the number of reconnect attempts before
re-raising the :py:exc:`ldap.SERVER_DOWN` exception.
.. autoclass:: ldap.ldapobject.SimpleLDAPObject
*retry_delay* specifies the time in seconds between reconnect attempts.
.. autoclass:: ldap.ldapobject.ReconnectLDAPObject
.. _ldap-controls:
......
......@@ -26,15 +26,14 @@ Clone the repository::
$ git clone https://github.com/python-ldap/python-ldap
$ cd python-ldap
Create a `virtual environment`_ to ensure you in-development python-ldap won't
affect the rest of your system::
Create a :mod:`virtual environment <venv>` to ensure you in-development
python-ldap won't affect the rest of your system::
$ python3 -m venv __venv__
(For Python 2, install `virtualenv`_ and use it instead of ``python3 -m venv``.)
.. _git: https://git-scm.com/
.. _virtual environment: https://docs.python.org/3/library/venv.html
.. _virtualenv: https://virtualenv.pypa.io/en/stable/
Activate the virtual environment::
......
......@@ -23,6 +23,13 @@ if __debug__:
_trace_file = open(_trace_file, 'a')
atexit.register(_trace_file.close)
_trace_stack_limit = None
else:
# Any use of the _trace attributes should be guarded by `if __debug__`,
# so they should not be needed here.
# But, providing different API for debug mode is unnecessarily fragile.
_trace_level = 0
_trace_file = sys.stderr
_trace_stack_limit = None
import _ldap
assert _ldap.__version__==__version__, \
......
......@@ -12,6 +12,8 @@ __all__ = [
]
import sys
import ldap
from ldap.ldapobject import LDAPObject
from ldap.controls import (RequestControl, ResponseControl,
......@@ -20,6 +22,10 @@ from ldap.controls import (RequestControl, ResponseControl,
from pyasn1.type import univ, namedtype, tag, namedval, constraint
from pyasn1.codec.ber import encoder, decoder
PY2 = sys.version_info[0] <= 2
if not PY2:
basestring = str
# SortKeyList ::= SEQUENCE OF SEQUENCE {
# attributeType AttributeDescription,
......
......@@ -65,7 +65,10 @@ def _ldap_function_call(lock,func,*args,**kwargs):
return result
def initialize(uri,trace_level=0,trace_file=sys.stdout,trace_stack_limit=None, bytes_mode=None):
def initialize(
uri, trace_level=0, trace_file=sys.stdout, trace_stack_limit=None,
bytes_mode=None, **kwargs
):
"""
Return LDAPObject instance by opening LDAP connection to
LDAP host specified by LDAP URL
......@@ -81,8 +84,12 @@ def initialize(uri,trace_level=0,trace_file=sys.stdout,trace_stack_limit=None, b
Default is to use stdout.
bytes_mode
Whether to enable :ref:`bytes_mode` for backwards compatibility under Py2.
Additional keyword arguments (such as ``bytes_strictness``) are
passed to ``LDAPObject``.
"""
return LDAPObject(uri,trace_level,trace_file,trace_stack_limit,bytes_mode)
return LDAPObject(
uri, trace_level, trace_file, trace_stack_limit, bytes_mode, **kwargs)
def get_option(option):
......
......@@ -76,7 +76,9 @@ class NO_UNIQUE_ENTRY(ldap.NO_SUCH_OBJECT):
class SimpleLDAPObject:
"""
Drop-in wrapper class around _ldap.LDAPObject
This basic class wraps all methods of the underlying C API object.
The arguments are same as for the :func:`~ldap.initialize()` function.
"""
CLASSATTR_OPTION_MAPPING = {
......@@ -1057,15 +1059,20 @@ class SimpleLDAPObject:
class ReconnectLDAPObject(SimpleLDAPObject):
"""
In case of server failure (ldap.SERVER_DOWN) the implementations
of all synchronous operation methods (search_s() etc.) are doing
an automatic reconnect and rebind and will retry the very same
operation.
This is very handy for broken LDAP server implementations
(e.g. in Lotus Domino) which drop connections very often making
it impossible to have a long-lasting control flow in the
application.
:py:class:`SimpleLDAPObject` subclass whose synchronous request methods
automatically reconnect and re-try in case of server failure
(:exc:`ldap.SERVER_DOWN`).
The first arguments are same as for the :py:func:`~ldap.initialize()`
function.
For automatic reconnects it has additional arguments:
* retry_max: specifies the number of reconnect attempts before
re-raising the :py:exc:`ldap.SERVER_DOWN` exception.
* retry_delay: specifies the time in seconds between reconnect attempts.
This class also implements the pickle protocol.
"""
__transient_attrs__ = {
......
......@@ -2,6 +2,6 @@
"""
meta attributes for packaging which does not import any dependencies
"""
__version__ = '3.1.0'
__version__ = '3.2.0'
__author__ = u'python-ldap project'
__license__ = 'Python style'
......@@ -106,26 +106,32 @@ class ObjectClass(SchemaElement):
oid
OID assigned to the object class
names
This list of strings contains all NAMEs of the object class
All NAMEs of the object class (tuple of strings)
desc
This string contains description text (DESC) of the object class
Description text (DESC) of the object class (string, or None if missing)
obsolete
Integer flag (0 or 1) indicating whether the object class is marked
as OBSOLETE in the schema
must
This list of strings contains NAMEs or OIDs of all attributes
an entry of the object class must have
NAMEs or OIDs of all attributes an entry of the object class must have
(tuple of strings)
may
This list of strings contains NAMEs or OIDs of additional attributes
an entry of the object class may have
NAMEs or OIDs of additional attributes an entry of the object class may
have (tuple of strings)
kind
Kind of an object class:
0 = STRUCTURAL,
1 = ABSTRACT,
2 = AUXILIARY
sup
This list of strings contains NAMEs or OIDs of object classes
this object class is derived from
NAMEs or OIDs of object classes this object class is derived from
(tuple of strings)
x_origin
Value of the X-ORIGIN extension flag (tuple of strings)
Although it's not official, X-ORIGIN is used in several LDAP server
implementations to indicate the source of the associated schema
element
"""
schema_attribute = u'objectClasses'
token_defaults = {
......@@ -137,7 +143,8 @@ class ObjectClass(SchemaElement):
'AUXILIARY':None,
'ABSTRACT':None,
'MUST':(()),
'MAY':()
'MAY':(),
'X-ORIGIN':()
}
def _set_attrs(self,l,d):
......@@ -146,6 +153,7 @@ class ObjectClass(SchemaElement):
self.desc = d['DESC'][0]
self.must = d['MUST']
self.may = d['MAY']
self.x_origin = d['X-ORIGIN']
# Default is STRUCTURAL, see RFC2552 or draft-ietf-ldapbis-syntaxes
self.kind = 0
if d['ABSTRACT']!=None:
......@@ -168,6 +176,7 @@ class ObjectClass(SchemaElement):
result.append({0:' STRUCTURAL',1:' ABSTRACT',2:' AUXILIARY'}[self.kind])
result.append(self.key_list('MUST',self.must,sep=' $ '))
result.append(self.key_list('MAY',self.may,sep=' $ '))
result.append(self.key_list('X-ORIGIN',self.x_origin,quoted=1))
return '( %s )' % ''.join(result)
......@@ -190,11 +199,11 @@ class AttributeType(SchemaElement):
Class attributes:
oid
OID assigned to the attribute type
OID assigned to the attribute type (string)
names
This list of strings contains all NAMEs of the attribute type
All NAMEs of the attribute type (tuple of strings)
desc
This string contains description text (DESC) of the attribute type
Description text (DESC) of the attribute type (string, or None if missing)
obsolete
Integer flag (0 or 1) indicating whether the attribute type is marked
as OBSOLETE in the schema
......@@ -202,19 +211,19 @@ class AttributeType(SchemaElement):
Integer flag (0 or 1) indicating whether the attribute must
have only one value
syntax
String contains OID of the LDAP syntax assigned to the attribute type
OID of the LDAP syntax assigned to the attribute type
no_user_mod
Integer flag (0 or 1) indicating whether the attribute is modifiable
by a client application
equality
String contains NAME or OID of the matching rule used for
checking whether attribute values are equal
NAME or OID of the matching rule used for checking whether attribute values
are equal (string, or None if missing)
substr
String contains NAME or OID of the matching rule used for
checking whether an attribute value contains another value
NAME or OID of the matching rule used for checking whether an attribute
value contains another value (string, or None if missing)
ordering
String contains NAME or OID of the matching rule used for
checking whether attribute values are lesser-equal than
NAME or OID of the matching rule used for checking whether attribute values
are lesser-equal than (string, or None if missing)
usage
USAGE of an attribute type:
0 = userApplications
......@@ -222,8 +231,14 @@ class AttributeType(SchemaElement):
2 = distributedOperation,
3 = dSAOperation
sup
This list of strings contains NAMEs or OIDs of attribute types
this attribute type is derived from
NAMEs or OIDs of attribute types this attribute type is derived from
(tuple of strings)
x_origin
Value of the X-ORIGIN extension flag (tuple of strings).
Although it's not official, X-ORIGIN is used in several LDAP server
implementations to indicate the source of the associated schema
element
"""
schema_attribute = u'attributeTypes'
token_defaults = {
......@@ -239,7 +254,7 @@ class AttributeType(SchemaElement):
'COLLECTIVE':None,
'NO-USER-MODIFICATION':None,
'USAGE':('userApplications',),
'X-ORIGIN':(None,),
'X-ORIGIN':(),
'X-ORDERED':(None,),
}
......@@ -251,7 +266,7 @@ class AttributeType(SchemaElement):
self.equality = d['EQUALITY'][0]
self.ordering = d['ORDERING'][0]
self.substr = d['SUBSTR'][0]
self.x_origin = d['X-ORIGIN'][0]
self.x_origin = d['X-ORIGIN']
self.x_ordered = d['X-ORDERED'][0]
try:
syntax = d['SYNTAX'][0]
......@@ -302,7 +317,7 @@ class AttributeType(SchemaElement):
3:" USAGE dSAOperation",
}[self.usage]
)
result.append(self.key_attr('X-ORIGIN',self.x_origin,quoted=1))
result.append(self.key_list('X-ORIGIN',self.x_origin,quoted=1))
result.append(self.key_attr('X-ORDERED',self.x_ordered,quoted=1))
return '( %s )' % ''.join(result)
......@@ -314,7 +329,7 @@ class LDAPSyntax(SchemaElement):
oid
OID assigned to the LDAP syntax
desc
This string contains description text (DESC) of the LDAP syntax
Description text (DESC) of the LDAP syntax (string, or None if missing)
not_human_readable
Integer flag (0 or 1) indicating whether the attribute type is marked
as not human-readable (X-NOT-HUMAN-READABLE)
......@@ -358,14 +373,15 @@ class MatchingRule(SchemaElement):
oid
OID assigned to the matching rule
names
This list of strings contains all NAMEs of the matching rule
All NAMEs of the matching rule (tuple of strings)
desc
This string contains description text (DESC) of the matching rule
Description text (DESC) of the matching rule
obsolete
Integer flag (0 or 1) indicating whether the matching rule is marked
as OBSOLETE in the schema
syntax
String contains OID of the LDAP syntax this matching rule is usable with
OID of the LDAP syntax this matching rule is usable with
(string, or None if missing)
"""
schema_attribute = u'matchingRules'
token_defaults = {
......@@ -403,15 +419,15 @@ class MatchingRuleUse(SchemaElement):
oid
OID of the accompanying matching rule
names
This list of strings contains all NAMEs of the matching rule
All NAMEs of the matching rule (tuple of strings)
desc
This string contains description text (DESC) of the matching rule
Description text (DESC) of the matching rule (string, or None if missing)
obsolete
Integer flag (0 or 1) indicating whether the matching rule is marked
as OBSOLETE in the schema
applies
This list of strings contains NAMEs or OIDs of attribute types
for which this matching rule is used
NAMEs or OIDs of attribute types for which this matching rule is used
(tuple of strings)
"""
schema_attribute = u'matchingRuleUse'
token_defaults = {
......@@ -449,26 +465,29 @@ class DITContentRule(SchemaElement):
oid
OID of the accompanying structural object class
names
This list of strings contains all NAMEs of the DIT content rule
All NAMEs of the DIT content rule (tuple of strings)
desc
This string contains description text (DESC) of the DIT content rule
Description text (DESC) of the DIT content rule
(string, or None if missing)
obsolete
Integer flag (0 or 1) indicating whether the DIT content rule is marked
as OBSOLETE in the schema
aux
This list of strings contains NAMEs or OIDs of all auxiliary
object classes usable in an entry of the object class
NAMEs or OIDs of all auxiliary object classes usable in an entry of the
object class (tuple of strings)
must
This list of strings contains NAMEs or OIDs of all attributes
an entry of the object class must have which may extend the
list of required attributes of the object classes of an entry
NAMEs or OIDs of all attributes an entry of the object class must
have, which may extend the list of required attributes of the object
classes of an entry.
(tuple of strings)
may
This list of strings contains NAMEs or OIDs of additional attributes
an entry of the object class may have which may extend the
list of optional attributes of the object classes of an entry
NAMEs or OIDs of additional attributes an entry of the object class may
have. which may extend the list of optional attributes of the object
classes of an entry.
(tuple of strings)
nots
This list of strings contains NAMEs or OIDs of attributes which
may not be present in an entry of the object class
NAMEs or OIDs of attributes which may not be present in an entry of the
object class. (tuple of strings)
"""
schema_attribute = u'dITContentRules'
token_defaults = {
......@@ -515,17 +534,18 @@ class DITStructureRule(SchemaElement):
ruleid
rule ID of the DIT structure rule (only locally unique)
names
This list of strings contains all NAMEs of the DIT structure rule
All NAMEs of the DIT structure rule (tuple of strings)
desc
This string contains description text (DESC) of the DIT structure rule
Description text (DESC) of the DIT structure rule
(string, or None if missing)
obsolete
Integer flag (0 or 1) indicating whether the DIT content rule is marked
as OBSOLETE in the schema
form
List of strings with NAMEs or OIDs of associated name forms
NAMEs or OIDs of associated name forms (tuple of strings)
sup
List of strings with NAMEs or OIDs of allowed structural object classes
of superior entries in the DIT
NAMEs or OIDs of allowed structural object classes
of superior entries in the DIT (tuple of strings)
"""
schema_attribute = u'dITStructureRules'
......@@ -573,23 +593,22 @@ class NameForm(SchemaElement):
oid
OID of the name form
names
This list of strings contains all NAMEs of the name form
All NAMEs of the name form (tuple of strings)
desc
This string contains description text (DESC) of the name form
Description text (DESC) of the name form (string, or None if missing)
obsolete
Integer flag (0 or 1) indicating whether the name form is marked
as OBSOLETE in the schema
form
List of strings with NAMEs or OIDs of associated name forms
NAMEs or OIDs of associated name forms (tuple of strings)
oc
String with NAME or OID of structural object classes this name form
is usable with
NAME or OID of structural object classes this name form
is usable with (string)
must
This list of strings contains NAMEs or OIDs of all attributes
an RDN must contain
NAMEs or OIDs of all attributes an RDN must contain (tuple of strings)
may
This list of strings contains NAMEs or OIDs of additional attributes
an RDN may contain
NAMEs or OIDs of additional attributes an RDN may contain
(tuple of strings)
"""
schema_attribute = u'nameForms'
token_defaults = {
......
......@@ -4,7 +4,7 @@ ldapurl - handling of LDAP URLs as described in RFC 4516
See https://www.python-ldap.org/ for details.
"""
__version__ = '3.1.0'
__version__ = '3.2.0'
__all__ = [
# constants
......
......@@ -6,7 +6,7 @@ See https://www.python-ldap.org/ for details.
from __future__ import unicode_literals
__version__ = '3.1.0'
__version__ = '3.2.0'
__all__ = [
# constants
......
Metadata-Version: 1.2
Name: python-ldap
Version: 3.1.0
Version: 3.2.0
Summary: Python modules for implementing LDAP clients
Home-page: https://www.python-ldap.org/
Author: python-ldap project
......@@ -30,6 +30,7 @@ Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Database
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
......
......@@ -152,6 +152,7 @@ Tests/t_edit.py
Tests/t_ldap_asyncsearch.py
Tests/t_ldap_controls_libldap.py
Tests/t_ldap_controls_ppolicy.py
Tests/t_ldap_controls_sss.py
Tests/t_ldap_dn.py
Tests/t_ldap_filter.py
Tests/t_ldap_functions.py
......
......@@ -5,7 +5,7 @@ slapdtest - module for spawning test instances of OpenLDAP's slapd server
See https://www.python-ldap.org/ for details.
"""
__version__ = '3.1.0'
__version__ = '3.2.0'
from slapdtest._slapdtest import SlapdObject, SlapdTestCase, SysLogHandler
from slapdtest._slapdtest import requires_ldapi, requires_sasl, requires_tls
......
Metadata-Version: 1.2
Name: python-ldap
Version: 3.1.0
Version: 3.2.0
Summary: Python modules for implementing LDAP clients
Home-page: https://www.python-ldap.org/
Author: python-ldap project
......@@ -30,6 +30,7 @@ Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Database
Classifier: Topic :: Internet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
......
......@@ -7,6 +7,7 @@ See https://www.python-ldap.org/ for details.
from __future__ import unicode_literals
import errno
import os
import unittest
......@@ -731,15 +732,16 @@ class TestLdapCExtension(SlapdTestCase):
if not self._require_attr(l, 'cancel'): # FEATURE_CANCEL
return
def test_errno107(self):
def test_enotconn(self):
l = _ldap.initialize('ldap://127.0.0.1:42')
try:
m = l.simple_bind("", "")
r = l.result4(m, _ldap.MSG_ALL, self.timeout)
except _ldap.SERVER_DOWN as ldap_err:
errno = ldap_err.args[0]['errno']
if errno != 107:
self.fail("expected errno=107, got %d" % errno)
errno_val = ldap_err.args[0]['errno']
if errno_val != errno.ENOTCONN:
self.fail("expected errno=%d, got %d"
% (errno.ENOTCONN, errno_val))
else:
self.fail("expected SERVER_DOWN, got %r" % r)
......
import os
import unittest
# Switch off processing .ldaprc or ldap.conf before importing _ldap
os.environ['LDAPNOINIT'] = '1'
from ldap.controls import sss
class TestControlsPPolicy(unittest.TestCase):
def test_create_sss_request_control(self):
control = sss.SSSRequestControl(ordering_rules=['-uidNumber'])
self.assertEqual(control.ordering_rules, ['-uidNumber'])
if __name__ == '__main__':
unittest.main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment