[Python-Dev] PEP 443 - Single-dispatch generic functions (original) (raw)
Nick Coghlan ncoghlan at gmail.com
Fri May 24 14:08:16 CEST 2013
- Previous message: [Python-Dev] PEP 443 - Single-dispatch generic functions
- Next message: [Python-Dev] PEP 443 - Single-dispatch generic functions
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Fri, May 24, 2013 at 7:54 PM, Sam Partington <sam.partington at gmail.com> wrote:
But isn't it much much worse than names in scope, as with assigning names in a scope it is only your scope that is affected :
from os.path import join def join(wibble): 'overloads join in this module only' any other module is unaffected, os.path.join still calls os.path.join however with this all scopes globally are affected by the last one wins rule.
Indeed, as with any modification of process global state, generic implementation registration is something to be approached with care. ABC registration is similar.
There's actually three kinds of registration that can happen, and only two of them are appropriate for libraries to do implicitly, while the last should only be explicitly triggered from main:
- registering a class your library defines with a stdlib or third party generic function
- registering a stdlib or third party class with a generic function your library defines
- registering a stdlib or third party class with a stdlib or third party generic function
The first two cases? Those are just part of defining class behaviour or function behaviour. That's entirely up to the library developer and an entirely sensible thing for them to be doing.
That third case? It's the moral equivalent of monkey patching, and it's the strict prerogative of application integrators.
The core assumption is that on import, you're just providing one component of an application, and you don't know what that application is or what it's needs are. By contrast, when you're explicitly called from main, then you can assume that this is an explicit request from the integrated application that wants you to modify the global state.
One of the best examples of a project that gets this distinction right is gevent - you can general import gevent without any side effects on the process global state. However, the gevent.monkey module exposes monkeypatching that the application developer can request.
You know you have a well written library if someone else could import every single one of your modules into their application and it would have zero effect on them until they call a function. This is often the tipping point that pushes things over from being libraries to being frameworks: the frameworks have side effects on import that mean they don't play well with others (implicitly configuring the logging system is a common example - the changes to the logging module's default behaviour in 3.2 were designed to make it easier for library developers to stop doing that, because it causes spurious incompatibilities. Messing too much with the import system as a side effect of import is also framework-like behaviour).
Making any changes outside your module scope as a side effect of import can be problematic, since even if it doesn't conflict with another library, it has a tendency to break module reloading. One of the minor reasons that ABC registration, and the proposed single dispatch registration, permit silent overwriting is that being too aggressive about enforcing "once and only once" can make module reloading even more fragile than it is already.
Cheers, Nick.
-- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
- Previous message: [Python-Dev] PEP 443 - Single-dispatch generic functions
- Next message: [Python-Dev] PEP 443 - Single-dispatch generic functions
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]