diff --git a/.pylintrc b/.pylintrc index 66b3c38..d7466ee 100644 --- a/.pylintrc +++ b/.pylintrc @@ -36,3 +36,8 @@ disable=fixme, ungrouped-imports, unidiomatic-typecheck, unnecessary-comprehension, + unnecessary-lambda, + unnecessary-lambda-assignment, + unspecified-encoding, + unused-argument, + use-a-generator, diff --git a/src/wuttaweb/app.py b/src/wuttaweb/app.py index 1593095..f7f768e 100644 --- a/src/wuttaweb/app.py +++ b/src/wuttaweb/app.py @@ -52,7 +52,7 @@ class WebAppProvider(AppProvider): email_modules = ["wuttaweb.emails"] email_templates = ["wuttaweb:email-templates"] - def get_web_handler(self): + def get_web_handler(self, **kwargs): """ Get the configured "web" handler for the app. @@ -167,7 +167,7 @@ def make_pyramid_config(settings): return pyramid_config -def main(global_config, **settings): # pylint: disable=unused-argument +def main(global_config, **settings): """ Make and return the WSGI application, per given settings. diff --git a/src/wuttaweb/auth.py b/src/wuttaweb/auth.py index e6222c0..e18cb78 100644 --- a/src/wuttaweb/auth.py +++ b/src/wuttaweb/auth.py @@ -137,7 +137,7 @@ class WuttaSecurityPolicy: def forget(self, request, **kw): return self.session_helper.forget(request, **kw) - def permits(self, request, context, permission): # pylint: disable=unused-argument + def permits(self, request, context, permission): # nb. root user can do anything if getattr(request, "is_root", False): diff --git a/src/wuttaweb/cli/webapp.py b/src/wuttaweb/cli/webapp.py index b7fa076..24695a4 100644 --- a/src/wuttaweb/cli/webapp.py +++ b/src/wuttaweb/cli/webapp.py @@ -35,7 +35,7 @@ from wuttjamaican.cli import wutta_typer @wutta_typer.command() -def webapp( # pylint: disable=unused-argument +def webapp( ctx: typer.Context, auto_reload: Annotated[ bool, diff --git a/src/wuttaweb/forms/base.py b/src/wuttaweb/forms/base.py index a4a469a..8eeed6f 100644 --- a/src/wuttaweb/forms/base.py +++ b/src/wuttaweb/forms/base.py @@ -982,7 +982,7 @@ class Form: # pylint: disable=too-many-instance-attributes output = render(template, context) return HTML.literal(output) - def render_vue_field( # pylint: disable=unused-argument + def render_vue_field( self, fieldname, readonly=None, diff --git a/src/wuttaweb/forms/schema.py b/src/wuttaweb/forms/schema.py index dc839fb..f3384b1 100644 --- a/src/wuttaweb/forms/schema.py +++ b/src/wuttaweb/forms/schema.py @@ -352,9 +352,7 @@ class ObjectRef(colander.SchemaType): """ return obj.uuid.hex - def deserialize( # pylint: disable=empty-docstring,unused-argument - self, node, cstruct - ): + def deserialize(self, node, cstruct): # pylint: disable=empty-docstring """ """ if not cstruct: return colander.null diff --git a/src/wuttaweb/forms/widgets.py b/src/wuttaweb/forms/widgets.py index 108572f..a09edd0 100644 --- a/src/wuttaweb/forms/widgets.py +++ b/src/wuttaweb/forms/widgets.py @@ -438,9 +438,7 @@ class RoleRefsWidget(WuttaCheckboxChoiceWidget): kw["roles"] = roles # url - def url(role): - return self.request.route_url("roles.view", uuid=role.uuid) - + url = lambda role: self.request.route_url("roles.view", uuid=role.uuid) kw["url"] = url # default logic from here diff --git a/src/wuttaweb/grids/base.py b/src/wuttaweb/grids/base.py index fb764c9..0468a6a 100644 --- a/src/wuttaweb/grids/base.py +++ b/src/wuttaweb/grids/base.py @@ -835,7 +835,7 @@ class Grid: # pylint: disable=too-many-instance-attributes This will normalize the list/dict to desired internal format. """ if tools and isinstance(tools, list): - if not any(isinstance(t, (tuple, list)) for t in tools): + if not any([isinstance(t, (tuple, list)) for t in tools]): tools = [(self.app.make_uuid(), t) for t in tools] self.tools = OrderedDict(tools or []) @@ -1058,27 +1058,13 @@ class Grid: # pylint: disable=too-many-instance-attributes # TODO: may need this for String etc. as well? if isinstance(model_property.type, sa.Text): if foldcase: - - def kfunc_folded(obj): - return (obj[key] or "").lower() - - kfunc = kfunc_folded - + kfunc = lambda obj: (obj[key] or "").lower() else: - - def kfunc_standard(obj): - return obj[key] or "" - - kfunc = kfunc_standard - + kfunc = lambda obj: obj[key] or "" if not kfunc: # nb. sorting with this can raise error if data # contains varying types, e.g. str and None - - def kfunc_fallback(obj): - return obj[key] - - kfunc = kfunc_fallback + kfunc = lambda obj: obj[key] # then sort the data and return return sorted(data, key=kfunc, reverse=direction == "desc") @@ -1752,7 +1738,7 @@ class Grid: # pylint: disable=too-many-instance-attributes raise ValueError(f"invalid dest identifier: {dest}") # func to save a setting value to user session - def persist(key, value=settings.get): + def persist(key, value=lambda k: settings.get(k)): assert dest == "session" skey = f"grid.{self.key}.{key}" self.request.session[skey] = value(key) @@ -1946,7 +1932,7 @@ class Grid: # pylint: disable=too-many-instance-attributes # rendering methods ############################## - def render_batch_id(self, obj, key, value): # pylint: disable=unused-argument + def render_batch_id(self, obj, key, value): """ Column renderer for batch ID values. @@ -1960,7 +1946,7 @@ class Grid: # pylint: disable=too-many-instance-attributes batch_id = int(value) return f"{batch_id:08d}" - def render_boolean(self, obj, key, value): # pylint: disable=unused-argument + def render_boolean(self, obj, key, value): """ Column renderer for boolean values. @@ -1975,9 +1961,7 @@ class Grid: # pylint: disable=too-many-instance-attributes """ return self.app.render_boolean(value) - def render_currency( # pylint: disable=unused-argument - self, obj, key, value, **kwargs - ): + def render_currency(self, obj, key, value, **kwargs): """ Column renderer for currency values. @@ -1992,7 +1976,7 @@ class Grid: # pylint: disable=too-many-instance-attributes """ return self.app.render_currency(value, **kwargs) - def render_date(self, obj, key, value): # pylint: disable=unused-argument + def render_date(self, obj, key, value): """ Column renderer for :class:`python:datetime.date` values. @@ -2008,7 +1992,7 @@ class Grid: # pylint: disable=too-many-instance-attributes dt = getattr(obj, key) return self.app.render_date(dt) - def render_datetime(self, obj, key, value): # pylint: disable=unused-argument + def render_datetime(self, obj, key, value): """ Column renderer for :class:`python:datetime.datetime` values. @@ -2051,9 +2035,7 @@ class Grid: # pylint: disable=too-many-instance-attributes return value - def render_percent( # pylint: disable=unused-argument - self, obj, key, value, **kwargs - ): + def render_percent(self, obj, key, value, **kwargs): """ Column renderer for percentage values. @@ -2067,7 +2049,7 @@ class Grid: # pylint: disable=too-many-instance-attributes """ return self.app.render_percent(value, **kwargs) - def render_quantity(self, obj, key, value): # pylint: disable=unused-argument + def render_quantity(self, obj, key, value): """ Column renderer for quantity values. diff --git a/src/wuttaweb/grids/filters.py b/src/wuttaweb/grids/filters.py index 331aebc..9bf2b9f 100644 --- a/src/wuttaweb/grids/filters.py +++ b/src/wuttaweb/grids/filters.py @@ -380,7 +380,7 @@ class GridFilter: # pylint: disable=too-many-instance-attributes # invoke filter method return func(data, value) - def filter_is_any(self, data, value): # pylint: disable=unused-argument + def filter_is_any(self, data, value): """ This is a no-op which always ignores the value and returns the data as-is. @@ -487,13 +487,13 @@ class AlchemyFilter(GridFilter): return query return query.filter(self.model_property <= value) - def filter_is_null(self, query, value): # pylint: disable=unused-argument + def filter_is_null(self, query, value): """ Filter data with an ``IS NULL`` query. The value is ignored. """ return query.filter(self.model_property == None) - def filter_is_not_null(self, query, value): # pylint: disable=unused-argument + def filter_is_not_null(self, query, value): """ Filter data with an ``IS NOT NULL`` query. The value is ignored. @@ -623,21 +623,21 @@ class BooleanAlchemyFilter(AlchemyFilter): return bool(value) return None - def filter_is_true(self, query, value): # pylint: disable=unused-argument + def filter_is_true(self, query, value): """ Filter data with an "is true" condition. The value is ignored. """ return query.filter(self.model_property == True) - def filter_is_false(self, query, value): # pylint: disable=unused-argument + def filter_is_false(self, query, value): """ Filter data with an "is false" condition. The value is ignored. """ return query.filter(self.model_property == False) - def filter_is_false_null(self, query, value): # pylint: disable=unused-argument + def filter_is_false_null(self, query, value): """ Filter data with "is false or null" condition. The value is ignored. diff --git a/src/wuttaweb/handler.py b/src/wuttaweb/handler.py index 3b63022..e3520b5 100644 --- a/src/wuttaweb/handler.py +++ b/src/wuttaweb/handler.py @@ -107,7 +107,7 @@ class WebHandler(GenericHandler): return url return self.get_fanstatic_url(request, static.logo) - def get_menu_handler(self): + def get_menu_handler(self, **kwargs): """ Get the configured :term:`menu handler` for the web app. diff --git a/src/wuttaweb/menus.py b/src/wuttaweb/menus.py index 10e9a97..f8c44c1 100644 --- a/src/wuttaweb/menus.py +++ b/src/wuttaweb/menus.py @@ -89,7 +89,7 @@ class MenuHandler(GenericHandler): # default menu definitions ############################## - def make_menus(self, request): + def make_menus(self, request, **kwargs): """ Generate the full set of menus for the app. @@ -109,7 +109,7 @@ class MenuHandler(GenericHandler): self.make_admin_menu(request), ] - def make_people_menu(self, request): # pylint: disable=unused-argument + def make_people_menu(self, request, **kwargs): """ Generate a typical People menu. @@ -132,7 +132,7 @@ class MenuHandler(GenericHandler): ], } - def make_admin_menu(self, request, **kwargs): # pylint: disable=unused-argument + def make_admin_menu(self, request, **kwargs): """ Generate a typical Admin menu. diff --git a/src/wuttaweb/testing.py b/src/wuttaweb/testing.py index d6f6767..cced4ef 100644 --- a/src/wuttaweb/testing.py +++ b/src/wuttaweb/testing.py @@ -76,7 +76,7 @@ class WebTestCase(DataTestCase): event = MagicMock(request=self.request) subscribers.new_request(event) - def user_getter(request, **kwargs): # pylint: disable=unused-argument + def user_getter(request, **kwargs): pass subscribers.new_request_set_user( diff --git a/src/wuttaweb/views/base.py b/src/wuttaweb/views/base.py index 04ce768..dd00877 100644 --- a/src/wuttaweb/views/base.py +++ b/src/wuttaweb/views/base.py @@ -54,7 +54,7 @@ class View: Reference to the app :term:`config object`. """ - def __init__(self, request, context=None): # pylint: disable=unused-argument + def __init__(self, request, context=None): self.request = request self.config = self.request.wutta_config self.app = self.config.get_app() diff --git a/src/wuttaweb/views/batch.py b/src/wuttaweb/views/batch.py index 3690a20..23441ab 100644 --- a/src/wuttaweb/views/batch.py +++ b/src/wuttaweb/views/batch.py @@ -144,9 +144,7 @@ class BatchMasterView(MasterView): # description g.set_link("description") - def render_batch_id( # pylint: disable=empty-docstring,unused-argument - self, batch, key, value - ): + def render_batch_id(self, batch, key, value): # pylint: disable=empty-docstring """ """ if value: batch_id = int(value) @@ -408,9 +406,7 @@ class BatchMasterView(MasterView): g.set_renderer("status_code", self.render_row_status) - def render_row_status( # pylint: disable=empty-docstring,unused-argument - self, row, key, value - ): + def render_row_status(self, row, key, value): # pylint: disable=empty-docstring """ """ return row.STATUS.get(value, value) diff --git a/src/wuttaweb/views/email.py b/src/wuttaweb/views/email.py index a50977f..34e6a29 100644 --- a/src/wuttaweb/views/email.py +++ b/src/wuttaweb/views/email.py @@ -122,9 +122,7 @@ class EmailSettingView(MasterView): # to g.set_renderer("to", self.render_to_short) - def render_to_short( # pylint: disable=empty-docstring,unused-argument - self, setting, field, value - ): + def render_to_short(self, setting, field, value): # pylint: disable=empty-docstring """ """ recips = value if not recips: diff --git a/src/wuttaweb/views/essential.py b/src/wuttaweb/views/essential.py index b46a658..a35b07d 100644 --- a/src/wuttaweb/views/essential.py +++ b/src/wuttaweb/views/essential.py @@ -42,9 +42,7 @@ That will in turn include the following modules: def defaults(config, **kwargs): - - def mod(spec): - return kwargs.get(spec, spec) + mod = lambda spec: kwargs.get(spec, spec) config.include(mod("wuttaweb.views.common")) config.include(mod("wuttaweb.views.auth")) diff --git a/src/wuttaweb/views/master.py b/src/wuttaweb/views/master.py index a356534..d2086ea 100644 --- a/src/wuttaweb/views/master.py +++ b/src/wuttaweb/views/master.py @@ -814,7 +814,7 @@ class MasterView(View): return self.render_progress(progress) def delete_bulk_thread( # pylint: disable=empty-docstring - self, query, progress=None + self, query, success_url=None, progress=None ): """ """ model_title_plural = self.get_model_title_plural() @@ -859,7 +859,7 @@ class MasterView(View): """ model_title_plural = self.get_model_title_plural() - def delete(obj, i): # pylint: disable=unused-argument + def delete(obj, i): if self.is_deletable(obj): self.delete_instance(obj) @@ -1440,7 +1440,7 @@ class MasterView(View): # grid rendering methods ############################## - def grid_render_bool(self, record, key, value): # pylint: disable=unused-argument + def grid_render_bool(self, record, key, value): """ Custom grid value renderer for "boolean" fields. @@ -1537,9 +1537,7 @@ class MasterView(View): return value - def grid_render_notes( # pylint: disable=unused-argument - self, record, key, value, maxlen=100 - ): + def grid_render_notes(self, record, key, value, maxlen=100): """ Custom grid value renderer for "notes" fields. @@ -1696,7 +1694,7 @@ class MasterView(View): return button - def get_xref_buttons(self, obj): # pylint: disable=unused-argument + def get_xref_buttons(self, obj): """ Should return a list of "cross-reference" buttons to be shown when viewing the given object. @@ -2080,9 +2078,7 @@ class MasterView(View): return self.grid_columns return None - def get_grid_data( # pylint: disable=unused-argument - self, columns=None, session=None - ): + def get_grid_data(self, columns=None, session=None): """ Returns the grid data for the :meth:`index()` view. @@ -2272,7 +2268,7 @@ class MasterView(View): route_prefix = self.get_route_prefix() return self.request.route_url(f"{route_prefix}.{action}", **kw) - def get_action_url_view(self, obj, i): # pylint: disable=unused-argument + def get_action_url_view(self, obj, i): """ Returns the "view" grid action URL for the given object. @@ -2283,7 +2279,7 @@ class MasterView(View): """ return self.get_action_url("view", obj) - def get_action_url_edit(self, obj, i): # pylint: disable=unused-argument + def get_action_url_edit(self, obj, i): """ Returns the "edit" grid action URL for the given object, if applicable. @@ -2300,7 +2296,7 @@ class MasterView(View): return self.get_action_url("edit", obj) return None - def get_action_url_delete(self, obj, i): # pylint: disable=unused-argument + def get_action_url_delete(self, obj, i): """ Returns the "delete" grid action URL for the given object, if applicable. @@ -2317,7 +2313,7 @@ class MasterView(View): return self.get_action_url("delete", obj) return None - def is_editable(self, obj): # pylint: disable=unused-argument + def is_editable(self, obj): """ Returns a boolean indicating whether "edit" should be allowed for the given model instance (and for current user). @@ -2330,7 +2326,7 @@ class MasterView(View): """ return True - def is_deletable(self, obj): # pylint: disable=unused-argument + def is_deletable(self, obj): """ Returns a boolean indicating whether "delete" should be allowed for the given model instance (and for current user). @@ -2811,7 +2807,7 @@ class MasterView(View): [ prop.key for prop in inspector.column_attrs - if all(col.name in keys for col in prop.columns) + if all([col.name in keys for col in prop.columns]) ] ) diff --git a/src/wuttaweb/views/people.py b/src/wuttaweb/views/people.py index d8cc189..f9de00e 100644 --- a/src/wuttaweb/views/people.py +++ b/src/wuttaweb/views/people.py @@ -119,19 +119,13 @@ class PersonView(MasterView): ) if self.request.has_perm("users.view"): - - def view_url(user, i): # pylint: disable=unused-argument - return self.request.route_url("users.view", uuid=user.uuid) - - grid.add_action("view", icon="eye", url=view_url) + url = lambda user, i: self.request.route_url("users.view", uuid=user.uuid) + grid.add_action("view", icon="eye", url=url) grid.set_link("username") if self.request.has_perm("users.edit"): - - def edit_url(user, i): # pylint: disable=unused-argument - return self.request.route_url("users.edit", uuid=user.uuid) - - grid.add_action("edit", url=edit_url) + url = lambda user, i: self.request.route_url("users.edit", uuid=user.uuid) + grid.add_action("edit", url=url) return grid diff --git a/src/wuttaweb/views/roles.py b/src/wuttaweb/views/roles.py index 62d2dd0..2d19ef1 100644 --- a/src/wuttaweb/views/roles.py +++ b/src/wuttaweb/views/roles.py @@ -160,20 +160,14 @@ class RoleView(MasterView): ) if self.request.has_perm("users.view"): - - def view_url(user, i): # pylint: disable=unused-argument - return self.request.route_url("users.view", uuid=user.uuid) - - grid.add_action("view", icon="eye", url=view_url) + url = lambda user, i: self.request.route_url("users.view", uuid=user.uuid) + grid.add_action("view", icon="eye", url=url) grid.set_link("person") grid.set_link("username") if self.request.has_perm("users.edit"): - - def edit_url(user, i): # pylint: disable=unused-argument - return self.request.route_url("users.edit", uuid=user.uuid) - - grid.add_action("edit", url=edit_url) + url = lambda user, i: self.request.route_url("users.edit", uuid=user.uuid) + grid.add_action("edit", url=url) return grid diff --git a/src/wuttaweb/views/upgrades.py b/src/wuttaweb/views/upgrades.py index bc4e29c..a3bc205 100644 --- a/src/wuttaweb/views/upgrades.py +++ b/src/wuttaweb/views/upgrades.py @@ -110,9 +110,7 @@ class UpgradeView(MasterView): ) g.set_filter("executed_by", Executor.username, label="Executed By Username") - def grid_row_class( # pylint: disable=empty-docstring,unused-argument - self, upgrade, data, i - ): + def grid_row_class(self, upgrade, data, i): # pylint: disable=empty-docstring """ """ enum = self.app.enum if upgrade.status == enum.UpgradeStatus.EXECUTING: @@ -323,7 +321,7 @@ class UpgradeView(MasterView): size = os.path.getsize(path) - offset if size > 0: # with open(path, 'rb') as f: - with open(path, "rt", encoding="utf_8") as f: + with open(path) as f: f.seek(offset) chunk = f.read(size) # data['stdout'] = chunk.decode('utf8').replace('\n', '
') diff --git a/src/wuttaweb/views/users.py b/src/wuttaweb/views/users.py index eefc4af..cd09c66 100644 --- a/src/wuttaweb/views/users.py +++ b/src/wuttaweb/views/users.py @@ -98,9 +98,7 @@ class UserView(MasterView): g.set_sorter("person", model.Person.full_name) g.set_filter("person", model.Person.full_name, label="Person Full Name") - def grid_row_class( # pylint: disable=empty-docstring,unused-argument - self, user, data, i - ): + def grid_row_class(self, user, data, i): # pylint: disable=empty-docstring """ """ if not user.active: return "has-background-warning" diff --git a/tests/views/test_people.py b/tests/views/test_people.py index 5167534..eed285a 100644 --- a/tests/views/test_people.py +++ b/tests/views/test_people.py @@ -54,15 +54,9 @@ class TestPersonView(WebTestCase): self.assertIsInstance(form.widgets["users"], GridWidget) def test_make_users_grid(self): - self.pyramid_config.add_route("users.view", "/users/{uuid}/view") - self.pyramid_config.add_route("users.edit", "/users/{uuid}/edit") model = self.app.model view = self.make_view() person = model.Person(full_name="John Doe") - self.session.add(person) - user = model.User(username="john", person=person) - self.session.add(user) - self.session.commit() # basic grid = view.make_users_grid(person) @@ -79,9 +73,6 @@ class TestPersonView(WebTestCase): self.assertEqual(grid.actions[0].key, "view") self.assertEqual(grid.actions[1].key, "edit") - # render grid to ensure coverage for link urls - grid.render_vue_template() - def test_objectify(self): model = self.app.model view = self.make_view() diff --git a/tests/views/test_roles.py b/tests/views/test_roles.py index 0eef4d2..d023043 100644 --- a/tests/views/test_roles.py +++ b/tests/views/test_roles.py @@ -95,16 +95,9 @@ class TestRoleView(WebTestCase): self.assertIsNotNone(form.validators["name"]) def test_make_users_grid(self): - self.pyramid_config.add_route("users.view", "/users/{uuid}/view") - self.pyramid_config.add_route("users.edit", "/users/{uuid}/edit") model = self.app.model view = self.make_view() role = model.Role(name="Manager") - self.session.add(role) - user = model.User(username="freddie") - user.roles.append(role) - self.session.add(user) - self.session.commit() # basic grid = view.make_users_grid(role) @@ -122,9 +115,6 @@ class TestRoleView(WebTestCase): self.assertEqual(grid.actions[0].key, "view") self.assertEqual(grid.actions[1].key, "edit") - # render grid to ensure coverage for link urls - grid.render_vue_template() - def test_unique_name(self): model = self.app.model view = self.make_view()