[python3-ldap] python3-ldap 0.9.3 released - new Exception hierarchy and "raise_exceptions" connection mode

python3ldap python3ldap at gmail.com
Tue May 20 19:33:53 CEST 2014


Hello everybody,
I've released the 0.9.3 version of python3-ldap. It includes many
fixes and a few new features:

This is the changelog:
    - Now the key in server.schema.attribute_type is the attribute
name (was the oid)
    - Now the key in server.schema.object_classes is the class name
(was the oid)
    - Added check_names to Connection definition to have the names of
attributes and object class checked against the schema
    - Updated setuptools to 3.6
    - Added wheel installation format
    - Added raise_exceptions mode for connection
    - Exception hierarchy reworked
    - Added locking to Server object (for multithreading)

There is a major feature in this version, I've rewritten the Exception
hierarchy and you can now use the Connection in a "raise_exceptions"
mode, as suggested by Michael on this mailing list.

The new hierarchy includes a LDAPException root class with two main
branches: LDAPExceptionError and LDAPExceptionResult. The
LDAPExceptionError contains 42 different exceptions that should help
to understand what's wrong when you have an error. A few of these
(including all the LDAPCommunicationError exceptions) have multiple
inheritance either from the LDAPExceptionError and from specific
Python exceptions. This is to let you choose to catch standard Python
errors or the more detailed python3-ldap errors. The
LDAPCommunicationError exceptions will be created at runtime and
inherit the specific socket exception raised by the interpreter, so
you can catch them with the specific socket.error or the more general
LDAPCommunicationError.

LDAPOperationResult (the other branch of LDAPException hierarchy)
includes 48 exceptions, one for each possible error result (except
RESULT_SUCCESS) specified in the LDAPv3 protocol. When you create a
connection object with the "raise_exceptions" parameter set to True
any LDAP operation will throw an exception of this class, subclassed
to the specific LDAP result code exception. For example if you get an
INVALID_DN_SYNTAX (result code 34) the connection will raise the
LDAPInvalidDNSyntaxResult exception, with the following parameter:
result, description, dn, message, response_type, and the whole
response filled with the values received in the response of the LDAP
operation. You can specify which result code you don't want to raise
exceptions, default is : RESULT_COMPARE_FALSE, RESULT_COMPARE_TRUE,
RESULT_REFERRAL (and of course RESULT_SUCCESS). You can change this
behaviour in the ldap3 __init__.py package or at runtime modifying the
ldap3.DO_NOT_RAISE_EXCEPTIONS list.

The "raise_exceptions" mode is helpful if you want exceptions to flow
up in the code and manage them at a upper level than the single
operation level. This mode works in every kind of strategy, even in
the ReusableStrategy (for connection pooling) where exceptions are
trapped in the "effective" Connection thread and are sent back to the
calling Connection object in the main (or another) thread.
I admit that I don't use this kind of "flow up" exception handling so
let me know if something is not working as expected.

Another minor feature I added in this release is the "check_names"
flag in the Connection object. If you set this parameter to True and
the Server object has a get_info parameter of GET_SCHEMAINFO or
GET_ALL_INFO assertions and filters attributes and object class names
will be checked against the real schema of the server and the
operation will not be performed if the attribute or object name is not
defined in the schema. This kind of checking is requested by the LDAP
RFCs but I've made it optional because it require extra-work (really a
little work) to read the schema and check the assertions and the
filter values.

I've also added machinery to the Server object to work in a
multi-threaded strategy.

Last thing, I've included a "wheel" installation package that should
be suitable for python2 and python3, let me know if you have problem
with it.

Have fun,
gc


The Exception Hierarchy:

LDAPException
    LDAPExceptionError
        LDAPAttributeError (inherits also from AttributeError)
        LDAPBindError
        LDAPCertificateError
        LDAPChangesError (inherits also from ValueError)
        LDAPCommunicationError (all may inherit from socket.error)
            LDAPReferralError
            LDAPSessionTerminatedByServer
            LDAPSocketCloseError
            LDAPSocketOpenError
            LDAPSocketReceiveError
            LDAPSocketSendError
            LDAPUnknownRequestError
            LDAPUnknownResponseError
        LDAPConnectionIsReadOnlyError
        LDAPConnectionPoolNameIsMandatoryError
        LDAPConnectionPoolNotStartedError
        LDAPControlsError (inherits also from ValueError)
        LDAPEntryError
        LDAPInvalidDereferenceAliasesError (inherits also from ValueError)
        LDAPInvalidFilterError
        LDAPInvalidPort
        LDAPInvalidScopeError (inherits also from ValueError)
        LDAPInvalidServerError
        LDAPKeyError (inherits also from KeyError)
        LDAPLDIFError
        LDAPMetricsError
        LDAPObjectClassError (inherits also from ValueError)
        LDAPObjectError
        LDAPPasswordIsMandatoryError
        LDAPReaderError
        LDAPSASLBindInProgressError
        LDAPSASLMechanismNotSupportedError
        LDAPSASLPrepError
        LDAPSchemaError
        LDAPServerPoolError
        LDAPServerPoolExhaustedError
        LDAPSSLConfigurationError
        LDAPSSLNotSupportedError (inherits also from ImportError)
        LDAPStartTLSError
        LDAPTypeError
        LDAPUnknownAuthenticationMethodError
        LDAPUnknownStrategyError
    LDAPOperationResult
        LDAPAdminLimitExceededResult
        LDAPAffectMultipleDSASResult
        LDAPAliasDereferencingProblemResult
        LDAPAliasProblemResult
        LDAPAssertionFailedResult
        LDAPAttributeOrValueExistsResult
        LDAPAuthMethodNotSupportedResult
        LDAPAuthorizationDeniedResult
        LDAPBusyResult
        LDAPCanceledResult
        LDAPCannotCancelResult
        LDAPConfidentialityRequiredResult
        LDAPConstraintViolationResult
        LDAPEntryAlreadyExistsResult
        LDAPESyncRefreshRequiredResult
        LDAPInappropriateAuthenticationResult
        LDAPInappropriateMatchingResult
        LDAPInsufficientAccessRightsResult
        LDAPInvalidAttributeSyntaxResult
        LDAPInvalidCredentialsResult
        LDAPInvalidDNSyntaxResult
        LDAPLCUPInvalidDataResult
        LDAPLCUPReloadRequiredResult
        LDAPLCUPResourcesExhaustedResult
        LDAPLCUPSecurityViolationResult
        LDAPLCUPUnsupportedSchemeResult
        LDAPLoopDetectedResult
        LDAPNamingViolationResult
        LDAPNoSuchAttributeResult
        LDAPNoSuchObjectResult
        LDAPNoSuchOperationResult
        LDAPNotAllowedOnNotLeafResult
        LDAPNotAllowedOnRDNResult
        LDAPObjectClassModsProhibitedResult
        LDAPObjectClassViolationResult
        LDAPOperationsErrorResult
        LDAPOtherResult
        LDAPProtocolErrorResult
        LDAPReferralResult
        LDAPSASLBindInProgressResult
        LDAPSizeLimitExceededResult
        LDAPStrongerAuthRequiredResult
        LDAPTimeLimitExceededResult
        LDAPTooLateResult
        LDAPUnavailableCriticalExtensionResult
        LDAPUnavailableResult
        LDAPUndefinedAttributeTypeResult
        LDAPUnwillingToPerformResult

I know, I should work on the docs to make a brief description of each
of the exception and should generally improve the whole documentation.


More information about the python3-ldap mailing list