<commit_before>"""Test the integration of namespaces with abstract base classes."""

from abc import abstractmethod
import abc as abc_main
from inspect import isabstract
import sys

import pytest


def test_import_compat(compat):
    """Test the module is importable. See conftest.py for the actual import."""
    assert compat


def test_import_abc(abc):
    """Test the module is importable. See conftest.py for the actual import."""
    assert abc


def test_has_class(abc):
    """Test the convenience class exists."""
    assert abc.NamespaceableABC


def test_abc_helper(abc):
    """Test the convenience class works as expected."""
    # create an ABC using the helper class and perform basic checks
    class CClass(abc.NamespaceableABC):
        """A throwaway test class."""
        @classmethod
        @abstractmethod
        def footer(cls):
            """Return the class's name. Abstract."""
            return cls.__name__
    assert isinstance(CClass, abc.NamespaceableABCMeta)
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @classmethod
        def footer(cls):
            """Return the class's name. Concrete."""
            return super().footer()
    assert DClass.footer() == 'DClass'


def test_abstractmethod_basics():
    """Test abstractmethod works as expected.

    Adapted from Python's test suite.
    """
    @abstractmethod
    def footer(self):
        """Return self. Abstract."""
        return self
    assert footer.__isabstractmethod__

    def barter(self):
        """Return self. Concrete."""
        return self
    assert not hasattr(barter, "__isabstractmethod__")


# IT IS TOO USED.
def test_abstractproperty_basics(abc):
    """Test abstract property works as expected.

    Adapted from Python's test suite.
    """
    @property
    @abstractmethod
    def footer(self):
        """Return nothing. Abstract."""
    assert footer.__isabstractmethod__

    def barter(self):
        """Return nothing. Concrete."""
    assert not getattr(barter, "__isabstractmethod__", False)

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @property
        @abstractmethod
        def footer(self):
            """Return 3. Abstract."""
            return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @CClass.footer.getter
        def footer(self):
            """Return 3. Concrete."""
            return super().footer
    assert DClass().footer == 3


def test_abstractproperty_namespaced(abc, namespace):
    """Test interaction between namespaces and abstract properties."""
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @property
            @abstractmethod
            def footer(self):
                """Return 3. Abstract."""
                return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @CClass.ns.footer.getter
            def footer(self):
                """Return 3. Concrete."""
                return super().ns.footer
    assert DClass().ns.footer == 3


def test_abstractclassmethod_basics(abc):
    """Test abstract classmethod works as expected.

    Adapted from Python's test suite.
    """
    @classmethod
    @abstractmethod
    def footer(cls):
        """Return cls. Abstract."""
        return cls
    assert footer.__isabstractmethod__

    @classmethod
    def barter(cls):
        """Return cls. Concrete."""
        return cls
    assert not getattr(barter, "__isabstractmethod__", False)

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @classmethod
        @abstractmethod
        def footer(cls):
            return cls.__name__
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @classmethod
        def footer(cls):
            return super().footer()
    assert DClass.footer() == 'DClass'
    assert DClass().footer() == 'DClass'


def test_abstractclassmethod_namespaced(abc, namespace):
    """Test interaction between namespaces and abstract classmethods."""
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @classmethod
            @abstractmethod
            def footer(cls):
                return cls.__name__
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @classmethod
            def footer(cls):
                return super().ns.footer()
    assert DClass.ns.footer() == 'DClass'
    assert DClass().ns.footer() == 'DClass'


def test_abstractstaticmethod_basics(abc):
    """Test abstract staticmethod works as expected.

    Adapted from Python's test suite.
    """
    @staticmethod
    @abstractmethod
    def footer():
        """Do nothing. Abstract."""
    assert footer.__isabstractmethod__

    @staticmethod
    def barter():
        """Do nothing. Concrete."""
    assert not getattr(barter, "__isabstractmethod__", False)

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @staticmethod
        @abstractmethod
        def footer():
            """Return 3. Abstract."""
            return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @staticmethod
        def footer():
            """Return 4. Concrete."""
            return 4
    assert DClass.footer() == 4
    assert DClass().footer() == 4


def test_abstractstaticmethod_namespaced(abc, namespace):
    """Test interaction between namespaces and abstract staticmethods."""
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @staticmethod
            @abstractmethod
            def footer():
                return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @staticmethod
            def footer():
                return 4
    assert DClass.ns.footer() == 4
    assert DClass().ns.footer() == 4


