From fb174fef90687d4d4a3db8a276773d20558690bf Mon Sep 17 00:00:00 2001 From: Tim Vergenz Date: Thu, 25 Apr 2024 14:06:20 -0400 Subject: [PATCH] refactor: add ruff linting & fix initial violations --- .github/workflows/ci.yml | 6 +++ .pre-commit-config.yaml | 1 + cogapp/__init__.py | 2 +- cogapp/cogapp.py | 96 ++++++++++++++++++++-------------------- cogapp/test_cogapp.py | 28 ++++++------ cogapp/test_makefiles.py | 2 +- cogapp/utils.py | 6 +-- cogapp/whiteutils.py | 10 ++--- 8 files changed, 79 insertions(+), 72 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8a16a1..d37413d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,6 +25,12 @@ jobs: with: args: 'format --check' + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: chartboost/ruff-action@v1 + tests: name: "Python ${{ matrix.python }} on ${{ matrix.os }}" runs-on: "${{ matrix.os }}-${{ matrix.os-version || 'latest' }}" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1417062..5745136 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,3 +4,4 @@ repos: rev: v0.4.1 hooks: - id: ruff-format + - id: ruff diff --git a/cogapp/__init__.py b/cogapp/__init__.py index d710539..bfcb793 100644 --- a/cogapp/__init__.py +++ b/cogapp/__init__.py @@ -4,4 +4,4 @@ Copyright 2004-2024, Ned Batchelder. """ -from .cogapp import Cog, CogUsageError, main +from .cogapp import Cog as Cog, CogUsageError as CogUsageError, main as main diff --git a/cogapp/cogapp.py b/cogapp/cogapp.py index 71c7df7..e8f1827 100644 --- a/cogapp/cogapp.py +++ b/cogapp/cogapp.py @@ -114,11 +114,11 @@ def __init__(self, options=None): self.lines = [] self.options = options or CogOptions() - def parseMarker(self, l): - self.markers.append(l) + def parseMarker(self, line): + self.markers.append(line) - def parseLine(self, l): - self.lines.append(l.strip("\n")) + def parseLine(self, line): + self.lines.append(line.strip("\n")) def getCode(self): """Extract the executable Python code from the generator.""" @@ -127,8 +127,8 @@ def getCode(self): # then remove it from all the lines. prefIn = commonPrefix(self.markers + self.lines) if prefIn: - self.markers = [l.replace(prefIn, "", 1) for l in self.markers] - self.lines = [l.replace(prefIn, "", 1) for l in self.lines] + self.markers = [line.replace(prefIn, "", 1) for line in self.markers] + self.lines = [line.replace(prefIn, "", 1) for line in self.lines] return reindentBlock(self.lines, "") @@ -160,7 +160,7 @@ def evaluate(self, cog, globals, fname): eval(code, globals) except CogError: raise - except: + except: # noqa: E722 (we're just wrapping in CogUserException and rethrowing) typ, err, tb = sys.exc_info() frames = (tuple(fr) for fr in traceback.extract_tb(tb.tb_next)) frames = find_cog_source(frames, prologue) @@ -433,71 +433,71 @@ def processFile(self, fIn, fOut, fname=None, globals=None): globals.update(self.options.defines) # loop over generator chunks - l = fIn.readline() - while l: + line = fIn.readline() + while line: # Find the next spec begin - while l and not self.isBeginSpecLine(l): - if self.isEndSpecLine(l): + while line and not self.isBeginSpecLine(line): + if self.isEndSpecLine(line): raise CogError( f"Unexpected {self.options.sEndSpec!r}", file=sFileIn, line=fIn.linenumber(), ) - if self.isEndOutputLine(l): + if self.isEndOutputLine(line): raise CogError( f"Unexpected {self.options.sEndOutput!r}", file=sFileIn, line=fIn.linenumber(), ) - fOut.write(l) - l = fIn.readline() - if not l: + fOut.write(line) + line = fIn.readline() + if not line: break if not self.options.bDeleteCode: - fOut.write(l) + fOut.write(line) # l is the begin spec gen = CogGenerator(options=self.options) gen.setOutput(stdout=self.stdout) - gen.parseMarker(l) + gen.parseMarker(line) firstLineNum = fIn.linenumber() self.cogmodule.firstLineNum = firstLineNum # If the spec begin is also a spec end, then process the single # line of code inside. - if self.isEndSpecLine(l): - beg = l.find(self.options.sBeginSpec) - end = l.find(self.options.sEndSpec) + if self.isEndSpecLine(line): + beg = line.find(self.options.sBeginSpec) + end = line.find(self.options.sEndSpec) if beg > end: raise CogError( "Cog code markers inverted", file=sFileIn, line=firstLineNum ) else: - sCode = l[beg + len(self.options.sBeginSpec) : end].strip() + sCode = line[beg + len(self.options.sBeginSpec) : end].strip() gen.parseLine(sCode) else: # Deal with an ordinary code block. - l = fIn.readline() + line = fIn.readline() # Get all the lines in the spec - while l and not self.isEndSpecLine(l): - if self.isBeginSpecLine(l): + while line and not self.isEndSpecLine(line): + if self.isBeginSpecLine(line): raise CogError( f"Unexpected {self.options.sBeginSpec!r}", file=sFileIn, line=fIn.linenumber(), ) - if self.isEndOutputLine(l): + if self.isEndOutputLine(line): raise CogError( f"Unexpected {self.options.sEndOutput!r}", file=sFileIn, line=fIn.linenumber(), ) if not self.options.bDeleteCode: - fOut.write(l) - gen.parseLine(l) - l = fIn.readline() - if not l: + fOut.write(line) + gen.parseLine(line) + line = fIn.readline() + if not line: raise CogError( "Cog block begun but never ended.", file=sFileIn, @@ -505,34 +505,34 @@ def processFile(self, fIn, fOut, fname=None, globals=None): ) if not self.options.bDeleteCode: - fOut.write(l) - gen.parseMarker(l) + fOut.write(line) + gen.parseMarker(line) - l = fIn.readline() + line = fIn.readline() # Eat all the lines in the output section. While reading past # them, compute the md5 hash of the old output. previous = [] hasher = md5() - while l and not self.isEndOutputLine(l): - if self.isBeginSpecLine(l): + while line and not self.isEndOutputLine(line): + if self.isBeginSpecLine(line): raise CogError( f"Unexpected {self.options.sBeginSpec!r}", file=sFileIn, line=fIn.linenumber(), ) - if self.isEndSpecLine(l): + if self.isEndSpecLine(line): raise CogError( f"Unexpected {self.options.sEndSpec!r}", file=sFileIn, line=fIn.linenumber(), ) - previous.append(l) - hasher.update(l.encode("utf-8")) - l = fIn.readline() + previous.append(line) + hasher.update(line.encode("utf-8")) + line = fIn.readline() curHash = hasher.hexdigest() - if not l and not self.options.bEofCanBeEnd: + if not line and not self.options.bEofCanBeEnd: # We reached end of file before we found the end output line. raise CogError( f"Missing {self.options.sEndOutput!r} before end of file.", @@ -557,7 +557,7 @@ def processFile(self, fIn, fOut, fname=None, globals=None): bSawCog = True # Write the ending output line - hashMatch = self.reEndOutput.search(l) + hashMatch = self.reEndOutput.search(line) if self.options.bHashOutput: if hashMatch: oldHash = hashMatch["hash"] @@ -568,20 +568,20 @@ def processFile(self, fIn, fOut, fname=None, globals=None): line=fIn.linenumber(), ) # Create a new end line with the correct hash. - endpieces = l.split(hashMatch.group(0), 1) + endpieces = line.split(hashMatch.group(0), 1) else: # There was no old hash, but we want a new hash. - endpieces = l.split(self.options.sEndOutput, 1) - l = (self.sEndFormat % newHash).join(endpieces) + endpieces = line.split(self.options.sEndOutput, 1) + line = (self.sEndFormat % newHash).join(endpieces) else: # We don't want hashes output, so if there was one, get rid of # it. if hashMatch: - l = l.replace(hashMatch["hashsect"], "", 1) + line = line.replace(hashMatch["hashsect"], "", 1) if not self.options.bDeleteCode: - fOut.write(l) - l = fIn.readline() + fOut.write(line) + line = fIn.readline() if not bSawCog and self.options.bWarnEmpty: self.showWarning(f"no cog code found in {sFileIn}") @@ -712,9 +712,9 @@ def processFileList(self, sFileList): flist = self.openInputFile(sFileList) lines = flist.readlines() flist.close() - for l in lines: + for line in lines: # Use shlex to parse the line like a shell. - lex = shlex.shlex(l, posix=True) + lex = shlex.shlex(line, posix=True) lex.whitespace_split = True lex.commenters = "#" # No escapes, so that backslash can be part of the path diff --git a/cogapp/test_cogapp.py b/cogapp/test_cogapp.py index 050bf10..a6f7a16 100644 --- a/cogapp/test_cogapp.py +++ b/cogapp/test_cogapp.py @@ -709,7 +709,7 @@ def setUp(self): # the functions we're going to use. self.gen = CogGenerator() self.m = self.gen.parseMarker - self.l = self.gen.parseLine + self.parseLine = self.gen.parseLine def testEmpty(self): self.m("// [[[cog") @@ -718,40 +718,40 @@ def testEmpty(self): def testSimple(self): self.m("// [[[cog") - self.l(' print "hello"') - self.l(' print "bye"') + self.parseLine(' print "hello"') + self.parseLine(' print "bye"') self.m("// ]]]") self.assertEqual(self.gen.getCode(), 'print "hello"\nprint "bye"') def testCompressed1(self): # For a while, I supported compressed code blocks, but no longer. self.m('// [[[cog: print """') - self.l("// hello") - self.l("// bye") + self.parseLine("// hello") + self.parseLine("// bye") self.m('// """)]]]') self.assertEqual(self.gen.getCode(), "hello\nbye") def testCompressed2(self): # For a while, I supported compressed code blocks, but no longer. self.m('// [[[cog: print """') - self.l("hello") - self.l("bye") + self.parseLine("hello") + self.parseLine("bye") self.m('// """)]]]') self.assertEqual(self.gen.getCode(), "hello\nbye") def testCompressed3(self): # For a while, I supported compressed code blocks, but no longer. self.m("// [[[cog") - self.l('print """hello') - self.l("bye") + self.parseLine('print """hello') + self.parseLine("bye") self.m('// """)]]]') self.assertEqual(self.gen.getCode(), 'print """hello\nbye') def testCompressed4(self): # For a while, I supported compressed code blocks, but no longer. self.m('// [[[cog: print """') - self.l("hello") - self.l('bye""")') + self.parseLine("hello") + self.parseLine('bye""")') self.m("// ]]]") self.assertEqual(self.gen.getCode(), 'hello\nbye""")') @@ -759,9 +759,9 @@ def testNoCommonPrefixForMarkers(self): # It's important to be able to use #if 0 to hide lines from a # C++ compiler. self.m("#if 0 //[[[cog") - self.l("\timport cog, sys") - self.l("") - self.l("\tprint sys.argv") + self.parseLine("\timport cog, sys") + self.parseLine("") + self.parseLine("\tprint sys.argv") self.m("#endif //]]]") self.assertEqual(self.gen.getCode(), "import cog, sys\n\nprint sys.argv") diff --git a/cogapp/test_makefiles.py b/cogapp/test_makefiles.py index ab2796a..3cff6a5 100644 --- a/cogapp/test_makefiles.py +++ b/cogapp/test_makefiles.py @@ -26,7 +26,7 @@ def exists(self, dname, fname): def checkFilesExist(self, d, dname): for fname in d.keys(): assert self.exists(dname, fname) - if type(d[fname]) == type({}): + if isinstance(d[fname], dict): self.checkFilesExist(d[fname], os.path.join(dname, fname)) def checkFilesDontExist(self, d, dname): diff --git a/cogapp/utils.py b/cogapp/utils.py index 8c008b9..e718001 100644 --- a/cogapp/utils.py +++ b/cogapp/utils.py @@ -44,10 +44,10 @@ def __init__(self, f): self.n = 0 def readline(self): - l = self.f.readline() - if l: + line = self.f.readline() + if line: self.n += 1 - return l + return line def linenumber(self): return self.n diff --git a/cogapp/whiteutils.py b/cogapp/whiteutils.py index 309dd75..ebdceaa 100644 --- a/cogapp/whiteutils.py +++ b/cogapp/whiteutils.py @@ -43,12 +43,12 @@ def reindentBlock(lines, newIndent=""): lines = lines.split(sep) oldIndent = whitePrefix(lines) outLines = [] - for l in lines: + for line in lines: if oldIndent: - l = l.replace(oldIndent, nothing, 1) - if l and newIndent: - l = newIndent + l - outLines.append(l) + line = line.replace(oldIndent, nothing, 1) + if line and newIndent: + line = newIndent + line + outLines.append(line) return sep.join(outLines)