<commit_before>"""
A source code linting analyzer for checking PEP8 and Pyflakes warnings
"""
from glob import glob
import os
import subprocess

from .report import Grade


class LintError(object):
    """A struct for lint error message

    location: File path location of error or warning
    line:     The number of line where the error or warning occurred
    message:  Lint error or warning message
    """
    def __init__(self, location, line, message):
        self.location = location
        self.line = line
        self.message = message

    def to_document(self):
        """Make document dict of instance to store to db"""
        return {
            'location': self.location,
            'line': self.line,
            'message': self.message
        }


class LintAnalyzer(Grade):
    """A common analyzer struct
    
    lint_error_list: LintError list for linting
    """
    def __init__(self):
        self.lint_error_list = []

    def _parse_lint_message(self, line):
        """Parse a lint message line

        Args:
            line: A line of lint message

        Returns:
            A tuple of location, line, message of LintError
        """
        tokenized_by_colon = line.split(':')
        location = tokenized_by_colon[0].split('/')[-1]
        line = tokenized_by_colon[1]
        # In PEP8 case, tokenized_by_colon[2] refers to column number of a line
        message = tokenized_by_colon[-1]
        return location, line, message
    
    def _save_lint_results(self, output):
        """Save the linting results
        
        Args:
            output: Output result of linter command
        """
        if output:
            for line in output.decode().split('\n')[:-1]:
                self.lint_error_list.append(LintError(*self._parse_lint_message(line)))

    def calculate_score(self, total_line_count):
        """Calculate the linting score"""
        self.score = int(100 * ((total_line_count - len(self.lint_error_list)) / total_line_count))

    def to_document(self):
        """Make document dict of instance to store to db"""
        raise NotImplementedError('Must implement this method')


class PEP8LintAnalyzer(LintAnalyzer):
    """An analyzer for PEP8 linting"""
    def __init__(self):
        super().__init__()
        self.weight = 0.5

    def run(self, path):<commit_msg>Fix a bug for getting file location when running lint<commit_after>"""
A source code linting analyzer for checking PEP8 and Pyflakes warnings
"""
from glob import glob
import os
import subprocess

from .report import Grade


class LintError(object):
    """A struct for lint error message

    location: File path location of error or warning
    line:     The number of line where the error or warning occurred
    message:  Lint error or warning message
    """
    def __init__(self, location, line, message):
        self.location = location
        self.line = line
        self.message = message

    def to_document(self):
        """Make document dict of instance to store to db"""
        return {
            'location': self.location,
            'line': self.line,
            'message': self.message
        }


class LintAnalyzer(Grade):
    """A common analyzer struct
    
    lint_error_list: LintError list for linting
    """
    def __init__(self):
        self.lint_error_list = []

    def _parse_lint_message(self, line):
        """Parse a lint message line

        Args:
            line: A line of lint message

        Returns:
            A tuple of location, line, message of LintError
        """
        tokenized_by_colon = line.split(':')
        location = '/'.join(tokenized_by_colon[0].split('/')[1:])
        line = tokenized_by_colon[1]
        # In PEP8 case, tokenized_by_colon[2] refers to column number of a line
        message = tokenized_by_colon[-1]
        return location, line, message
    
    def _save_lint_results(self, output):
        """Save the linting results
        
        Args:
            output: Output result of linter command
        """
        if output:
            for line in output.decode().split('\n')[:-1]:
                self.lint_error_list.append(LintError(*self._parse_lint_message(line)))

    def calculate_score(self, total_line_count):
        """Calculate the linting score"""
        self.score = int(100 * ((total_line_count - len(self.lint_error_list)) / total_line_count))

    def to_document(self):
        """Make document dict of instance to store to db"""
        raise NotImplementedError('Must implement this method')


class PEP8LintAnalyzer(LintAnalyzer):
    """An analyzer for PEP8 linting"""
    def __init__(self):
        super().__init__()
        self.weight = 0.5

    def run(self, path):
{'fraction_non_alphanumeric': 0.09447490510333192, 'fraction_numerical': 0.0063264445381695485, 'mean_word_length': 2.4295010845986984, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '2526901', 'n_tokens_mistral': 1366, 'n_tokens_neox': 1325, 'n_words': 430}