def test_abstractmethod_integration(abc):
    """Test abstract shortcut decorators work as expected.

    Adapted from Python's test suite.
    """
    for abstractthing in [abstractmethod, abc_main.abstractproperty,
                          abc_main.abstractclassmethod,
                          abc_main.abstractstaticmethod]:
        class CClass(metaclass=abc.NamespaceableABCMeta):
            """A throwaway test class."""
            @abstractthing
            def footer(self):
                """Do nothing. Abstract."""

            def barter(self):
                """Do nothing. Concrete."""
        assert CClass.__abstractmethods__ == {"footer"}
        with pytest.raises(TypeError):
            print(CClass())  # because footer is abstract
        assert isabstract(CClass)

        class DClass(CClass):
            """A throwaway test class."""

            def barter(self):
                pass  # concrete override of concrete
        assert DClass.__abstractmethods__ == {"footer"}
        with pytest.raises(TypeError):
            print(DClass())  # because footer is still abstract
        assert isabstract(DClass)

        class EClass(DClass):
            """A throwaway test class."""

            def footer(self):
                pass
        assert EClass.__abstractmethods__ == set()
        EClass()  # now footer is concrete, too
        assert not isabstract(EClass)

        class FClass(EClass):
            """A throwaway test class."""
            @abstractthing
            def barter(self):
                pass  # abstract override of concrete
        assert FClass.__abstractmethods__ == {"barter"}
        with pytest.raises(TypeError):
            print(FClass())  # because barter is abstract now
        assert isabstract(FClass)


def test_abstractmethod_integration_namespaced(abc, namespace):
    """Test abstract shortcut decorators work as expected, under a namespace.

    Adapted from Python's test suite.
    """
    for abstractthing in [abstractmethod, abc_main.abstractproperty,
                          abc_main.abstractclassmethod,
                          abc_main.abstractstaticmethod]:
        class CClass(metaclass=abc.NamespaceableABCMeta):
            """A throwaway test class."""
            with namespace() as ns:
                @abstractthing
                def footer(self):
                    pass  # abstract

                def barter(self):
                    pass  # concrete
        assert CClass.__abstractmethods__ == {"ns.footer"}
        with pytest.raises(TypeError):
            print(CClass())  # because footer is abstract
        assert isabstract(CClass)

        class DClass(CClass):
            """A throwaway test class."""
            with namespace() as ns:
                def barter(self):
                    pass  # concrete override of concrete
        assert DClass.__abstractmethods__ == {"ns.footer"}
        with pytest.raises(TypeError):
            print(DClass())  # because footer is still abstract
        assert isabstract(DClass)

        class EClass(DClass):
            """A throwaway test class."""
            with namespace() as ns:
                def footer(self):
                    pass
        assert EClass.__abstractmethods__ == set()
        EClass()  # now footer is concrete, too
        assert not isabstract(EClass)

        class FClass(EClass):
            """A throwaway test class."""
            with namespace() as ns:
                @abstractthing
                def barter(self):
                    pass  # abstract override of concrete
        assert FClass.__abstractmethods__ == {"ns.barter"}
        with pytest.raises(TypeError):
            print(FClass())  # because barter is abstract now
        assert isabstract(FClass)


def test_descriptors_with_abstractmethod(abc):
    """Test abstract property methods work as expected.

    Adapted from Python's test suite.
    """
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @property
        @abstractmethod
        def footer(self):
            return 3

        @footer.setter
        @abstractmethod
        def footer(self, val):
            pass
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @CClass.footer.getter
        def footer(self):
            return super().footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        @DClass.footer.setter
        def footer(self, val):
            pass
    assert EClass().footer == 3
    # check that the property's __isabstractmethod__ descriptor does the
    # right thing when presented with a value that fails truth testing:

    class NotBool(object):
        """A pathological class for test purposes."""

        def __bool__(self):
            raise ValueError()
        __len__ = __bool__
    with pytest.raises(ValueError):
        class FClass(CClass):
            """A throwaway test class."""

            def barter(self):
                pass
            barter.__isabstractmethod__ = NotBool()
            footer = property(barter)


