<commit_before>from __future__ import print_function

from .xkb import *
from ctypes import *
from collections import namedtuple

import re


OPEN_DISPLAY_ERRORS = {
    XkbOD_BadLibraryVersion: "Compile-time and runtime XKB libraries not compatible",
    XkbOD_ConnectionRefused: "Display could not be opened",
    XkbOD_BadServerVersion: "Library and server have incompatible XKB versions",
    XkbOD_NonXkbServer: "XKB not present in the X server"
}

GET_CONTROLS_ERRORS = {
    BadAlloc: "Unable to allocate storage",
    BadImplementation: "Invalid reply from server",
    BadMatch: "A compatible version of Xkb was not available in the server or "
              "an argument has correct type and range, but is otherwise invalid"
}

GET_NAMES_ERRORS = {
    BadAlloc: "Unable to allocate storage",
    BadImplementation: "Invalid reply from server",
    BadLength: "The length of a request is shorter or longer than that "
               "required to minimally contain the arguments",
    BadMatch: "A compatible version of Xkb was not available in the server or "
              "an argument has correct type and range, but is otherwise invalid"
}

class X11Error(Exception):
    pass

def ensure_type(obj, type):
    if not isinstance(obj, type):
        raise ValueError("Wrong value type, must be {}.".format(str(type)))


class XKeyboard:
    # XKeyboard methods

    def __init__(self, auto_open=True):
        if auto_open:
            self.open_display()

    def open_display(self):
        self.close_display()    # Properly finish previous open_display()

        XkbIgnoreExtension(False)

        display_name = None
        major = c_int(XkbMajorVersion)
        minor = c_int(XkbMinorVersion)
        reason = c_int()

        self._display = XkbOpenDisplay(
            display_name,
            None, None, byref(major), byref(minor), byref(reason))
        if reason.value in OPEN_DISPLAY_ERRORS:
            raise X11Error(OPEN_DISPLAY_ERRORS[reason.value] + ".")

        self._keyboard_description = XkbGetMap(self._display, 0, XkbUseCoreKbd)
        if not self._keyboard_description:
            self.close_display()
            raise X11Error("Failed to get keyboard description.")

        # Controls mask doesn't affect the availability of xkb->ctrls->num_groups anyway
        # Just use a valid value, and xkb->ctrls-> will be definitely set
        status = XkbGetControls(self._display, XkbAllControlsMask, self._keyboard_description)
        if status != Success:
            self.close_display()
            raise X11Error(GET_CONTROLS_ERRORS[status] + ".")

        #names_mask = XkbSymbolsNameMask | XkbGroupNamesMask
        names_mask = XkbAllNamesMask
        status = XkbGetNames(self._display, names_mask, self._keyboard_description)
        if status != Success:<commit_msg>core: use specific names mask for XkbGetNames<commit_after>from __future__ import print_function

from .xkb import *
from ctypes import *
from collections import namedtuple

import re


OPEN_DISPLAY_ERRORS = {
    XkbOD_BadLibraryVersion: "Compile-time and runtime XKB libraries not compatible",
    XkbOD_ConnectionRefused: "Display could not be opened",
    XkbOD_BadServerVersion: "Library and server have incompatible XKB versions",
    XkbOD_NonXkbServer: "XKB not present in the X server"
}

GET_CONTROLS_ERRORS = {
    BadAlloc: "Unable to allocate storage",
    BadImplementation: "Invalid reply from server",
    BadMatch: "A compatible version of Xkb was not available in the server or "
              "an argument has correct type and range, but is otherwise invalid"
}

GET_NAMES_ERRORS = {
    BadAlloc: "Unable to allocate storage",
    BadImplementation: "Invalid reply from server",
    BadLength: "The length of a request is shorter or longer than that "
               "required to minimally contain the arguments",
    BadMatch: "A compatible version of Xkb was not available in the server or "
              "an argument has correct type and range, but is otherwise invalid"
}

class X11Error(Exception):
    pass

def ensure_type(obj, type):
    if not isinstance(obj, type):
        raise ValueError("Wrong value type, must be {}.".format(str(type)))


class XKeyboard:
    # XKeyboard methods

    def __init__(self, auto_open=True):
        if auto_open:
            self.open_display()

    def open_display(self):
        self.close_display()    # Properly finish previous open_display()

        XkbIgnoreExtension(False)

        display_name = None
        major = c_int(XkbMajorVersion)
        minor = c_int(XkbMinorVersion)
        reason = c_int()

        self._display = XkbOpenDisplay(
            display_name,
            None, None, byref(major), byref(minor), byref(reason))
        if reason.value in OPEN_DISPLAY_ERRORS:
            raise X11Error(OPEN_DISPLAY_ERRORS[reason.value] + ".")

        self._keyboard_description = XkbGetMap(self._display, 0, XkbUseCoreKbd)
        if not self._keyboard_description:
            self.close_display()
            raise X11Error("Failed to get keyboard description.")

        # Controls mask doesn't affect the availability of xkb->ctrls->num_groups anyway
        # Just use a valid value, and xkb->ctrls-> will be definitely set
        status = XkbGetControls(self._display, XkbAllControlsMask, self._keyboard_description)
        if status != Success:
            self.close_display()
            raise X11Error(GET_CONTROLS_ERRORS[status] + ".")

        names_mask = XkbSymbolsNameMask | XkbGroupNamesMask
        status = XkbGetNames(self._display, names_mask, self._keyboard_description)
        if status != Success:
{'fraction_non_alphanumeric': 0.07477797513321492, 'fraction_numerical': 0.003197158081705151, 'mean_word_length': 3.0863570391872277, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '717883', 'n_tokens_mistral': 1607, 'n_tokens_neox': 1560, 'n_words': 499}