Проверьте, что код Python использует только методы ABC

Допустим, у меня есть функция, которая задокументирована, чтобы взять collections.Sequence Азбука Как проверить код в этой функции на соответствие интерфейсу ABC? Могу ли я написать модульный тест (или тесты), подтверждающий, что мой код вызывает только методы, определенные этим ABC, а не, скажем, метод, определенный list или какой-то другой конкретной реализации collections.Sequence? Или есть другой инструмент или метод, чтобы проверить это?

2 ответа

Просто протестируйте функцию, передав экземпляр класса, который реализует только эти методы. Если вам нужно, вы можете создать подкласс встроенного типа, такого как list и переопределите его метод __getattribute__, например так:

class TestSequence(list):
    def __getattribute__(self, name):
        if name not in collections.Sequence.__abstractmethods__:
            assert(False) # or however you'd like the test to fail
        return object.__getattribute__(self, name)

Реализуйте ABC непосредственно самостоятельно, используя методы, тривиальные или сложные, как того требует код:

import collections

class TestSequence(collections.Sequence):

    def __init__(self):
        pass

    def __len__(self):
        return 3

    def __getitem__(self, index):
        return index

Если вы допустили ошибку и пропустили реализации абстрактных методов, ваш код выдаст ошибку:

TypeError: Can't instantiate abstract class TestSequence with abstract methods __getitem__

Если в тестируемом коде вызывается метод, не определенный ABC, вы увидите обычную ошибку отсутствия атрибута:

AttributeError: 'TestSequence' object has no attribute 'pop'
Другие вопросы по тегам