やりたかったこと
ゆるふわにpytestでテストをしようとしたかったのですが、その過程である__init__.pyに書かれているメソッドを全てテストする。ということをしようとしました。
が、そこで問題となったのがabstractクラスも__init__.pyに含まれていて、こいつをいい感じに省いてやらなければいけなかったのです。
AbstractBaseClassの判定方法
inspect.isabstractを使いましょう。That’s ALL。
まずは適当なクラスを定義してあげます。
1 2 3 4 5 6 7 8 9 10 11 12 |
from abc import ABCMeta, abstractclassmethod class A(metaclass=ABCMeta): @abstractclassmethod def ab(): pass class B(A): def ab(): pass class C: pass |
本題の判定(+失敗した例です。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import inspect for c in [A,B,C]: print('-----') try: print(c.__name__) print(f'type={type(c)}') print(f'isabstract={inspect.isabstract(c)}') print(f'type(instance)={type(c())}') except TypeError as e: print(e) # ----- # A # type=<class 'abc.ABCMeta'> # isabstract=True # Can't instantiate abstract class A with abstract methods ab # ----- # B # type=<class 'abc.ABCMeta'> # isabstract=False # type(instance)=<class '__main__.B'> # ----- # C # type=<class 'type'> # isabstract=False # type(instance)=<class '__main__.C'> # |
参考
stack overflowさんはやはり偉大でしたが、中々見つからなかったので未来の自分のために残しておきます。
なお、きちんと公式ドキュメントにもinspect.isabstractの記載がありますが、英語だし見つけにくい…。
まあ中々使わないメソッドですしね、仕方ない。