Ecco quello che ho trovato: se si imposta l'attributo __abstractmethods__
di essere un insieme vuoto sarete in grado di creare un'istanza di classe astratta. Questo comportamento è specificato in PEP 3119:
Se la risultante __abstractmethods__
set non è vuoto, la classe è considerata astratta, e tenta di istanziare alzerà TypeError.
Quindi è sufficiente cancellare questo attributo per la durata dei test.
>>> import abc
>>> class A(metaclass = abc.ABCMeta):
... @abc.abstractmethod
... def foo(self): pass
Non puoi creare un'istanza di un:
>>> A()
Traceback (most recent call last):
TypeError: Can't instantiate abstract class A with abstract methods foo
Se si ignora __abstractmethods__
è possibile:
>>> A.__abstractmethods__=set()
>>> A() #doctest: +ELLIPSIS
<....A object at 0x...>
funziona in entrambi i modi:
>>> class B(object): pass
>>> B() #doctest: +ELLIPSIS
<....B object at 0x...>
>>> B.__abstractmethods__={"foo"}
>>> B()
Traceback (most recent call last):
TypeError: Can't instantiate abstract class B with abstract methods foo
è anche possibile utilizzare unittest.mock
(dalla versione 3.3) per ignorare temporaneamente il comportamento ABC.
>>> class A(metaclass = abc.ABCMeta):
... @abc.abstractmethod
... def foo(self): pass
>>> from unittest.mock import patch
>>> p = patch.multiple(A, __abstractmethods__=set())
>>> p.start()
{}
>>> A() #doctest: +ELLIPSIS
<....A object at 0x...>
>>> p.stop()
>>> A()
Traceback (most recent call last):
TypeError: Can't instantiate abstract class A with abstract methods foo
fonte
2013-06-27 14:16:13
Freddo. Proverò a giocherellare con questo codice su alcuni dei miei test :). Grazie! – bow