Samuel Marks wrote at 2020-8-24 18:24 +1000: >After a discussion on #python on Freenode, I'm here. > >The gist of it is: >> Falc - Signature of method 'Pharm.foo()' does not match signature of base >> method in class 'Base' > >What's the right way of specialising the children and leaving the Base >pretty much empty? > >Specifically I want: >• All implementers to be forced to implement Base's method >• Base to be able to do very basic things with kwargs, namely log it >(to a file like stdout or a db) >• Support for [at least] Python 3.6–3.9 (I don't think `Protocol` has >been backported?) >• Implementors to have access to the proper name, rather than having >to unpack kwargs > >Should I be using a Base class? - Metaclass? - Something else >entirely? - I know giving `b` a default value would resolve the >[PyCharm] linter error… but I want it to be a required argument. > >Full example: > >from abc import ABC, abstractmethod > > >class Base(ABC): > @abstractmethod > def foo(self, a, **kwargs): > ... >class Pharm(Base): > def foo(self, a, b): > ...
Python make a distinction between positional and keyword arguments. A positional argument is identified by its position in the parameter list; a keyword argument is identified by its name. `**` introduces arbitrary keyword arguments. In a call, all those arguments must be passed as "name=value". In your case above, `b` is not a keyword argument and thus is not matched by `**kwargs`. The error you observe is justified. You can try: class Base(ABC): @abstractmethod def foo(self, a, *args, **kwargs): ... class Pharm(Base): def foo(self, a, b, *args, **kwargs): ... Note that the base method signature allows arbitrary positional and keyword arguments. As a consequence, derived methods must do the same. If this is not what you want, you might want to explore the use of a decorator or a meta class rather than a base class. -- https://mail.python.org/mailman/listinfo/python-list