<commit_before>#
# linter.py
# Linter for SublimeLinter3, a code checking framework for Sublime Text 3
#
# Written by <NAME>
# Copyright (c) 2014 <NAME>
#
# License: MIT
#

"""This module exports the Frosted plugin linter class."""

from io import StringIO
from SublimeLinter.lint import persist, PythonLinter


class Frosted(PythonLinter):

    """Provides an interface to the frosted python module/script."""

    syntax = 'python'
    cmd = ('frosted@python', '--verbose', '*', '-')
    version_args = '--version'
    version_re = r'(?P<version>\d+\.\d+\.\d+)'
    version_requirement = '>=1.2.0'
    regex = r"""(?x)
        ^
        (?:
            .+?  # filename
            :
            (?P<line>\d+)
            :
            (?P<col>\d+)
            :
            (?P<code>(?:(?P<error>E)|(?P<warning>[IW]))\d{3})
            :
            (?P<near>[^:\r\n]*)
            :
            (?P<message>[^\r\n]*)
            |
            (?P<syntax_error>
                .+?  # filename
                :
                (?P<syntax_error_line>\d+)
                :
                (?:
                    (?P<syntax_error_col>\d+)
                    :
                )?
                [ ]
                (?P<syntax_error_message>[^\r\n]*)
                (?:
                    \r?\n
                    [^\r\n]*
                    \r?\n
                    [ ]*\^
                    \r?\n
                )?
            )
            |
            (?P<unexpected_error>
                .+?  # filename
                :
                [ ]
                (?P<unexpected_error_message>[^\r\n]*)
            )
        )
    """
    multiline = True
    line_col_base = (1, 0)
    defaults = {
        '--ignore:': []
    }
    inline_overrides = ('ignore', )
    module = 'frosted.api'
    check_version = True

    # Internal
    reporter = None

    __transform_options = {
        'ignore': 'ignore_frosted_errors'
    }

    def split_match(self, match):
        match, line, col, error, warning, message, near = super().split_match(match)

        if not match:
            return match, line, col, error, warning, message, near

        groups = match.groupdict()

        if groups.get('syntax_error'):
            error = True
            warning = False
            line, col, message = [
                groups.get('syntax_error_{}'.format(key)) for key in
                ('line', 'col', 'message')
            ]

            line = int(line) - self.line_col_base[0]

            if col:
                col = int(col) - self.line_col_base[1]
            else:
                col = 0

        elif groups.get('unexpected_error'):
            message = groups.get('unexpected_error_message')
            line, col, error, warning, near = 0, 0, True, False, None

        else:
            col = int(groups.get('offset', 0))

        if near:
            col = None

        return match, line, col, error, warning, message, near

    def check(self, code, filename):
        """Run frosted.check on code and return the output."""

        output = StringIO()
        Reporter = self.get_reporter()

        options = {
            'filename': filename,
            'reporter': Reporter(output, output),
            'verbose': True
        }

        type_map = {
            'ignore': []
        }

        transform = lambda s: self.__transform_options.get(s, s.replace('-', '_'))
        self.build_options(options, type_map, transform)

        if persist.debug_mode():
            persist.printf('{} options: {}'.format(self.name, options))

        self.module.check(code, **options)
        return output.getvalue()

    def get_reporter(self):
        """Return frosted.Reporter. Must be deferred to runtime."""

        if self.reporter is None:
            from frosted.reporter import Reporter
            self.__class__.reporter = Reporter

        return self.reporter<commit_msg>fix version detection when builtin python is used<commit_after>#
# linter.py
# Linter for SublimeLinter3, a code checking framework for Sublime Text 3
#
# Written by <NAME>
# Copyright (c) 2014 <NAME>
#
# License: MIT
#

"""This module exports the Frosted plugin linter class."""

from io import StringIO
from SublimeLinter.lint import persist, PythonLinter


class Frosted(PythonLinter):

    """Provides an interface to the frosted python module/script."""

    syntax = 'python'
    cmd = ('frosted@python', '--verbose', '*', '-')
    version_args = '--version'
    version_re = r'frosted (?P<version>\d+\.\d+\.\d+)'
    version_requirement = '>=1.2.0'
    regex = r"""(?x)
        ^
        (?:
            .+?  # filename
            :
            (?P<line>\d+)
            :
            (?P<col>\d+)
            :
            (?P<code>(?:(?P<error>E)|(?P<warning>[IW]))\d{3})
            :
            (?P<near>[^:\r\n]*)
            :
            (?P<message>[^\r\n]*)
            |
            (?P<syntax_error>
                .+?  # filename
                :
                (?P<syntax_error_line>\d+)
                :
                (?:
                    (?P<syntax_error_col>\d+)
                    :
                )?
                [ ]
                (?P<syntax_error_message>[^\r\n]*)
                (?:
                    \r?\n
                    [^\r\n]*
                    \r?\n
                    [ ]*\^
                    \r?\n
                )?
            )
            |
            (?P<unexpected_error>
                .+?  # filename
                :
                [ ]
                (?P<unexpected_error_message>[^\r\n]*)
            )
        )
    """
    multiline = True
    line_col_base = (1, 0)
    defaults = {
        '--ignore:': []
    }
    inline_overrides = ('ignore', )
    module = 'frosted.api'
    check_version = True

    # Internal
    reporter = None

    __transform_options = {
        'ignore': 'ignore_frosted_errors'
    }

    def split_match(self, match):
        match, line, col, error, warning, message, near = super().split_match(match)

        if not match:
            return match, line, col, error, warning, message, near

        groups = match.groupdict()

        if groups.get('syntax_error'):
            error = True
            warning = False
            line, col, message = [
                groups.get('syntax_error_{}'.format(key)) for key in
                ('line', 'col', 'message')
            ]

            line = int(line) - self.line_col_base[0]

            if col:
                col = int(col) - self.line_col_base[1]
            else:
                col = 0

        elif groups.get('unexpected_error'):
            message = groups.get('unexpected_error_message')
            line, col, error, warning, near = 0, 0, True, False, None

        else:
            col = int(groups.get('offset', 0))

        if near:
            col = None

        return match, line, col, error, warning, message, near

    def check(self, code, filename):
        """Run frosted.check on code and return the output."""

        output = StringIO()
        Reporter = self.get_reporter()

        options = {
            'filename': filename,
            'reporter': Reporter(output, output),
            'verbose': True
        }

        type_map = {
            'ignore': []
        }

        transform = lambda s: self.__transform_options.get(s, s.replace('-', '_'))
        self.build_options(options, type_map, transform)

        if persist.debug_mode():
            persist.printf('{} options: {}'.format(self.name, options))

        self.module.check(code, **options)
        return output.getvalue()

    def get_reporter(self):
        """Return frosted.Reporter. Must be deferred to runtime."""

        if self.reporter is None:
            from frosted.reporter import Reporter
            self.__class__.reporter = Reporter

        return self.reporter

    @classmethod
    def get_executable_version(cls):
        """Extract and return the string version of the linter executable."""

        if cls.executable_path == "<builtin>":
            from frosted import __version__ as version
            persist.debug('{} version: {}'.format(cls.name, version))
            return version

        else:
            return super(cls, cls).get_executable_version()
{'fraction_non_alphanumeric': 0.13519054510371442, 'fraction_numerical': 0.004341534008683068, 'mean_word_length': 1.4586421583160392, 'pattern_counts': {'":': 1, '<': 36, '<?xml version=': 0, '>': 38, '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': '1907036', 'n_tokens_mistral': 2550, 'n_tokens_neox': 2341, 'n_words': 529}