def test_descriptors_with_abstractmethod_namespaced(abc, namespace):
    """Test abstract property methods work as expected under a namespace.

    Adapted from Python's test suite.
    """
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @property
            @abstractmethod
            def footer(self):
                """Return 3. Abstract."""
                return 3

            @footer.setter
            @abstractmethod
            def footer(self, val):
                """Discard input value. Abstract."""
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @CClass.ns.footer.getter
            def footer(self):
                """Return 3. Concrete."""
                return super().ns.footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        with namespace() as ns:
            @DClass.ns.footer.setter
            def footer(self, val):
                """Discard input value. Concrete"""
    assert EClass().ns.footer == 3
    # check that the property's __isabstractmethod__ descriptor does the
    # right thing when presented with a value that fails truth testing:

    class NotBool(object):
        """A pathological class for test purposes."""

        def __bool__(self):
            raise ValueError()
        __len__ = __bool__
    with pytest.raises(ValueError):
        class FClass(CClass):
            """A throwaway test class."""
            with namespace() as ns:
                def barter(self):
                    """Do nothing."""
                barter.__isabstractmethod__ = NotBool()
                footer = property(barter)


def test_customdescriptors_with_abstractmethod(abc):
    """Test abstract custom descriptors work as expected.

    Adapted from Python's test suite.
    """
    class Descriptor:
        """A descriptor class integrated some with the ABC protocol."""

        def __init__(self, fget, fset=None):
            self._fget = fget
            self._fset = fset

        def getter(self, callable):
            return Descriptor(callable, self._fget)

        def setter(self, callable):
            return Descriptor(self._fget, callable)

        @property
        def __isabstractmethod__(self):
            return (getattr(self._fget, '__isabstractmethod__', False) or
                    getattr(self._fset, '__isabstractmethod__', False))

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @Descriptor
        @abstractmethod
        def footer(self):
            return 3

        @footer.setter
        @abstractmethod
        def footer(self, val):
            pass
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @CClass.footer.getter
        def footer(self):
            return super().footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        @DClass.footer.setter
        def footer(self, val):
            pass
    assert not EClass.footer.__isabstractmethod__


def test_customdescriptors_with_abstractmethod_namespaced(abc, namespace):
    """Test abstract custom descriptors work as expected under a namespace.

    Adapted from Python's test suite.
    """
    class Descriptor:
        """A descriptor class integrated some with the ABC protocol."""

        def __init__(self, fget, fset=None):
            self._fget = fget
            self._fset = fset

        def getter(self, callable):
            return Descriptor(callable, self._fget)

        def setter(self, callable):
            return Descriptor(self._fget, callable)

        @property
        def __isabstractmethod__(self):
            return (getattr(self._fget, '__isabstractmethod__', False) or
                    getattr(self._fset, '__isabstractmethod__', False))

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @Descriptor
            @abstractmethod
            def footer(self):
                return 3

            @footer.setter
            @abstractmethod
            def footer(self, val):
                pass
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @CClass.ns.footer.getter
            def footer(self):
                return super().ns.footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        with namespace() as ns:
            @DClass.ns.footer.setter
            def footer(self, val):
                pass
    assert not EClass.ns.footer.__isabstractmethod__


def test_metaclass_abc(abc):
    """Test abstract metaclasses work as expected.

    Adapted from Python's test suite.
    """
    # Metaclasses can be ABCs, too.
    class AClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @abstractmethod
        def x(self):
            pass
    assert AClass.__abstractmethods__ == {"x"}

    class Meta(type, AClass):
        """A throwaway test metaclass."""

        def x(self):
            return 1

    class CClass(metaclass=Meta):
        """A throwaway test class."""


def test_metaclass_abc_namespaced(abc, namespace):
    """Test abstract metaclasses work as expected, with namespaces.

    Adapted from Python's test suite.
    """
    # Metaclasses can be ABCs, too.
    class AClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @abstractmethod
            def x(self):
                pass
    assert AClass.__abstractmethods__ == {"ns.x"}

    class Meta(type, AClass):
        """A throwaway test metaclass."""
        with namespace() as ns:
            def x(self):
                return 1

    class CClass(metaclass=Meta):<commit_msg>Some doc fixes.<commit_after>"""Test the integration of namespaces with abstract base classes."""

from abc import abstractmethod
import abc as abc_main
from inspect import isabstract
import sys

import pytest


def test_import_compat(compat):
    """Test the module is importable. See conftest.py for the actual import."""
    assert compat


def test_import_abc(abc):
    """Test the module is importable. See conftest.py for the actual import."""
    assert abc


