Prevent instantiation of abstract base classes
Python prevents instantiation of abstract base classes, but only if they have abstract methods. Thus, for example, the following works:
>>> QuantumSymbol('a', hs=1)
despite QuantumSymbol being an abstract class:
class QuantumSymbol(QuantumExpression, metaclass=ABCMeta)
This can cause problems, as abstract classes may not define all the necessary class attributes for algebraic operations to work (and there's no way in Python to declare abstract class attributes, which Python could catch similar to abstract methods)
We should figure out some general way in Expression.__init__ to raise an exception if any class whose type is a direct subclass of ABCMeta is being instantiated. So far, I haven't found a way to perform this check.
An alternative is to implement "abstract class attributes", using a custom meta-class, as described in
https://stackoverflow.com/questions/23831510/abstract-attribute-not-property/23833055
Specifically:
- define a singleton
AbstractClassAttributes - subclass
ABCMetaintoQnetABCMeta - In the abstract class, set class attributes that subclasses must overwrites to
AbstractClassAttributes - In
QnetABCMeta, check that no class attributes areAbstractClassAttributes, otherwise raise aTypeError: Can't instantiate abstract class with abstract class attribute
QnetABCMeta might also implement some mechanism to categorically forbid instantiating classes that directly have the QnetABCMeta class, but this would be in addition to providing abstract class attributes.