Message362233
I couldn't get the example given for the interaction between @singledispatchmethod and @classmethod to work https://docs.python.org/3/library/functools.html?highlight=singledispatch#functools.singledispatchmethod
from functools import singledispatchmethod
class Negator:
@singledispatchmethod
@classmethod
def neg(cls, arg):
raise NotImplementedError("Cannot negate a")
@neg.register
@classmethod
def _(cls, arg: int):
return -arg
@neg.register
@classmethod
def _(cls, arg: bool):
return not arg
if __name__ == "__main__":
print(Negator.neg(0))
print(Negator.neg(False))
Leads to
$ python -m bad_classmethod_as_documented
Traceback (most recent call last):
File "/usr/lib/python3.8/runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.8/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/viktor/scratch/bad_classmethod_as_documented.py", line 4, in <module>
class Negator:
File "/home/viktor/scratch/bad_classmethod_as_documented.py", line 12, in Negator
def _(cls, arg: int):
File "/usr/lib/python3.8/functools.py", line 906, in register
return self.dispatcher.register(cls, func=method)
File "/usr/lib/python3.8/functools.py", line 848, in register
raise TypeError(
TypeError: Invalid first argument to `register()`: <classmethod object at 0x7f37d1469070>. Use either `@register(some_class)` or plain `@register` on an annotated function.
Curiously, @staticmethod does work, but not as documented (don't decorate the actual implementations):
from functools import singledispatchmethod
class Negator:
@singledispatchmethod
@staticmethod
def neg(arg):
raise NotImplementedError("Cannot negate a")
@neg.register
def _(arg: int):
return -arg
@neg.register
def _(arg: bool):
return not arg
if __name__ == "__main__":
print(Negator.neg(0))
print(Negator.neg(False))
Leads to
$ python -m good_staticmethod
0
True
Removing @classmethod from the implementation methods doesn't work, though
Traceback (most recent call last):
File "/usr/lib/python3.8/runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.8/runpy.py", line 86, in _run_code
exec(code, run_globals)
File "/home/viktor/scratch/bad_classmethod_alternative.py", line 20, in <module>
print(Negator.neg(0))
File "/usr/lib/python3.8/functools.py", line 911, in _method
return method.__get__(obj, cls)(*args, **kwargs)
TypeError: _() missing 1 required positional argument: 'arg' |
|
Date |
User |
Action |
Args |
2020-02-18 19:16:15 | Viktor Roytman | set | recipients:
+ Viktor Roytman |
2020-02-18 19:16:15 | Viktor Roytman | set | messageid: <1582053375.25.0.178240077179.issue39679@roundup.psfhosted.org> |
2020-02-18 19:16:15 | Viktor Roytman | link | issue39679 messages |
2020-02-18 19:16:14 | Viktor Roytman | create | |
|