def test_has_class(abc):
    """Test the convenience class exists."""
    assert abc.NamespaceableABC


def test_abc_helper(abc):
    """Test the convenience class works as expected."""
    # create an ABC using the helper class and perform basic checks
    class CClass(abc.NamespaceableABC):
        """A throwaway test class."""
        @classmethod
        @abstractmethod
        def footer(cls):
            """Return the class's name. Abstract."""
            return cls.__name__
    assert isinstance(CClass, abc.NamespaceableABCMeta)
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @classmethod
        def footer(cls):
            """Return the class's name. Concrete."""
            return super().footer()
    assert DClass.footer() == 'DClass'


def test_abstractmethod_basics():
    """Test abstractmethod works as expected.

    Adapted from Python's test suite.
    """
    @abstractmethod
    def footer(self):
        """Return self. Abstract."""
        return self
    assert footer.__isabstractmethod__

    def barter(self):
        """Return self. Concrete."""
        return self
    assert not hasattr(barter, "__isabstractmethod__")


# IT IS TOO USED.
def test_abstractproperty_basics(abc):
    """Test abstract property works as expected.

    Adapted from Python's test suite.
    """
    @property
    @abstractmethod
    def footer(self):
        """Return nothing. Abstract."""
    assert footer.__isabstractmethod__

    def barter(self):
        """Return nothing. Concrete."""
    assert not getattr(barter, "__isabstractmethod__", False)

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @property
        @abstractmethod
        def footer(self):
            """Return 3. Abstract."""
            return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @CClass.footer.getter
        def footer(self):
            """Return 3. Concrete."""
            return super().footer
    assert DClass().footer == 3


def test_abstractproperty_namespaced(abc, namespace):
    """Test interaction between namespaces and abstract properties."""
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @property
            @abstractmethod
            def footer(self):
                """Return 3. Abstract."""
                return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @CClass.ns.footer.getter
            def footer(self):
                """Return 3. Concrete."""
                return super().ns.footer
    assert DClass().ns.footer == 3


def test_abstractclassmethod_basics(abc):
    """Test abstract classmethod works as expected.

    Adapted from Python's test suite.
    """
    @classmethod
    @abstractmethod
    def footer(cls):
        """Return cls. Abstract."""
        return cls
    assert footer.__isabstractmethod__

    @classmethod
    def barter(cls):
        """Return cls. Concrete."""
        return cls
    assert not getattr(barter, "__isabstractmethod__", False)

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @classmethod
        @abstractmethod
        def footer(cls):
            return cls.__name__
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @classmethod
        def footer(cls):
            return super().footer()
    assert DClass.footer() == 'DClass'
    assert DClass().footer() == 'DClass'


def test_abstractclassmethod_namespaced(abc, namespace):
    """Test interaction between namespaces and abstract classmethods."""
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @classmethod
            @abstractmethod
            def footer(cls):
                return cls.__name__
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @classmethod
            def footer(cls):
                return super().ns.footer()
    assert DClass.ns.footer() == 'DClass'
    assert DClass().ns.footer() == 'DClass'


def test_abstractstaticmethod_basics(abc):
    """Test abstract staticmethod works as expected.

    Adapted from Python's test suite.
    """
    @staticmethod
    @abstractmethod
    def footer():
        """Do nothing. Abstract."""
    assert footer.__isabstractmethod__

    @staticmethod
    def barter():
        """Do nothing. Concrete."""
    assert not getattr(barter, "__isabstractmethod__", False)

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @staticmethod
        @abstractmethod
        def footer():
            """Return 3. Abstract."""
            return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @staticmethod
        def footer():
            """Return 4. Concrete."""
            return 4
    assert DClass.footer() == 4
    assert DClass().footer() == 4


def test_abstractstaticmethod_namespaced(abc, namespace):
    """Test interaction between namespaces and abstract staticmethods."""
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @staticmethod
            @abstractmethod
            def footer():
                return 3
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @staticmethod
            def footer():
                return 4
    assert DClass.ns.footer() == 4
    assert DClass().ns.footer() == 4


