Skip to content

Commit 82f1314

Browse files
committed
Add warning on abstract building subclasses
1 parent 667ed63 commit 82f1314

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

python/style.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,27 @@ If your class may be used in multiple inheritance, ensure that all relevant clas
762762

763763
For more details, see the `super documentation <super>`, the `astropy coding guide <http://docs.astropy.org/en/stable/development/codeguide.html#super-vs-direct-calling>`__, and `this article from Raymond Hettinger <https://rhettinger.wordpress.com/2011/05/26/super-considered-super/>`__.
764764

765+
766+
.. warning::
767+
Abstract subclasses of builtins (classes that include both `abc.ABC` and a :ref:`builtin class <bltin-types>` in their hierarchy) are not checked for abstract methods on instantiation.
768+
This means that `abc.abstractmethod` decorators will not prevent the class from being instantiated.
769+
For example, an abstract :ref:`Exception <bltin-exceptions>` subclass can still be instantiated without a concrete override of its abstract method(s), resulting in runtime errors when those methods are called.
770+
You can work around this by defining ``__new__`` on an abstract builtin subclass to check for abstract methods:
771+
772+
.. code-block:: python
773+
:name: abstract-builtin
774+
775+
def __new__(cls, *args: Any, **kwargs: Any) -> MyAbstractClass:
776+
# Have to override __new__ because builtin subclasses aren't checked
777+
# for abstract methods; see https://github.com/python/cpython/issues/50246
778+
if cls.__abstractmethods__:
779+
raise TypeError(
780+
f"Can't instantiate abstract class {cls.__name__} with "
781+
f"abstract methods: {','.join(sorted(cls.__abstractmethods__))}"
782+
)
783+
return super().__new__(cls, *args, **kwargs)
784+
785+
765786
.. _style-guide-py-comparisons:
766787

767788
9. Comparisons

0 commit comments

Comments
 (0)