On 22 January 2017 at 17:34, Cory Benfield <cory@lukasa.co.uk> wrote:
This module should be entirely unattached to the ssl module, IMO. This is most important because the ssl module doesn’t exist when Python is not linked against OpenSSL: being unable to define the exceptions in a “you don’t need OpenSSL module” because Python isn’t linked against OpenSSL seems like a pretty silly problem.
The way Python handles inheritance means that we have a fair bit of flexibility in how we handle the exception catching transition. To be clear, the specific case where I'm interested in improving the migration strategy is the one where: - a networking helper library inside a project or app handles ssl API calls on behalf of its clients - the helper library wants to migrate to use the tls API instead - the only aspect of the ssl API exposed directly to users of the helper library is the exceptions, with everything else being handled by the library Option 1: No assistance is provided, so either all SSL exception catching code in clients of the helper library *must* be updated to also catch the corresponding new TLS exceptions in order to be agnostic regarding the use of the old ssl API or the new tls one, or else the library has to define its own wrapper exceptions that inherit from both the old ssl exceptions and the new tls ones Option 2: ssl.SSLError, ssl.SSLWantReadError, and ssl.SSLWantWriteError are redefined as subclasses of tls.TLSError, tls.WantReadError, tls.WantWriteError respectively Option 3: the tls API defines tls.LegacySSLError, tls.LegacyWantReadError, tls.LegacyWantWriteError as aliases for ssl.SSLError, ssl.SSLWantReadError, and ssl.SSLWantWriteError *if* the latter are defined, and otherwise defines them as new exception types Option 4: tls.TLSError, tls.WantReadError, tls.WantWriteError are defined as inheriting from ssl.SSLError, ssl.SSLWantReadError, and ssl.SSLWantWriteError *if* the latter are defined Option 5: as with Option 4, but the "ssl" module is also changed such that it *always* defines at least ssl.SSLError, ssl.SSLWantReadError, and ssl.SSLWantWriteError (and perhaps some of the other APIs that can be emulated atop the new tls abstraction), even if OpenSSL itself is unavailable I really don't like Option 1, as it just pushes the decision on how to deal with this migration to library designers, rather than coming up with a standardised approach that minimises the collective hassle for the overall ecosystem Option 2 isn't particularly appealing either - it still requires that all code catching these exceptions be modified in order to cope with underlying libraries migrating from using the legacy ssl API to the updated tls API, and it also isn't particularly amenable to being backported to earlier Python versions Option 3 starts being slightly more helpful to API consumers, but still doesn't really help library authors hide the backend migration for their API clients Option 4 by contrast means that library authors can still hide the migration to the new backend APIs even if they previously allowed the ssl module exceptions to escape as part of their public API - any clients catching those exceptions will still catch the new exceptions, and will only require changing in order to support running in environments that don't provide an OpenSSL backend at all Option 5 would cover even that last case: legacy API consumers that only relied on being able to catch the legacy exceptions would tolerate the use of non-OpenSSL backends even in environments where OpenSSL itself wasn't available Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia