[Python-Dev] PEP 443 - Single-dispatch generic functions

Sam Partington sam.partington at gmail.com
Fri May 24 11:54:27 CEST 2013


On 23 May 2013 22:02, Ronan Lamy <ronan.lamy at gmail.com> wrote:
> 2013/5/23 Łukasz Langa <lukasz at langa.pl>
>> Last one wins. Just like with assigning names in a scope, defining methods
>> in a class or overriding them in a subclass.
>
> This is a serious annoyance, considering that there are several places where
> a large library can reasonably define the implementations (i.e. with the
> class, with the function, or in some utility module). Note that in contrast
> with the case of functions in a module or methods in a class, linting tools
> cannot be expected to detect a duplication between functions with different
> names defined in different modules.

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.

-----default.py-------
from pkgutil import simplegeneric

@simplegeneric
def fun(x):
    print 'default impl'

-------a.py--------
from default import fun

@fun.register(int)
def impl_a(x):
    print 'impl_a'

def f():
    fun(0) # expect this to call impl_a

-------b.py------
from default import fun

@fun.register(int)
def impl_b(x):
    print 'impl_b'

def f():
    fun(0) # expect this to call impl_b

--------

>>> import a, b
>>> a.f()
impl_b
>>> b.f()
impl_b

>>> import b, a
>>> a.f()
impl_a
>>> b.f()
impl_a
>>> exit()

That is rather worrying.  It is more analagous in the above example to
sys.modules['os.path'].join = myjoin

I don't have a solution mind though.

Sam


More information about the Python-Dev mailing list