brain_qt.py 2.41 KB
Newer Older
Stelios Karozis's avatar
Stelios Karozis committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com>
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
# Copyright (c) 2017 Roy Wright <roy@wright.org>
# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk>

# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER

"""Astroid hooks for the PyQT library."""

from astroid import MANAGER, register_module_extender
from astroid.builder import AstroidBuilder
from astroid import nodes
from astroid import parse


def _looks_like_signal(node, signal_name="pyqtSignal"):
    if "__class__" in node.instance_attrs:
        try:
            cls = node.instance_attrs["__class__"][0]
            return cls.name == signal_name
        except AttributeError:
            # return False if the cls does not have a name attribute
            pass
    return False


def transform_pyqt_signal(node):
    module = parse(
        """
    class pyqtSignal(object):
        def connect(self, slot, type=None, no_receiver_check=False):
            pass
        def disconnect(self, slot):
            pass
        def emit(self, *args):
            pass
    """
    )
    signal_cls = module["pyqtSignal"]
    node.instance_attrs["emit"] = signal_cls["emit"]
    node.instance_attrs["disconnect"] = signal_cls["disconnect"]
    node.instance_attrs["connect"] = signal_cls["connect"]


def transform_pyside_signal(node):
    module = parse(
        """
    class NotPySideSignal(object):
        def connect(self, receiver, type=None):
            pass
        def disconnect(self, receiver):
            pass
        def emit(self, *args):
            pass
    """
    )
    signal_cls = module["NotPySideSignal"]
    node.instance_attrs["connect"] = signal_cls["connect"]
    node.instance_attrs["disconnect"] = signal_cls["disconnect"]
    node.instance_attrs["emit"] = signal_cls["emit"]


def pyqt4_qtcore_transform():
    return AstroidBuilder(MANAGER).string_build(
        """

def SIGNAL(signal_name): pass

class QObject(object):
    def emit(self, signal): pass
"""
    )


register_module_extender(MANAGER, "PyQt4.QtCore", pyqt4_qtcore_transform)
MANAGER.register_transform(nodes.FunctionDef, transform_pyqt_signal, _looks_like_signal)
MANAGER.register_transform(
    nodes.ClassDef,
    transform_pyside_signal,
    lambda node: node.qname() in ("PySide.QtCore.Signal", "PySide2.QtCore.Signal"),
)