7

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.

sfinkens
  • 1,210
  • 12
  • 15
  • 3
    You can define it as: `lambda f: property(abstractmethod(f))` in a utils module. AFAICT neither `six` not `future` define a compatibility function. Note that while `abstractproperty` is deprecated all python versions currently support it. I believe it will probably be dropped in python4.0 which is several years from now. Do you really need the current version of your library to be compatible with a future version of python several years in the future? – Giacomo Alzetta Jan 09 '19 at 12:55
  • It has been deprecated since 3.3 and now we have 3.7 so I thought it's time... But if it remains until Python 4 that's fine. The lambda solution you suggested doesn't work in Python 2 (doesn't raise an exception if you forget to implement property `x` in `C`) – sfinkens Jan 09 '19 at 13:50

1 Answers1

0

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.

Suyog Soti
  • 96
  • 4