Kann das irgendjemand nachvollziehen?
Fuer pylint ist eine Klasse abstrakt, sobald mindestens eine Methode abstrakt ist.
Eine Methode ist fuer pylint abstrakt, wenn sie entweder nur ein pass enthaelt
(was allerdings nicht fuer die Checker fuer W0231 und W0223 gilt), oder wenn
sie nur ein raise NotImplementedError() enthaelt.
Das funktioniert aber wohl nicht mit abstrakten Klassen, die von abstrakten Klassen
erben. Gegeben sei eine Klasse A und eine abgeleitete Klasse B.
class A(object):
def __init__( self ):
raise NotImplementedError() # makes A abstract
def f( self ):
raise NotImplementedError() # sub-classes must override f
def g( self ):
raise NotImplementedError() # sub-classes must override g
class B(A):
def __init__( self ):
raise NotImplementedError() # B shall be abstract as well
def f( self ):
raise NotImplementedError() # still not implemented
def g( self ):
print self
B ist also abstrakt, implementiert aber B.g, welche somit fuer alle von B
abgeleiteten Klassen gilt.
Pylint noelt nun zweierlei herum: Pylint mag nicht, dass B nicht A.__init__
aufruft (W0231), was voelliger Unfug ist, denn A ist abstrakt, A.__init__
soll explizit nicht aufgerufen werden, um Instanziierung (zumindest die
naive mittels A()) zu verhindern. Pylint bemerkt hier also nicht, dass A
abstrakt ist.
Und pylint mag auch nicht, dass B nicht f implemeniert (B.f also selbst
abstrakt ist, W0223), obwohl das raise in B.__init__ eigentlich B abstrakt
machen sollte, und somit es pylint egal sein kann, ob B.f implementiert ist
oder nicht.
Kann das jemand nachvollziehen? IMHO handelt es sich hier um zwei Bugs
in pylint.
Um das zu umschiffen, habe ich temporaer alle raise's durch pass'es ersetzt,
was die Klassen instanziierbar (wenn auch leer) macht, aber zumindest
pylint happy macht. Mittelfristig frickle ich mir zwei decorators @abstractclass
und @abstractmethod zusammen.
O'Brien
PS: pylint 0.21.1, astng 0.20.1, common 0.50.3, Python 2.7 (r27:82500)
Das Posting wurde vom Benutzer editiert (25.04.2013 08:45).