<commit_before># coding=utf-8
"""
Basic parser objects + logic
"""

import re
from abc import ABC, abstractmethod
from collections import OrderedDict
from typing import List, Tuple, Dict, Iterable, AnyStr

TAGS_SENTINEL = '@'
TAGS_SEP = ';'
TAG_VALUE_SEP = '='

PREFIX_SENTINEL = ':'
PREFIX_USER_SEP = '!'
PREFIX_HOST_SEP = '@'

PARAM_SEP = ' '
TRAIL_SENTINEL = ':'

CAP_SEP = ' '
CAP_VALUE_SEP = '='

PREFIX_RE = re.compile(r':?(?P<nick>.+?)(?:!(?P<user>.+?))?(?:@(?P<host>.+?))?')

TAG_VALUE_ESCAPES = {
    '\\s': ' ',
    '\\:': ';',
    '\\r': '\r',
    '\\n': '\n',
    '\\\\': '\\',
}
TAG_VALUE_UNESCAPES = {
    unescaped: escaped
    for escaped, unescaped in TAG_VALUE_ESCAPES.items()
}


class Parseable(ABC):
    """Abstract class for parseable objects"""

    @abstractmethod
    def __str__(self):
        return NotImplemented

    @staticmethod
    @abstractmethod
    def parse(text: str) -> 'Parseable':
        """Parse the object from a string"""
        return NotImplemented


class Cap(Parseable):
    """Represents a CAP entity as defined in IRCv3.2"""

    def __init__(self, name: str, value: str = None):
        self.name = name
        self.value = value or None

    def __str__(self):
        if self.value:
            return CAP_VALUE_SEP.join((self.name, self.value))
        return self.name

    @staticmethod
    def parse(text: str) -> 'Cap':
        """Parse a CAP entity from a string"""
        name, _, value = text.partition(CAP_VALUE_SEP)
        return Cap(name, value)


class CapList(Parseable, List[Cap]):
    """Represents a list of CAP entities"""

    def __str__(self) -> str:
        return CAP_SEP.join(self)

    @staticmethod
    def parse(text: str) -> 'CapList':
        """Parse a list of CAPs from a string"""
        return CapList(map(Cap.parse, text.split(CAP_SEP)))
<commit_msg>Add equality check to Cap objects  so the value doesn't matter<commit_after># coding=utf-8
"""
Basic parser objects + logic
"""

import re
from abc import ABC, abstractmethod
from collections import OrderedDict
from typing import List, Tuple, Dict, Iterable, AnyStr

TAGS_SENTINEL = '@'
TAGS_SEP = ';'
TAG_VALUE_SEP = '='

PREFIX_SENTINEL = ':'
PREFIX_USER_SEP = '!'
PREFIX_HOST_SEP = '@'

PARAM_SEP = ' '
TRAIL_SENTINEL = ':'

CAP_SEP = ' '
CAP_VALUE_SEP = '='

PREFIX_RE = re.compile(r':?(?P<nick>.+?)(?:!(?P<user>.+?))?(?:@(?P<host>.+?))?')

TAG_VALUE_ESCAPES = {
    '\\s': ' ',
    '\\:': ';',
    '\\r': '\r',
    '\\n': '\n',
    '\\\\': '\\',
}
TAG_VALUE_UNESCAPES = {
    unescaped: escaped
    for escaped, unescaped in TAG_VALUE_ESCAPES.items()
}


class Parseable(ABC):
    """Abstract class for parseable objects"""

    @abstractmethod
    def __str__(self):
        return NotImplemented

    @staticmethod
    @abstractmethod
    def parse(text: str) -> 'Parseable':
        """Parse the object from a string"""
        return NotImplemented


class Cap(Parseable):
    """Represents a CAP entity as defined in IRCv3.2"""

    def __init__(self, name: str, value: str = None):
        self.name = name
        self.value = value or None

    def __str__(self):
        if self.value:
            return CAP_VALUE_SEP.join((self.name, self.value))
        return self.name

    def __eq__(self, other):
        if isinstance(other, Cap):
            return self.name == other.name
        return False

    @staticmethod
    def parse(text: str) -> 'Cap':
        """Parse a CAP entity from a string"""
        name, _, value = text.partition(CAP_VALUE_SEP)
        return Cap(name, value)


class CapList(Parseable, List[Cap]):
    """Represents a list of CAP entities"""

    def __str__(self) -> str:
        return CAP_SEP.join(self)

    @staticmethod
    def parse(text: str) -> 'CapList':
        """Parse a list of CAPs from a string"""
        return CapList(map(Cap.parse, text.split(CAP_SEP)))

{'fraction_non_alphanumeric': 0.15458311755567064, 'fraction_numerical': 0.0015535991714137752, 'mean_word_length': 2.8980827447023207, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, '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': '3986258', 'n_tokens_mistral': 1372, 'n_tokens_neox': 1313, 'n_words': 335}