From 80bb905891675b9bf46b573dc2076caa27579c05 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 30 Aug 2025 15:52:14 -0500 Subject: [PATCH 1/4] fix: fix 'unspecified-encoding' for pylint --- .pylintrc | 3 ++- src/wuttjamaican/app.py | 2 +- src/wuttjamaican/conf.py | 4 ++-- src/wuttjamaican/testing.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.pylintrc b/.pylintrc index e634a21..a076c68 100644 --- a/.pylintrc +++ b/.pylintrc @@ -2,4 +2,5 @@ [MESSAGES CONTROL] disable=all -enable=dangerous-default-value +enable=dangerous-default-value, + unspecified-encoding diff --git a/src/wuttjamaican/app.py b/src/wuttjamaican/app.py index c7d0e23..28dddcc 100644 --- a/src/wuttjamaican/app.py +++ b/src/wuttjamaican/app.py @@ -464,7 +464,7 @@ class AppHandler: """ output = template.render(**context) if output_path: - with open(output_path, 'wt') as f: + with open(output_path, 'wt', encoding='utf_8') as f: f.write(output) return output diff --git a/src/wuttjamaican/conf.py b/src/wuttjamaican/conf.py index 3eff415..3c16e2d 100644 --- a/src/wuttjamaican/conf.py +++ b/src/wuttjamaican/conf.py @@ -274,7 +274,7 @@ class WuttaConfig: # re-write as temp file with "final" values fd, temp_path = tempfile.mkstemp(suffix='.ini') os.close(fd) - with open(temp_path, 'wt') as f: + with open(temp_path, 'wt', encoding='utf_8') as f: temp_config.write(f) # and finally, load that into our main config @@ -611,7 +611,7 @@ class WuttaConfig: # write INI file and return path fd, path = tempfile.mkstemp(suffix='.conf') os.close(fd) - with open(path, 'wt') as f: + with open(path, 'wt', encoding='utf_8') as f: parser.write(f) return path diff --git a/src/wuttjamaican/testing.py b/src/wuttjamaican/testing.py index 5d34960..3ec7ae8 100644 --- a/src/wuttjamaican/testing.py +++ b/src/wuttjamaican/testing.py @@ -95,7 +95,7 @@ class FileTestCase(TestCase): myconf = self.write_file('my.conf', '') """ path = os.path.join(self.tempdir, filename) - with open(path, 'wt') as f: + with open(path, 'wt', encoding='utf_8') as f: f.write(content) return path From 38e4ce628dc16fe5116c3fbc24d7a59ecc82f512 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 30 Aug 2025 15:56:27 -0500 Subject: [PATCH 2/4] fix: fix 'unused-import' for pylint --- .pylintrc | 3 ++- src/wuttjamaican/app.py | 3 +-- src/wuttjamaican/conf.py | 3 +-- src/wuttjamaican/db/model/auth.py | 2 +- src/wuttjamaican/db/model/base.py | 5 ++--- src/wuttjamaican/db/model/batch.py | 4 ++-- src/wuttjamaican/db/model/upgrades.py | 4 ++-- src/wuttjamaican/install.py | 3 +-- 8 files changed, 12 insertions(+), 15 deletions(-) diff --git a/.pylintrc b/.pylintrc index a076c68..37ab470 100644 --- a/.pylintrc +++ b/.pylintrc @@ -3,4 +3,5 @@ [MESSAGES CONTROL] disable=all enable=dangerous-default-value, - unspecified-encoding + unspecified-encoding, + unused-import, diff --git a/src/wuttjamaican/app.py b/src/wuttjamaican/app.py index 28dddcc..3a24995 100644 --- a/src/wuttjamaican/app.py +++ b/src/wuttjamaican/app.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -24,7 +24,6 @@ WuttJamaican - app handler """ -import datetime import importlib import logging import os diff --git a/src/wuttjamaican/conf.py b/src/wuttjamaican/conf.py index 3c16e2d..91681f4 100644 --- a/src/wuttjamaican/conf.py +++ b/src/wuttjamaican/conf.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -25,7 +25,6 @@ WuttJamaican - app configuration """ import configparser -import importlib import logging import logging.config import os diff --git a/src/wuttjamaican/db/model/auth.py b/src/wuttjamaican/db/model/auth.py index eb42a47..b776d04 100644 --- a/src/wuttjamaican/db/model/auth.py +++ b/src/wuttjamaican/db/model/auth.py @@ -45,7 +45,7 @@ import sqlalchemy as sa from sqlalchemy import orm from sqlalchemy.ext.associationproxy import association_proxy -from .base import Base, uuid_column, uuid_fk_column +from . import Base, uuid_column, uuid_fk_column class Role(Base): diff --git a/src/wuttjamaican/db/model/base.py b/src/wuttjamaican/db/model/base.py index 8086cd0..1b68bd4 100644 --- a/src/wuttjamaican/db/model/base.py +++ b/src/wuttjamaican/db/model/base.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -36,8 +36,7 @@ import sqlalchemy as sa from sqlalchemy import orm from sqlalchemy.ext.associationproxy import association_proxy -from wuttjamaican.db.util import (naming_convention, ModelBase, - uuid_column, uuid_fk_column) +from wuttjamaican.db.util import naming_convention, ModelBase, uuid_column class WuttaModelBase(ModelBase): diff --git a/src/wuttjamaican/db/model/batch.py b/src/wuttjamaican/db/model/batch.py index 9b414b5..6f81641 100644 --- a/src/wuttjamaican/db/model/batch.py +++ b/src/wuttjamaican/db/model/batch.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -31,7 +31,7 @@ from sqlalchemy import orm from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.orderinglist import ordering_list -from wuttjamaican.db.model import uuid_column, uuid_fk_column, User +from wuttjamaican.db.model import uuid_column, User from wuttjamaican.db.util import UUID diff --git a/src/wuttjamaican/db/model/upgrades.py b/src/wuttjamaican/db/model/upgrades.py index 750a9a6..8e94abd 100644 --- a/src/wuttjamaican/db/model/upgrades.py +++ b/src/wuttjamaican/db/model/upgrades.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -29,7 +29,7 @@ import datetime import sqlalchemy as sa from sqlalchemy import orm -from .base import Base, uuid_column, uuid_fk_column +from . import Base, uuid_column, uuid_fk_column from wuttjamaican.enum import UpgradeStatus from wuttjamaican.db.util import UUID from wuttjamaican.util import make_true_uuid diff --git a/src/wuttjamaican/install.py b/src/wuttjamaican/install.py index 28dfb60..457a17f 100644 --- a/src/wuttjamaican/install.py +++ b/src/wuttjamaican/install.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -25,7 +25,6 @@ Install Handler """ import os -import shutil import stat import subprocess import sys From 4f6229e5d951a87521465b655a52e1076ed854c6 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 30 Aug 2025 16:06:04 -0500 Subject: [PATCH 3/4] fix: fix 'redefined-argument-from-local' for pylint --- .pylintrc | 1 + src/wuttjamaican/conf.py | 8 ++++---- src/wuttjamaican/email.py | 6 +++--- src/wuttjamaican/util.py | 16 ++++++++-------- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.pylintrc b/.pylintrc index 37ab470..4ffc2d7 100644 --- a/.pylintrc +++ b/.pylintrc @@ -3,5 +3,6 @@ [MESSAGES CONTROL] disable=all enable=dangerous-default-value, + redefined-argument-from-local, unspecified-encoding, unused-import, diff --git a/src/wuttjamaican/conf.py b/src/wuttjamaican/conf.py index 91681f4..0920cae 100644 --- a/src/wuttjamaican/conf.py +++ b/src/wuttjamaican/conf.py @@ -285,14 +285,14 @@ class WuttaConfig: # bring in any "required" files requires = config.get(f'{self.appname}.config.require') if requires: - for path in self.parse_list(requires): - self._load_ini_configs(path, configs, require=True) + for p in self.parse_list(requires): + self._load_ini_configs(p, configs, require=True) # bring in any "included" files includes = config.get(f'{self.appname}.config.include') if includes: - for path in self.parse_list(includes): - self._load_ini_configs(path, configs, require=False) + for p in self.parse_list(includes): + self._load_ini_configs(p, configs, require=False) def get_prioritized_files(self): """ diff --git a/src/wuttjamaican/email.py b/src/wuttjamaican/email.py index af039d6..6b4b124 100644 --- a/src/wuttjamaican/email.py +++ b/src/wuttjamaican/email.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -652,8 +652,8 @@ class EmailHandler(GenericHandler): :returns: True if this email type is enabled, otherwise false. """ - for key in set([key, 'default']): - enabled = self.config.get_bool(f'{self.config.appname}.email.{key}.enabled') + for k in set([key, 'default']): + enabled = self.config.get_bool(f'{self.config.appname}.email.{k}.enabled') if enabled is not None: return enabled return True diff --git a/src/wuttjamaican/util.py b/src/wuttjamaican/util.py index 161dbce..6296bb5 100644 --- a/src/wuttjamaican/util.py +++ b/src/wuttjamaican/util.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -256,11 +256,11 @@ def parse_list(value): parser.whitespace += ',' parser.whitespace_split = True values = list(parser) - for i, value in enumerate(values): - if value.startswith('"') and value.endswith('"'): - values[i] = value[1:-1] - elif value.startswith("'") and value.endswith("'"): - values[i] = value[1:-1] + for i, val in enumerate(values): + if val.startswith('"') and val.endswith('"'): + values[i] = val[1:-1] + elif val.startswith("'") and val.endswith("'"): + values[i] = val[1:-1] return values @@ -354,8 +354,8 @@ def resource_path(path): package, filename = path.split(':') ref = files(package) / filename - with as_file(ref) as path: - return str(path) + with as_file(ref) as p: + return str(p) return path From 2fcff6b2a4a1df07ef2e49dfb46cf4502fa58cce Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sat, 30 Aug 2025 16:36:52 -0500 Subject: [PATCH 4/4] fix: fix 'inconsistent-return-statements' for pylint --- .pylintrc | 1 + src/wuttjamaican/app.py | 6 +++--- src/wuttjamaican/auth.py | 6 +++++- src/wuttjamaican/conf.py | 4 ++++ src/wuttjamaican/db/model/base.py | 1 + src/wuttjamaican/db/model/batch.py | 1 + src/wuttjamaican/db/util.py | 3 ++- src/wuttjamaican/email.py | 4 ++++ src/wuttjamaican/install.py | 1 + src/wuttjamaican/people.py | 4 +++- src/wuttjamaican/problems.py | 4 ++-- src/wuttjamaican/reports.py | 3 ++- tests/db/model/test_batch.py | 4 ++++ tests/db/test_util.py | 2 ++ tests/test_app.py | 4 ++++ tests/test_reports.py | 4 ++++ 16 files changed, 43 insertions(+), 9 deletions(-) diff --git a/.pylintrc b/.pylintrc index 4ffc2d7..d917385 100644 --- a/.pylintrc +++ b/.pylintrc @@ -3,6 +3,7 @@ [MESSAGES CONTROL] disable=all enable=dangerous-default-value, + inconsistent-return-statements, redefined-argument-from-local, unspecified-encoding, unused-import, diff --git a/src/wuttjamaican/app.py b/src/wuttjamaican/app.py index 3a24995..7047f43 100644 --- a/src/wuttjamaican/app.py +++ b/src/wuttjamaican/app.py @@ -229,7 +229,7 @@ class AppHandler: If ``obj`` is *not* specified, this behaves a bit differently. It first will look for a :term:`config setting` named - ``wutta.app_dist`` (or similar, dpending on :attr:`appname`). + ``wutta.app_dist`` (or similar, depending on :attr:`appname`). If there is such a config value, it is returned. Otherwise the "auto-locate" logic described above happens, but using ``self`` instead of ``obj``. @@ -280,8 +280,7 @@ class AppHandler: return dist # fall back to configured dist, if obj lookup failed - if obj is not None: - return self.config.get(f'{self.appname}.app_dist') + return self.config.get(f'{self.appname}.app_dist') def get_version(self, dist=None, obj=None): """ @@ -301,6 +300,7 @@ class AppHandler: dist = self.get_distribution(obj=obj) if dist: return version(dist) + return None def get_model(self): """ diff --git a/src/wuttjamaican/auth.py b/src/wuttjamaican/auth.py index 0643cff..fa3054f 100644 --- a/src/wuttjamaican/auth.py +++ b/src/wuttjamaican/auth.py @@ -93,6 +93,7 @@ class AuthHandler(GenericHandler): if user and user.active and user.password: if self.check_user_password(user, password): return user + return None def authenticate_user_token(self, session, token): """ @@ -122,6 +123,7 @@ class AuthHandler(GenericHandler): user = token.user if user.active: return user + return None def check_user_password(self, user, password, **kwargs): """ @@ -158,7 +160,7 @@ class AuthHandler(GenericHandler): model = self.app.model if not key: - return + return None # maybe it is a uuid if isinstance(key, _uuid.UUID): @@ -188,6 +190,7 @@ class AuthHandler(GenericHandler): session=session) if key: return self.get_role(session, key) + return None def get_user(self, obj, session=None, **kwargs): """ @@ -256,6 +259,7 @@ class AuthHandler(GenericHandler): person = self.app.get_person(obj) if person: return person.user + return None def make_person(self, **kwargs): """ diff --git a/src/wuttjamaican/conf.py b/src/wuttjamaican/conf.py index 0920cae..103d2cc 100644 --- a/src/wuttjamaican/conf.py +++ b/src/wuttjamaican/conf.py @@ -466,6 +466,8 @@ class WuttaConfig: if default is not UNSPECIFIED: return default + return None + def get_from_db(self, key, session=None, **kwargs): """ Retrieve a config value from database settings table. @@ -510,6 +512,7 @@ class WuttaConfig: value = self.get(*args, **kwargs) if value is not None: return int(value) + return None def get_list(self, *args, **kwargs): """ @@ -524,6 +527,7 @@ class WuttaConfig: value = self.get(*args, **kwargs) if value is not None: return self.parse_list(value) + return None def get_dict(self, prefix): """ diff --git a/src/wuttjamaican/db/model/base.py b/src/wuttjamaican/db/model/base.py index 1b68bd4..9dc49ae 100644 --- a/src/wuttjamaican/db/model/base.py +++ b/src/wuttjamaican/db/model/base.py @@ -214,3 +214,4 @@ class Person(Base): if self.users: return self.users[0] + return None diff --git a/src/wuttjamaican/db/model/batch.py b/src/wuttjamaican/db/model/batch.py index 6f81641..e253e84 100644 --- a/src/wuttjamaican/db/model/batch.py +++ b/src/wuttjamaican/db/model/batch.py @@ -263,6 +263,7 @@ class BatchMixin: """ if self.id: return f'{self.id:08d}' + return None class BatchRowMixin: diff --git a/src/wuttjamaican/db/util.py b/src/wuttjamaican/db/util.py index ff4b69b..ebaf0b1 100644 --- a/src/wuttjamaican/db/util.py +++ b/src/wuttjamaican/db/util.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -66,6 +66,7 @@ class ModelBase: state = sa.inspect(self) if hasattr(state.attrs, key): return getattr(self, key) + raise KeyError(f"model instance has no attr with key: {key}") class UUID(sa.types.TypeDecorator): diff --git a/src/wuttjamaican/email.py b/src/wuttjamaican/email.py index 6b4b124..8ad9997 100644 --- a/src/wuttjamaican/email.py +++ b/src/wuttjamaican/email.py @@ -358,6 +358,7 @@ class EmailHandler(GenericHandler): if instance: setting = setting(self.config) return setting + return None def make_message(self, **kwargs): """ @@ -573,6 +574,7 @@ class EmailHandler(GenericHandler): if template: context = context or {} return template.render(**context) + return None def get_auto_html_body(self, key, context=None): """ @@ -585,6 +587,7 @@ class EmailHandler(GenericHandler): if template: context = context or {} return template.render(**context) + return None def get_auto_body_template(self, key, mode): """ """ @@ -601,6 +604,7 @@ class EmailHandler(GenericHandler): return templates.get_template(f'{key}.{mode}.mako') except TopLevelLookupException: pass + return None def get_notes(self, key): """ diff --git a/src/wuttjamaican/install.py b/src/wuttjamaican/install.py index 457a17f..8ca35ec 100644 --- a/src/wuttjamaican/install.py +++ b/src/wuttjamaican/install.py @@ -254,6 +254,7 @@ class InstallHandler(GenericHandler): sa.inspect(engine).has_table('whatever') except Exception as error: return str(error) + return None def make_template_context(self, dbinfo, **kwargs): """ diff --git a/src/wuttjamaican/people.py b/src/wuttjamaican/people.py index 1c855a8..1cc6fda 100644 --- a/src/wuttjamaican/people.py +++ b/src/wuttjamaican/people.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -88,3 +88,5 @@ class PeopleHandler(GenericHandler): user = obj if user.person: return user.person + + return None diff --git a/src/wuttjamaican/problems.py b/src/wuttjamaican/problems.py index 76a5282..608ef66 100644 --- a/src/wuttjamaican/problems.py +++ b/src/wuttjamaican/problems.py @@ -308,14 +308,14 @@ class ProblemHandler(GenericHandler): if not self.is_enabled(check): log.debug("problem check is not enabled: %s", key) if not force: - return + return None weekday = datetime.date.today().weekday() if not self.should_run_for_weekday(check, weekday): log.debug("problem check is not scheduled for %s: %s", calendar.day_name[weekday], key) if not force: - return + return None check_instance = check(self.config) problems = self.find_problems(check_instance) diff --git a/src/wuttjamaican/reports.py b/src/wuttjamaican/reports.py index 6d5cb88..7a55a19 100644 --- a/src/wuttjamaican/reports.py +++ b/src/wuttjamaican/reports.py @@ -2,7 +2,7 @@ ################################################################################ # # WuttJamaican -- Base package for Wutta Framework -# Copyright © 2023-2024 Lance Edgar +# Copyright © 2023-2025 Lance Edgar # # This file is part of Wutta Framework. # @@ -196,6 +196,7 @@ class ReportHandler(GenericHandler): if instance: report = report(self.config) return report + return None def make_report_data(self, report, params=None, progress=None, **kwargs): """ diff --git a/tests/db/model/test_batch.py b/tests/db/model/test_batch.py index fa16d25..308cb6f 100644 --- a/tests/db/model/test_batch.py +++ b/tests/db/model/test_batch.py @@ -27,6 +27,10 @@ else: batch = MyBatch(id=42, uuid=_uuid.UUID('0675cdac-ffc9-7690-8000-6023de1c8cfd')) self.assertEqual(repr(batch), "MyBatch(uuid=UUID('0675cdac-ffc9-7690-8000-6023de1c8cfd'))") self.assertEqual(str(batch), "00000042") + self.assertEqual(batch.id_str, "00000042") + + batch2 = MyBatch() + self.assertIsNone(batch2.id_str) class TestBatchRowMixin(DataTestCase): diff --git a/tests/db/test_util.py b/tests/db/test_util.py index 44ff6f0..f2002b8 100644 --- a/tests/db/test_util.py +++ b/tests/db/test_util.py @@ -22,9 +22,11 @@ else: def test_dict_behavior(self): setting = Setting() self.assertEqual(list(iter(setting)), [('name', None), ('value', None)]) + self.assertIsNone(setting.name) self.assertIsNone(setting['name']) setting.name = 'foo' self.assertEqual(setting['name'], 'foo') + self.assertRaises(KeyError, lambda: setting['notfound']) class TestUUID(TestCase): diff --git a/tests/test_app.py b/tests/test_app.py index e20e324..e05334d 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -375,6 +375,10 @@ app_title = WuttaTest ver = self.app.get_version(obj=query) self.assertEqual(ver, version('SQLAlchemy')) + # random object will not yield a dist nor version + ver = self.app.get_version(obj=42) + self.assertIsNone(ver) + # can override dist via config self.config.setdefault('wuttatest.app_dist', 'python-configuration') ver = self.app.get_version() diff --git a/tests/test_reports.py b/tests/test_reports.py index 7b19385..7d730e7 100644 --- a/tests/test_reports.py +++ b/tests/test_reports.py @@ -94,6 +94,10 @@ class TestReportHandler(ConfigTestCase): self.assertTrue(issubclass(report, mod.Report)) self.assertIs(report, MockFooReport) + # not found + report = handler.get_report('unknown') + self.assertIsNone(report) + def test_make_report_data(self): providers = { 'wuttatest': MagicMock(report_modules=['tests.test_reports']),