def test_abstractmethod_integration(abc):
    """Test abstract shortcut decorators work as expected.

    Adapted from Python's test suite.
    """
    for abstractthing in [abstractmethod, abc_main.abstractproperty,
                          abc_main.abstractclassmethod,
                          abc_main.abstractstaticmethod]:
        class CClass(metaclass=abc.NamespaceableABCMeta):
            """A throwaway test class."""
            @abstractthing
            def footer(self):
                """Do nothing. Abstract."""

            def barter(self):
                """Do nothing. Concrete."""
        assert CClass.__abstractmethods__ == {"footer"}
        with pytest.raises(TypeError):
            print(CClass())  # because footer is abstract
        assert isabstract(CClass)

        class DClass(CClass):
            """A throwaway test class."""

            def barter(self):
                pass  # concrete override of concrete
        assert DClass.__abstractmethods__ == {"footer"}
        with pytest.raises(TypeError):
            print(DClass())  # because footer is still abstract
        assert isabstract(DClass)

        class EClass(DClass):
            """A throwaway test class."""

            def footer(self):
                pass
        assert EClass.__abstractmethods__ == set()
        EClass()  # now footer is concrete, too
        assert not isabstract(EClass)

        class FClass(EClass):
            """A throwaway test class."""
            @abstractthing
            def barter(self):
                pass  # abstract override of concrete
        assert FClass.__abstractmethods__ == {"barter"}
        with pytest.raises(TypeError):
            print(FClass())  # because barter is abstract now
        assert isabstract(FClass)


def test_abstractmethod_integration_namespaced(abc, namespace):
    """Test abstract shortcut decorators work as expected, under a namespace.

    Adapted from Python's test suite.
    """
    for abstractthing in [abstractmethod, abc_main.abstractproperty,
                          abc_main.abstractclassmethod,
                          abc_main.abstractstaticmethod]:
        class CClass(metaclass=abc.NamespaceableABCMeta):
            """A throwaway test class."""
            with namespace() as ns:
                @abstractthing
                def footer(self):
                    pass  # abstract

                def barter(self):
                    pass  # concrete
        assert CClass.__abstractmethods__ == {"ns.footer"}
        with pytest.raises(TypeError):
            print(CClass())  # because footer is abstract
        assert isabstract(CClass)

        class DClass(CClass):
            """A throwaway test class."""
            with namespace() as ns:
                def barter(self):
                    pass  # concrete override of concrete
        assert DClass.__abstractmethods__ == {"ns.footer"}
        with pytest.raises(TypeError):
            print(DClass())  # because footer is still abstract
        assert isabstract(DClass)

        class EClass(DClass):
            """A throwaway test class."""
            with namespace() as ns:
                def footer(self):
                    pass
        assert EClass.__abstractmethods__ == set()
        EClass()  # now footer is concrete, too
        assert not isabstract(EClass)

        class FClass(EClass):
            """A throwaway test class."""
            with namespace() as ns:
                @abstractthing
                def barter(self):
                    pass  # abstract override of concrete
        assert FClass.__abstractmethods__ == {"ns.barter"}
        with pytest.raises(TypeError):
            print(FClass())  # because barter is abstract now
        assert isabstract(FClass)


def test_descriptors_with_abstractmethod(abc):
    """Test abstract property methods work as expected.

    Adapted from Python's test suite.
    """
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @property
        @abstractmethod
        def footer(self):
            return 3

        @footer.setter
        @abstractmethod
        def footer(self, val):
            pass
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @CClass.footer.getter
        def footer(self):
            return super().footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        @DClass.footer.setter
        def footer(self, val):
            pass
    assert EClass().footer == 3
    # check that the property's __isabstractmethod__ descriptor does the
    # right thing when presented with a value that fails truth testing:

    class NotBool(object):
        """A pathological class for test purposes."""

        def __bool__(self):
            raise ValueError()
        __len__ = __bool__
    with pytest.raises(ValueError):
        class FClass(CClass):
            """A throwaway test class."""

            def barter(self):
                pass
            barter.__isabstractmethod__ = NotBool()
            footer = property(barter)


