Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions foxylint/loggingcase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import re


class _AnalyzeFile:
def __init__(self, file):
self._file = file
self._go()

def _go(self):
BAD_PATTERN = re.compile(r"""(logging|logger)\.(info|warning|error|debug|critical)\(["'][A-Z]""")
errors = []
with open(self._file) as f:
for line_number, line in enumerate(f, start=1):
match = BAD_PATTERN.search(line)
if match is not None:
if self._acceptable(line):
continue
errors.append({'line_number': line_number, 'line_content': line.strip()})
ok = len(errors) == 0
self._result = {'ok': ok, 'errors': errors}

def _acceptable(self, line):
if self._comment(line):
return True
IGNORE_PATTERN = re.compile(r'#\s*foxylint-loggingcase:ignore\s*$')
return IGNORE_PATTERN.search(line) is not None

def _comment(self, line):
return line.strip().startswith('#')

@property
def result(self):
return self._result


def analyze(files):
analyses = {file: _AnalyzeFile(file).result for file in files}
return analyses
37 changes: 36 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ twine = "^5.1.1"

pytest = "^8.3.3"
ptpython = "^3.0.29"
python-box = "^7.2.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Expand Down
6 changes: 5 additions & 1 deletion tests/fixtures/bad.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import logging
from pathlib import Path
from bad import behavior


def main():
pass
logger = logging.getLogger(__name__)
logger.info('I am also bad')
logging.info('I start with a captial letter, that is why I am bad')
logging.info('Another line starts with a capital, this is bad')
7 changes: 7 additions & 0 deletions tests/fixtures/good.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import namespace.x.y
from . import something
from .. import something_else
Expand All @@ -9,3 +10,9 @@

def f():
namespace.x.y.go()
logger = logging.getLogger(__name__)
logging.info('hi there')
logger.info('hello')
# logger.info('I start with a capital but I am commented out')
logging.info('I start with a capital, but I have a comment that allows this') # foxylint-loggingcase:ignore
logging.info('Another line starts with a capital, but I have a comment that allows this') # foxylint-loggingcase:ignore
23 changes: 18 additions & 5 deletions tests/test_blackbox.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import pytest
import pathlib
import foxylint.imports
import foxylint.loggingcase
import box

HERE = pathlib.Path(__file__).parent


def test_blackbox():
@pytest.fixture
def files():
good = str(HERE / 'fixtures' / 'good.py')
bad = str(HERE / 'fixtures' / 'bad.py')
files = [good, bad]
return box.Box(good=good, bad=bad)


def test_imports(files):
LOGGING_PATTERN = 'from mylogging import logger'
ACCEPTABLE_PATTERNS = [LOGGING_PATTERN]
findings = foxylint.imports.analyze(files, acceptable_patterns=ACCEPTABLE_PATTERNS)
assert findings[good]['ok'] is True
assert findings[bad]['ok'] is False
findings = foxylint.imports.analyze([files.good, files.bad], acceptable_patterns=ACCEPTABLE_PATTERNS)
assert findings[files.good]['ok'] is True
assert findings[files.bad]['ok'] is False


def test_loggingcase(files):
findings = foxylint.loggingcase.analyze([files.good, files.bad])
assert findings[files.good]['ok'] is True
assert findings[files.bad]['ok'] is False