<commit_before>"""
Superclasses for various Pyte things.
"""
import functools

from pyte.exc import ValidationError


class _PyteOp(object):
    """
    This is a superclass for an opcode object, I.E an operation like `LOAD_FAST`.
    """
    def __init__(self, *args):
        # Generic init
        self.args = args

    # How wide this operation is (in bytes)
    op_width = 0

    def to_bytes(self) -> bytes:
        """
        Produces a byte string representing the `co_code` of this operator.
        """
        raise NotImplementedError


class _PyteAugmentedValidator(object):
    """
    An augmented validator ensures that the bytecode objects do not segfault when the bytecode is compiled and ran,
    by validating the arguments.
    """
    def __init__(self, index, get_partial, name):
        self.index = index
        self.partial = get_partial
        self._l_name = name

    @property
    def list_name(self):
        return self._l_name

    def validate(self):
        try:
            return self.partial()
        except IndexError:
            raise ValidationError("Index `{}` does not exist at compile-time".format(self.index))

    def get(self):
        return self.validate()


class PyteAugmentedArgList(list):
    """
    This is a superclass for an augmented argument list.

    This is not actually subclassed, but used directly in an alias.

    Instead of providing items to use, it provides validators that are validated in `compile`.
    """
    def __init__(self, *args, name: str="consts"):
        super().__init__(*args)
        self.name = name

    def all(self):
        """
        Return all values of self.
        """
        return [x for x in self]

    def __getitem__(self, item):
        # Create a partial to get the list item.
        part = functools.partial(super().__getitem__, item)
        # Return a new _PyteAugmentedValidator.
        return _PyteAugmentedValidator(item, part, self.name)
<commit_msg>Add __comparator__ methods to _AugmentedValidator.<commit_after>"""
Superclasses for various Pyte things.
"""
import functools

from pyte import tokens
from pyte.exc import ValidationError
from pyte import util

import dis


class _PyteOp(object):
    """
    This is a superclass for an opcode object, I.E an operation like `LOAD_FAST`.
    """

    def __init__(self, *args):
        # Generic init
        self.args = args

    # How wide this operation is (in bytes)
    op_width = 0

    def to_bytes(self) -> bytes:
        """
        Produces a byte string representing the `co_code` of this operator.
        """
        raise NotImplementedError


class _PyteAugmentedComparator(object):
    """
    An augmented comparator is used for the IF statements, in order to generate the correct bytecode.
    """

    def __init__(self, opcode: int, first: _PyteAugmentedValidator, second: _PyteAugmentedValidator):
        self.opcode = opcode
        self.first = first
        self.second = second

    def to_bytecode(self):
        # Validate both
        self.first.validate()
        self.second.validate()
        bc = b""
        # Generate LOAD_
        for val in [self.first, self.second]:
            if val.list_name == "consts":
                bc += util.generate_load_const(val.index)
            elif val.list_name == "names":
                bc += util.generate_load_global(val.index)
            elif val.list_name == "varnames":
                bc += util.generate_load_fast(val.index)
        # Add the CMP_OP
        bc += tokens.COMPARE_OP.to_bytes(1, byteorder="little")
        # Add the operator
        bc += self.opcode.to_bytes(2, byteorder="little")
        return bc


class _PyteAugmentedValidator(object):
    """
    An augmented validator ensures that the bytecode objects do not segfault when the bytecode is compiled and ran,
    by validating the arguments.
    """

    def __init__(self, index, get_partial, name):
        self.index = index
        self.partial = get_partial
        self._l_name = name

    @property
    def list_name(self):
        return self._l_name

    def validate(self):
        try:
            return self.partial()
        except IndexError:
            raise ValidationError("Index `{}` does not exist at compile-time".format(self.index))

    def get(self):
        return self.validate()

    def __eq__(self, other):
        return _PyteAugmentedComparator(dis.cmp_op[2], self, other)

    def __ne__(self, other):
        return _PyteAugmentedComparator(dis.cmp_op[3], self, other)

    def __gt__(self, other):
        return _PyteAugmentedComparator(dis.cmp_op[4], self, other)

    def __lt__(self, other):
        return _PyteAugmentedComparator(dis.cmp_op[0], self, other)

    def __ge__(self, other):
        return _PyteAugmentedComparator(dis.cmp_op[1], self, other)

    def __le__(self, other):
        return _PyteAugmentedComparator(dis.cmp_op[5], self, other)


class PyteAugmentedArgList(list):
    """
    This is a superclass for an augmented argument list.

    This is not actually subclassed, but used directly in an alias.

    Instead of providing items to use, it provides validators that are validated in `compile`.
    """

    def __init__(self, *args, name: str = "consts"):
        super().__init__(*args)
        self.name = name

    def all(self):
        """
        Return all values of self.
        """
        return [x for x in self]

    def __getitem__(self, item):
        # Create a partial to get the list item.
        part = functools.partial(super().__getitem__, item)
        # Return a new _PyteAugmentedValidator.
        return _PyteAugmentedValidator(item, part, self.name)
{'fraction_non_alphanumeric': 0.0915182507494269, 'fraction_numerical': 0.0017633574325515782, 'mean_word_length': 2.5055624227441284, 'pattern_counts': {'":': 3, '<': 3, '<?xml version=': 0, '>': 5, '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': '1316308', 'n_tokens_mistral': 1676, 'n_tokens_neox': 1613, 'n_words': 523}