Подклассы типа Pycharm - PullRequest
       62

Подклассы типа Pycharm

0 голосов
/ 18 марта 2020

При попытке настроить конструкцию python для регистрации объекта я столкнулся со следующей проблемой. При выполнении приведенного ниже кода в python 3.7 «success» дважды выводится на консоль, после чего следует ошибка AttributeError. PyCharm неправильно выделяет Y (). Foo () как ошибочный, но принимает Y (). Red_button ().

class XInstance:
    @staticmethod
    def foo():
        print('success')

class X:
    def __new__(cls, *args, **kwargs):
        return XInstance()

    @classmethod
    def red_button(cls):
        print('kaboom')

class Y(X):
    pass

X().foo()  # correctly accepted by pycharm
Y().foo()  # incorrectly highlighted

# These give an error as is desired
X().red_button()  # correctly highlighted
Y().red_button()  # incorrectly accepted by pycharm

Мое намерение состоит в том, чтобы удалить функцию red_button из любого экземпляра, созданного X и Y, и добавить функцию foo (). При запуске этого фрагмента в python я действительно получаю AttributeError как X (). Red_button (), так и Y (). Red_button (), как и ожидалось. PyCharm, однако, может только правильно аннотировать X (). Red_button () как отсутствующий атрибут, но принимает Y (). Red_button () и неправильно выделяет Y.foo ().

Для решения, любые изменения в X, включая метаклассы и заглушки, являются приемлемыми. Я стараюсь сохранить определение класса Y как можно более простым, чтобы не перегружать его __new__ и не назначать ему метаклассы. Мне известно, что перегрузка конструктора и создание подклассов таким способом может считаться неприятным запахом кода, и что надежная проверка типа stati c для python практически невозможна, но я бы предпочел сохранить этот синтаксис для поддержки декораторов, которые регистрируют классы к X, которые создаются при создании экземпляра X (я могу предоставить более подробную информацию, но я подозреваю, что это выходит за рамки этого вопроса).

Я уже пытался перегрузить метод __call__ с помощью метакласса, добавив type- подсказки и несколько способов форматирования __new__. Я также пытался найти средство отслеживания ошибок PyCharm , но безрезультатно.

Изображение, на котором PyCharm неправильно подсвечивает

...