lru_cache interferes with type checking done by single_dispatch
我有一个方法分派装饰器,它有三个注册函数。一个发到
(为了使事情稍微复杂一点,类是通过另一个类的
1 2 3 | @lru_cache(maxsize=None, typed=True) class QualifiedInterval: # stuff that works |
在球场等级内:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @oph_utils.method_dispatch def augmented(self, other): raise NotImplementedError @augmented.register(int) def _(self, other): return"works fine" @augmented.register(Interval) def _(self, other): return"works fine too" @augmented.register(QualifiedInterval) def _(self, other): return"only works if QualifiedInterval class does NOT have lru_cache" |
号
(还有很多事情要做,但这是不起作用的部分。)
基本上-如果我有lru缓存,并将一个限定的interval传递给函数,那么它不会分派并引发notimplementederror。如果我注释掉缓存装饰器,它就会工作。而repl上的手动类型检查则以任何方式显示相同的类型("qualifiedinterval")。我尝试了几种不同的方法调用创建限定interval的命令,并尝试将其分配给一个变量。还是不行。我尝试在增广函数中执行显式类型检查。如果启用了缓存,类型检查也会在那里失败。
分析出了什么问题
Basically - if I have lru_cache, and pass a QualifiedInterval into the function, it does not dispatch
号
lru缓存是返回包装任何可调用(包括类)的修饰符的函数。因此,当您将lru缓存应用于QualifiedInterval类时,该变量将被分配给包装函数,而不是类本身。
1 2 3 4 5 6 | >>> @lru_cache(maxsize=None, typed=True) class QualifiedInterval: pass >>> type(QualifiedInterval) <class 'functools._lru_cache_wrapper'> |
单调度通过将第一个参数的类型与适当的方法匹配来工作。但是,当传入QualifiedInterval实例时,它的类型与functools._lru_cache_wrapper不匹配,因此单个分派返回到基方法(引发NotImplemented)。
解决方案教单个分派以匹配实际的原始类(类型),而不是包装类:
1 2 3 | @augmented.register(QualifiedInterval.__wrapped__) def _(self, other): return"show now work QualifiedInterval class has an lru_cache" |
号
注意添加了
希望能把一切都弄清楚,并显示出前进的方向。