<commit_before>from wq.io.base import BaseIO
from wq.io.loaders import FileLoader, BinaryFileLoader, NetLoader, StringLoader
from wq.io.parsers import CsvParser, JsonParser, XmlParser, ExcelParser
from wq.io.mappers import TupleMapper
import mimetypes

PARSERS = {
    'application/vnd.ms-excel': ExcelParser,
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
    ExcelParser,
    'text/csv': CsvParser,
    'application/json': JsonParser,
    'application/xml': XmlParser,
}
BINARY_FORMATS = (
    'application/vnd.ms-excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
)


# Save generated classes to avoid recreating them
_io_classes = {}


def make_io(loader, parser, mapper=TupleMapper, name=None):
    """
    Mix the specified loader, parser, and mapper classes into a usable IO
    """
    key = (loader, parser, mapper)
    if key in _io_classes:
        return _io_classes[key]

    if name is None:
        lname = parser.__name__.replace('Parser', '')
        pname = loader.__name__.replace('Loader', '')
        if mapper == TupleMapper:
            mname = ""
        else:
            mname = mapper.__name__.replace('Mapper', '')
        name = lname + pname + mname + "IO"
    cls = type(name, (loader, parser, mapper, BaseIO), {})
    cls.__module__ = "wq.io"
    _io_classes[key] = cls
    return cls


def guess_type(filename, buffer=None):
    mimetype, encoding = mimetypes.guess_type(filename)
    if mimetype is None:
        try:<commit_msg>allow module to be overridden<commit_after>from wq.io.base import BaseIO
from wq.io.loaders import FileLoader, BinaryFileLoader, NetLoader, StringLoader
from wq.io.parsers import CsvParser, JsonParser, XmlParser, ExcelParser
from wq.io.mappers import TupleMapper
import mimetypes

PARSERS = {
    'application/vnd.ms-excel': ExcelParser,
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
    ExcelParser,
    'text/csv': CsvParser,
    'application/json': JsonParser,
    'application/xml': XmlParser,
}
BINARY_FORMATS = (
    'application/vnd.ms-excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
)


# Save generated classes to avoid recreating them
_io_classes = {}


def make_io(loader, parser, mapper=TupleMapper, name=None, module="wq.io"):
    """
    Mix the specified loader, parser, and mapper classes into a usable IO
    """
    key = (loader, parser, mapper)
    if key in _io_classes:
        return _io_classes[key]

    if name is None:
        lname = parser.__name__.replace('Parser', '')
        pname = loader.__name__.replace('Loader', '')
        if mapper == TupleMapper:
            mname = ""
        else:
            mname = mapper.__name__.replace('Mapper', '')
        name = lname + pname + mname + "IO"
    cls = type(name, (loader, parser, mapper, BaseIO), {})
    cls.__module__ = module
    _io_classes[key] = cls
    return cls


def guess_type(filename, buffer=None):
    mimetype, encoding = mimetypes.guess_type(filename)
    if mimetype is None:
        try:
{'fraction_non_alphanumeric': 0.11274030628869339, 'fraction_numerical': 0.0, 'mean_word_length': 3.3607954545454546, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, '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': '6548483', 'n_tokens_mistral': 1001, 'n_tokens_neox': 972, 'n_words': 236}