Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
119 views
in Technique[技术] by (71.8m points)

python inspect.isabstract incorrect result per ABC docs

it appears inspect.isabstract will only return true if BOTH the metaclass AND @abstractmethod are present. But this is not what the doc says, at least as I read it - and more importantly I don't believe it's Least Surprise at all. Do I have this correct / bug needed?

this class evaluates as abstract as expected

class Both(ABC):
    isabstract_result = True

    @abstractmethod
    def foo(self):
        pass

the result of isabstract() here is consistent with neither the docs NOR common usage https://docs.python.org/3/library/abc.html

class JustABC(ABC):
    # docs: "an abstract base class can be created by simply deriving from ABC"
    isabstract_result = False

I suppose the technical argument here is that in order for derived classes to become concrete, they'd need to implement a (previously abstractmethod) method; thus by induction a base class without such a method in its mro must not be abstract - but the IMHO this would be a documentation bugfix need, as it doesn't seem Least Surprise especially given the explicit phrasing as it exists today.

Here's runnable code showing the above (and a couple other results of the above). The unittest.Testcase passes when run on pythong 3.8.5 (ubuntu 20.04 default)

from unittest import TestCase
from abc import abstractmethod, ABC
from inspect import isabstract

# these classes evaluate as abstract as expected
class Both(ABC):
    isabstract_result = True

    @abstractmethod
    def foo(self):
        pass


# the result of isabstract() here
# is consistent with neither the docs NOR common usage
# https://docs.python.org/3/library/abc.html
class JustABC(ABC):
    # docs: "an abstract base class can be created by simply deriving from ABC"
    isabstract_result = False


# that this code loads without error would seem to be inconsistent with the docs
# although admittedly nothing about "required" implies there is any error checking
class JustABm:
    isabstract_result = False
    # docs: Using this decorator requires that the class [...] or is derived from [ABC]"
    @abstractmethod
    def foo(self):
        pass


# for reference, trivial derrived classes preserve the above
class ChildBoth(Both):
    isabstract_result = True


class ChildJustABm(JustABC):
    isabstract_result = False


class ChildJustABC(JustABm, ABC):
    isabstract_result = False


# and there is asymitry about adding the other abc notion;
# although this probably makes sense given the implementation & inheritance
class ChildAddABm(JustABC):
    isabstract_result = True

    @abstractmethod
    def foo(self):
        pass


class ChildAddABC(JustABm, ABC):
    isabstract_result = False


CLASSES = (
    JustABC,
    JustABm,
    Both,
    ChildJustABC,
    ChildJustABm,
    ChildBoth,
    ChildAddABm,
    ChildAddABC,
)


class test_isabstract(TestCase):
    """ verify the flags above: test passes """

    def test_isabstract(self):

        for cls, status in zip(CLASSES, map(isabstract, CLASSES)):
            self.assertEqual(
                cls.isabstract_result,
                status,
                f"error, {cls.__name__ = } {'IS' if status else 'is NOT'} abs, which is not expected.",
            )

    def test_runtime_matches_isabstract(self):
        # at least the actual runtime behavior is consistent with inspect.isabstract
        for cls in CLASSES:
            try:
                cls()
                self.assertFalse(
                    cls.isabstract_result,
                    f"{cls} instantiated, but should have failed as ABC",
                )
            except TypeError as _ex:
                self.assertTrue(
                    cls.isabstract_result,
                    f"{cls} failed to instantiate as abc unexpectedly",
                )
question from:https://stackoverflow.com/questions/65647468/python-inspect-isabstract-incorrect-result-per-abc-docs

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...