def test_descriptors_with_abstractmethod_namespaced(abc, namespace):
    """Test abstract property methods work as expected under a namespace.

    Adapted from Python's test suite.
    """
    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @property
            @abstractmethod
            def footer(self):
                """Return 3. Abstract."""
                return 3

            @footer.setter
            @abstractmethod
            def footer(self, val):
                """Discard input value. Abstract."""
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @CClass.ns.footer.getter
            def footer(self):
                """Return 3. Concrete."""
                return super().ns.footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        with namespace() as ns:
            @DClass.ns.footer.setter
            def footer(self, val):
                """Discard input value. Concrete"""
    assert EClass().ns.footer == 3
    # check that the property's __isabstractmethod__ descriptor does the
    # right thing when presented with a value that fails truth testing:

    class NotBool(object):
        """A pathological class for test purposes."""

        def __bool__(self):
            raise ValueError()
        __len__ = __bool__
    with pytest.raises(ValueError):
        class FClass(CClass):
            """A throwaway test class."""
            with namespace() as ns:
                def barter(self):
                    """Do nothing."""
                barter.__isabstractmethod__ = NotBool()
                footer = property(barter)


def test_customdescriptors_with_abstractmethod(abc):
    """Test abstract custom descriptors work as expected.

    Adapted from Python's test suite.
    """
    class Descriptor:
        """A descriptor class integrated some with the ABC protocol."""

        def __init__(self, fget, fset=None):
            self._fget = fget
            self._fset = fset

        def getter(self, callable):
            return Descriptor(callable, self._fget)

        def setter(self, callable):
            return Descriptor(self._fget, callable)

        @property
        def __isabstractmethod__(self):
            return (getattr(self._fget, '__isabstractmethod__', False) or
                    getattr(self._fset, '__isabstractmethod__', False))

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @Descriptor
        @abstractmethod
        def footer(self):
            return 3

        @footer.setter
        @abstractmethod
        def footer(self, val):
            pass
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        @CClass.footer.getter
        def footer(self):
            return super().footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        @DClass.footer.setter
        def footer(self, val):
            pass
    assert not EClass.footer.__isabstractmethod__


def test_customdescriptors_with_abstractmethod_namespaced(abc, namespace):
    """Test abstract custom descriptors work as expected under a namespace.

    Adapted from Python's test suite.
    """
    class Descriptor:
        """A descriptor class integrated some with the ABC protocol."""

        def __init__(self, fget, fset=None):
            self._fget = fget
            self._fset = fset

        def getter(self, callable):
            return Descriptor(callable, self._fget)

        def setter(self, callable):
            return Descriptor(self._fget, callable)

        @property
        def __isabstractmethod__(self):
            return (getattr(self._fget, '__isabstractmethod__', False) or
                    getattr(self._fset, '__isabstractmethod__', False))

    class CClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @Descriptor
            @abstractmethod
            def footer(self):
                return 3

            @footer.setter
            @abstractmethod
            def footer(self, val):
                pass
    with pytest.raises(TypeError):
        print(CClass())

    class DClass(CClass):
        """A throwaway test class."""
        with namespace() as ns:
            @CClass.ns.footer.getter
            def footer(self):
                return super().ns.footer
    with pytest.raises(TypeError):
        print(DClass())

    class EClass(DClass):
        """A throwaway test class."""
        with namespace() as ns:
            @DClass.ns.footer.setter
            def footer(self, val):
                pass
    assert not EClass.ns.footer.__isabstractmethod__


def test_metaclass_abc(abc):
    """Test abstract metaclasses work as expected.

    Adapted from Python's test suite.
    """
    # Metaclasses can be ABCs, too.
    class AClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        @abstractmethod
        def x_m(self):
            """Do nothing. Abstract."""
    assert AClass.__abstractmethods__ == {"x_m"}

    class Meta(type, AClass):
        """A throwaway test metaclass."""

        def x_m(self):
            """Return 1. Concrete."""
            return 1

    class CClass(metaclass=Meta):
        """A throwaway test class."""


def test_metaclass_abc_namespaced(abc, namespace):
    """Test abstract metaclasses work as expected, with namespaces.

    Adapted from Python's test suite.
    """
    # Metaclasses can be ABCs, too.
    class AClass(metaclass=abc.NamespaceableABCMeta):
        """A throwaway test class."""
        with namespace() as ns:
            @abstractmethod
            def x(self):
                pass
    assert AClass.__abstractmethods__ == {"ns.x"}

    class Meta(type, AClass):
        """A throwaway test metaclass."""
        with namespace() as ns:
            def x(self):
                return 1

    class CClass(metaclass=Meta):
{'fraction_non_alphanumeric': 0.10103047213857502, 'fraction_numerical': 0.0015747161366964112, 'mean_word_length': 2.073618069117772, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2601912', 'n_tokens_mistral': 9755, 'n_tokens_neox': 9358, 'n_words': 2752}