basilisp
basilisp copied to clipboard
`deftype`/`reify` abstract super-type rules are overly restrictive
The rules Basilisp uses for assessing deftype
/reify
super-type abstractness are overly restrictive for the Python ecosystem.
Unlike Java, Python does not require an interface type inherit from abc.ABC
and even many such classes which do inherit from it don't necessarily mark all of their abstract methods with @abstractmethod
. The "abstract base classes" of io
for instance are not truly abstract (inspect.isabstract
) returns False for these types. However, they are clearly intended to be used as abstract base classes. Basilisp's requirement that they either be truly abc.ABC
instances and properly declare members means that it is impossible to use them in reify*
or deftype*
forms.
During the initial implementation of these special forms, I did add a small escape hatch in the form of "artificial abstractness" which could be declared by using the ^:abstract
meta key on the supertype symbol. However, the compiler checks for this only after checking for "true" abstractness and has some specific checks to allow classes such as those in io
to only be considered under the "true" abstract base class branch.
Given the limitations described above, I think it would be appropriate to check for artificial abstractness first and then assess true abc.ABC
rules later. This weakens some of the constraints that Clojure places on its supertype list, but I think it may be necessary to allow users to actually use deftype*
and reify*
.