diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aad1b0e..dfa0af8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,18 @@ name: Build on: [push] jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-python@v6 + with: + python-version: "3.14" + - uses: astral-sh/setup-uv@v6 + - run: uv sync --locked --all-extras --dev + - run: uv run ruff check --output-format=github --target-version=py314 + - run: uv run ruff format --diff --target-version=py314 + test: runs-on: ubuntu-latest strategy: diff --git a/pyproject.toml b/pyproject.toml index 113fa5e..9cc23ed 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,3 +22,8 @@ watch-diff = "watch_diff.__main__:main" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" + +[dependency-groups] +dev = [ + "ruff>=0.14.6", +] diff --git a/tests/test_watch_diff.py b/tests/test_watch_diff.py index 9b2646f..1ab0b80 100644 --- a/tests/test_watch_diff.py +++ b/tests/test_watch_diff.py @@ -1,20 +1,15 @@ -""" -""" - import os import unittest import watch_diff - -smtp_host = os.environ.get('SMTP_HOST') -smtp_port = os.environ.get('SMTP_PORT') -smtp_user = os.environ.get('SMTP_USER') -smtp_pass = os.environ.get('SMTP_PASS') +smtp_host = os.environ.get("SMTP_HOST") +smtp_port = os.environ.get("SMTP_PORT") +smtp_user = os.environ.get("SMTP_USER") +smtp_pass = os.environ.get("SMTP_PASS") class TestWatchDiff(unittest.TestCase): - def test_api_available(self): self.assertTrue(watch_diff.Command) self.assertTrue(watch_diff.Diff) @@ -25,16 +20,18 @@ def test_api_available(self): self.assertTrue(watch_diff.OutputFormatting) def test_command(self): - c = watch_diff.Command('date') + c = watch_diff.Command("date") self.assertFalse(c) d = c.run() self.assertTrue(c) self.assertTrue(d) - @unittest.skipIf(not smtp_host, 'SMTP_HOST is not available') - @unittest.skipIf(not smtp_port, 'SMTP_PORT is not available') - @unittest.skipIf(not smtp_user, 'SMTP_USER is not available') - @unittest.skipIf(not smtp_pass, 'SMTP_PASS is not available') + @unittest.skipIf(not smtp_host, "SMTP_HOST is not available") + @unittest.skipIf(not smtp_port, "SMTP_PORT is not available") + @unittest.skipIf(not smtp_user, "SMTP_USER is not available") + @unittest.skipIf(not smtp_pass, "SMTP_PASS is not available") def test_email(self): - e = watch_diff.Email(smtp_host, smtp_port, smtp_user, smtp_pass, 'watch-diff-tests', smtp_user) - e.send_email('watch diff tests', 'text', 'html') + e = watch_diff.Email( + smtp_host, smtp_port, smtp_user, smtp_pass, "watch-diff-tests", smtp_user + ) + e.send_email("watch diff tests", "text", "html") diff --git a/uv.lock b/uv.lock index 0696abd..6774edf 100644 --- a/uv.lock +++ b/uv.lock @@ -2,7 +2,43 @@ version = 1 revision = 3 requires-python = ">=3.10" +[[package]] +name = "ruff" +version = "0.14.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/f0/62b5a1a723fe183650109407fa56abb433b00aa1c0b9ba555f9c4efec2c6/ruff-0.14.6.tar.gz", hash = "sha256:6f0c742ca6a7783a736b867a263b9a7a80a45ce9bee391eeda296895f1b4e1cc", size = 5669501, upload-time = "2025-11-21T14:26:17.903Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/d2/7dd544116d107fffb24a0064d41a5d2ed1c9d6372d142f9ba108c8e39207/ruff-0.14.6-py3-none-linux_armv6l.whl", hash = "sha256:d724ac2f1c240dbd01a2ae98db5d1d9a5e1d9e96eba999d1c48e30062df578a3", size = 13326119, upload-time = "2025-11-21T14:25:24.2Z" }, + { url = "https://files.pythonhosted.org/packages/36/6a/ad66d0a3315d6327ed6b01f759d83df3c4d5f86c30462121024361137b6a/ruff-0.14.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9f7539ea257aa4d07b7ce87aed580e485c40143f2473ff2f2b75aee003186004", size = 13526007, upload-time = "2025-11-21T14:25:26.906Z" }, + { url = "https://files.pythonhosted.org/packages/a3/9d/dae6db96df28e0a15dea8e986ee393af70fc97fd57669808728080529c37/ruff-0.14.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7f6007e55b90a2a7e93083ba48a9f23c3158c433591c33ee2e99a49b889c6332", size = 12676572, upload-time = "2025-11-21T14:25:29.826Z" }, + { url = "https://files.pythonhosted.org/packages/76/a4/f319e87759949062cfee1b26245048e92e2acce900ad3a909285f9db1859/ruff-0.14.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a8e7b9d73d8728b68f632aa8e824ef041d068d231d8dbc7808532d3629a6bef", size = 13140745, upload-time = "2025-11-21T14:25:32.788Z" }, + { url = "https://files.pythonhosted.org/packages/95/d3/248c1efc71a0a8ed4e8e10b4b2266845d7dfc7a0ab64354afe049eaa1310/ruff-0.14.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d50d45d4553a3ebcbd33e7c5e0fe6ca4aafd9a9122492de357205c2c48f00775", size = 13076486, upload-time = "2025-11-21T14:25:35.601Z" }, + { url = "https://files.pythonhosted.org/packages/a5/19/b68d4563fe50eba4b8c92aa842149bb56dd24d198389c0ed12e7faff4f7d/ruff-0.14.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:118548dd121f8a21bfa8ab2c5b80e5b4aed67ead4b7567790962554f38e598ce", size = 13727563, upload-time = "2025-11-21T14:25:38.514Z" }, + { url = "https://files.pythonhosted.org/packages/47/ac/943169436832d4b0e867235abbdb57ce3a82367b47e0280fa7b4eabb7593/ruff-0.14.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:57256efafbfefcb8748df9d1d766062f62b20150691021f8ab79e2d919f7c11f", size = 15199755, upload-time = "2025-11-21T14:25:41.516Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b9/288bb2399860a36d4bb0541cb66cce3c0f4156aaff009dc8499be0c24bf2/ruff-0.14.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff18134841e5c68f8e5df1999a64429a02d5549036b394fafbe410f886e1989d", size = 14850608, upload-time = "2025-11-21T14:25:44.428Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b1/a0d549dd4364e240f37e7d2907e97ee80587480d98c7799d2d8dc7a2f605/ruff-0.14.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c4b7ec1e66a105d5c27bd57fa93203637d66a26d10ca9809dc7fc18ec58440", size = 14118754, upload-time = "2025-11-21T14:25:47.214Z" }, + { url = "https://files.pythonhosted.org/packages/13/ac/9b9fe63716af8bdfddfacd0882bc1586f29985d3b988b3c62ddce2e202c3/ruff-0.14.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:167843a6f78680746d7e226f255d920aeed5e4ad9c03258094a2d49d3028b105", size = 13949214, upload-time = "2025-11-21T14:25:50.002Z" }, + { url = "https://files.pythonhosted.org/packages/12/27/4dad6c6a77fede9560b7df6802b1b697e97e49ceabe1f12baf3ea20862e9/ruff-0.14.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:16a33af621c9c523b1ae006b1b99b159bf5ac7e4b1f20b85b2572455018e0821", size = 14106112, upload-time = "2025-11-21T14:25:52.841Z" }, + { url = "https://files.pythonhosted.org/packages/6a/db/23e322d7177873eaedea59a7932ca5084ec5b7e20cb30f341ab594130a71/ruff-0.14.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1432ab6e1ae2dc565a7eea707d3b03a0c234ef401482a6f1621bc1f427c2ff55", size = 13035010, upload-time = "2025-11-21T14:25:55.536Z" }, + { url = "https://files.pythonhosted.org/packages/a8/9c/20e21d4d69dbb35e6a1df7691e02f363423658a20a2afacf2a2c011800dc/ruff-0.14.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4c55cfbbe7abb61eb914bfd20683d14cdfb38a6d56c6c66efa55ec6570ee4e71", size = 13054082, upload-time = "2025-11-21T14:25:58.625Z" }, + { url = "https://files.pythonhosted.org/packages/66/25/906ee6a0464c3125c8d673c589771a974965c2be1a1e28b5c3b96cb6ef88/ruff-0.14.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:efea3c0f21901a685fff4befda6d61a1bf4cb43de16da87e8226a281d614350b", size = 13303354, upload-time = "2025-11-21T14:26:01.816Z" }, + { url = "https://files.pythonhosted.org/packages/4c/58/60577569e198d56922b7ead07b465f559002b7b11d53f40937e95067ca1c/ruff-0.14.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:344d97172576d75dc6afc0e9243376dbe1668559c72de1864439c4fc95f78185", size = 14054487, upload-time = "2025-11-21T14:26:05.058Z" }, + { url = "https://files.pythonhosted.org/packages/67/0b/8e4e0639e4cc12547f41cb771b0b44ec8225b6b6a93393176d75fe6f7d40/ruff-0.14.6-py3-none-win32.whl", hash = "sha256:00169c0c8b85396516fdd9ce3446c7ca20c2a8f90a77aa945ba6b8f2bfe99e85", size = 13013361, upload-time = "2025-11-21T14:26:08.152Z" }, + { url = "https://files.pythonhosted.org/packages/fb/02/82240553b77fd1341f80ebb3eaae43ba011c7a91b4224a9f317d8e6591af/ruff-0.14.6-py3-none-win_amd64.whl", hash = "sha256:390e6480c5e3659f8a4c8d6a0373027820419ac14fa0d2713bd8e6c3e125b8b9", size = 14432087, upload-time = "2025-11-21T14:26:10.891Z" }, + { url = "https://files.pythonhosted.org/packages/a5/1f/93f9b0fad9470e4c829a5bb678da4012f0c710d09331b860ee555216f4ea/ruff-0.14.6-py3-none-win_arm64.whl", hash = "sha256:d43c81fbeae52cfa8728d8766bbf46ee4298c888072105815b392da70ca836b2", size = 13520930, upload-time = "2025-11-21T14:26:13.951Z" }, +] + [[package]] name = "watch-diff" version = "0.7.1" source = { editable = "." } + +[package.dev-dependencies] +dev = [ + { name = "ruff" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [{ name = "ruff", specifier = ">=0.14.6" }] diff --git a/watch_diff/__init__.py b/watch_diff/__init__.py index ee88321..9b78a05 100644 --- a/watch_diff/__init__.py +++ b/watch_diff/__init__.py @@ -1,10 +1,19 @@ -""" -""" +from watch_diff.command import Command +from watch_diff.diff import Diff +from watch_diff.email import Email +from watch_diff.format import ( + ConsoleFormatter, + DefaultFormatter, + HTMLFormatter, + OutputFormatting, +) -__version__ = '0.6.0' - - -from .command import Command -from .diff import Diff -from .email import Email -from .format import DefaultFormatter, ConsoleFormatter, HTMLFormatter, OutputFormatting +__all__ = [ + "Command", + "Diff", + "Email", + "ConsoleFormatter", + "DefaultFormatter", + "HTMLFormatter", + "OutputFormatting", +] diff --git a/watch_diff/__main__.py b/watch_diff/__main__.py index 7d09b40..3dbd1c9 100644 --- a/watch_diff/__main__.py +++ b/watch_diff/__main__.py @@ -1,32 +1,48 @@ -""" -""" - import argparse import datetime import getpass import logging import os import time - from email.utils import make_msgid -from . import command -from . import email - +from watch_diff import command, email logger = logging.getLogger(__name__) -parser = argparse.ArgumentParser(description='Watch command output and get notified on changes') -logging_group = parser.add_argument_group('logging level').add_mutually_exclusive_group() -logging_group.add_argument('-v', '--verbose', action='store_const', - const=logging.INFO, default=logging.CRITICAL, - dest='loglevel', help='enable verbose output') -logging_group.add_argument('-d', '--debug', action='store_const', - const=logging.DEBUG, dest='loglevel', - help='show debugging statements') -parser.add_argument('-i', '--interval', type=int, default=5, metavar='SECONDS', help='number of seconds between executions') -parser.add_argument('-r', '--recipient', help='send email to recipient') -parser.add_argument('command', help='the command to watch') +parser = argparse.ArgumentParser( + description="Watch command output and get notified on changes" +) +logging_group = parser.add_argument_group( + "logging level" +).add_mutually_exclusive_group() +logging_group.add_argument( + "-v", + "--verbose", + action="store_const", + const=logging.INFO, + default=logging.CRITICAL, + dest="loglevel", + help="enable verbose output", +) +logging_group.add_argument( + "-d", + "--debug", + action="store_const", + const=logging.DEBUG, + dest="loglevel", + help="show debugging statements", +) +parser.add_argument( + "-i", + "--interval", + type=int, + default=5, + metavar="SECONDS", + help="number of seconds between executions", +) +parser.add_argument("-r", "--recipient", help="send email to recipient") +parser.add_argument("command", help="the command to watch") def _main(): @@ -35,11 +51,13 @@ def _main(): e = None if args.recipient: - smtp_host = os.environ.get('SMTP_HOST') or input('SMTP_HOST: ') - smtp_port = os.environ.get('SMTP_PORT') or input('SMTP_PORT: ') - smtp_user = os.environ.get('SMTP_USER') or input('SMTP_USER: ') - smtp_pass = os.environ.get('SMTP_PASS') or getpass.getpass('SMTP_PASS: ') - e = email.Email(smtp_host, smtp_port, smtp_user, smtp_pass, 'watch-diff', args.recipient) + smtp_host = os.environ.get("SMTP_HOST") or input("SMTP_HOST: ") + smtp_port = os.environ.get("SMTP_PORT") or input("SMTP_PORT: ") + smtp_user = os.environ.get("SMTP_USER") or input("SMTP_USER: ") + smtp_pass = os.environ.get("SMTP_PASS") or getpass.getpass("SMTP_PASS: ") + e = email.Email( + smtp_host, smtp_port, smtp_user, smtp_pass, "watch-diff", args.recipient + ) first_run = True c = command.Command(args.command) @@ -47,31 +65,37 @@ def _main(): while True: now = str(datetime.datetime.now()) - logger.info('executing command with time {}'.format(now)) + logger.info("executing command with time {}".format(now)) diff = c.run(now) if first_run: - print('[{}] first_run:'.format(now)) + print("[{}] first_run:".format(now)) print(c.to_console()) - subject = 'watch-diff first_run: {}'.format(args.command) + subject = "watch-diff first_run: {}".format(args.command) if e: - logger.info('sending first_run email to {}'.format(args.recipient)) + logger.info("sending first_run email to {}".format(args.recipient)) msg_id = make_msgid() e.send_email(subject, str(c), c.to_html(full_html=True), msg_id) previous_msg_id = msg_id elif diff: - print('[{}] diff:'.format(now)) + print("[{}] diff:".format(now)) print(diff.to_console()) - subject = 'watch-diff diff: {}'.format(args.command) + subject = "watch-diff diff: {}".format(args.command) if e: - logger.info('sending diff email to {}'.format(args.recipient)) + logger.info("sending diff email to {}".format(args.recipient)) msg_id = make_msgid() - e.send_email(subject, str(diff), diff.to_html(full_html=True), msg_id, previous_msg_id) + e.send_email( + subject, + str(diff), + diff.to_html(full_html=True), + msg_id, + previous_msg_id, + ) previous_msg_id = msg_id else: - print('[{}] no diff'.format(now)) + print("[{}] no diff".format(now)) - logger.info('sleeping for {} seconds'.format(args.interval)) + logger.info("sleeping for {} seconds".format(args.interval)) time.sleep(args.interval) first_run = False diff --git a/watch_diff/command.py b/watch_diff/command.py index e69e632..be89056 100644 --- a/watch_diff/command.py +++ b/watch_diff/command.py @@ -1,23 +1,18 @@ -""" -""" - import datetime import subprocess -from . import diff -from . import format +from watch_diff import diff, format class Command(format.OutputFormatting): - def __init__(self, command): self._command = command - self._previous_datetime = '' - self._previous_result = '' + self._previous_datetime = "" + self._previous_result = "" - self._current_datetime = '' - self._current_result = '' + self._current_datetime = "" + self._current_result = "" def __bool__(self): return bool(self._current_result) @@ -26,7 +21,12 @@ def _format(self, formatter=format.DefaultFormatter): return self._current_result def _diff(self): - return diff.Diff(self._previous_result, self._current_result, self._previous_datetime, self._current_datetime) + return diff.Diff( + self._previous_result, + self._current_result, + self._previous_datetime, + self._current_datetime, + ) def _run(self): return subprocess.getoutput(self._command) diff --git a/watch_diff/diff.py b/watch_diff/diff.py index 408186b..2c09639 100644 --- a/watch_diff/diff.py +++ b/watch_diff/diff.py @@ -1,17 +1,26 @@ -""" -""" - import difflib -from . import format +from watch_diff import format class Diff(format.OutputFormatting): - def __init__(self, a, b, previous_datetime, current_datetime): self._a = a self._b = b - self._diff = '\n'.join(difflib.unified_diff(a.splitlines(), b.splitlines(), 'Previous', 'Current', previous_datetime, current_datetime, lineterm='')) or None + self._diff = ( + "\n".join( + difflib.unified_diff( + a.splitlines(), + b.splitlines(), + "Previous", + "Current", + previous_datetime, + current_datetime, + lineterm="", + ) + ) + or None + ) def __bool__(self): return bool(self._diff) @@ -20,12 +29,22 @@ def _format(self, formatter=format.DefaultFormatter): lines = self._diff.splitlines() output = [] for line in lines[:2]: - output.append('{}{}{}'.format(formatter.header_start, line, formatter.header_end)) + output.append( + "{}{}{}".format(formatter.header_start, line, formatter.header_end) + ) for line in lines[2:]: - if line[0] == '+': - output.append('{}{}{}'.format(formatter.addition_start, line, formatter.addition_end)) - elif line[0] == '-': - output.append('{}{}{}'.format(formatter.subtraction_start, line, formatter.subtraction_end)) + if line[0] == "+": + output.append( + "{}{}{}".format( + formatter.addition_start, line, formatter.addition_end + ) + ) + elif line[0] == "-": + output.append( + "{}{}{}".format( + formatter.subtraction_start, line, formatter.subtraction_end + ) + ) else: output.append(line) - return '\n'.join(output) + return "\n".join(output) diff --git a/watch_diff/email.py b/watch_diff/email.py index f6ea7c9..01433cc 100644 --- a/watch_diff/email.py +++ b/watch_diff/email.py @@ -1,16 +1,11 @@ -""" -""" - import functools import logging import smtplib import socket import time - from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText -from email.utils import make_msgid, formatdate - +from email.utils import formatdate, make_msgid logger = logging.getLogger(__name__) @@ -22,22 +17,29 @@ def wrapper(*args, **kwargs): count = 1 while True: try: - logger.info('running func: "{}", count: {}'.format(func.__name__, count)) + logger.info( + 'running func: "{}", count: {}'.format(func.__name__, count) + ) return func(*args, **kwargs) except Exception as e: - if (not exceptions or e.__class__ in exceptions) and count < num_times: + if ( + not exceptions or e.__class__ in exceptions + ) and count < num_times: count += 1 time.sleep(30) continue else: raise + return wrapper + return decorator class Email: - - def __init__(self, smtp_host, smtp_port, smtp_user, smtp_pass, from_name, recipient): + def __init__( + self, smtp_host, smtp_port, smtp_user, smtp_pass, from_name, recipient + ): self._smtp_host = smtp_host self._smtp_port = smtp_port self._smtp_user = smtp_user @@ -45,30 +47,34 @@ def __init__(self, smtp_host, smtp_port, smtp_user, smtp_pass, from_name, recipi self._from_name = from_name self._recipient = recipient - @_repeat_on_exceptions(3, smtplib.SMTPServerDisconnected, socket.gaierror, socket.timeout) + @_repeat_on_exceptions( + 3, smtplib.SMTPServerDisconnected, socket.gaierror, socket.timeout + ) def _smtp_connect(self, smtp_host, smtp_port): return smtplib.SMTP(host=self._smtp_host, port=self._smtp_port) - @_repeat_on_exceptions(3, smtplib.SMTPAuthenticationError, socket.gaierror, socket.timeout) + @_repeat_on_exceptions( + 3, smtplib.SMTPAuthenticationError, socket.gaierror, socket.timeout + ) def _smtp_login(self, session, smtp_user, smtp_pass): session.login(self._smtp_user, self._smtp_pass) def send_email(self, subject, text, html, msg_id=None, previous_msg_id=None): - logger.info('sending email') + logger.info("sending email") - msg = MIMEMultipart('alternative') + msg = MIMEMultipart("alternative") - msg['From'] = '{} <{}>'.format(self._from_name, self._smtp_user) - msg['To'] = self._recipient - msg['Subject'] = subject - msg['Date'] = formatdate() - msg['Message-ID'] = msg_id or make_msgid() + msg["From"] = "{} <{}>".format(self._from_name, self._smtp_user) + msg["To"] = self._recipient + msg["Subject"] = subject + msg["Date"] = formatdate() + msg["Message-ID"] = msg_id or make_msgid() if previous_msg_id: - msg['In-Reply-To'] = previous_msg_id + msg["In-Reply-To"] = previous_msg_id - part1 = MIMEText(text, 'plain') - part2 = MIMEText(html, 'html') + part1 = MIMEText(text, "plain") + part2 = MIMEText(html, "html") msg.attach(part1) msg.attach(part2) @@ -81,4 +87,4 @@ def send_email(self, subject, text, html, msg_id=None, previous_msg_id=None): s.sendmail(self._smtp_user, self._recipient, msg.as_string()) s.quit() - logger.info('email sent successfully') + logger.info("email sent successfully") diff --git a/watch_diff/format.py b/watch_diff/format.py index b6d8da3..8bacd42 100644 --- a/watch_diff/format.py +++ b/watch_diff/format.py @@ -1,32 +1,31 @@ -""" -""" - class DefaultFormatter: - header_start = '' - header_end = '' - addition_start = '' - addition_end = '' - subtraction_start = '' - subtraction_end = '' + header_start = "" + header_end = "" + addition_start = "" + addition_end = "" + subtraction_start = "" + subtraction_end = "" + class ConsoleFormatter(DefaultFormatter): - header_start = '\033[1m' - header_end = '\033[0m' - addition_start = '\033[92m' - addition_end = '\033[0m' - subtraction_start = '\033[91m' - subtraction_end = '\033[0m' + header_start = "\033[1m" + header_end = "\033[0m" + addition_start = "\033[92m" + addition_end = "\033[0m" + subtraction_start = "\033[91m" + subtraction_end = "\033[0m" + class HTMLFormatter(DefaultFormatter): - header_start = '' - header_end = '' + header_start = "" + header_end = "" addition_start = '' - addition_end = '' + addition_end = "" subtraction_start = '' - subtraction_end = '' + subtraction_end = "" -class OutputFormatting: +class OutputFormatting: def __str__(self): return self._format(DefaultFormatter) @@ -38,7 +37,7 @@ def to_html(self, full_html=False): if not full_html: return partial_html else: - html_page = ''' + html_page = """
@@ -46,6 +45,6 @@ def to_html(self, full_html=False):
                         
- ''' - html_page = '\n'.join([l.strip() for l in html_page.splitlines()]) + """ + html_page = "\n".join([line.strip() for line in html_page.splitlines()]) return html_page.format(partial_html)