Python abc.abstractproperty compatibility

Viewed 1003

The Python 3 documentation mentions that abc.abstractproperty is deprecated since 3.3 in favour of @property and @abstractmethod. Is there an alternative way to implement an abstract property (without abc.abstractproperty) that is compatible with both Python 2 and 3 ?

I tried

import abc
from future.utils import with_metaclass

class Base(with_metaclass(abc.ABCMeta, object)):
    @property
    @abc.abstractmethod
    def x(self):
        raise NotImplementedError

class C(Base):
    pass

C()

which correctly raises TypeError: Can't instantiate abstract class C with abstract methods x in Python 3, but not in Python 2.

1 Answers

I know this requires you to import ABC, but why don't you use a try except.

import abc
try:
    ABC = abc.ABC
    abstractproperty = lambda f: property(abc.abstractmethod(f))
except AttributeError:  # Python 2.7, abc exists, but not ABC
    ABC = abc.ABCMeta("ABC", (object,), {"__slots__": ()})
    from abc import abstractproperty

I borrow the python3 solution from @Giacomo Alzetta in the comments in the question.

Related