<commit_before>import inspect

from i3pystatus.core.settings import SettingsBase
from i3pystatus.core.threading import Manager
from i3pystatus.core.util import (convert_position,
                                  MultiClickHandler)
from i3pystatus.core.command import execute
from i3pystatus.core.command import run_through_shell


def is_method_of(method, object):
    """Decide whether ``method`` is contained within the MRO of ``object``."""
    if not callable(method) or not hasattr(method, "__name__"):
        return False
    if inspect.ismethod(method):
        return method.__self__ is object
    for cls in inspect.getmro(object.__class__):
        if cls.__dict__.get(method.__name__, None) is method:
            return True
    return False


class Module(SettingsBase):
    output = None
    position = 0

    settings = (
        ('on_leftclick', "Callback called on left click (see :ref:`callbacks`)"),
        ('on_rightclick', "Callback called on right click (see :ref:`callbacks`)"),
        ('on_upscroll', "Callback called on scrolling up (see :ref:`callbacks`)"),
        ('on_downscroll', "Callback called on scrolling down (see :ref:`callbacks`)"),
        ('on_doubleleftclick', "Callback called on double left click (see :ref:`callbacks`)"),
        ('on_doublerightclick', "Callback called on double right click (see :ref:`callbacks`)"),
        ('on_doubleupscroll', "Callback called on double scroll up (see :ref:`callbacks`)"),
        ('on_doubledownscroll', "Callback called on double scroll down (see :ref:`callbacks`)"),
        ('multi_click_timeout', "Time (in seconds) before a single click is executed."),
        ('hints', "Additional output blocks for module output (see :ref:`hints`)"),
    )

    on_leftclick = None
    on_rightclick = None
    on_upscroll = None
    on_downscroll = None
    on_doubleleftclick = None
    on_doublerightclick = None
    on_doubleupscroll = None
    on_doubledownscroll = None

    multi_click_timeout = 0.25

    hints = {"markup": "none"}

    def __init__(self, *args, **kwargs):
        super(Module, self).__init__(*args, **kwargs)
        self.__multi_click = MultiClickHandler(self.__button_callback_handler,
                                               self.multi_click_timeout)

    def registered(self, status_handler):
        """Called when this module is registered with a status handler"""
        self.__status_handler = status_handler

    def inject(self, json):
        if self.output:
            if "name" not in self.output:
                self.output["name"] = self.__name__
            self.output["instance"] = str(id(self))
            if (self.output.get("color", "") or "").lower() == "#ffffff":
                del self.output["color"]
            if self.hints:
                for key, val in self.hints.items():
                    if key not in self.output:
                        self.output.update({key: val})
            if self.output.get("markup") == "pango":
                self.text_to_pango()

            json.insert(convert_position(self.position, json), self.output)

    def run(self):
        pass

    def __log_button_event(self, button, cb, args, action):
        msg = "{}: button={}, cb='{}', args={}, type='{}'".format(
            self.__name__, button, cb, args, action)
        self.logger.debug(msg)

    def __button_callback_handler(self, button, cb):
        if not cb:
            self.__log_button_event(button, None, None,
                                    "No callback attached")
            return False

        if isinstance(cb, list):
            cb, args = (cb[0], cb[1:])
        else:
            args = []

        our_method = is_method_of(cb, self)
        if callable(cb) and not our_method:
            self.__log_button_event(button, cb, args, "Python callback")
            cb(*args)
        elif our_method:
            cb(self, *args)
        elif hasattr(self, cb):
            if cb is not "run":
                self.__log_button_event(button, cb, args, "Member callback")
                getattr(self, cb)(*args)
        else:
            self.__log_button_event(button, cb, args, "External command")
            if hasattr(self, "data"):<commit_msg>Lift restriction that "run" cannot be used as a callback<commit_after>import inspect

from i3pystatus.core.settings import SettingsBase
from i3pystatus.core.threading import Manager
from i3pystatus.core.util import (convert_position,
                                  MultiClickHandler)
from i3pystatus.core.command import execute
from i3pystatus.core.command import run_through_shell


def is_method_of(method, object):
    """Decide whether ``method`` is contained within the MRO of ``object``."""
    if not callable(method) or not hasattr(method, "__name__"):
        return False
    if inspect.ismethod(method):
        return method.__self__ is object
    for cls in inspect.getmro(object.__class__):
        if cls.__dict__.get(method.__name__, None) is method:
            return True
    return False


class Module(SettingsBase):
    output = None
    position = 0

    settings = (
        ('on_leftclick', "Callback called on left click (see :ref:`callbacks`)"),
        ('on_rightclick', "Callback called on right click (see :ref:`callbacks`)"),
        ('on_upscroll', "Callback called on scrolling up (see :ref:`callbacks`)"),
        ('on_downscroll', "Callback called on scrolling down (see :ref:`callbacks`)"),
        ('on_doubleleftclick', "Callback called on double left click (see :ref:`callbacks`)"),
        ('on_doublerightclick', "Callback called on double right click (see :ref:`callbacks`)"),
        ('on_doubleupscroll', "Callback called on double scroll up (see :ref:`callbacks`)"),
        ('on_doubledownscroll', "Callback called on double scroll down (see :ref:`callbacks`)"),
        ('multi_click_timeout', "Time (in seconds) before a single click is executed."),
        ('hints', "Additional output blocks for module output (see :ref:`hints`)"),
    )

    on_leftclick = None
    on_rightclick = None
    on_upscroll = None
    on_downscroll = None
    on_doubleleftclick = None
    on_doublerightclick = None
    on_doubleupscroll = None
    on_doubledownscroll = None

    multi_click_timeout = 0.25

    hints = {"markup": "none"}

    def __init__(self, *args, **kwargs):
        super(Module, self).__init__(*args, **kwargs)
        self.__multi_click = MultiClickHandler(self.__button_callback_handler,
                                               self.multi_click_timeout)

    def registered(self, status_handler):
        """Called when this module is registered with a status handler"""
        self.__status_handler = status_handler

    def inject(self, json):
        if self.output:
            if "name" not in self.output:
                self.output["name"] = self.__name__
            self.output["instance"] = str(id(self))
            if (self.output.get("color", "") or "").lower() == "#ffffff":
                del self.output["color"]
            if self.hints:
                for key, val in self.hints.items():
                    if key not in self.output:
                        self.output.update({key: val})
            if self.output.get("markup") == "pango":
                self.text_to_pango()

            json.insert(convert_position(self.position, json), self.output)

    def run(self):
        pass

    def __log_button_event(self, button, cb, args, action):
        msg = "{}: button={}, cb='{}', args={}, type='{}'".format(
            self.__name__, button, cb, args, action)
        self.logger.debug(msg)

    def __button_callback_handler(self, button, cb):
        if not cb:
            self.__log_button_event(button, None, None,
                                    "No callback attached")
            return False

        if isinstance(cb, list):
            cb, args = (cb[0], cb[1:])
        else:
            args = []

        our_method = is_method_of(cb, self)
        if callable(cb) and not our_method:
            self.__log_button_event(button, cb, args, "Python callback")
            cb(*args)
        elif our_method:
            cb(self, *args)
        elif hasattr(self, cb):
            self.__log_button_event(button, cb, args, "Member callback")
            getattr(self, cb)(*args)
        else:
            self.__log_button_event(button, cb, args, "External command")
            if hasattr(self, "data"):
{'fraction_non_alphanumeric': 0.11651060803603176, 'fraction_numerical': 0.002607561929595828, 'mean_word_length': 2.434269434269434, 'pattern_counts': {'":': 7, '<': 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': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3485115', 'n_tokens_mistral': 2404, 'n_tokens_neox': 2351, 'n_words': 668}